gpio: ab8500: Mark broken
[pandora-kernel.git] / drivers / net / netxen / netxen_nic_ethtool.c
1 /*
2  * Copyright (C) 2003 - 2009 NetXen, Inc.
3  * Copyright (C) 2009 - QLogic Corporation.
4  * All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
19  * MA  02111-1307, USA.
20  *
21  * The full GNU General Public License is included in this distribution
22  * in the file called "COPYING".
23  *
24  */
25
26 #include <linux/types.h>
27 #include <linux/delay.h>
28 #include <linux/pci.h>
29 #include <asm/io.h>
30 #include <linux/netdevice.h>
31 #include <linux/ethtool.h>
32
33 #include "netxen_nic.h"
34 #include "netxen_nic_hw.h"
35
36 struct netxen_nic_stats {
37         char stat_string[ETH_GSTRING_LEN];
38         int sizeof_stat;
39         int stat_offset;
40 };
41
42 #define NETXEN_NIC_STAT(m) sizeof(((struct netxen_adapter *)0)->m), \
43                         offsetof(struct netxen_adapter, m)
44
45 #define NETXEN_NIC_PORT_WINDOW 0x10000
46 #define NETXEN_NIC_INVALID_DATA 0xDEADBEEF
47
48 static const struct netxen_nic_stats netxen_nic_gstrings_stats[] = {
49         {"xmit_called", NETXEN_NIC_STAT(stats.xmitcalled)},
50         {"xmit_finished", NETXEN_NIC_STAT(stats.xmitfinished)},
51         {"rx_dropped", NETXEN_NIC_STAT(stats.rxdropped)},
52         {"tx_dropped", NETXEN_NIC_STAT(stats.txdropped)},
53         {"csummed", NETXEN_NIC_STAT(stats.csummed)},
54         {"rx_pkts", NETXEN_NIC_STAT(stats.rx_pkts)},
55         {"lro_pkts", NETXEN_NIC_STAT(stats.lro_pkts)},
56         {"rx_bytes", NETXEN_NIC_STAT(stats.rxbytes)},
57         {"tx_bytes", NETXEN_NIC_STAT(stats.txbytes)},
58 };
59
60 #define NETXEN_NIC_STATS_LEN    ARRAY_SIZE(netxen_nic_gstrings_stats)
61
62 static const char netxen_nic_gstrings_test[][ETH_GSTRING_LEN] = {
63         "Register_Test_on_offline",
64         "Link_Test_on_offline"
65 };
66
67 #define NETXEN_NIC_TEST_LEN     ARRAY_SIZE(netxen_nic_gstrings_test)
68
69 #define NETXEN_NIC_REGS_COUNT 30
70 #define NETXEN_NIC_REGS_LEN (NETXEN_NIC_REGS_COUNT * sizeof(__le32))
71 #define NETXEN_MAX_EEPROM_LEN   1024
72
73 static int netxen_nic_get_eeprom_len(struct net_device *dev)
74 {
75         return NETXEN_FLASH_TOTAL_SIZE;
76 }
77
78 static void
79 netxen_nic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
80 {
81         struct netxen_adapter *adapter = netdev_priv(dev);
82         u32 fw_major = 0;
83         u32 fw_minor = 0;
84         u32 fw_build = 0;
85
86         strncpy(drvinfo->driver, netxen_nic_driver_name, 32);
87         strncpy(drvinfo->version, NETXEN_NIC_LINUX_VERSIONID, 32);
88         fw_major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR);
89         fw_minor = NXRD32(adapter, NETXEN_FW_VERSION_MINOR);
90         fw_build = NXRD32(adapter, NETXEN_FW_VERSION_SUB);
91         sprintf(drvinfo->fw_version, "%d.%d.%d", fw_major, fw_minor, fw_build);
92
93         strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
94         drvinfo->regdump_len = NETXEN_NIC_REGS_LEN;
95         drvinfo->eedump_len = netxen_nic_get_eeprom_len(dev);
96 }
97
98 static int
99 netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
100 {
101         struct netxen_adapter *adapter = netdev_priv(dev);
102         int check_sfp_module = 0;
103
104         /* read which mode */
105         if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
106                 ecmd->supported = (SUPPORTED_10baseT_Half |
107                                    SUPPORTED_10baseT_Full |
108                                    SUPPORTED_100baseT_Half |
109                                    SUPPORTED_100baseT_Full |
110                                    SUPPORTED_1000baseT_Half |
111                                    SUPPORTED_1000baseT_Full);
112
113                 ecmd->advertising = (ADVERTISED_100baseT_Half |
114                                      ADVERTISED_100baseT_Full |
115                                      ADVERTISED_1000baseT_Half |
116                                      ADVERTISED_1000baseT_Full);
117
118                 ecmd->port = PORT_TP;
119
120                 ecmd->speed = adapter->link_speed;
121                 ecmd->duplex = adapter->link_duplex;
122                 ecmd->autoneg = adapter->link_autoneg;
123
124         } else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
125                 u32 val;
126
127                 val = NXRD32(adapter, NETXEN_PORT_MODE_ADDR);
128                 if (val == NETXEN_PORT_MODE_802_3_AP) {
129                         ecmd->supported = SUPPORTED_1000baseT_Full;
130                         ecmd->advertising = ADVERTISED_1000baseT_Full;
131                 } else {
132                         ecmd->supported = SUPPORTED_10000baseT_Full;
133                         ecmd->advertising = ADVERTISED_10000baseT_Full;
134                 }
135
136                 if (netif_running(dev) && adapter->has_link_events) {
137                         ecmd->speed = adapter->link_speed;
138                         ecmd->autoneg = adapter->link_autoneg;
139                         ecmd->duplex = adapter->link_duplex;
140                         goto skip;
141                 }
142
143                 ecmd->port = PORT_TP;
144
145                 if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
146                         u16 pcifn = adapter->ahw.pci_func;
147
148                         val = NXRD32(adapter, P3_LINK_SPEED_REG(pcifn));
149                         ecmd->speed = P3_LINK_SPEED_MHZ *
150                                         P3_LINK_SPEED_VAL(pcifn, val);
151                 } else
152                         ecmd->speed = SPEED_10000;
153
154                 ecmd->duplex = DUPLEX_FULL;
155                 ecmd->autoneg = AUTONEG_DISABLE;
156         } else
157                 return -EIO;
158
159 skip:
160         ecmd->phy_address = adapter->physical_port;
161         ecmd->transceiver = XCVR_EXTERNAL;
162
163         switch (adapter->ahw.board_type) {
164         case NETXEN_BRDTYPE_P2_SB35_4G:
165         case NETXEN_BRDTYPE_P2_SB31_2G:
166         case NETXEN_BRDTYPE_P3_REF_QG:
167         case NETXEN_BRDTYPE_P3_4_GB:
168         case NETXEN_BRDTYPE_P3_4_GB_MM:
169
170                 ecmd->supported |= SUPPORTED_Autoneg;
171                 ecmd->advertising |= ADVERTISED_Autoneg;
172         case NETXEN_BRDTYPE_P2_SB31_10G_CX4:
173         case NETXEN_BRDTYPE_P3_10G_CX4:
174         case NETXEN_BRDTYPE_P3_10G_CX4_LP:
175         case NETXEN_BRDTYPE_P3_10000_BASE_T:
176                 ecmd->supported |= SUPPORTED_TP;
177                 ecmd->advertising |= ADVERTISED_TP;
178                 ecmd->port = PORT_TP;
179                 ecmd->autoneg = (adapter->ahw.board_type ==
180                                  NETXEN_BRDTYPE_P2_SB31_10G_CX4) ?
181                     (AUTONEG_DISABLE) : (adapter->link_autoneg);
182                 break;
183         case NETXEN_BRDTYPE_P2_SB31_10G_HMEZ:
184         case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ:
185         case NETXEN_BRDTYPE_P3_IMEZ:
186         case NETXEN_BRDTYPE_P3_XG_LOM:
187         case NETXEN_BRDTYPE_P3_HMEZ:
188                 ecmd->supported |= SUPPORTED_MII;
189                 ecmd->advertising |= ADVERTISED_MII;
190                 ecmd->port = PORT_MII;
191                 ecmd->autoneg = AUTONEG_DISABLE;
192                 break;
193         case NETXEN_BRDTYPE_P3_10G_SFP_PLUS:
194         case NETXEN_BRDTYPE_P3_10G_SFP_CT:
195         case NETXEN_BRDTYPE_P3_10G_SFP_QT:
196                 ecmd->advertising |= ADVERTISED_TP;
197                 ecmd->supported |= SUPPORTED_TP;
198                 check_sfp_module = netif_running(dev) &&
199                         adapter->has_link_events;
200         case NETXEN_BRDTYPE_P2_SB31_10G:
201         case NETXEN_BRDTYPE_P3_10G_XFP:
202                 ecmd->supported |= SUPPORTED_FIBRE;
203                 ecmd->advertising |= ADVERTISED_FIBRE;
204                 ecmd->port = PORT_FIBRE;
205                 ecmd->autoneg = AUTONEG_DISABLE;
206                 break;
207         case NETXEN_BRDTYPE_P3_10G_TP:
208                 if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
209                         ecmd->autoneg = AUTONEG_DISABLE;
210                         ecmd->supported |= (SUPPORTED_FIBRE | SUPPORTED_TP);
211                         ecmd->advertising |=
212                                 (ADVERTISED_FIBRE | ADVERTISED_TP);
213                         ecmd->port = PORT_FIBRE;
214                         check_sfp_module = netif_running(dev) &&
215                                 adapter->has_link_events;
216                 } else {
217                         ecmd->supported |= (SUPPORTED_TP |SUPPORTED_Autoneg);
218                         ecmd->advertising |=
219                                 (ADVERTISED_TP | ADVERTISED_Autoneg);
220                         ecmd->port = PORT_TP;
221                 }
222                 break;
223         default:
224                 printk(KERN_ERR "netxen-nic: Unsupported board model %d\n",
225                                 adapter->ahw.board_type);
226                 return -EIO;
227         }
228
229         if (check_sfp_module) {
230                 switch (adapter->module_type) {
231                 case LINKEVENT_MODULE_OPTICAL_UNKNOWN:
232                 case LINKEVENT_MODULE_OPTICAL_SRLR:
233                 case LINKEVENT_MODULE_OPTICAL_LRM:
234                 case LINKEVENT_MODULE_OPTICAL_SFP_1G:
235                         ecmd->port = PORT_FIBRE;
236                         break;
237                 case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE:
238                 case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN:
239                 case LINKEVENT_MODULE_TWINAX:
240                         ecmd->port = PORT_TP;
241                         break;
242                 default:
243                         ecmd->port = -1;
244                 }
245         }
246
247         return 0;
248 }
249
250 static int
251 netxen_nic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
252 {
253         struct netxen_adapter *adapter = netdev_priv(dev);
254         int ret;
255
256         if (adapter->ahw.port_type != NETXEN_NIC_GBE)
257                 return -EOPNOTSUPP;
258
259         if (!(adapter->capabilities & NX_FW_CAPABILITY_GBE_LINK_CFG))
260                 return -EOPNOTSUPP;
261
262         ret = nx_fw_cmd_set_gbe_port(adapter, ecmd->speed, ecmd->duplex,
263                                      ecmd->autoneg);
264         if (ret == NX_RCODE_NOT_SUPPORTED)
265                 return -EOPNOTSUPP;
266         else if (ret)
267                 return -EIO;
268
269         adapter->link_speed = ecmd->speed;
270         adapter->link_duplex = ecmd->duplex;
271         adapter->link_autoneg = ecmd->autoneg;
272
273         if (!netif_running(dev))
274                 return 0;
275
276         dev->netdev_ops->ndo_stop(dev);
277         return dev->netdev_ops->ndo_open(dev);
278 }
279
280 static int netxen_nic_get_regs_len(struct net_device *dev)
281 {
282         return NETXEN_NIC_REGS_LEN;
283 }
284
285 static void
286 netxen_nic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
287 {
288         struct netxen_adapter *adapter = netdev_priv(dev);
289         struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
290         struct nx_host_sds_ring *sds_ring;
291         u32 *regs_buff = p;
292         int ring, i = 0;
293         int port = adapter->physical_port;
294
295         memset(p, 0, NETXEN_NIC_REGS_LEN);
296
297         regs->version = (1 << 24) | (adapter->ahw.revision_id << 16) |
298             (adapter->pdev)->device;
299
300         if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
301                 return;
302
303         regs_buff[i++] = NXRD32(adapter, CRB_CMDPEG_STATE);
304         regs_buff[i++] = NXRD32(adapter, CRB_RCVPEG_STATE);
305         regs_buff[i++] = NXRD32(adapter, CRB_FW_CAPABILITIES_1);
306         regs_buff[i++] = NXRDIO(adapter, adapter->crb_int_state_reg);
307         regs_buff[i++] = NXRD32(adapter, NX_CRB_DEV_REF_COUNT);
308         regs_buff[i++] = NXRD32(adapter, NX_CRB_DEV_STATE);
309         regs_buff[i++] = NXRD32(adapter, NETXEN_PEG_ALIVE_COUNTER);
310         regs_buff[i++] = NXRD32(adapter, NETXEN_PEG_HALT_STATUS1);
311         regs_buff[i++] = NXRD32(adapter, NETXEN_PEG_HALT_STATUS2);
312
313         regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_0+0x3c);
314         regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_1+0x3c);
315         regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_2+0x3c);
316         regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_3+0x3c);
317
318         if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
319
320                 regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_4+0x3c);
321                 i += 2;
322
323                 regs_buff[i++] = NXRD32(adapter, CRB_XG_STATE_P3);
324                 regs_buff[i++] = le32_to_cpu(*(adapter->tx_ring->hw_consumer));
325
326         } else {
327                 i++;
328
329                 regs_buff[i++] = NXRD32(adapter,
330                                         NETXEN_NIU_XGE_CONFIG_0+(0x10000*port));
331                 regs_buff[i++] = NXRD32(adapter,
332                                         NETXEN_NIU_XGE_CONFIG_1+(0x10000*port));
333
334                 regs_buff[i++] = NXRD32(adapter, CRB_XG_STATE);
335                 regs_buff[i++] = NXRDIO(adapter,
336                                  adapter->tx_ring->crb_cmd_consumer);
337         }
338
339         regs_buff[i++] = NXRDIO(adapter, adapter->tx_ring->crb_cmd_producer);
340
341         regs_buff[i++] = NXRDIO(adapter,
342                          recv_ctx->rds_rings[0].crb_rcv_producer);
343         regs_buff[i++] = NXRDIO(adapter,
344                          recv_ctx->rds_rings[1].crb_rcv_producer);
345
346         regs_buff[i++] = adapter->max_sds_rings;
347
348         for (ring = 0; ring < adapter->max_sds_rings; ring++) {
349                 sds_ring = &(recv_ctx->sds_rings[ring]);
350                 regs_buff[i++] = NXRDIO(adapter,
351                                         sds_ring->crb_sts_consumer);
352         }
353 }
354
355 static u32 netxen_nic_test_link(struct net_device *dev)
356 {
357         struct netxen_adapter *adapter = netdev_priv(dev);
358         u32 val, port;
359
360         port = adapter->physical_port;
361         if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
362                 val = NXRD32(adapter, CRB_XG_STATE_P3);
363                 val = XG_LINK_STATE_P3(adapter->ahw.pci_func, val);
364                 return (val == XG_LINK_UP_P3) ? 0 : 1;
365         } else {
366                 val = NXRD32(adapter, CRB_XG_STATE);
367                 val = (val >> port*8) & 0xff;
368                 return (val == XG_LINK_UP) ? 0 : 1;
369         }
370 }
371
372 static int
373 netxen_nic_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
374                       u8 * bytes)
375 {
376         struct netxen_adapter *adapter = netdev_priv(dev);
377         int offset;
378         int ret;
379
380         if (eeprom->len == 0)
381                 return -EINVAL;
382
383         eeprom->magic = (adapter->pdev)->vendor |
384                         ((adapter->pdev)->device << 16);
385         offset = eeprom->offset;
386
387         ret = netxen_rom_fast_read_words(adapter, offset, bytes,
388                                                 eeprom->len);
389         if (ret < 0)
390                 return ret;
391
392         return 0;
393 }
394
395 static void
396 netxen_nic_get_ringparam(struct net_device *dev,
397                 struct ethtool_ringparam *ring)
398 {
399         struct netxen_adapter *adapter = netdev_priv(dev);
400
401         ring->rx_pending = adapter->num_rxd;
402         ring->rx_jumbo_pending = adapter->num_jumbo_rxd;
403         ring->rx_jumbo_pending += adapter->num_lro_rxd;
404         ring->tx_pending = adapter->num_txd;
405
406         if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
407                 ring->rx_max_pending = MAX_RCV_DESCRIPTORS_1G;
408                 ring->rx_jumbo_max_pending = MAX_JUMBO_RCV_DESCRIPTORS_1G;
409         } else {
410                 ring->rx_max_pending = MAX_RCV_DESCRIPTORS_10G;
411                 ring->rx_jumbo_max_pending = MAX_JUMBO_RCV_DESCRIPTORS_10G;
412         }
413
414         ring->tx_max_pending = MAX_CMD_DESCRIPTORS;
415
416         ring->rx_mini_max_pending = 0;
417         ring->rx_mini_pending = 0;
418 }
419
420 static u32
421 netxen_validate_ringparam(u32 val, u32 min, u32 max, char *r_name)
422 {
423         u32 num_desc;
424         num_desc = max(val, min);
425         num_desc = min(num_desc, max);
426         num_desc = roundup_pow_of_two(num_desc);
427
428         if (val != num_desc) {
429                 printk(KERN_INFO "%s: setting %s ring size %d instead of %d\n",
430                        netxen_nic_driver_name, r_name, num_desc, val);
431         }
432
433         return num_desc;
434 }
435
436 static int
437 netxen_nic_set_ringparam(struct net_device *dev,
438                 struct ethtool_ringparam *ring)
439 {
440         struct netxen_adapter *adapter = netdev_priv(dev);
441         u16 max_rcv_desc = MAX_RCV_DESCRIPTORS_10G;
442         u16 max_jumbo_desc = MAX_JUMBO_RCV_DESCRIPTORS_10G;
443         u16 num_rxd, num_jumbo_rxd, num_txd;
444
445         if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
446                 return -EOPNOTSUPP;
447
448         if (ring->rx_mini_pending)
449                 return -EOPNOTSUPP;
450
451         if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
452                 max_rcv_desc = MAX_RCV_DESCRIPTORS_1G;
453                 max_jumbo_desc = MAX_JUMBO_RCV_DESCRIPTORS_10G;
454         }
455
456         num_rxd = netxen_validate_ringparam(ring->rx_pending,
457                         MIN_RCV_DESCRIPTORS, max_rcv_desc, "rx");
458
459         num_jumbo_rxd = netxen_validate_ringparam(ring->rx_jumbo_pending,
460                         MIN_JUMBO_DESCRIPTORS, max_jumbo_desc, "rx jumbo");
461
462         num_txd = netxen_validate_ringparam(ring->tx_pending,
463                         MIN_CMD_DESCRIPTORS, MAX_CMD_DESCRIPTORS, "tx");
464
465         if (num_rxd == adapter->num_rxd && num_txd == adapter->num_txd &&
466                         num_jumbo_rxd == adapter->num_jumbo_rxd)
467                 return 0;
468
469         adapter->num_rxd = num_rxd;
470         adapter->num_jumbo_rxd = num_jumbo_rxd;
471         adapter->num_txd = num_txd;
472
473         return netxen_nic_reset_context(adapter);
474 }
475
476 static void
477 netxen_nic_get_pauseparam(struct net_device *dev,
478                           struct ethtool_pauseparam *pause)
479 {
480         struct netxen_adapter *adapter = netdev_priv(dev);
481         __u32 val;
482         int port = adapter->physical_port;
483
484         if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
485                 if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS))
486                         return;
487                 /* get flow control settings */
488                 val = NXRD32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port));
489                 pause->rx_pause = netxen_gb_get_rx_flowctl(val);
490                 val = NXRD32(adapter, NETXEN_NIU_GB_PAUSE_CTL);
491                 switch (port) {
492                         case 0:
493                                 pause->tx_pause = !(netxen_gb_get_gb0_mask(val));
494                                 break;
495                         case 1:
496                                 pause->tx_pause = !(netxen_gb_get_gb1_mask(val));
497                                 break;
498                         case 2:
499                                 pause->tx_pause = !(netxen_gb_get_gb2_mask(val));
500                                 break;
501                         case 3:
502                         default:
503                                 pause->tx_pause = !(netxen_gb_get_gb3_mask(val));
504                                 break;
505                 }
506         } else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
507                 if ((port < 0) || (port > NETXEN_NIU_MAX_XG_PORTS))
508                         return;
509                 pause->rx_pause = 1;
510                 val = NXRD32(adapter, NETXEN_NIU_XG_PAUSE_CTL);
511                 if (port == 0)
512                         pause->tx_pause = !(netxen_xg_get_xg0_mask(val));
513                 else
514                         pause->tx_pause = !(netxen_xg_get_xg1_mask(val));
515         } else {
516                 printk(KERN_ERR"%s: Unknown board type: %x\n",
517                                 netxen_nic_driver_name, adapter->ahw.port_type);
518         }
519 }
520
521 static int
522 netxen_nic_set_pauseparam(struct net_device *dev,
523                           struct ethtool_pauseparam *pause)
524 {
525         struct netxen_adapter *adapter = netdev_priv(dev);
526         __u32 val;
527         int port = adapter->physical_port;
528         /* read mode */
529         if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
530                 if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS))
531                         return -EIO;
532                 /* set flow control */
533                 val = NXRD32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port));
534
535                 if (pause->rx_pause)
536                         netxen_gb_rx_flowctl(val);
537                 else
538                         netxen_gb_unset_rx_flowctl(val);
539
540                 NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
541                                 val);
542                 /* set autoneg */
543                 val = NXRD32(adapter, NETXEN_NIU_GB_PAUSE_CTL);
544                 switch (port) {
545                         case 0:
546                                 if (pause->tx_pause)
547                                         netxen_gb_unset_gb0_mask(val);
548                                 else
549                                         netxen_gb_set_gb0_mask(val);
550                                 break;
551                         case 1:
552                                 if (pause->tx_pause)
553                                         netxen_gb_unset_gb1_mask(val);
554                                 else
555                                         netxen_gb_set_gb1_mask(val);
556                                 break;
557                         case 2:
558                                 if (pause->tx_pause)
559                                         netxen_gb_unset_gb2_mask(val);
560                                 else
561                                         netxen_gb_set_gb2_mask(val);
562                                 break;
563                         case 3:
564                         default:
565                                 if (pause->tx_pause)
566                                         netxen_gb_unset_gb3_mask(val);
567                                 else
568                                         netxen_gb_set_gb3_mask(val);
569                                 break;
570                 }
571                 NXWR32(adapter, NETXEN_NIU_GB_PAUSE_CTL, val);
572         } else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
573                 if ((port < 0) || (port > NETXEN_NIU_MAX_XG_PORTS))
574                         return -EIO;
575                 val = NXRD32(adapter, NETXEN_NIU_XG_PAUSE_CTL);
576                 if (port == 0) {
577                         if (pause->tx_pause)
578                                 netxen_xg_unset_xg0_mask(val);
579                         else
580                                 netxen_xg_set_xg0_mask(val);
581                 } else {
582                         if (pause->tx_pause)
583                                 netxen_xg_unset_xg1_mask(val);
584                         else
585                                 netxen_xg_set_xg1_mask(val);
586                 }
587                 NXWR32(adapter, NETXEN_NIU_XG_PAUSE_CTL, val);
588         } else {
589                 printk(KERN_ERR "%s: Unknown board type: %x\n",
590                                 netxen_nic_driver_name,
591                                 adapter->ahw.port_type);
592         }
593         return 0;
594 }
595
596 static int netxen_nic_reg_test(struct net_device *dev)
597 {
598         struct netxen_adapter *adapter = netdev_priv(dev);
599         u32 data_read, data_written;
600
601         data_read = NXRD32(adapter, NETXEN_PCIX_PH_REG(0));
602         if ((data_read & 0xffff) != adapter->pdev->vendor)
603                 return 1;
604
605         if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
606                 return 0;
607
608         data_written = (u32)0xa5a5a5a5;
609
610         NXWR32(adapter, CRB_SCRATCHPAD_TEST, data_written);
611         data_read = NXRD32(adapter, CRB_SCRATCHPAD_TEST);
612         if (data_written != data_read)
613                 return 1;
614
615         return 0;
616 }
617
618 static int netxen_get_sset_count(struct net_device *dev, int sset)
619 {
620         switch (sset) {
621         case ETH_SS_TEST:
622                 return NETXEN_NIC_TEST_LEN;
623         case ETH_SS_STATS:
624                 return NETXEN_NIC_STATS_LEN;
625         default:
626                 return -EOPNOTSUPP;
627         }
628 }
629
630 static void
631 netxen_nic_diag_test(struct net_device *dev, struct ethtool_test *eth_test,
632                      u64 * data)
633 {
634         memset(data, 0, sizeof(uint64_t) * NETXEN_NIC_TEST_LEN);
635         if ((data[0] = netxen_nic_reg_test(dev)))
636                 eth_test->flags |= ETH_TEST_FL_FAILED;
637         /* link test */
638         if ((data[1] = (u64) netxen_nic_test_link(dev)))
639                 eth_test->flags |= ETH_TEST_FL_FAILED;
640 }
641
642 static void
643 netxen_nic_get_strings(struct net_device *dev, u32 stringset, u8 * data)
644 {
645         int index;
646
647         switch (stringset) {
648         case ETH_SS_TEST:
649                 memcpy(data, *netxen_nic_gstrings_test,
650                        NETXEN_NIC_TEST_LEN * ETH_GSTRING_LEN);
651                 break;
652         case ETH_SS_STATS:
653                 for (index = 0; index < NETXEN_NIC_STATS_LEN; index++) {
654                         memcpy(data + index * ETH_GSTRING_LEN,
655                                netxen_nic_gstrings_stats[index].stat_string,
656                                ETH_GSTRING_LEN);
657                 }
658                 break;
659         }
660 }
661
662 static void
663 netxen_nic_get_ethtool_stats(struct net_device *dev,
664                              struct ethtool_stats *stats, u64 * data)
665 {
666         struct netxen_adapter *adapter = netdev_priv(dev);
667         int index;
668
669         for (index = 0; index < NETXEN_NIC_STATS_LEN; index++) {
670                 char *p =
671                     (char *)adapter +
672                     netxen_nic_gstrings_stats[index].stat_offset;
673                 data[index] =
674                     (netxen_nic_gstrings_stats[index].sizeof_stat ==
675                      sizeof(u64)) ? *(u64 *) p : *(u32 *) p;
676         }
677 }
678
679 static u32 netxen_nic_get_tx_csum(struct net_device *dev)
680 {
681         return dev->features & NETIF_F_IP_CSUM;
682 }
683
684 static u32 netxen_nic_get_rx_csum(struct net_device *dev)
685 {
686         struct netxen_adapter *adapter = netdev_priv(dev);
687         return adapter->rx_csum;
688 }
689
690 static int netxen_nic_set_rx_csum(struct net_device *dev, u32 data)
691 {
692         struct netxen_adapter *adapter = netdev_priv(dev);
693
694         if (data) {
695                 adapter->rx_csum = data;
696                 return 0;
697         }
698
699         if (dev->features & NETIF_F_LRO) {
700                 if (netxen_config_hw_lro(adapter, NETXEN_NIC_LRO_DISABLED))
701                         return -EIO;
702
703                 dev->features &= ~NETIF_F_LRO;
704                 netxen_send_lro_cleanup(adapter);
705                 netdev_info(dev, "disabling LRO as rx_csum is off\n");
706         }
707         adapter->rx_csum = data;
708         return 0;
709 }
710
711 static u32 netxen_nic_get_tso(struct net_device *dev)
712 {
713         struct netxen_adapter *adapter = netdev_priv(dev);
714
715         if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
716                 return (dev->features & (NETIF_F_TSO | NETIF_F_TSO6)) != 0;
717
718         return (dev->features & NETIF_F_TSO) != 0;
719 }
720
721 static int netxen_nic_set_tso(struct net_device *dev, u32 data)
722 {
723         if (data) {
724                 struct netxen_adapter *adapter = netdev_priv(dev);
725
726                 dev->features |= NETIF_F_TSO;
727                 if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
728                         dev->features |= NETIF_F_TSO6;
729         } else
730                 dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
731
732         return 0;
733 }
734
735 static void
736 netxen_nic_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
737 {
738         struct netxen_adapter *adapter = netdev_priv(dev);
739         u32 wol_cfg = 0;
740
741         wol->supported = 0;
742         wol->wolopts = 0;
743
744         if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
745                 return;
746
747         wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG_NV);
748         if (wol_cfg & (1UL << adapter->portnum))
749                 wol->supported |= WAKE_MAGIC;
750
751         wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG);
752         if (wol_cfg & (1UL << adapter->portnum))
753                 wol->wolopts |= WAKE_MAGIC;
754 }
755
756 static int
757 netxen_nic_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
758 {
759         struct netxen_adapter *adapter = netdev_priv(dev);
760         u32 wol_cfg = 0;
761
762         if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
763                 return -EOPNOTSUPP;
764
765         if (wol->wolopts & ~WAKE_MAGIC)
766                 return -EOPNOTSUPP;
767
768         wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG_NV);
769         if (!(wol_cfg & (1 << adapter->portnum)))
770                 return -EOPNOTSUPP;
771
772         wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG);
773         if (wol->wolopts & WAKE_MAGIC)
774                 wol_cfg |= 1UL << adapter->portnum;
775         else
776                 wol_cfg &= ~(1UL << adapter->portnum);
777         NXWR32(adapter, NETXEN_WOL_CONFIG, wol_cfg);
778
779         return 0;
780 }
781
782 /*
783  * Set the coalescing parameters. Currently only normal is supported.
784  * If rx_coalesce_usecs == 0 or rx_max_coalesced_frames == 0 then set the
785  * firmware coalescing to default.
786  */
787 static int netxen_set_intr_coalesce(struct net_device *netdev,
788                         struct ethtool_coalesce *ethcoal)
789 {
790         struct netxen_adapter *adapter = netdev_priv(netdev);
791
792         if (!NX_IS_REVISION_P3(adapter->ahw.revision_id))
793                 return -EINVAL;
794
795         if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
796                 return -EINVAL;
797
798         /*
799         * Return Error if unsupported values or
800         * unsupported parameters are set.
801         */
802         if (ethcoal->rx_coalesce_usecs > 0xffff ||
803                 ethcoal->rx_max_coalesced_frames > 0xffff ||
804                 ethcoal->tx_coalesce_usecs > 0xffff ||
805                 ethcoal->tx_max_coalesced_frames > 0xffff ||
806                 ethcoal->rx_coalesce_usecs_irq ||
807                 ethcoal->rx_max_coalesced_frames_irq ||
808                 ethcoal->tx_coalesce_usecs_irq ||
809                 ethcoal->tx_max_coalesced_frames_irq ||
810                 ethcoal->stats_block_coalesce_usecs ||
811                 ethcoal->use_adaptive_rx_coalesce ||
812                 ethcoal->use_adaptive_tx_coalesce ||
813                 ethcoal->pkt_rate_low ||
814                 ethcoal->rx_coalesce_usecs_low ||
815                 ethcoal->rx_max_coalesced_frames_low ||
816                 ethcoal->tx_coalesce_usecs_low ||
817                 ethcoal->tx_max_coalesced_frames_low ||
818                 ethcoal->pkt_rate_high ||
819                 ethcoal->rx_coalesce_usecs_high ||
820                 ethcoal->rx_max_coalesced_frames_high ||
821                 ethcoal->tx_coalesce_usecs_high ||
822                 ethcoal->tx_max_coalesced_frames_high)
823                 return -EINVAL;
824
825         if (!ethcoal->rx_coalesce_usecs ||
826                 !ethcoal->rx_max_coalesced_frames) {
827                 adapter->coal.flags = NETXEN_NIC_INTR_DEFAULT;
828                 adapter->coal.normal.data.rx_time_us =
829                         NETXEN_DEFAULT_INTR_COALESCE_RX_TIME_US;
830                 adapter->coal.normal.data.rx_packets =
831                         NETXEN_DEFAULT_INTR_COALESCE_RX_PACKETS;
832         } else {
833                 adapter->coal.flags = 0;
834                 adapter->coal.normal.data.rx_time_us =
835                 ethcoal->rx_coalesce_usecs;
836                 adapter->coal.normal.data.rx_packets =
837                 ethcoal->rx_max_coalesced_frames;
838         }
839         adapter->coal.normal.data.tx_time_us = ethcoal->tx_coalesce_usecs;
840         adapter->coal.normal.data.tx_packets =
841         ethcoal->tx_max_coalesced_frames;
842
843         netxen_config_intr_coalesce(adapter);
844
845         return 0;
846 }
847
848 static int netxen_get_intr_coalesce(struct net_device *netdev,
849                         struct ethtool_coalesce *ethcoal)
850 {
851         struct netxen_adapter *adapter = netdev_priv(netdev);
852
853         if (!NX_IS_REVISION_P3(adapter->ahw.revision_id))
854                 return -EINVAL;
855
856         if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
857                 return -EINVAL;
858
859         ethcoal->rx_coalesce_usecs = adapter->coal.normal.data.rx_time_us;
860         ethcoal->tx_coalesce_usecs = adapter->coal.normal.data.tx_time_us;
861         ethcoal->rx_max_coalesced_frames =
862                 adapter->coal.normal.data.rx_packets;
863         ethcoal->tx_max_coalesced_frames =
864                 adapter->coal.normal.data.tx_packets;
865
866         return 0;
867 }
868
869 static int netxen_nic_set_flags(struct net_device *netdev, u32 data)
870 {
871         struct netxen_adapter *adapter = netdev_priv(netdev);
872         int hw_lro;
873
874         if (data & ~ETH_FLAG_LRO)
875                 return -EINVAL;
876
877         if (!(adapter->capabilities & NX_FW_CAPABILITY_HW_LRO))
878                 return -EINVAL;
879
880         if (!adapter->rx_csum) {
881                 netdev_info(netdev, "rx csum is off, cannot toggle LRO\n");
882                 return -EINVAL;
883         }
884
885         if (!!(data & ETH_FLAG_LRO) == !!(netdev->features & NETIF_F_LRO))
886                 return 0;
887
888         if (data & ETH_FLAG_LRO) {
889                 hw_lro = NETXEN_NIC_LRO_ENABLED;
890                 netdev->features |= NETIF_F_LRO;
891         } else {
892                 hw_lro = NETXEN_NIC_LRO_DISABLED;
893                 netdev->features &= ~NETIF_F_LRO;
894         }
895
896         if (netxen_config_hw_lro(adapter, hw_lro))
897                 return -EIO;
898
899         if ((hw_lro == 0) && netxen_send_lro_cleanup(adapter))
900                 return -EIO;
901
902
903         return 0;
904 }
905
906 const struct ethtool_ops netxen_nic_ethtool_ops = {
907         .get_settings = netxen_nic_get_settings,
908         .set_settings = netxen_nic_set_settings,
909         .get_drvinfo = netxen_nic_get_drvinfo,
910         .get_regs_len = netxen_nic_get_regs_len,
911         .get_regs = netxen_nic_get_regs,
912         .get_link = ethtool_op_get_link,
913         .get_eeprom_len = netxen_nic_get_eeprom_len,
914         .get_eeprom = netxen_nic_get_eeprom,
915         .get_ringparam = netxen_nic_get_ringparam,
916         .set_ringparam = netxen_nic_set_ringparam,
917         .get_pauseparam = netxen_nic_get_pauseparam,
918         .set_pauseparam = netxen_nic_set_pauseparam,
919         .get_tx_csum = netxen_nic_get_tx_csum,
920         .set_tx_csum = ethtool_op_set_tx_csum,
921         .set_sg = ethtool_op_set_sg,
922         .get_tso = netxen_nic_get_tso,
923         .set_tso = netxen_nic_set_tso,
924         .get_wol = netxen_nic_get_wol,
925         .set_wol = netxen_nic_set_wol,
926         .self_test = netxen_nic_diag_test,
927         .get_strings = netxen_nic_get_strings,
928         .get_ethtool_stats = netxen_nic_get_ethtool_stats,
929         .get_sset_count = netxen_get_sset_count,
930         .get_rx_csum = netxen_nic_get_rx_csum,
931         .set_rx_csum = netxen_nic_set_rx_csum,
932         .get_coalesce = netxen_get_intr_coalesce,
933         .set_coalesce = netxen_set_intr_coalesce,
934         .get_flags = ethtool_op_get_flags,
935         .set_flags = netxen_nic_set_flags,
936 };