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