Merge git://git.kernel.org/pub/scm/linux/kernel/git/davej/cpufreq
[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 =
50                     readl(pci_base_offset
51                           (adapter, NETXEN_PCIE_REG(PCIE_SEM3_LOCK)));
52                 if (done == 1)
53                         break;
54                 if (timeout >= phy_lock_timeout) {
55                         return -1;
56                 }
57                 timeout++;
58                 if (!in_atomic())
59                         schedule();
60                 else {
61                         for (i = 0; i < 20; i++)
62                                 cpu_relax();
63                 }
64         }
65
66         writel(PHY_LOCK_DRIVER,
67                NETXEN_CRB_NORMALIZE(adapter, NETXEN_PHY_LOCK_ID));
68         return 0;
69 }
70
71 static int phy_unlock(struct netxen_adapter *adapter)
72 {
73         readl(pci_base_offset(adapter, NETXEN_PCIE_REG(PCIE_SEM3_UNLOCK)));
74
75         return 0;
76 }
77
78 /*
79  * netxen_niu_gbe_phy_read - read a register from the GbE PHY via
80  * mii management interface.
81  *
82  * Note: The MII management interface goes through port 0.
83  *      Individual phys are addressed as follows:
84  * @param phy  [15:8]  phy id
85  * @param reg  [7:0]   register number
86  *
87  * @returns  0 on success
88  *        -1 on error
89  *
90  */
91 int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg,
92                                 __u32 * readval)
93 {
94         long timeout = 0;
95         long result = 0;
96         long restore = 0;
97         long phy = physical_port[adapter->portnum];
98         __u32 address;
99         __u32 command;
100         __u32 status;
101         __u32 mac_cfg0;
102
103         if (phy_lock(adapter) != 0) {
104                 return -1;
105         }
106
107         /*
108          * MII mgmt all goes through port 0 MAC interface,
109          * so it cannot be in reset
110          */
111
112         if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0),
113                                   &mac_cfg0, 4))
114                 return -EIO;
115         if (netxen_gb_get_soft_reset(mac_cfg0)) {
116                 __u32 temp;
117                 temp = 0;
118                 netxen_gb_tx_reset_pb(temp);
119                 netxen_gb_rx_reset_pb(temp);
120                 netxen_gb_tx_reset_mac(temp);
121                 netxen_gb_rx_reset_mac(temp);
122                 if (netxen_nic_hw_write_wx(adapter,
123                                            NETXEN_NIU_GB_MAC_CONFIG_0(0),
124                                            &temp, 4))
125                         return -EIO;
126                 restore = 1;
127         }
128
129         address = 0;
130         netxen_gb_mii_mgmt_reg_addr(address, reg);
131         netxen_gb_mii_mgmt_phy_addr(address, phy);
132         if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0),
133                                    &address, 4))
134                 return -EIO;
135         command = 0;            /* turn off any prior activity */
136         if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0),
137                                    &command, 4))
138                 return -EIO;
139         /* send read command */
140         netxen_gb_mii_mgmt_set_read_cycle(command);
141         if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0),
142                                    &command, 4))
143                 return -EIO;
144
145         status = 0;
146         do {
147                 if (netxen_nic_hw_read_wx(adapter,
148                                           NETXEN_NIU_GB_MII_MGMT_INDICATE(0),
149                                           &status, 4))
150                         return -EIO;
151                 timeout++;
152         } while ((netxen_get_gb_mii_mgmt_busy(status)
153                   || netxen_get_gb_mii_mgmt_notvalid(status))
154                  && (timeout++ < NETXEN_NIU_PHY_WAITMAX));
155
156         if (timeout < NETXEN_NIU_PHY_WAITMAX) {
157                 if (netxen_nic_hw_read_wx(adapter,
158                                           NETXEN_NIU_GB_MII_MGMT_STATUS(0),
159                                           readval, 4))
160                         return -EIO;
161                 result = 0;
162         } else
163                 result = -1;
164
165         if (restore)
166                 if (netxen_nic_hw_write_wx(adapter,
167                                            NETXEN_NIU_GB_MAC_CONFIG_0(0),
168                                            &mac_cfg0, 4))
169                         return -EIO;
170         phy_unlock(adapter);
171         return result;
172 }
173
174 /*
175  * netxen_niu_gbe_phy_write - write a register to the GbE PHY via
176  * mii management interface.
177  *
178  * Note: The MII management interface goes through port 0.
179  *      Individual phys are addressed as follows:
180  * @param phy      [15:8]  phy id
181  * @param reg      [7:0]   register number
182  *
183  * @returns  0 on success
184  *        -1 on error
185  *
186  */
187 int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long reg,
188                                 __u32 val)
189 {
190         long timeout = 0;
191         long result = 0;
192         long restore = 0;
193         long phy = physical_port[adapter->portnum];
194         __u32 address;
195         __u32 command;
196         __u32 status;
197         __u32 mac_cfg0;
198
199         /*
200          * MII mgmt all goes through port 0 MAC interface, so it
201          * cannot be in reset
202          */
203
204         if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0),
205                                   &mac_cfg0, 4))
206                 return -EIO;
207         if (netxen_gb_get_soft_reset(mac_cfg0)) {
208                 __u32 temp;
209                 temp = 0;
210                 netxen_gb_tx_reset_pb(temp);
211                 netxen_gb_rx_reset_pb(temp);
212                 netxen_gb_tx_reset_mac(temp);
213                 netxen_gb_rx_reset_mac(temp);
214
215                 if (netxen_nic_hw_write_wx(adapter,
216                                            NETXEN_NIU_GB_MAC_CONFIG_0(0),
217                                            &temp, 4))
218                         return -EIO;
219                 restore = 1;
220         }
221
222         command = 0;            /* turn off any prior activity */
223         if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0),
224                                    &command, 4))
225                 return -EIO;
226
227         address = 0;
228         netxen_gb_mii_mgmt_reg_addr(address, reg);
229         netxen_gb_mii_mgmt_phy_addr(address, phy);
230         if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0),
231                                    &address, 4))
232                 return -EIO;
233
234         if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_CTRL(0),
235                                    &val, 4))
236                 return -EIO;
237
238         status = 0;
239         do {
240                 if (netxen_nic_hw_read_wx(adapter,
241                                           NETXEN_NIU_GB_MII_MGMT_INDICATE(0),
242                                           &status, 4))
243                         return -EIO;
244                 timeout++;
245         } while ((netxen_get_gb_mii_mgmt_busy(status))
246                  && (timeout++ < NETXEN_NIU_PHY_WAITMAX));
247
248         if (timeout < NETXEN_NIU_PHY_WAITMAX)
249                 result = 0;
250         else
251                 result = -EIO;
252
253         /* restore the state of port 0 MAC in case we tampered with it */
254         if (restore)
255                 if (netxen_nic_hw_write_wx(adapter,
256                                            NETXEN_NIU_GB_MAC_CONFIG_0(0),
257                                            &mac_cfg0, 4))
258                         return -EIO;
259
260         return result;
261 }
262
263 int netxen_niu_xgbe_enable_phy_interrupts(struct netxen_adapter *adapter)
264 {
265         netxen_crb_writelit_adapter(adapter, NETXEN_NIU_INT_MASK, 0x3f);
266         return 0;
267 }
268
269 int netxen_niu_gbe_enable_phy_interrupts(struct netxen_adapter *adapter)
270 {
271         int result = 0;
272         __u32 enable = 0;
273         netxen_set_phy_int_link_status_changed(enable);
274         netxen_set_phy_int_autoneg_completed(enable);
275         netxen_set_phy_int_speed_changed(enable);
276
277         if (0 !=
278             netxen_niu_gbe_phy_write(adapter,
279                                      NETXEN_NIU_GB_MII_MGMT_ADDR_INT_ENABLE,
280                                      enable))
281                 result = -EIO;
282
283         return result;
284 }
285
286 int netxen_niu_xgbe_disable_phy_interrupts(struct netxen_adapter *adapter)
287 {
288         netxen_crb_writelit_adapter(adapter, NETXEN_NIU_INT_MASK, 0x7f);
289         return 0;
290 }
291
292 int netxen_niu_gbe_disable_phy_interrupts(struct netxen_adapter *adapter)
293 {
294         int result = 0;
295         if (0 !=
296             netxen_niu_gbe_phy_write(adapter,
297                                      NETXEN_NIU_GB_MII_MGMT_ADDR_INT_ENABLE, 0))
298                 result = -EIO;
299
300         return result;
301 }
302
303 #if 0
304 int netxen_niu_xgbe_clear_phy_interrupts(struct netxen_adapter *adapter)
305 {
306         netxen_crb_writelit_adapter(adapter, NETXEN_NIU_ACTIVE_INT, -1);
307         return 0;
308 }
309 #endif  /*  0  */
310
311 static int netxen_niu_gbe_clear_phy_interrupts(struct netxen_adapter *adapter)
312 {
313         int result = 0;
314         if (0 !=
315             netxen_niu_gbe_phy_write(adapter,
316                                      NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS,
317                                      -EIO))
318                 result = -EIO;
319
320         return result;
321 }
322
323 /*
324  * netxen_niu_gbe_set_mii_mode- Set 10/100 Mbit Mode for GbE MAC
325  *
326  */
327 static void netxen_niu_gbe_set_mii_mode(struct netxen_adapter *adapter,
328                                         int port, long enable)
329 {
330         netxen_crb_writelit_adapter(adapter, NETXEN_NIU_MODE, 0x2);
331         netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
332                                     0x80000000);
333         netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
334                                     0x0000f0025);
335         netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_1(port),
336                                     0xf1ff);
337         netxen_crb_writelit_adapter(adapter,
338                                     NETXEN_NIU_GB0_GMII_MODE + (port << 3), 0);
339         netxen_crb_writelit_adapter(adapter,
340                                     NETXEN_NIU_GB0_MII_MODE + (port << 3), 1);
341         netxen_crb_writelit_adapter(adapter,
342                                     (NETXEN_NIU_GB0_HALF_DUPLEX + port * 4), 0);
343         netxen_crb_writelit_adapter(adapter,
344                                     NETXEN_NIU_GB_MII_MGMT_CONFIG(port), 0x7);
345
346         if (enable) {
347                 /*
348                  * Do NOT enable flow control until a suitable solution for
349                  *  shutting down pause frames is found.
350                  */
351                 netxen_crb_writelit_adapter(adapter,
352                                             NETXEN_NIU_GB_MAC_CONFIG_0(port),
353                                             0x5);
354         }
355
356         if (netxen_niu_gbe_enable_phy_interrupts(adapter))
357                 printk(KERN_ERR PFX "ERROR enabling PHY interrupts\n");
358         if (netxen_niu_gbe_clear_phy_interrupts(adapter))
359                 printk(KERN_ERR PFX "ERROR clearing PHY interrupts\n");
360 }
361
362 /*
363  * netxen_niu_gbe_set_gmii_mode- Set GbE Mode for GbE MAC
364  */
365 static void netxen_niu_gbe_set_gmii_mode(struct netxen_adapter *adapter,
366                                          int port, long enable)
367 {
368         netxen_crb_writelit_adapter(adapter, NETXEN_NIU_MODE, 0x2);
369         netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
370                                     0x80000000);
371         netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
372                                     0x0000f0025);
373         netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_1(port),
374                                     0xf2ff);
375         netxen_crb_writelit_adapter(adapter,
376                                     NETXEN_NIU_GB0_MII_MODE + (port << 3), 0);
377         netxen_crb_writelit_adapter(adapter,
378                                     NETXEN_NIU_GB0_GMII_MODE + (port << 3), 1);
379         netxen_crb_writelit_adapter(adapter,
380                                     (NETXEN_NIU_GB0_HALF_DUPLEX + port * 4), 0);
381         netxen_crb_writelit_adapter(adapter,
382                                     NETXEN_NIU_GB_MII_MGMT_CONFIG(port), 0x7);
383
384         if (enable) {
385                 /*
386                  * Do NOT enable flow control until a suitable solution for
387                  *  shutting down pause frames is found.
388                  */
389                 netxen_crb_writelit_adapter(adapter,
390                                             NETXEN_NIU_GB_MAC_CONFIG_0(port),
391                                             0x5);
392         }
393
394         if (netxen_niu_gbe_enable_phy_interrupts(adapter))
395                 printk(KERN_ERR PFX "ERROR enabling PHY interrupts\n");
396         if (netxen_niu_gbe_clear_phy_interrupts(adapter))
397                 printk(KERN_ERR PFX "ERROR clearing PHY interrupts\n");
398 }
399
400 int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port)
401 {
402         int result = 0;
403         __u32 status;
404         if (adapter->disable_phy_interrupts)
405                 adapter->disable_phy_interrupts(adapter);
406         mdelay(2);
407
408         if (0 ==
409             netxen_niu_gbe_phy_read(adapter,
410                                     NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
411                                     &status)) {
412                 if (netxen_get_phy_link(status)) {
413                         if (netxen_get_phy_speed(status) == 2) {
414                                 netxen_niu_gbe_set_gmii_mode(adapter, port, 1);
415                         } else if ((netxen_get_phy_speed(status) == 1)
416                                    || (netxen_get_phy_speed(status) == 0)) {
417                                 netxen_niu_gbe_set_mii_mode(adapter, port, 1);
418                         } else {
419                                 result = -1;
420                         }
421
422                 } else {
423                         /*
424                          * We don't have link. Cable  must be unconnected.
425                          * Enable phy interrupts so we take action when
426                          * plugged in.
427                          */
428
429                         netxen_crb_writelit_adapter(adapter,
430                                                     NETXEN_NIU_GB_MAC_CONFIG_0
431                                                     (port),
432                                                     NETXEN_GB_MAC_SOFT_RESET);
433                         netxen_crb_writelit_adapter(adapter,
434                                                     NETXEN_NIU_GB_MAC_CONFIG_0
435                                                     (port),
436                                                     NETXEN_GB_MAC_RESET_PROT_BLK
437                                                     | NETXEN_GB_MAC_ENABLE_TX_RX
438                                                     |
439                                                     NETXEN_GB_MAC_PAUSED_FRMS);
440                         if (netxen_niu_gbe_clear_phy_interrupts(adapter))
441                                 printk(KERN_ERR PFX
442                                        "ERROR clearing PHY interrupts\n");
443                         if (netxen_niu_gbe_enable_phy_interrupts(adapter))
444                                 printk(KERN_ERR PFX
445                                        "ERROR enabling PHY interrupts\n");
446                         if (netxen_niu_gbe_clear_phy_interrupts(adapter))
447                                 printk(KERN_ERR PFX
448                                        "ERROR clearing PHY interrupts\n");
449                         result = -1;
450                 }
451         } else {
452                 result = -EIO;
453         }
454         return result;
455 }
456
457 int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port)
458 {
459         u32 portnum = physical_port[adapter->portnum];
460
461         netxen_crb_writelit_adapter(adapter,
462                 NETXEN_NIU_XGE_CONFIG_1+(0x10000*portnum), 0x1447);
463         netxen_crb_writelit_adapter(adapter,
464                 NETXEN_NIU_XGE_CONFIG_0+(0x10000*portnum), 0x5);
465
466         return 0;
467 }
468
469 #if 0
470 /*
471  * netxen_niu_gbe_handle_phy_interrupt - Handles GbE PHY interrupts
472  * @param enable 0 means don't enable the port
473  *               1 means enable (or re-enable) the port
474  */
475 int netxen_niu_gbe_handle_phy_interrupt(struct netxen_adapter *adapter,
476                                         int port, long enable)
477 {
478         int result = 0;
479         __u32 int_src;
480
481         printk(KERN_INFO PFX "NETXEN: Handling PHY interrupt on port %d"
482                " (device enable = %d)\n", (int)port, (int)enable);
483
484         /*
485          * The read of the PHY INT status will clear the pending
486          * interrupt status
487          */
488         if (netxen_niu_gbe_phy_read(adapter,
489                                     NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS,
490                                     &int_src) != 0)
491                 result = -EINVAL;
492         else {
493                 printk(KERN_INFO PFX "PHY Interrupt source = 0x%x \n", int_src);
494                 if (netxen_get_phy_int_jabber(int_src))
495                         printk(KERN_INFO PFX "jabber Interrupt ");
496                 if (netxen_get_phy_int_polarity_changed(int_src))
497                         printk(KERN_INFO PFX "polarity changed ");
498                 if (netxen_get_phy_int_energy_detect(int_src))
499                         printk(KERN_INFO PFX "energy detect \n");
500                 if (netxen_get_phy_int_downshift(int_src))
501                         printk(KERN_INFO PFX "downshift \n");
502                 if (netxen_get_phy_int_mdi_xover_changed(int_src))
503                         printk(KERN_INFO PFX "mdi_xover_changed ");
504                 if (netxen_get_phy_int_fifo_over_underflow(int_src))
505                         printk(KERN_INFO PFX "fifo_over_underflow ");
506                 if (netxen_get_phy_int_false_carrier(int_src))
507                         printk(KERN_INFO PFX "false_carrier ");
508                 if (netxen_get_phy_int_symbol_error(int_src))
509                         printk(KERN_INFO PFX "symbol_error ");
510                 if (netxen_get_phy_int_autoneg_completed(int_src))
511                         printk(KERN_INFO PFX "autoneg_completed ");
512                 if (netxen_get_phy_int_page_received(int_src))
513                         printk(KERN_INFO PFX "page_received ");
514                 if (netxen_get_phy_int_duplex_changed(int_src))
515                         printk(KERN_INFO PFX "duplex_changed ");
516                 if (netxen_get_phy_int_autoneg_error(int_src))
517                         printk(KERN_INFO PFX "autoneg_error ");
518                 if ((netxen_get_phy_int_speed_changed(int_src))
519                     || (netxen_get_phy_int_link_status_changed(int_src))) {
520                         __u32 status;
521
522                         printk(KERN_INFO PFX
523                                "speed_changed or link status changed");
524                         if (netxen_niu_gbe_phy_read
525                             (adapter,
526                              NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
527                              &status) == 0) {
528                                 if (netxen_get_phy_speed(status) == 2) {
529                                         printk
530                                             (KERN_INFO PFX "Link speed changed"
531                                              " to 1000 Mbps\n");
532                                         netxen_niu_gbe_set_gmii_mode(adapter,
533                                                                      port,
534                                                                      enable);
535                                 } else if (netxen_get_phy_speed(status) == 1) {
536                                         printk
537                                             (KERN_INFO PFX "Link speed changed"
538                                              " to 100 Mbps\n");
539                                         netxen_niu_gbe_set_mii_mode(adapter,
540                                                                     port,
541                                                                     enable);
542                                 } else if (netxen_get_phy_speed(status) == 0) {
543                                         printk
544                                             (KERN_INFO PFX "Link speed changed"
545                                              " to 10 Mbps\n");
546                                         netxen_niu_gbe_set_mii_mode(adapter,
547                                                                     port,
548                                                                     enable);
549                                 } else {
550                                         printk(KERN_ERR PFX "ERROR reading "
551                                                "PHY status. Invalid speed.\n");
552                                         result = -1;
553                                 }
554                         } else {
555                                 printk(KERN_ERR PFX
556                                        "ERROR reading PHY status.\n");
557                                 result = -1;
558                         }
559
560                 }
561                 printk(KERN_INFO "\n");
562         }
563         return result;
564 }
565 #endif  /*  0  */
566
567 /*
568  * Return the current station MAC address.
569  * Note that the passed-in value must already be in network byte order.
570  */
571 static int netxen_niu_macaddr_get(struct netxen_adapter *adapter,
572                                   netxen_ethernet_macaddr_t * addr)
573 {
574         u32 stationhigh;
575         u32 stationlow;
576         int phy = physical_port[adapter->portnum];
577         u8 val[8];
578
579         if (addr == NULL)
580                 return -EINVAL;
581         if ((phy < 0) || (phy > 3))
582                 return -EINVAL;
583
584         if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_GB_STATION_ADDR_0(phy),
585                                   &stationhigh, 4))
586                 return -EIO;
587         if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_GB_STATION_ADDR_1(phy),
588                                   &stationlow, 4))
589                 return -EIO;
590         ((__le32 *)val)[1] = cpu_to_le32(stationhigh);
591         ((__le32 *)val)[0] = cpu_to_le32(stationlow);
592
593         memcpy(addr, val + 2, 6);
594
595         return 0;
596 }
597
598 /*
599  * Set the station MAC address.
600  * Note that the passed-in value must already be in network byte order.
601  */
602 int netxen_niu_macaddr_set(struct netxen_adapter *adapter,
603                            netxen_ethernet_macaddr_t addr)
604 {
605         u8 temp[4];
606         u32 val;
607         int phy = physical_port[adapter->portnum];
608         unsigned char mac_addr[6];
609         int i;
610         DECLARE_MAC_BUF(mac);
611
612         for (i = 0; i < 10; i++) {
613                 temp[0] = temp[1] = 0;
614                 memcpy(temp + 2, addr, 2);
615                 val = le32_to_cpu(*(__le32 *)temp);
616                 if (netxen_nic_hw_write_wx
617                     (adapter, NETXEN_NIU_GB_STATION_ADDR_1(phy), &val, 4))
618                         return -EIO;
619
620                 memcpy(temp, ((u8 *) addr) + 2, sizeof(__le32));
621                 val = le32_to_cpu(*(__le32 *)temp);
622                 if (netxen_nic_hw_write_wx
623                     (adapter, NETXEN_NIU_GB_STATION_ADDR_0(phy), &val, 4))
624                         return -2;
625
626                 netxen_niu_macaddr_get(adapter,
627                                        (netxen_ethernet_macaddr_t *) mac_addr);
628                 if (memcmp(mac_addr, addr, 6) == 0)
629                         break;
630         }
631
632         if (i == 10) {
633                 printk(KERN_ERR "%s: cannot set Mac addr for %s\n",
634                        netxen_nic_driver_name, adapter->netdev->name);
635                 printk(KERN_ERR "MAC address set: %s.\n",
636                        print_mac(mac, addr));
637                 printk(KERN_ERR "MAC address get: %s.\n",
638                        print_mac(mac, mac_addr));
639         }
640         return 0;
641 }
642
643 #if 0
644 /* Enable a GbE interface */
645 int netxen_niu_enable_gbe_port(struct netxen_adapter *adapter,
646                                int port, netxen_niu_gbe_ifmode_t mode)
647 {
648         __u32 mac_cfg0;
649         __u32 mac_cfg1;
650         __u32 mii_cfg;
651
652         if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS))
653                 return -EINVAL;
654
655         mac_cfg0 = 0;
656         netxen_gb_soft_reset(mac_cfg0);
657         if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
658                                    &mac_cfg0, 4))
659                 return -EIO;
660         mac_cfg0 = 0;
661         netxen_gb_enable_tx(mac_cfg0);
662         netxen_gb_enable_rx(mac_cfg0);
663         netxen_gb_unset_rx_flowctl(mac_cfg0);
664         netxen_gb_tx_reset_pb(mac_cfg0);
665         netxen_gb_rx_reset_pb(mac_cfg0);
666         netxen_gb_tx_reset_mac(mac_cfg0);
667         netxen_gb_rx_reset_mac(mac_cfg0);
668
669         if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
670                                    &mac_cfg0, 4))
671                 return -EIO;
672         mac_cfg1 = 0;
673         netxen_gb_set_preamblelen(mac_cfg1, 0xf);
674         netxen_gb_set_duplex(mac_cfg1);
675         netxen_gb_set_crc_enable(mac_cfg1);
676         netxen_gb_set_padshort(mac_cfg1);
677         netxen_gb_set_checklength(mac_cfg1);
678         netxen_gb_set_hugeframes(mac_cfg1);
679
680         if (mode == NETXEN_NIU_10_100_MB) {
681                 netxen_gb_set_intfmode(mac_cfg1, 1);
682                 if (netxen_nic_hw_write_wx(adapter,
683                                            NETXEN_NIU_GB_MAC_CONFIG_1(port),
684                                            &mac_cfg1, 4))
685                         return -EIO;
686
687                 /* set mii mode */
688                 netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB0_GMII_MODE +
689                                             (port << 3), 0);
690                 netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB0_MII_MODE +
691                                             (port << 3), 1);
692
693         } else if (mode == NETXEN_NIU_1000_MB) {
694                 netxen_gb_set_intfmode(mac_cfg1, 2);
695                 if (netxen_nic_hw_write_wx(adapter,
696                                            NETXEN_NIU_GB_MAC_CONFIG_1(port),
697                                            &mac_cfg1, 4))
698                         return -EIO;
699                 /* set gmii mode */
700                 netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB0_MII_MODE +
701                                             (port << 3), 0);
702                 netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB0_GMII_MODE +
703                                             (port << 3), 1);
704         }
705         mii_cfg = 0;
706         netxen_gb_set_mii_mgmt_clockselect(mii_cfg, 7);
707         if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_CONFIG(port),
708                                    &mii_cfg, 4))
709                 return -EIO;
710         mac_cfg0 = 0;
711         netxen_gb_enable_tx(mac_cfg0);
712         netxen_gb_enable_rx(mac_cfg0);
713         netxen_gb_unset_rx_flowctl(mac_cfg0);
714         netxen_gb_unset_tx_flowctl(mac_cfg0);
715
716         if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
717                                    &mac_cfg0, 4))
718                 return -EIO;
719         return 0;
720 }
721 #endif  /*  0  */
722
723 /* Disable a GbE interface */
724 int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter)
725 {
726         __u32 mac_cfg0;
727         u32 port = physical_port[adapter->portnum];
728
729         if (port > NETXEN_NIU_MAX_GBE_PORTS)
730                 return -EINVAL;
731         mac_cfg0 = 0;
732         netxen_gb_soft_reset(mac_cfg0);
733         if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
734                                    &mac_cfg0, 4))
735                 return -EIO;
736         return 0;
737 }
738
739 /* Disable an XG interface */
740 int netxen_niu_disable_xg_port(struct netxen_adapter *adapter)
741 {
742         __u32 mac_cfg;
743         u32 port = physical_port[adapter->portnum];
744
745         if (port > NETXEN_NIU_MAX_XG_PORTS)
746                 return -EINVAL;
747
748         mac_cfg = 0;
749         if (netxen_nic_hw_write_wx(adapter,
750                 NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port), &mac_cfg, 4))
751                 return -EIO;
752         return 0;
753 }
754
755 /* Set promiscuous mode for a GbE interface */
756 int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter,
757                                     netxen_niu_prom_mode_t mode)
758 {
759         __u32 reg;
760         u32 port = physical_port[adapter->portnum];
761
762         if (port > NETXEN_NIU_MAX_GBE_PORTS)
763                 return -EINVAL;
764
765         /* save previous contents */
766         if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_GB_DROP_WRONGADDR,
767                                   &reg, 4))
768                 return -EIO;
769         if (mode == NETXEN_NIU_PROMISC_MODE) {
770                 switch (port) {
771                 case 0:
772                         netxen_clear_gb_drop_gb0(reg);
773                         break;
774                 case 1:
775                         netxen_clear_gb_drop_gb1(reg);
776                         break;
777                 case 2:
778                         netxen_clear_gb_drop_gb2(reg);
779                         break;
780                 case 3:
781                         netxen_clear_gb_drop_gb3(reg);
782                         break;
783                 default:
784                         return -EIO;
785                 }
786         } else {
787                 switch (port) {
788                 case 0:
789                         netxen_set_gb_drop_gb0(reg);
790                         break;
791                 case 1:
792                         netxen_set_gb_drop_gb1(reg);
793                         break;
794                 case 2:
795                         netxen_set_gb_drop_gb2(reg);
796                         break;
797                 case 3:
798                         netxen_set_gb_drop_gb3(reg);
799                         break;
800                 default:
801                         return -EIO;
802                 }
803         }
804         if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_DROP_WRONGADDR,
805                                    &reg, 4))
806                 return -EIO;
807         return 0;
808 }
809
810 /*
811  * Set the MAC address for an XG port
812  * Note that the passed-in value must already be in network byte order.
813  */
814 int netxen_niu_xg_macaddr_set(struct netxen_adapter *adapter,
815                               netxen_ethernet_macaddr_t addr)
816 {
817         int phy = physical_port[adapter->portnum];
818         u8 temp[4];
819         u32 val;
820
821         if ((phy < 0) || (phy > NETXEN_NIU_MAX_XG_PORTS))
822                 return -EIO;
823
824         temp[0] = temp[1] = 0;
825         switch (phy) {
826         case 0:
827             memcpy(temp + 2, addr, 2);
828             val = le32_to_cpu(*(__le32 *)temp);
829             if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_1,
830                                 &val, 4))
831                 return -EIO;
832
833             memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32));
834             val = le32_to_cpu(*(__le32 *)temp);
835             if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_HI,
836                                 &val, 4))
837                 return -EIO;
838             break;
839
840         case 1:
841             memcpy(temp + 2, addr, 2);
842             val = le32_to_cpu(*(__le32 *)temp);
843             if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XG1_STATION_ADDR_0_1,
844                                 &val, 4))
845                 return -EIO;
846
847             memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32));
848             val = le32_to_cpu(*(__le32 *)temp);
849             if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XG1_STATION_ADDR_0_HI,
850                                 &val, 4))
851                 return -EIO;
852             break;
853
854         default:
855             printk(KERN_ERR "Unknown port %d\n", phy);
856             break;
857         }
858
859         return 0;
860 }
861
862 #if 0
863 /*
864  * Return the current station MAC address.
865  * Note that the passed-in value must already be in network byte order.
866  */
867 int netxen_niu_xg_macaddr_get(struct netxen_adapter *adapter,
868                               netxen_ethernet_macaddr_t * addr)
869 {
870         int phy = physical_port[adapter->portnum];
871         u32 stationhigh;
872         u32 stationlow;
873         u8 val[8];
874
875         if (addr == NULL)
876                 return -EINVAL;
877         if (phy != 0)
878                 return -EINVAL;
879
880         if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_HI,
881                                   &stationhigh, 4))
882                 return -EIO;
883         if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_1,
884                                   &stationlow, 4))
885                 return -EIO;
886         ((__le32 *)val)[1] = cpu_to_le32(stationhigh);
887         ((__le32 *)val)[0] = cpu_to_le32(stationlow);
888
889         memcpy(addr, val + 2, 6);
890
891         return 0;
892 }
893 #endif  /*  0  */
894
895 int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter,
896                                        netxen_niu_prom_mode_t mode)
897 {
898         __u32 reg;
899         u32 port = physical_port[adapter->portnum];
900
901         if (port > NETXEN_NIU_MAX_XG_PORTS)
902                 return -EINVAL;
903
904         if (netxen_nic_hw_read_wx(adapter,
905                 NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), &reg, 4))
906                         return -EIO;
907         if (mode == NETXEN_NIU_PROMISC_MODE)
908                 reg = (reg | 0x2000UL);
909         else
910                 reg = (reg & ~0x2000UL);
911
912         netxen_crb_writelit_adapter(adapter,
913                 NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), reg);
914
915         return 0;
916 }