ath9k: fix 802.11g conformance test limit typo
[linux-2.6] / drivers / net / netxen / netxen_nic_niu.c
1 /*
2  * Copyright (C) 2003 - 2006 NetXen, Inc.
3  * All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18  * MA  02111-1307, USA.
19  *
20  * The full GNU General Public License is included in this distribution
21  * in the file called LICENSE.
22  *
23  * Contact Information:
24  *    info@netxen.com
25  * NetXen,
26  * 3965 Freedom Circle, Fourth floor,
27  * Santa Clara, CA 95054
28  *
29  *
30  * Provides access to the Network Interface Unit h/w block.
31  *
32  */
33
34 #include "netxen_nic.h"
35
36 #define NETXEN_GB_MAC_SOFT_RESET        0x80000000
37 #define NETXEN_GB_MAC_RESET_PROT_BLK   0x000F0000
38 #define NETXEN_GB_MAC_ENABLE_TX_RX     0x00000005
39 #define NETXEN_GB_MAC_PAUSED_FRMS      0x00000020
40
41 static long phy_lock_timeout = 100000000;
42
43 static int phy_lock(struct netxen_adapter *adapter)
44 {
45         int i;
46         int done = 0, timeout = 0;
47
48         while (!done) {
49                 done = netxen_nic_reg_read(adapter,
50                                 NETXEN_PCIE_REG(PCIE_SEM3_LOCK));
51                 if (done == 1)
52                         break;
53                 if (timeout >= phy_lock_timeout) {
54                         return -1;
55                 }
56                 timeout++;
57                 if (!in_atomic())
58                         schedule();
59                 else {
60                         for (i = 0; i < 20; i++)
61                                 cpu_relax();
62                 }
63         }
64
65         netxen_crb_writelit_adapter(adapter,
66                         NETXEN_PHY_LOCK_ID, PHY_LOCK_DRIVER);
67         return 0;
68 }
69
70 static int phy_unlock(struct netxen_adapter *adapter)
71 {
72         adapter->pci_read_immediate(adapter, NETXEN_PCIE_REG(PCIE_SEM3_UNLOCK));
73
74         return 0;
75 }
76
77 /*
78  * netxen_niu_gbe_phy_read - read a register from the GbE PHY via
79  * mii management interface.
80  *
81  * Note: The MII management interface goes through port 0.
82  *      Individual phys are addressed as follows:
83  * @param phy  [15:8]  phy id
84  * @param reg  [7:0]   register number
85  *
86  * @returns  0 on success
87  *        -1 on error
88  *
89  */
90 int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg,
91                                 __u32 * readval)
92 {
93         long timeout = 0;
94         long result = 0;
95         long restore = 0;
96         long phy = adapter->physical_port;
97         __u32 address;
98         __u32 command;
99         __u32 status;
100         __u32 mac_cfg0;
101
102         if (phy_lock(adapter) != 0) {
103                 return -1;
104         }
105
106         /*
107          * MII mgmt all goes through port 0 MAC interface,
108          * so it cannot be in reset
109          */
110
111         if (adapter->hw_read_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0),
112                                   &mac_cfg0, 4))
113                 return -EIO;
114         if (netxen_gb_get_soft_reset(mac_cfg0)) {
115                 __u32 temp;
116                 temp = 0;
117                 netxen_gb_tx_reset_pb(temp);
118                 netxen_gb_rx_reset_pb(temp);
119                 netxen_gb_tx_reset_mac(temp);
120                 netxen_gb_rx_reset_mac(temp);
121                 if (adapter->hw_write_wx(adapter,
122                                            NETXEN_NIU_GB_MAC_CONFIG_0(0),
123                                            &temp, 4))
124                         return -EIO;
125                 restore = 1;
126         }
127
128         address = 0;
129         netxen_gb_mii_mgmt_reg_addr(address, reg);
130         netxen_gb_mii_mgmt_phy_addr(address, phy);
131         if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0),
132                                    &address, 4))
133                 return -EIO;
134         command = 0;            /* turn off any prior activity */
135         if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0),
136                                    &command, 4))
137                 return -EIO;
138         /* send read command */
139         netxen_gb_mii_mgmt_set_read_cycle(command);
140         if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0),
141                                    &command, 4))
142                 return -EIO;
143
144         status = 0;
145         do {
146                 if (adapter->hw_read_wx(adapter,
147                                           NETXEN_NIU_GB_MII_MGMT_INDICATE(0),
148                                           &status, 4))
149                         return -EIO;
150                 timeout++;
151         } while ((netxen_get_gb_mii_mgmt_busy(status)
152                   || netxen_get_gb_mii_mgmt_notvalid(status))
153                  && (timeout++ < NETXEN_NIU_PHY_WAITMAX));
154
155         if (timeout < NETXEN_NIU_PHY_WAITMAX) {
156                 if (adapter->hw_read_wx(adapter,
157                                           NETXEN_NIU_GB_MII_MGMT_STATUS(0),
158                                           readval, 4))
159                         return -EIO;
160                 result = 0;
161         } else
162                 result = -1;
163
164         if (restore)
165                 if (adapter->hw_write_wx(adapter,
166                                            NETXEN_NIU_GB_MAC_CONFIG_0(0),
167                                            &mac_cfg0, 4))
168                         return -EIO;
169         phy_unlock(adapter);
170         return result;
171 }
172
173 /*
174  * netxen_niu_gbe_phy_write - write a register to the GbE PHY via
175  * mii management interface.
176  *
177  * Note: The MII management interface goes through port 0.
178  *      Individual phys are addressed as follows:
179  * @param phy      [15:8]  phy id
180  * @param reg      [7:0]   register number
181  *
182  * @returns  0 on success
183  *        -1 on error
184  *
185  */
186 int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long reg,
187                                 __u32 val)
188 {
189         long timeout = 0;
190         long result = 0;
191         long restore = 0;
192         long phy = adapter->physical_port;
193         __u32 address;
194         __u32 command;
195         __u32 status;
196         __u32 mac_cfg0;
197
198         /*
199          * MII mgmt all goes through port 0 MAC interface, so it
200          * cannot be in reset
201          */
202
203         if (adapter->hw_read_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0),
204                                   &mac_cfg0, 4))
205                 return -EIO;
206         if (netxen_gb_get_soft_reset(mac_cfg0)) {
207                 __u32 temp;
208                 temp = 0;
209                 netxen_gb_tx_reset_pb(temp);
210                 netxen_gb_rx_reset_pb(temp);
211                 netxen_gb_tx_reset_mac(temp);
212                 netxen_gb_rx_reset_mac(temp);
213
214                 if (adapter->hw_write_wx(adapter,
215                                            NETXEN_NIU_GB_MAC_CONFIG_0(0),
216                                            &temp, 4))
217                         return -EIO;
218                 restore = 1;
219         }
220
221         command = 0;            /* turn off any prior activity */
222         if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0),
223                                    &command, 4))
224                 return -EIO;
225
226         address = 0;
227         netxen_gb_mii_mgmt_reg_addr(address, reg);
228         netxen_gb_mii_mgmt_phy_addr(address, phy);
229         if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0),
230                                    &address, 4))
231                 return -EIO;
232
233         if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_CTRL(0),
234                                    &val, 4))
235                 return -EIO;
236
237         status = 0;
238         do {
239                 if (adapter->hw_read_wx(adapter,
240                                           NETXEN_NIU_GB_MII_MGMT_INDICATE(0),
241                                           &status, 4))
242                         return -EIO;
243                 timeout++;
244         } while ((netxen_get_gb_mii_mgmt_busy(status))
245                  && (timeout++ < NETXEN_NIU_PHY_WAITMAX));
246
247         if (timeout < NETXEN_NIU_PHY_WAITMAX)
248                 result = 0;
249         else
250                 result = -EIO;
251
252         /* restore the state of port 0 MAC in case we tampered with it */
253         if (restore)
254                 if (adapter->hw_write_wx(adapter,
255                                            NETXEN_NIU_GB_MAC_CONFIG_0(0),
256                                            &mac_cfg0, 4))
257                         return -EIO;
258
259         return result;
260 }
261
262 int netxen_niu_xgbe_enable_phy_interrupts(struct netxen_adapter *adapter)
263 {
264         netxen_crb_writelit_adapter(adapter, NETXEN_NIU_INT_MASK, 0x3f);
265         return 0;
266 }
267
268 int netxen_niu_gbe_enable_phy_interrupts(struct netxen_adapter *adapter)
269 {
270         int result = 0;
271         __u32 enable = 0;
272         netxen_set_phy_int_link_status_changed(enable);
273         netxen_set_phy_int_autoneg_completed(enable);
274         netxen_set_phy_int_speed_changed(enable);
275
276         if (0 !=
277             netxen_niu_gbe_phy_write(adapter,
278                                      NETXEN_NIU_GB_MII_MGMT_ADDR_INT_ENABLE,
279                                      enable))
280                 result = -EIO;
281
282         return result;
283 }
284
285 int netxen_niu_xgbe_disable_phy_interrupts(struct netxen_adapter *adapter)
286 {
287         netxen_crb_writelit_adapter(adapter, NETXEN_NIU_INT_MASK, 0x7f);
288         return 0;
289 }
290
291 int netxen_niu_gbe_disable_phy_interrupts(struct netxen_adapter *adapter)
292 {
293         int result = 0;
294         if (0 !=
295             netxen_niu_gbe_phy_write(adapter,
296                                      NETXEN_NIU_GB_MII_MGMT_ADDR_INT_ENABLE, 0))
297                 result = -EIO;
298
299         return result;
300 }
301
302 static int netxen_niu_gbe_clear_phy_interrupts(struct netxen_adapter *adapter)
303 {
304         int result = 0;
305         if (0 !=
306             netxen_niu_gbe_phy_write(adapter,
307                                      NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS,
308                                      -EIO))
309                 result = -EIO;
310
311         return result;
312 }
313
314 /*
315  * netxen_niu_gbe_set_mii_mode- Set 10/100 Mbit Mode for GbE MAC
316  *
317  */
318 static void netxen_niu_gbe_set_mii_mode(struct netxen_adapter *adapter,
319                                         int port, long enable)
320 {
321         netxen_crb_writelit_adapter(adapter, NETXEN_NIU_MODE, 0x2);
322         netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
323                                     0x80000000);
324         netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
325                                     0x0000f0025);
326         netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_1(port),
327                                     0xf1ff);
328         netxen_crb_writelit_adapter(adapter,
329                                     NETXEN_NIU_GB0_GMII_MODE + (port << 3), 0);
330         netxen_crb_writelit_adapter(adapter,
331                                     NETXEN_NIU_GB0_MII_MODE + (port << 3), 1);
332         netxen_crb_writelit_adapter(adapter,
333                                     (NETXEN_NIU_GB0_HALF_DUPLEX + port * 4), 0);
334         netxen_crb_writelit_adapter(adapter,
335                                     NETXEN_NIU_GB_MII_MGMT_CONFIG(port), 0x7);
336
337         if (enable) {
338                 /*
339                  * Do NOT enable flow control until a suitable solution for
340                  *  shutting down pause frames is found.
341                  */
342                 netxen_crb_writelit_adapter(adapter,
343                                             NETXEN_NIU_GB_MAC_CONFIG_0(port),
344                                             0x5);
345         }
346
347         if (netxen_niu_gbe_enable_phy_interrupts(adapter))
348                 printk(KERN_ERR PFX "ERROR enabling PHY interrupts\n");
349         if (netxen_niu_gbe_clear_phy_interrupts(adapter))
350                 printk(KERN_ERR PFX "ERROR clearing PHY interrupts\n");
351 }
352
353 /*
354  * netxen_niu_gbe_set_gmii_mode- Set GbE Mode for GbE MAC
355  */
356 static void netxen_niu_gbe_set_gmii_mode(struct netxen_adapter *adapter,
357                                          int port, long enable)
358 {
359         netxen_crb_writelit_adapter(adapter, NETXEN_NIU_MODE, 0x2);
360         netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
361                                     0x80000000);
362         netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
363                                     0x0000f0025);
364         netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_1(port),
365                                     0xf2ff);
366         netxen_crb_writelit_adapter(adapter,
367                                     NETXEN_NIU_GB0_MII_MODE + (port << 3), 0);
368         netxen_crb_writelit_adapter(adapter,
369                                     NETXEN_NIU_GB0_GMII_MODE + (port << 3), 1);
370         netxen_crb_writelit_adapter(adapter,
371                                     (NETXEN_NIU_GB0_HALF_DUPLEX + port * 4), 0);
372         netxen_crb_writelit_adapter(adapter,
373                                     NETXEN_NIU_GB_MII_MGMT_CONFIG(port), 0x7);
374
375         if (enable) {
376                 /*
377                  * Do NOT enable flow control until a suitable solution for
378                  *  shutting down pause frames is found.
379                  */
380                 netxen_crb_writelit_adapter(adapter,
381                                             NETXEN_NIU_GB_MAC_CONFIG_0(port),
382                                             0x5);
383         }
384
385         if (netxen_niu_gbe_enable_phy_interrupts(adapter))
386                 printk(KERN_ERR PFX "ERROR enabling PHY interrupts\n");
387         if (netxen_niu_gbe_clear_phy_interrupts(adapter))
388                 printk(KERN_ERR PFX "ERROR clearing PHY interrupts\n");
389 }
390
391 int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port)
392 {
393         int result = 0;
394         __u32 status;
395
396         if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
397                 return 0;
398
399         if (adapter->disable_phy_interrupts)
400                 adapter->disable_phy_interrupts(adapter);
401         mdelay(2);
402
403         if (0 == netxen_niu_gbe_phy_read(adapter,
404                         NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, &status)) {
405                 if (netxen_get_phy_link(status)) {
406                         if (netxen_get_phy_speed(status) == 2) {
407                                 netxen_niu_gbe_set_gmii_mode(adapter, port, 1);
408                         } else if ((netxen_get_phy_speed(status) == 1)
409                                    || (netxen_get_phy_speed(status) == 0)) {
410                                 netxen_niu_gbe_set_mii_mode(adapter, port, 1);
411                         } else {
412                                 result = -1;
413                         }
414
415                 } else {
416                         /*
417                          * We don't have link. Cable  must be unconnected.
418                          * Enable phy interrupts so we take action when
419                          * plugged in.
420                          */
421
422                         netxen_crb_writelit_adapter(adapter,
423                                                     NETXEN_NIU_GB_MAC_CONFIG_0
424                                                     (port),
425                                                     NETXEN_GB_MAC_SOFT_RESET);
426                         netxen_crb_writelit_adapter(adapter,
427                                                     NETXEN_NIU_GB_MAC_CONFIG_0
428                                                     (port),
429                                                     NETXEN_GB_MAC_RESET_PROT_BLK
430                                                     | NETXEN_GB_MAC_ENABLE_TX_RX
431                                                     |
432                                                     NETXEN_GB_MAC_PAUSED_FRMS);
433                         if (netxen_niu_gbe_clear_phy_interrupts(adapter))
434                                 printk(KERN_ERR PFX
435                                        "ERROR clearing PHY interrupts\n");
436                         if (netxen_niu_gbe_enable_phy_interrupts(adapter))
437                                 printk(KERN_ERR PFX
438                                        "ERROR enabling PHY interrupts\n");
439                         if (netxen_niu_gbe_clear_phy_interrupts(adapter))
440                                 printk(KERN_ERR PFX
441                                        "ERROR clearing PHY interrupts\n");
442                         result = -1;
443                 }
444         } else {
445                 result = -EIO;
446         }
447         return result;
448 }
449
450 int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port)
451 {
452         if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
453                 netxen_crb_writelit_adapter(adapter,
454                         NETXEN_NIU_XGE_CONFIG_1+(0x10000*port), 0x1447);
455                 netxen_crb_writelit_adapter(adapter,
456                         NETXEN_NIU_XGE_CONFIG_0+(0x10000*port), 0x5);
457         }
458
459         return 0;
460 }
461
462 /*
463  * Return the current station MAC address.
464  * Note that the passed-in value must already be in network byte order.
465  */
466 static int netxen_niu_macaddr_get(struct netxen_adapter *adapter,
467                                   netxen_ethernet_macaddr_t * addr)
468 {
469         u32 stationhigh;
470         u32 stationlow;
471         int phy = adapter->physical_port;
472         u8 val[8];
473
474         if (addr == NULL)
475                 return -EINVAL;
476         if ((phy < 0) || (phy > 3))
477                 return -EINVAL;
478
479         if (adapter->hw_read_wx(adapter, NETXEN_NIU_GB_STATION_ADDR_0(phy),
480                                   &stationhigh, 4))
481                 return -EIO;
482         if (adapter->hw_read_wx(adapter, NETXEN_NIU_GB_STATION_ADDR_1(phy),
483                                   &stationlow, 4))
484                 return -EIO;
485         ((__le32 *)val)[1] = cpu_to_le32(stationhigh);
486         ((__le32 *)val)[0] = cpu_to_le32(stationlow);
487
488         memcpy(addr, val + 2, 6);
489
490         return 0;
491 }
492
493 /*
494  * Set the station MAC address.
495  * Note that the passed-in value must already be in network byte order.
496  */
497 int netxen_niu_macaddr_set(struct netxen_adapter *adapter,
498                            netxen_ethernet_macaddr_t addr)
499 {
500         u8 temp[4];
501         u32 val;
502         int phy = adapter->physical_port;
503         unsigned char mac_addr[6];
504         int i;
505
506         if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
507                 return 0;
508
509         for (i = 0; i < 10; i++) {
510                 temp[0] = temp[1] = 0;
511                 memcpy(temp + 2, addr, 2);
512                 val = le32_to_cpu(*(__le32 *)temp);
513                 if (adapter->hw_write_wx(adapter,
514                                 NETXEN_NIU_GB_STATION_ADDR_1(phy), &val, 4))
515                         return -EIO;
516
517                 memcpy(temp, ((u8 *) addr) + 2, sizeof(__le32));
518                 val = le32_to_cpu(*(__le32 *)temp);
519                 if (adapter->hw_write_wx(adapter,
520                                 NETXEN_NIU_GB_STATION_ADDR_0(phy), &val, 4))
521                         return -2;
522
523                 netxen_niu_macaddr_get(adapter,
524                                        (netxen_ethernet_macaddr_t *) mac_addr);
525                 if (memcmp(mac_addr, addr, 6) == 0)
526                         break;
527         }
528
529         if (i == 10) {
530                 printk(KERN_ERR "%s: cannot set Mac addr for %s\n",
531                        netxen_nic_driver_name, adapter->netdev->name);
532                 printk(KERN_ERR "MAC address set: %pM.\n", addr);
533                 printk(KERN_ERR "MAC address get: %pM.\n", mac_addr);
534         }
535         return 0;
536 }
537
538 /* Disable a GbE interface */
539 int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter)
540 {
541         __u32 mac_cfg0;
542         u32 port = adapter->physical_port;
543
544         if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
545                 return 0;
546
547         if (port > NETXEN_NIU_MAX_GBE_PORTS)
548                 return -EINVAL;
549         mac_cfg0 = 0;
550         netxen_gb_soft_reset(mac_cfg0);
551         if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
552                                    &mac_cfg0, 4))
553                 return -EIO;
554         return 0;
555 }
556
557 /* Disable an XG interface */
558 int netxen_niu_disable_xg_port(struct netxen_adapter *adapter)
559 {
560         __u32 mac_cfg;
561         u32 port = adapter->physical_port;
562
563         if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
564                 return 0;
565
566         if (port > NETXEN_NIU_MAX_XG_PORTS)
567                 return -EINVAL;
568
569         mac_cfg = 0;
570         if (adapter->hw_write_wx(adapter,
571                 NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port), &mac_cfg, 4))
572                 return -EIO;
573         return 0;
574 }
575
576 /* Set promiscuous mode for a GbE interface */
577 int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter,
578                 u32 mode)
579 {
580         __u32 reg;
581         u32 port = adapter->physical_port;
582
583         if (port > NETXEN_NIU_MAX_GBE_PORTS)
584                 return -EINVAL;
585
586         /* save previous contents */
587         if (adapter->hw_read_wx(adapter, NETXEN_NIU_GB_DROP_WRONGADDR,
588                                   &reg, 4))
589                 return -EIO;
590         if (mode == NETXEN_NIU_PROMISC_MODE) {
591                 switch (port) {
592                 case 0:
593                         netxen_clear_gb_drop_gb0(reg);
594                         break;
595                 case 1:
596                         netxen_clear_gb_drop_gb1(reg);
597                         break;
598                 case 2:
599                         netxen_clear_gb_drop_gb2(reg);
600                         break;
601                 case 3:
602                         netxen_clear_gb_drop_gb3(reg);
603                         break;
604                 default:
605                         return -EIO;
606                 }
607         } else {
608                 switch (port) {
609                 case 0:
610                         netxen_set_gb_drop_gb0(reg);
611                         break;
612                 case 1:
613                         netxen_set_gb_drop_gb1(reg);
614                         break;
615                 case 2:
616                         netxen_set_gb_drop_gb2(reg);
617                         break;
618                 case 3:
619                         netxen_set_gb_drop_gb3(reg);
620                         break;
621                 default:
622                         return -EIO;
623                 }
624         }
625         if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_DROP_WRONGADDR,
626                                    &reg, 4))
627                 return -EIO;
628         return 0;
629 }
630
631 /*
632  * Set the MAC address for an XG port
633  * Note that the passed-in value must already be in network byte order.
634  */
635 int netxen_niu_xg_macaddr_set(struct netxen_adapter *adapter,
636                               netxen_ethernet_macaddr_t addr)
637 {
638         int phy = adapter->physical_port;
639         u8 temp[4];
640         u32 val;
641
642         if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
643                 return 0;
644
645         if ((phy < 0) || (phy > NETXEN_NIU_MAX_XG_PORTS))
646                 return -EIO;
647
648         temp[0] = temp[1] = 0;
649         switch (phy) {
650         case 0:
651             memcpy(temp + 2, addr, 2);
652             val = le32_to_cpu(*(__le32 *)temp);
653             if (adapter->hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_1,
654                                 &val, 4))
655                 return -EIO;
656
657             memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32));
658             val = le32_to_cpu(*(__le32 *)temp);
659             if (adapter->hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_HI,
660                                 &val, 4))
661                 return -EIO;
662             break;
663
664         case 1:
665             memcpy(temp + 2, addr, 2);
666             val = le32_to_cpu(*(__le32 *)temp);
667             if (adapter->hw_write_wx(adapter, NETXEN_NIU_XG1_STATION_ADDR_0_1,
668                                 &val, 4))
669                 return -EIO;
670
671             memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32));
672             val = le32_to_cpu(*(__le32 *)temp);
673             if (adapter->hw_write_wx(adapter, NETXEN_NIU_XG1_STATION_ADDR_0_HI,
674                                 &val, 4))
675                 return -EIO;
676             break;
677
678         default:
679             printk(KERN_ERR "Unknown port %d\n", phy);
680             break;
681         }
682
683         return 0;
684 }
685
686 int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter,
687                 u32 mode)
688 {
689         __u32 reg;
690         u32 port = adapter->physical_port;
691
692         if (port > NETXEN_NIU_MAX_XG_PORTS)
693                 return -EINVAL;
694
695         if (adapter->hw_read_wx(adapter,
696                 NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), &reg, 4))
697                         return -EIO;
698         if (mode == NETXEN_NIU_PROMISC_MODE)
699                 reg = (reg | 0x2000UL);
700         else
701                 reg = (reg & ~0x2000UL);
702
703         if (mode == NETXEN_NIU_ALLMULTI_MODE)
704                 reg = (reg | 0x1000UL);
705         else
706                 reg = (reg & ~0x1000UL);
707
708         netxen_crb_writelit_adapter(adapter,
709                 NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), reg);
710
711         return 0;
712 }