]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/net/netxen/netxen_nic_niu.c
netxen: add 2MB PCI memory support
[linux-2.6-omap-h63xx.git] / 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 #if 0
303 int netxen_niu_xgbe_clear_phy_interrupts(struct netxen_adapter *adapter)
304 {
305         netxen_crb_writelit_adapter(adapter, NETXEN_NIU_ACTIVE_INT, -1);
306         return 0;
307 }
308 #endif  /*  0  */
309
310 static int netxen_niu_gbe_clear_phy_interrupts(struct netxen_adapter *adapter)
311 {
312         int result = 0;
313         if (0 !=
314             netxen_niu_gbe_phy_write(adapter,
315                                      NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS,
316                                      -EIO))
317                 result = -EIO;
318
319         return result;
320 }
321
322 /*
323  * netxen_niu_gbe_set_mii_mode- Set 10/100 Mbit Mode for GbE MAC
324  *
325  */
326 static void netxen_niu_gbe_set_mii_mode(struct netxen_adapter *adapter,
327                                         int port, long enable)
328 {
329         netxen_crb_writelit_adapter(adapter, NETXEN_NIU_MODE, 0x2);
330         netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
331                                     0x80000000);
332         netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
333                                     0x0000f0025);
334         netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_1(port),
335                                     0xf1ff);
336         netxen_crb_writelit_adapter(adapter,
337                                     NETXEN_NIU_GB0_GMII_MODE + (port << 3), 0);
338         netxen_crb_writelit_adapter(adapter,
339                                     NETXEN_NIU_GB0_MII_MODE + (port << 3), 1);
340         netxen_crb_writelit_adapter(adapter,
341                                     (NETXEN_NIU_GB0_HALF_DUPLEX + port * 4), 0);
342         netxen_crb_writelit_adapter(adapter,
343                                     NETXEN_NIU_GB_MII_MGMT_CONFIG(port), 0x7);
344
345         if (enable) {
346                 /*
347                  * Do NOT enable flow control until a suitable solution for
348                  *  shutting down pause frames is found.
349                  */
350                 netxen_crb_writelit_adapter(adapter,
351                                             NETXEN_NIU_GB_MAC_CONFIG_0(port),
352                                             0x5);
353         }
354
355         if (netxen_niu_gbe_enable_phy_interrupts(adapter))
356                 printk(KERN_ERR PFX "ERROR enabling PHY interrupts\n");
357         if (netxen_niu_gbe_clear_phy_interrupts(adapter))
358                 printk(KERN_ERR PFX "ERROR clearing PHY interrupts\n");
359 }
360
361 /*
362  * netxen_niu_gbe_set_gmii_mode- Set GbE Mode for GbE MAC
363  */
364 static void netxen_niu_gbe_set_gmii_mode(struct netxen_adapter *adapter,
365                                          int port, long enable)
366 {
367         netxen_crb_writelit_adapter(adapter, NETXEN_NIU_MODE, 0x2);
368         netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
369                                     0x80000000);
370         netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
371                                     0x0000f0025);
372         netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_1(port),
373                                     0xf2ff);
374         netxen_crb_writelit_adapter(adapter,
375                                     NETXEN_NIU_GB0_MII_MODE + (port << 3), 0);
376         netxen_crb_writelit_adapter(adapter,
377                                     NETXEN_NIU_GB0_GMII_MODE + (port << 3), 1);
378         netxen_crb_writelit_adapter(adapter,
379                                     (NETXEN_NIU_GB0_HALF_DUPLEX + port * 4), 0);
380         netxen_crb_writelit_adapter(adapter,
381                                     NETXEN_NIU_GB_MII_MGMT_CONFIG(port), 0x7);
382
383         if (enable) {
384                 /*
385                  * Do NOT enable flow control until a suitable solution for
386                  *  shutting down pause frames is found.
387                  */
388                 netxen_crb_writelit_adapter(adapter,
389                                             NETXEN_NIU_GB_MAC_CONFIG_0(port),
390                                             0x5);
391         }
392
393         if (netxen_niu_gbe_enable_phy_interrupts(adapter))
394                 printk(KERN_ERR PFX "ERROR enabling PHY interrupts\n");
395         if (netxen_niu_gbe_clear_phy_interrupts(adapter))
396                 printk(KERN_ERR PFX "ERROR clearing PHY interrupts\n");
397 }
398
399 int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port)
400 {
401         int result = 0;
402         __u32 status;
403         if (adapter->disable_phy_interrupts)
404                 adapter->disable_phy_interrupts(adapter);
405         mdelay(2);
406
407         if (0 ==
408             netxen_niu_gbe_phy_read(adapter,
409                                     NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
410                                     &status)) {
411                 if (netxen_get_phy_link(status)) {
412                         if (netxen_get_phy_speed(status) == 2) {
413                                 netxen_niu_gbe_set_gmii_mode(adapter, port, 1);
414                         } else if ((netxen_get_phy_speed(status) == 1)
415                                    || (netxen_get_phy_speed(status) == 0)) {
416                                 netxen_niu_gbe_set_mii_mode(adapter, port, 1);
417                         } else {
418                                 result = -1;
419                         }
420
421                 } else {
422                         /*
423                          * We don't have link. Cable  must be unconnected.
424                          * Enable phy interrupts so we take action when
425                          * plugged in.
426                          */
427
428                         netxen_crb_writelit_adapter(adapter,
429                                                     NETXEN_NIU_GB_MAC_CONFIG_0
430                                                     (port),
431                                                     NETXEN_GB_MAC_SOFT_RESET);
432                         netxen_crb_writelit_adapter(adapter,
433                                                     NETXEN_NIU_GB_MAC_CONFIG_0
434                                                     (port),
435                                                     NETXEN_GB_MAC_RESET_PROT_BLK
436                                                     | NETXEN_GB_MAC_ENABLE_TX_RX
437                                                     |
438                                                     NETXEN_GB_MAC_PAUSED_FRMS);
439                         if (netxen_niu_gbe_clear_phy_interrupts(adapter))
440                                 printk(KERN_ERR PFX
441                                        "ERROR clearing PHY interrupts\n");
442                         if (netxen_niu_gbe_enable_phy_interrupts(adapter))
443                                 printk(KERN_ERR PFX
444                                        "ERROR enabling PHY interrupts\n");
445                         if (netxen_niu_gbe_clear_phy_interrupts(adapter))
446                                 printk(KERN_ERR PFX
447                                        "ERROR clearing PHY interrupts\n");
448                         result = -1;
449                 }
450         } else {
451                 result = -EIO;
452         }
453         return result;
454 }
455
456 int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port)
457 {
458         u32 portnum = adapter->physical_port;
459
460         netxen_crb_writelit_adapter(adapter,
461                 NETXEN_NIU_XGE_CONFIG_1+(0x10000*portnum), 0x1447);
462         netxen_crb_writelit_adapter(adapter,
463                 NETXEN_NIU_XGE_CONFIG_0+(0x10000*portnum), 0x5);
464
465         return 0;
466 }
467
468 #if 0
469 /*
470  * netxen_niu_gbe_handle_phy_interrupt - Handles GbE PHY interrupts
471  * @param enable 0 means don't enable the port
472  *               1 means enable (or re-enable) the port
473  */
474 int netxen_niu_gbe_handle_phy_interrupt(struct netxen_adapter *adapter,
475                                         int port, long enable)
476 {
477         int result = 0;
478         __u32 int_src;
479
480         printk(KERN_INFO PFX "NETXEN: Handling PHY interrupt on port %d"
481                " (device enable = %d)\n", (int)port, (int)enable);
482
483         /*
484          * The read of the PHY INT status will clear the pending
485          * interrupt status
486          */
487         if (netxen_niu_gbe_phy_read(adapter,
488                                     NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS,
489                                     &int_src) != 0)
490                 result = -EINVAL;
491         else {
492                 printk(KERN_INFO PFX "PHY Interrupt source = 0x%x \n", int_src);
493                 if (netxen_get_phy_int_jabber(int_src))
494                         printk(KERN_INFO PFX "jabber Interrupt ");
495                 if (netxen_get_phy_int_polarity_changed(int_src))
496                         printk(KERN_INFO PFX "polarity changed ");
497                 if (netxen_get_phy_int_energy_detect(int_src))
498                         printk(KERN_INFO PFX "energy detect \n");
499                 if (netxen_get_phy_int_downshift(int_src))
500                         printk(KERN_INFO PFX "downshift \n");
501                 if (netxen_get_phy_int_mdi_xover_changed(int_src))
502                         printk(KERN_INFO PFX "mdi_xover_changed ");
503                 if (netxen_get_phy_int_fifo_over_underflow(int_src))
504                         printk(KERN_INFO PFX "fifo_over_underflow ");
505                 if (netxen_get_phy_int_false_carrier(int_src))
506                         printk(KERN_INFO PFX "false_carrier ");
507                 if (netxen_get_phy_int_symbol_error(int_src))
508                         printk(KERN_INFO PFX "symbol_error ");
509                 if (netxen_get_phy_int_autoneg_completed(int_src))
510                         printk(KERN_INFO PFX "autoneg_completed ");
511                 if (netxen_get_phy_int_page_received(int_src))
512                         printk(KERN_INFO PFX "page_received ");
513                 if (netxen_get_phy_int_duplex_changed(int_src))
514                         printk(KERN_INFO PFX "duplex_changed ");
515                 if (netxen_get_phy_int_autoneg_error(int_src))
516                         printk(KERN_INFO PFX "autoneg_error ");
517                 if ((netxen_get_phy_int_speed_changed(int_src))
518                     || (netxen_get_phy_int_link_status_changed(int_src))) {
519                         __u32 status;
520
521                         printk(KERN_INFO PFX
522                                "speed_changed or link status changed");
523                         if (netxen_niu_gbe_phy_read
524                             (adapter,
525                              NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
526                              &status) == 0) {
527                                 if (netxen_get_phy_speed(status) == 2) {
528                                         printk
529                                             (KERN_INFO PFX "Link speed changed"
530                                              " to 1000 Mbps\n");
531                                         netxen_niu_gbe_set_gmii_mode(adapter,
532                                                                      port,
533                                                                      enable);
534                                 } else if (netxen_get_phy_speed(status) == 1) {
535                                         printk
536                                             (KERN_INFO PFX "Link speed changed"
537                                              " to 100 Mbps\n");
538                                         netxen_niu_gbe_set_mii_mode(adapter,
539                                                                     port,
540                                                                     enable);
541                                 } else if (netxen_get_phy_speed(status) == 0) {
542                                         printk
543                                             (KERN_INFO PFX "Link speed changed"
544                                              " to 10 Mbps\n");
545                                         netxen_niu_gbe_set_mii_mode(adapter,
546                                                                     port,
547                                                                     enable);
548                                 } else {
549                                         printk(KERN_ERR PFX "ERROR reading "
550                                                "PHY status. Invalid speed.\n");
551                                         result = -1;
552                                 }
553                         } else {
554                                 printk(KERN_ERR PFX
555                                        "ERROR reading PHY status.\n");
556                                 result = -1;
557                         }
558
559                 }
560                 printk(KERN_INFO "\n");
561         }
562         return result;
563 }
564 #endif  /*  0  */
565
566 /*
567  * Return the current station MAC address.
568  * Note that the passed-in value must already be in network byte order.
569  */
570 static int netxen_niu_macaddr_get(struct netxen_adapter *adapter,
571                                   netxen_ethernet_macaddr_t * addr)
572 {
573         u32 stationhigh;
574         u32 stationlow;
575         int phy = adapter->physical_port;
576         u8 val[8];
577
578         if (addr == NULL)
579                 return -EINVAL;
580         if ((phy < 0) || (phy > 3))
581                 return -EINVAL;
582
583         if (adapter->hw_read_wx(adapter, NETXEN_NIU_GB_STATION_ADDR_0(phy),
584                                   &stationhigh, 4))
585                 return -EIO;
586         if (adapter->hw_read_wx(adapter, NETXEN_NIU_GB_STATION_ADDR_1(phy),
587                                   &stationlow, 4))
588                 return -EIO;
589         ((__le32 *)val)[1] = cpu_to_le32(stationhigh);
590         ((__le32 *)val)[0] = cpu_to_le32(stationlow);
591
592         memcpy(addr, val + 2, 6);
593
594         return 0;
595 }
596
597 /*
598  * Set the station MAC address.
599  * Note that the passed-in value must already be in network byte order.
600  */
601 int netxen_niu_macaddr_set(struct netxen_adapter *adapter,
602                            netxen_ethernet_macaddr_t addr)
603 {
604         u8 temp[4];
605         u32 val;
606         int phy = adapter->physical_port;
607         unsigned char mac_addr[6];
608         int i;
609         DECLARE_MAC_BUF(mac);
610
611         for (i = 0; i < 10; i++) {
612                 temp[0] = temp[1] = 0;
613                 memcpy(temp + 2, addr, 2);
614                 val = le32_to_cpu(*(__le32 *)temp);
615                 if (adapter->hw_write_wx(adapter,
616                                 NETXEN_NIU_GB_STATION_ADDR_1(phy), &val, 4))
617                         return -EIO;
618
619                 memcpy(temp, ((u8 *) addr) + 2, sizeof(__le32));
620                 val = le32_to_cpu(*(__le32 *)temp);
621                 if (adapter->hw_write_wx(adapter,
622                                 NETXEN_NIU_GB_STATION_ADDR_0(phy), &val, 4))
623                         return -2;
624
625                 netxen_niu_macaddr_get(adapter,
626                                        (netxen_ethernet_macaddr_t *) mac_addr);
627                 if (memcmp(mac_addr, addr, 6) == 0)
628                         break;
629         }
630
631         if (i == 10) {
632                 printk(KERN_ERR "%s: cannot set Mac addr for %s\n",
633                        netxen_nic_driver_name, adapter->netdev->name);
634                 printk(KERN_ERR "MAC address set: %s.\n",
635                        print_mac(mac, addr));
636                 printk(KERN_ERR "MAC address get: %s.\n",
637                        print_mac(mac, mac_addr));
638         }
639         return 0;
640 }
641
642 #if 0
643 /* Enable a GbE interface */
644 int netxen_niu_enable_gbe_port(struct netxen_adapter *adapter,
645                                int port, netxen_niu_gbe_ifmode_t mode)
646 {
647         __u32 mac_cfg0;
648         __u32 mac_cfg1;
649         __u32 mii_cfg;
650
651         if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS))
652                 return -EINVAL;
653
654         mac_cfg0 = 0;
655         netxen_gb_soft_reset(mac_cfg0);
656         if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
657                                    &mac_cfg0, 4))
658                 return -EIO;
659         mac_cfg0 = 0;
660         netxen_gb_enable_tx(mac_cfg0);
661         netxen_gb_enable_rx(mac_cfg0);
662         netxen_gb_unset_rx_flowctl(mac_cfg0);
663         netxen_gb_tx_reset_pb(mac_cfg0);
664         netxen_gb_rx_reset_pb(mac_cfg0);
665         netxen_gb_tx_reset_mac(mac_cfg0);
666         netxen_gb_rx_reset_mac(mac_cfg0);
667
668         if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
669                                    &mac_cfg0, 4))
670                 return -EIO;
671         mac_cfg1 = 0;
672         netxen_gb_set_preamblelen(mac_cfg1, 0xf);
673         netxen_gb_set_duplex(mac_cfg1);
674         netxen_gb_set_crc_enable(mac_cfg1);
675         netxen_gb_set_padshort(mac_cfg1);
676         netxen_gb_set_checklength(mac_cfg1);
677         netxen_gb_set_hugeframes(mac_cfg1);
678
679         if (mode == NETXEN_NIU_10_100_MB) {
680                 netxen_gb_set_intfmode(mac_cfg1, 1);
681                 if (adapter->hw_write_wx(adapter,
682                                            NETXEN_NIU_GB_MAC_CONFIG_1(port),
683                                            &mac_cfg1, 4))
684                         return -EIO;
685
686                 /* set mii mode */
687                 netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB0_GMII_MODE +
688                                             (port << 3), 0);
689                 netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB0_MII_MODE +
690                                             (port << 3), 1);
691
692         } else if (mode == NETXEN_NIU_1000_MB) {
693                 netxen_gb_set_intfmode(mac_cfg1, 2);
694                 if (adapter->hw_write_wx(adapter,
695                                            NETXEN_NIU_GB_MAC_CONFIG_1(port),
696                                            &mac_cfg1, 4))
697                         return -EIO;
698                 /* set gmii mode */
699                 netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB0_MII_MODE +
700                                             (port << 3), 0);
701                 netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB0_GMII_MODE +
702                                             (port << 3), 1);
703         }
704         mii_cfg = 0;
705         netxen_gb_set_mii_mgmt_clockselect(mii_cfg, 7);
706         if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_CONFIG(port),
707                                    &mii_cfg, 4))
708                 return -EIO;
709         mac_cfg0 = 0;
710         netxen_gb_enable_tx(mac_cfg0);
711         netxen_gb_enable_rx(mac_cfg0);
712         netxen_gb_unset_rx_flowctl(mac_cfg0);
713         netxen_gb_unset_tx_flowctl(mac_cfg0);
714
715         if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
716                                    &mac_cfg0, 4))
717                 return -EIO;
718         return 0;
719 }
720 #endif  /*  0  */
721
722 /* Disable a GbE interface */
723 int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter)
724 {
725         __u32 mac_cfg0;
726         u32 port = adapter->physical_port;
727
728         if (port > NETXEN_NIU_MAX_GBE_PORTS)
729                 return -EINVAL;
730         mac_cfg0 = 0;
731         netxen_gb_soft_reset(mac_cfg0);
732         if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
733                                    &mac_cfg0, 4))
734                 return -EIO;
735         return 0;
736 }
737
738 /* Disable an XG interface */
739 int netxen_niu_disable_xg_port(struct netxen_adapter *adapter)
740 {
741         __u32 mac_cfg;
742         u32 port = adapter->physical_port;
743
744         if (port > NETXEN_NIU_MAX_XG_PORTS)
745                 return -EINVAL;
746
747         mac_cfg = 0;
748         if (adapter->hw_write_wx(adapter,
749                 NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port), &mac_cfg, 4))
750                 return -EIO;
751         return 0;
752 }
753
754 /* Set promiscuous mode for a GbE interface */
755 int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter,
756                                     netxen_niu_prom_mode_t mode)
757 {
758         __u32 reg;
759         u32 port = adapter->physical_port;
760
761         if (port > NETXEN_NIU_MAX_GBE_PORTS)
762                 return -EINVAL;
763
764         /* save previous contents */
765         if (adapter->hw_read_wx(adapter, NETXEN_NIU_GB_DROP_WRONGADDR,
766                                   &reg, 4))
767                 return -EIO;
768         if (mode == NETXEN_NIU_PROMISC_MODE) {
769                 switch (port) {
770                 case 0:
771                         netxen_clear_gb_drop_gb0(reg);
772                         break;
773                 case 1:
774                         netxen_clear_gb_drop_gb1(reg);
775                         break;
776                 case 2:
777                         netxen_clear_gb_drop_gb2(reg);
778                         break;
779                 case 3:
780                         netxen_clear_gb_drop_gb3(reg);
781                         break;
782                 default:
783                         return -EIO;
784                 }
785         } else {
786                 switch (port) {
787                 case 0:
788                         netxen_set_gb_drop_gb0(reg);
789                         break;
790                 case 1:
791                         netxen_set_gb_drop_gb1(reg);
792                         break;
793                 case 2:
794                         netxen_set_gb_drop_gb2(reg);
795                         break;
796                 case 3:
797                         netxen_set_gb_drop_gb3(reg);
798                         break;
799                 default:
800                         return -EIO;
801                 }
802         }
803         if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_DROP_WRONGADDR,
804                                    &reg, 4))
805                 return -EIO;
806         return 0;
807 }
808
809 /*
810  * Set the MAC address for an XG port
811  * Note that the passed-in value must already be in network byte order.
812  */
813 int netxen_niu_xg_macaddr_set(struct netxen_adapter *adapter,
814                               netxen_ethernet_macaddr_t addr)
815 {
816         int phy = adapter->physical_port;
817         u8 temp[4];
818         u32 val;
819
820         if ((phy < 0) || (phy > NETXEN_NIU_MAX_XG_PORTS))
821                 return -EIO;
822
823         temp[0] = temp[1] = 0;
824         switch (phy) {
825         case 0:
826             memcpy(temp + 2, addr, 2);
827             val = le32_to_cpu(*(__le32 *)temp);
828             if (adapter->hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_1,
829                                 &val, 4))
830                 return -EIO;
831
832             memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32));
833             val = le32_to_cpu(*(__le32 *)temp);
834             if (adapter->hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_HI,
835                                 &val, 4))
836                 return -EIO;
837             break;
838
839         case 1:
840             memcpy(temp + 2, addr, 2);
841             val = le32_to_cpu(*(__le32 *)temp);
842             if (adapter->hw_write_wx(adapter, NETXEN_NIU_XG1_STATION_ADDR_0_1,
843                                 &val, 4))
844                 return -EIO;
845
846             memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32));
847             val = le32_to_cpu(*(__le32 *)temp);
848             if (adapter->hw_write_wx(adapter, NETXEN_NIU_XG1_STATION_ADDR_0_HI,
849                                 &val, 4))
850                 return -EIO;
851             break;
852
853         default:
854             printk(KERN_ERR "Unknown port %d\n", phy);
855             break;
856         }
857
858         return 0;
859 }
860
861 #if 0
862 /*
863  * Return the current station MAC address.
864  * Note that the passed-in value must already be in network byte order.
865  */
866 int netxen_niu_xg_macaddr_get(struct netxen_adapter *adapter,
867                               netxen_ethernet_macaddr_t * addr)
868 {
869         int phy = adapter->physical_port;
870         u32 stationhigh;
871         u32 stationlow;
872         u8 val[8];
873
874         if (addr == NULL)
875                 return -EINVAL;
876         if (phy != 0)
877                 return -EINVAL;
878
879         if (adapter->hw_read_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_HI,
880                                   &stationhigh, 4))
881                 return -EIO;
882         if (adapter->hw_read_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_1,
883                                   &stationlow, 4))
884                 return -EIO;
885         ((__le32 *)val)[1] = cpu_to_le32(stationhigh);
886         ((__le32 *)val)[0] = cpu_to_le32(stationlow);
887
888         memcpy(addr, val + 2, 6);
889
890         return 0;
891 }
892 #endif  /*  0  */
893
894 int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter,
895                                        netxen_niu_prom_mode_t mode)
896 {
897         __u32 reg;
898         u32 port = adapter->physical_port;
899
900         if (port > NETXEN_NIU_MAX_XG_PORTS)
901                 return -EINVAL;
902
903         if (adapter->hw_read_wx(adapter,
904                 NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), &reg, 4))
905                         return -EIO;
906         if (mode == NETXEN_NIU_PROMISC_MODE)
907                 reg = (reg | 0x2000UL);
908         else
909                 reg = (reg & ~0x2000UL);
910
911         if (mode == NETXEN_NIU_ALLMULTI_MODE)
912                 reg = (reg | 0x1000UL);
913         else
914                 reg = (reg & ~0x1000UL);
915
916         netxen_crb_writelit_adapter(adapter,
917                 NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), reg);
918
919         return 0;
920 }