Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/upstream-linus
[sfrench/cifs-2.6.git] / drivers / net / bnx2x / bnx2x_ethtool.c
1 /* bnx2x_ethtool.c: Broadcom Everest network driver.
2  *
3  * Copyright (c) 2007-2010 Broadcom Corporation
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation.
8  *
9  * Maintained by: Eilon Greenstein <eilong@broadcom.com>
10  * Written by: Eliezer Tamir
11  * Based on code from Michael Chan's bnx2 driver
12  * UDP CSUM errata workaround by Arik Gendelman
13  * Slowpath and fastpath rework by Vladislav Zolotarov
14  * Statistics and Link management by Yitchak Gertner
15  *
16  */
17 #include <linux/ethtool.h>
18 #include <linux/netdevice.h>
19 #include <linux/types.h>
20 #include <linux/sched.h>
21 #include <linux/crc32.h>
22
23
24 #include "bnx2x.h"
25 #include "bnx2x_cmn.h"
26 #include "bnx2x_dump.h"
27
28
29 static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
30 {
31         struct bnx2x *bp = netdev_priv(dev);
32
33         cmd->supported = bp->port.supported;
34         cmd->advertising = bp->port.advertising;
35
36         if ((bp->state == BNX2X_STATE_OPEN) &&
37             !(bp->flags & MF_FUNC_DIS) &&
38             (bp->link_vars.link_up)) {
39                 cmd->speed = bp->link_vars.line_speed;
40                 cmd->duplex = bp->link_vars.duplex;
41                 if (IS_E1HMF(bp)) {
42                         u16 vn_max_rate;
43
44                         vn_max_rate =
45                                 ((bp->mf_config & FUNC_MF_CFG_MAX_BW_MASK) >>
46                                 FUNC_MF_CFG_MAX_BW_SHIFT) * 100;
47                         if (vn_max_rate < cmd->speed)
48                                 cmd->speed = vn_max_rate;
49                 }
50         } else {
51                 cmd->speed = -1;
52                 cmd->duplex = -1;
53         }
54
55         if (bp->link_params.switch_cfg == SWITCH_CFG_10G) {
56                 u32 ext_phy_type =
57                         XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config);
58
59                 switch (ext_phy_type) {
60                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
61                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
62                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
63                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
64                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
65                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
66                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
67                         cmd->port = PORT_FIBRE;
68                         break;
69
70                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
71                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
72                         cmd->port = PORT_TP;
73                         break;
74
75                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
76                         BNX2X_ERR("XGXS PHY Failure detected 0x%x\n",
77                                   bp->link_params.ext_phy_config);
78                         break;
79
80                 default:
81                         DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
82                            bp->link_params.ext_phy_config);
83                         break;
84                 }
85         } else
86                 cmd->port = PORT_TP;
87
88         cmd->phy_address = bp->mdio.prtad;
89         cmd->transceiver = XCVR_INTERNAL;
90
91         if (bp->link_params.req_line_speed == SPEED_AUTO_NEG)
92                 cmd->autoneg = AUTONEG_ENABLE;
93         else
94                 cmd->autoneg = AUTONEG_DISABLE;
95
96         cmd->maxtxpkt = 0;
97         cmd->maxrxpkt = 0;
98
99         DP(NETIF_MSG_LINK, "ethtool_cmd: cmd %d\n"
100            DP_LEVEL "  supported 0x%x  advertising 0x%x  speed %d\n"
101            DP_LEVEL "  duplex %d  port %d  phy_address %d  transceiver %d\n"
102            DP_LEVEL "  autoneg %d  maxtxpkt %d  maxrxpkt %d\n",
103            cmd->cmd, cmd->supported, cmd->advertising, cmd->speed,
104            cmd->duplex, cmd->port, cmd->phy_address, cmd->transceiver,
105            cmd->autoneg, cmd->maxtxpkt, cmd->maxrxpkt);
106
107         return 0;
108 }
109
110 static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
111 {
112         struct bnx2x *bp = netdev_priv(dev);
113         u32 advertising;
114
115         if (IS_E1HMF(bp))
116                 return 0;
117
118         DP(NETIF_MSG_LINK, "ethtool_cmd: cmd %d\n"
119            DP_LEVEL "  supported 0x%x  advertising 0x%x  speed %d\n"
120            DP_LEVEL "  duplex %d  port %d  phy_address %d  transceiver %d\n"
121            DP_LEVEL "  autoneg %d  maxtxpkt %d  maxrxpkt %d\n",
122            cmd->cmd, cmd->supported, cmd->advertising, cmd->speed,
123            cmd->duplex, cmd->port, cmd->phy_address, cmd->transceiver,
124            cmd->autoneg, cmd->maxtxpkt, cmd->maxrxpkt);
125
126         if (cmd->autoneg == AUTONEG_ENABLE) {
127                 if (!(bp->port.supported & SUPPORTED_Autoneg)) {
128                         DP(NETIF_MSG_LINK, "Autoneg not supported\n");
129                         return -EINVAL;
130                 }
131
132                 /* advertise the requested speed and duplex if supported */
133                 cmd->advertising &= bp->port.supported;
134
135                 bp->link_params.req_line_speed = SPEED_AUTO_NEG;
136                 bp->link_params.req_duplex = DUPLEX_FULL;
137                 bp->port.advertising |= (ADVERTISED_Autoneg |
138                                          cmd->advertising);
139
140         } else { /* forced speed */
141                 /* advertise the requested speed and duplex if supported */
142                 switch (cmd->speed) {
143                 case SPEED_10:
144                         if (cmd->duplex == DUPLEX_FULL) {
145                                 if (!(bp->port.supported &
146                                       SUPPORTED_10baseT_Full)) {
147                                         DP(NETIF_MSG_LINK,
148                                            "10M full not supported\n");
149                                         return -EINVAL;
150                                 }
151
152                                 advertising = (ADVERTISED_10baseT_Full |
153                                                ADVERTISED_TP);
154                         } else {
155                                 if (!(bp->port.supported &
156                                       SUPPORTED_10baseT_Half)) {
157                                         DP(NETIF_MSG_LINK,
158                                            "10M half not supported\n");
159                                         return -EINVAL;
160                                 }
161
162                                 advertising = (ADVERTISED_10baseT_Half |
163                                                ADVERTISED_TP);
164                         }
165                         break;
166
167                 case SPEED_100:
168                         if (cmd->duplex == DUPLEX_FULL) {
169                                 if (!(bp->port.supported &
170                                                 SUPPORTED_100baseT_Full)) {
171                                         DP(NETIF_MSG_LINK,
172                                            "100M full not supported\n");
173                                         return -EINVAL;
174                                 }
175
176                                 advertising = (ADVERTISED_100baseT_Full |
177                                                ADVERTISED_TP);
178                         } else {
179                                 if (!(bp->port.supported &
180                                                 SUPPORTED_100baseT_Half)) {
181                                         DP(NETIF_MSG_LINK,
182                                            "100M half not supported\n");
183                                         return -EINVAL;
184                                 }
185
186                                 advertising = (ADVERTISED_100baseT_Half |
187                                                ADVERTISED_TP);
188                         }
189                         break;
190
191                 case SPEED_1000:
192                         if (cmd->duplex != DUPLEX_FULL) {
193                                 DP(NETIF_MSG_LINK, "1G half not supported\n");
194                                 return -EINVAL;
195                         }
196
197                         if (!(bp->port.supported & SUPPORTED_1000baseT_Full)) {
198                                 DP(NETIF_MSG_LINK, "1G full not supported\n");
199                                 return -EINVAL;
200                         }
201
202                         advertising = (ADVERTISED_1000baseT_Full |
203                                        ADVERTISED_TP);
204                         break;
205
206                 case SPEED_2500:
207                         if (cmd->duplex != DUPLEX_FULL) {
208                                 DP(NETIF_MSG_LINK,
209                                    "2.5G half not supported\n");
210                                 return -EINVAL;
211                         }
212
213                         if (!(bp->port.supported & SUPPORTED_2500baseX_Full)) {
214                                 DP(NETIF_MSG_LINK,
215                                    "2.5G full not supported\n");
216                                 return -EINVAL;
217                         }
218
219                         advertising = (ADVERTISED_2500baseX_Full |
220                                        ADVERTISED_TP);
221                         break;
222
223                 case SPEED_10000:
224                         if (cmd->duplex != DUPLEX_FULL) {
225                                 DP(NETIF_MSG_LINK, "10G half not supported\n");
226                                 return -EINVAL;
227                         }
228
229                         if (!(bp->port.supported & SUPPORTED_10000baseT_Full)) {
230                                 DP(NETIF_MSG_LINK, "10G full not supported\n");
231                                 return -EINVAL;
232                         }
233
234                         advertising = (ADVERTISED_10000baseT_Full |
235                                        ADVERTISED_FIBRE);
236                         break;
237
238                 default:
239                         DP(NETIF_MSG_LINK, "Unsupported speed\n");
240                         return -EINVAL;
241                 }
242
243                 bp->link_params.req_line_speed = cmd->speed;
244                 bp->link_params.req_duplex = cmd->duplex;
245                 bp->port.advertising = advertising;
246         }
247
248         DP(NETIF_MSG_LINK, "req_line_speed %d\n"
249            DP_LEVEL "  req_duplex %d  advertising 0x%x\n",
250            bp->link_params.req_line_speed, bp->link_params.req_duplex,
251            bp->port.advertising);
252
253         if (netif_running(dev)) {
254                 bnx2x_stats_handle(bp, STATS_EVENT_STOP);
255                 bnx2x_link_set(bp);
256         }
257
258         return 0;
259 }
260
261 #define IS_E1_ONLINE(info)      (((info) & RI_E1_ONLINE) == RI_E1_ONLINE)
262 #define IS_E1H_ONLINE(info)     (((info) & RI_E1H_ONLINE) == RI_E1H_ONLINE)
263
264 static int bnx2x_get_regs_len(struct net_device *dev)
265 {
266         struct bnx2x *bp = netdev_priv(dev);
267         int regdump_len = 0;
268         int i;
269
270         if (CHIP_IS_E1(bp)) {
271                 for (i = 0; i < REGS_COUNT; i++)
272                         if (IS_E1_ONLINE(reg_addrs[i].info))
273                                 regdump_len += reg_addrs[i].size;
274
275                 for (i = 0; i < WREGS_COUNT_E1; i++)
276                         if (IS_E1_ONLINE(wreg_addrs_e1[i].info))
277                                 regdump_len += wreg_addrs_e1[i].size *
278                                         (1 + wreg_addrs_e1[i].read_regs_count);
279
280         } else { /* E1H */
281                 for (i = 0; i < REGS_COUNT; i++)
282                         if (IS_E1H_ONLINE(reg_addrs[i].info))
283                                 regdump_len += reg_addrs[i].size;
284
285                 for (i = 0; i < WREGS_COUNT_E1H; i++)
286                         if (IS_E1H_ONLINE(wreg_addrs_e1h[i].info))
287                                 regdump_len += wreg_addrs_e1h[i].size *
288                                         (1 + wreg_addrs_e1h[i].read_regs_count);
289         }
290         regdump_len *= 4;
291         regdump_len += sizeof(struct dump_hdr);
292
293         return regdump_len;
294 }
295
296 static void bnx2x_get_regs(struct net_device *dev,
297                            struct ethtool_regs *regs, void *_p)
298 {
299         u32 *p = _p, i, j;
300         struct bnx2x *bp = netdev_priv(dev);
301         struct dump_hdr dump_hdr = {0};
302
303         regs->version = 0;
304         memset(p, 0, regs->len);
305
306         if (!netif_running(bp->dev))
307                 return;
308
309         dump_hdr.hdr_size = (sizeof(struct dump_hdr) / 4) - 1;
310         dump_hdr.dump_sign = dump_sign_all;
311         dump_hdr.xstorm_waitp = REG_RD(bp, XSTORM_WAITP_ADDR);
312         dump_hdr.tstorm_waitp = REG_RD(bp, TSTORM_WAITP_ADDR);
313         dump_hdr.ustorm_waitp = REG_RD(bp, USTORM_WAITP_ADDR);
314         dump_hdr.cstorm_waitp = REG_RD(bp, CSTORM_WAITP_ADDR);
315         dump_hdr.info = CHIP_IS_E1(bp) ? RI_E1_ONLINE : RI_E1H_ONLINE;
316
317         memcpy(p, &dump_hdr, sizeof(struct dump_hdr));
318         p += dump_hdr.hdr_size + 1;
319
320         if (CHIP_IS_E1(bp)) {
321                 for (i = 0; i < REGS_COUNT; i++)
322                         if (IS_E1_ONLINE(reg_addrs[i].info))
323                                 for (j = 0; j < reg_addrs[i].size; j++)
324                                         *p++ = REG_RD(bp,
325                                                       reg_addrs[i].addr + j*4);
326
327         } else { /* E1H */
328                 for (i = 0; i < REGS_COUNT; i++)
329                         if (IS_E1H_ONLINE(reg_addrs[i].info))
330                                 for (j = 0; j < reg_addrs[i].size; j++)
331                                         *p++ = REG_RD(bp,
332                                                       reg_addrs[i].addr + j*4);
333         }
334 }
335
336 #define PHY_FW_VER_LEN                  10
337
338 static void bnx2x_get_drvinfo(struct net_device *dev,
339                               struct ethtool_drvinfo *info)
340 {
341         struct bnx2x *bp = netdev_priv(dev);
342         u8 phy_fw_ver[PHY_FW_VER_LEN];
343
344         strcpy(info->driver, DRV_MODULE_NAME);
345         strcpy(info->version, DRV_MODULE_VERSION);
346
347         phy_fw_ver[0] = '\0';
348         if (bp->port.pmf) {
349                 bnx2x_acquire_phy_lock(bp);
350                 bnx2x_get_ext_phy_fw_version(&bp->link_params,
351                                              (bp->state != BNX2X_STATE_CLOSED),
352                                              phy_fw_ver, PHY_FW_VER_LEN);
353                 bnx2x_release_phy_lock(bp);
354         }
355
356         strncpy(info->fw_version, bp->fw_ver, 32);
357         snprintf(info->fw_version + strlen(bp->fw_ver), 32 - strlen(bp->fw_ver),
358                  "bc %d.%d.%d%s%s",
359                  (bp->common.bc_ver & 0xff0000) >> 16,
360                  (bp->common.bc_ver & 0xff00) >> 8,
361                  (bp->common.bc_ver & 0xff),
362                  ((phy_fw_ver[0] != '\0') ? " phy " : ""), phy_fw_ver);
363         strcpy(info->bus_info, pci_name(bp->pdev));
364         info->n_stats = BNX2X_NUM_STATS;
365         info->testinfo_len = BNX2X_NUM_TESTS;
366         info->eedump_len = bp->common.flash_size;
367         info->regdump_len = bnx2x_get_regs_len(dev);
368 }
369
370 static void bnx2x_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
371 {
372         struct bnx2x *bp = netdev_priv(dev);
373
374         if (bp->flags & NO_WOL_FLAG) {
375                 wol->supported = 0;
376                 wol->wolopts = 0;
377         } else {
378                 wol->supported = WAKE_MAGIC;
379                 if (bp->wol)
380                         wol->wolopts = WAKE_MAGIC;
381                 else
382                         wol->wolopts = 0;
383         }
384         memset(&wol->sopass, 0, sizeof(wol->sopass));
385 }
386
387 static int bnx2x_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
388 {
389         struct bnx2x *bp = netdev_priv(dev);
390
391         if (wol->wolopts & ~WAKE_MAGIC)
392                 return -EINVAL;
393
394         if (wol->wolopts & WAKE_MAGIC) {
395                 if (bp->flags & NO_WOL_FLAG)
396                         return -EINVAL;
397
398                 bp->wol = 1;
399         } else
400                 bp->wol = 0;
401
402         return 0;
403 }
404
405 static u32 bnx2x_get_msglevel(struct net_device *dev)
406 {
407         struct bnx2x *bp = netdev_priv(dev);
408
409         return bp->msg_enable;
410 }
411
412 static void bnx2x_set_msglevel(struct net_device *dev, u32 level)
413 {
414         struct bnx2x *bp = netdev_priv(dev);
415
416         if (capable(CAP_NET_ADMIN))
417                 bp->msg_enable = level;
418 }
419
420 static int bnx2x_nway_reset(struct net_device *dev)
421 {
422         struct bnx2x *bp = netdev_priv(dev);
423
424         if (!bp->port.pmf)
425                 return 0;
426
427         if (netif_running(dev)) {
428                 bnx2x_stats_handle(bp, STATS_EVENT_STOP);
429                 bnx2x_link_set(bp);
430         }
431
432         return 0;
433 }
434
435 static u32 bnx2x_get_link(struct net_device *dev)
436 {
437         struct bnx2x *bp = netdev_priv(dev);
438
439         if (bp->flags & MF_FUNC_DIS)
440                 return 0;
441
442         return bp->link_vars.link_up;
443 }
444
445 static int bnx2x_get_eeprom_len(struct net_device *dev)
446 {
447         struct bnx2x *bp = netdev_priv(dev);
448
449         return bp->common.flash_size;
450 }
451
452 static int bnx2x_acquire_nvram_lock(struct bnx2x *bp)
453 {
454         int port = BP_PORT(bp);
455         int count, i;
456         u32 val = 0;
457
458         /* adjust timeout for emulation/FPGA */
459         count = NVRAM_TIMEOUT_COUNT;
460         if (CHIP_REV_IS_SLOW(bp))
461                 count *= 100;
462
463         /* request access to nvram interface */
464         REG_WR(bp, MCP_REG_MCPR_NVM_SW_ARB,
465                (MCPR_NVM_SW_ARB_ARB_REQ_SET1 << port));
466
467         for (i = 0; i < count*10; i++) {
468                 val = REG_RD(bp, MCP_REG_MCPR_NVM_SW_ARB);
469                 if (val & (MCPR_NVM_SW_ARB_ARB_ARB1 << port))
470                         break;
471
472                 udelay(5);
473         }
474
475         if (!(val & (MCPR_NVM_SW_ARB_ARB_ARB1 << port))) {
476                 DP(BNX2X_MSG_NVM, "cannot get access to nvram interface\n");
477                 return -EBUSY;
478         }
479
480         return 0;
481 }
482
483 static int bnx2x_release_nvram_lock(struct bnx2x *bp)
484 {
485         int port = BP_PORT(bp);
486         int count, i;
487         u32 val = 0;
488
489         /* adjust timeout for emulation/FPGA */
490         count = NVRAM_TIMEOUT_COUNT;
491         if (CHIP_REV_IS_SLOW(bp))
492                 count *= 100;
493
494         /* relinquish nvram interface */
495         REG_WR(bp, MCP_REG_MCPR_NVM_SW_ARB,
496                (MCPR_NVM_SW_ARB_ARB_REQ_CLR1 << port));
497
498         for (i = 0; i < count*10; i++) {
499                 val = REG_RD(bp, MCP_REG_MCPR_NVM_SW_ARB);
500                 if (!(val & (MCPR_NVM_SW_ARB_ARB_ARB1 << port)))
501                         break;
502
503                 udelay(5);
504         }
505
506         if (val & (MCPR_NVM_SW_ARB_ARB_ARB1 << port)) {
507                 DP(BNX2X_MSG_NVM, "cannot free access to nvram interface\n");
508                 return -EBUSY;
509         }
510
511         return 0;
512 }
513
514 static void bnx2x_enable_nvram_access(struct bnx2x *bp)
515 {
516         u32 val;
517
518         val = REG_RD(bp, MCP_REG_MCPR_NVM_ACCESS_ENABLE);
519
520         /* enable both bits, even on read */
521         REG_WR(bp, MCP_REG_MCPR_NVM_ACCESS_ENABLE,
522                (val | MCPR_NVM_ACCESS_ENABLE_EN |
523                       MCPR_NVM_ACCESS_ENABLE_WR_EN));
524 }
525
526 static void bnx2x_disable_nvram_access(struct bnx2x *bp)
527 {
528         u32 val;
529
530         val = REG_RD(bp, MCP_REG_MCPR_NVM_ACCESS_ENABLE);
531
532         /* disable both bits, even after read */
533         REG_WR(bp, MCP_REG_MCPR_NVM_ACCESS_ENABLE,
534                (val & ~(MCPR_NVM_ACCESS_ENABLE_EN |
535                         MCPR_NVM_ACCESS_ENABLE_WR_EN)));
536 }
537
538 static int bnx2x_nvram_read_dword(struct bnx2x *bp, u32 offset, __be32 *ret_val,
539                                   u32 cmd_flags)
540 {
541         int count, i, rc;
542         u32 val;
543
544         /* build the command word */
545         cmd_flags |= MCPR_NVM_COMMAND_DOIT;
546
547         /* need to clear DONE bit separately */
548         REG_WR(bp, MCP_REG_MCPR_NVM_COMMAND, MCPR_NVM_COMMAND_DONE);
549
550         /* address of the NVRAM to read from */
551         REG_WR(bp, MCP_REG_MCPR_NVM_ADDR,
552                (offset & MCPR_NVM_ADDR_NVM_ADDR_VALUE));
553
554         /* issue a read command */
555         REG_WR(bp, MCP_REG_MCPR_NVM_COMMAND, cmd_flags);
556
557         /* adjust timeout for emulation/FPGA */
558         count = NVRAM_TIMEOUT_COUNT;
559         if (CHIP_REV_IS_SLOW(bp))
560                 count *= 100;
561
562         /* wait for completion */
563         *ret_val = 0;
564         rc = -EBUSY;
565         for (i = 0; i < count; i++) {
566                 udelay(5);
567                 val = REG_RD(bp, MCP_REG_MCPR_NVM_COMMAND);
568
569                 if (val & MCPR_NVM_COMMAND_DONE) {
570                         val = REG_RD(bp, MCP_REG_MCPR_NVM_READ);
571                         /* we read nvram data in cpu order
572                          * but ethtool sees it as an array of bytes
573                          * converting to big-endian will do the work */
574                         *ret_val = cpu_to_be32(val);
575                         rc = 0;
576                         break;
577                 }
578         }
579
580         return rc;
581 }
582
583 static int bnx2x_nvram_read(struct bnx2x *bp, u32 offset, u8 *ret_buf,
584                             int buf_size)
585 {
586         int rc;
587         u32 cmd_flags;
588         __be32 val;
589
590         if ((offset & 0x03) || (buf_size & 0x03) || (buf_size == 0)) {
591                 DP(BNX2X_MSG_NVM,
592                    "Invalid parameter: offset 0x%x  buf_size 0x%x\n",
593                    offset, buf_size);
594                 return -EINVAL;
595         }
596
597         if (offset + buf_size > bp->common.flash_size) {
598                 DP(BNX2X_MSG_NVM, "Invalid parameter: offset (0x%x) +"
599                                   " buf_size (0x%x) > flash_size (0x%x)\n",
600                    offset, buf_size, bp->common.flash_size);
601                 return -EINVAL;
602         }
603
604         /* request access to nvram interface */
605         rc = bnx2x_acquire_nvram_lock(bp);
606         if (rc)
607                 return rc;
608
609         /* enable access to nvram interface */
610         bnx2x_enable_nvram_access(bp);
611
612         /* read the first word(s) */
613         cmd_flags = MCPR_NVM_COMMAND_FIRST;
614         while ((buf_size > sizeof(u32)) && (rc == 0)) {
615                 rc = bnx2x_nvram_read_dword(bp, offset, &val, cmd_flags);
616                 memcpy(ret_buf, &val, 4);
617
618                 /* advance to the next dword */
619                 offset += sizeof(u32);
620                 ret_buf += sizeof(u32);
621                 buf_size -= sizeof(u32);
622                 cmd_flags = 0;
623         }
624
625         if (rc == 0) {
626                 cmd_flags |= MCPR_NVM_COMMAND_LAST;
627                 rc = bnx2x_nvram_read_dword(bp, offset, &val, cmd_flags);
628                 memcpy(ret_buf, &val, 4);
629         }
630
631         /* disable access to nvram interface */
632         bnx2x_disable_nvram_access(bp);
633         bnx2x_release_nvram_lock(bp);
634
635         return rc;
636 }
637
638 static int bnx2x_get_eeprom(struct net_device *dev,
639                             struct ethtool_eeprom *eeprom, u8 *eebuf)
640 {
641         struct bnx2x *bp = netdev_priv(dev);
642         int rc;
643
644         if (!netif_running(dev))
645                 return -EAGAIN;
646
647         DP(BNX2X_MSG_NVM, "ethtool_eeprom: cmd %d\n"
648            DP_LEVEL "  magic 0x%x  offset 0x%x (%d)  len 0x%x (%d)\n",
649            eeprom->cmd, eeprom->magic, eeprom->offset, eeprom->offset,
650            eeprom->len, eeprom->len);
651
652         /* parameters already validated in ethtool_get_eeprom */
653
654         rc = bnx2x_nvram_read(bp, eeprom->offset, eebuf, eeprom->len);
655
656         return rc;
657 }
658
659 static int bnx2x_nvram_write_dword(struct bnx2x *bp, u32 offset, u32 val,
660                                    u32 cmd_flags)
661 {
662         int count, i, rc;
663
664         /* build the command word */
665         cmd_flags |= MCPR_NVM_COMMAND_DOIT | MCPR_NVM_COMMAND_WR;
666
667         /* need to clear DONE bit separately */
668         REG_WR(bp, MCP_REG_MCPR_NVM_COMMAND, MCPR_NVM_COMMAND_DONE);
669
670         /* write the data */
671         REG_WR(bp, MCP_REG_MCPR_NVM_WRITE, val);
672
673         /* address of the NVRAM to write to */
674         REG_WR(bp, MCP_REG_MCPR_NVM_ADDR,
675                (offset & MCPR_NVM_ADDR_NVM_ADDR_VALUE));
676
677         /* issue the write command */
678         REG_WR(bp, MCP_REG_MCPR_NVM_COMMAND, cmd_flags);
679
680         /* adjust timeout for emulation/FPGA */
681         count = NVRAM_TIMEOUT_COUNT;
682         if (CHIP_REV_IS_SLOW(bp))
683                 count *= 100;
684
685         /* wait for completion */
686         rc = -EBUSY;
687         for (i = 0; i < count; i++) {
688                 udelay(5);
689                 val = REG_RD(bp, MCP_REG_MCPR_NVM_COMMAND);
690                 if (val & MCPR_NVM_COMMAND_DONE) {
691                         rc = 0;
692                         break;
693                 }
694         }
695
696         return rc;
697 }
698
699 #define BYTE_OFFSET(offset)             (8 * (offset & 0x03))
700
701 static int bnx2x_nvram_write1(struct bnx2x *bp, u32 offset, u8 *data_buf,
702                               int buf_size)
703 {
704         int rc;
705         u32 cmd_flags;
706         u32 align_offset;
707         __be32 val;
708
709         if (offset + buf_size > bp->common.flash_size) {
710                 DP(BNX2X_MSG_NVM, "Invalid parameter: offset (0x%x) +"
711                                   " buf_size (0x%x) > flash_size (0x%x)\n",
712                    offset, buf_size, bp->common.flash_size);
713                 return -EINVAL;
714         }
715
716         /* request access to nvram interface */
717         rc = bnx2x_acquire_nvram_lock(bp);
718         if (rc)
719                 return rc;
720
721         /* enable access to nvram interface */
722         bnx2x_enable_nvram_access(bp);
723
724         cmd_flags = (MCPR_NVM_COMMAND_FIRST | MCPR_NVM_COMMAND_LAST);
725         align_offset = (offset & ~0x03);
726         rc = bnx2x_nvram_read_dword(bp, align_offset, &val, cmd_flags);
727
728         if (rc == 0) {
729                 val &= ~(0xff << BYTE_OFFSET(offset));
730                 val |= (*data_buf << BYTE_OFFSET(offset));
731
732                 /* nvram data is returned as an array of bytes
733                  * convert it back to cpu order */
734                 val = be32_to_cpu(val);
735
736                 rc = bnx2x_nvram_write_dword(bp, align_offset, val,
737                                              cmd_flags);
738         }
739
740         /* disable access to nvram interface */
741         bnx2x_disable_nvram_access(bp);
742         bnx2x_release_nvram_lock(bp);
743
744         return rc;
745 }
746
747 static int bnx2x_nvram_write(struct bnx2x *bp, u32 offset, u8 *data_buf,
748                              int buf_size)
749 {
750         int rc;
751         u32 cmd_flags;
752         u32 val;
753         u32 written_so_far;
754
755         if (buf_size == 1)      /* ethtool */
756                 return bnx2x_nvram_write1(bp, offset, data_buf, buf_size);
757
758         if ((offset & 0x03) || (buf_size & 0x03) || (buf_size == 0)) {
759                 DP(BNX2X_MSG_NVM,
760                    "Invalid parameter: offset 0x%x  buf_size 0x%x\n",
761                    offset, buf_size);
762                 return -EINVAL;
763         }
764
765         if (offset + buf_size > bp->common.flash_size) {
766                 DP(BNX2X_MSG_NVM, "Invalid parameter: offset (0x%x) +"
767                                   " buf_size (0x%x) > flash_size (0x%x)\n",
768                    offset, buf_size, bp->common.flash_size);
769                 return -EINVAL;
770         }
771
772         /* request access to nvram interface */
773         rc = bnx2x_acquire_nvram_lock(bp);
774         if (rc)
775                 return rc;
776
777         /* enable access to nvram interface */
778         bnx2x_enable_nvram_access(bp);
779
780         written_so_far = 0;
781         cmd_flags = MCPR_NVM_COMMAND_FIRST;
782         while ((written_so_far < buf_size) && (rc == 0)) {
783                 if (written_so_far == (buf_size - sizeof(u32)))
784                         cmd_flags |= MCPR_NVM_COMMAND_LAST;
785                 else if (((offset + 4) % NVRAM_PAGE_SIZE) == 0)
786                         cmd_flags |= MCPR_NVM_COMMAND_LAST;
787                 else if ((offset % NVRAM_PAGE_SIZE) == 0)
788                         cmd_flags |= MCPR_NVM_COMMAND_FIRST;
789
790                 memcpy(&val, data_buf, 4);
791
792                 rc = bnx2x_nvram_write_dword(bp, offset, val, cmd_flags);
793
794                 /* advance to the next dword */
795                 offset += sizeof(u32);
796                 data_buf += sizeof(u32);
797                 written_so_far += sizeof(u32);
798                 cmd_flags = 0;
799         }
800
801         /* disable access to nvram interface */
802         bnx2x_disable_nvram_access(bp);
803         bnx2x_release_nvram_lock(bp);
804
805         return rc;
806 }
807
808 static int bnx2x_set_eeprom(struct net_device *dev,
809                             struct ethtool_eeprom *eeprom, u8 *eebuf)
810 {
811         struct bnx2x *bp = netdev_priv(dev);
812         int port = BP_PORT(bp);
813         int rc = 0;
814
815         if (!netif_running(dev))
816                 return -EAGAIN;
817
818         DP(BNX2X_MSG_NVM, "ethtool_eeprom: cmd %d\n"
819            DP_LEVEL "  magic 0x%x  offset 0x%x (%d)  len 0x%x (%d)\n",
820            eeprom->cmd, eeprom->magic, eeprom->offset, eeprom->offset,
821            eeprom->len, eeprom->len);
822
823         /* parameters already validated in ethtool_set_eeprom */
824
825         /* PHY eeprom can be accessed only by the PMF */
826         if ((eeprom->magic >= 0x50485900) && (eeprom->magic <= 0x504859FF) &&
827             !bp->port.pmf)
828                 return -EINVAL;
829
830         if (eeprom->magic == 0x50485950) {
831                 /* 'PHYP' (0x50485950): prepare phy for FW upgrade */
832                 bnx2x_stats_handle(bp, STATS_EVENT_STOP);
833
834                 bnx2x_acquire_phy_lock(bp);
835                 rc |= bnx2x_link_reset(&bp->link_params,
836                                        &bp->link_vars, 0);
837                 if (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config) ==
838                                         PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101)
839                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
840                                        MISC_REGISTERS_GPIO_HIGH, port);
841                 bnx2x_release_phy_lock(bp);
842                 bnx2x_link_report(bp);
843
844         } else if (eeprom->magic == 0x50485952) {
845                 /* 'PHYR' (0x50485952): re-init link after FW upgrade */
846                 if (bp->state == BNX2X_STATE_OPEN) {
847                         bnx2x_acquire_phy_lock(bp);
848                         rc |= bnx2x_link_reset(&bp->link_params,
849                                                &bp->link_vars, 1);
850
851                         rc |= bnx2x_phy_init(&bp->link_params,
852                                              &bp->link_vars);
853                         bnx2x_release_phy_lock(bp);
854                         bnx2x_calc_fc_adv(bp);
855                 }
856         } else if (eeprom->magic == 0x53985943) {
857                 /* 'PHYC' (0x53985943): PHY FW upgrade completed */
858                 if (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config) ==
859                                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101) {
860                         u8 ext_phy_addr =
861                              XGXS_EXT_PHY_ADDR(bp->link_params.ext_phy_config);
862
863                         /* DSP Remove Download Mode */
864                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
865                                        MISC_REGISTERS_GPIO_LOW, port);
866
867                         bnx2x_acquire_phy_lock(bp);
868
869                         bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
870
871                         /* wait 0.5 sec to allow it to run */
872                         msleep(500);
873                         bnx2x_ext_phy_hw_reset(bp, port);
874                         msleep(500);
875                         bnx2x_release_phy_lock(bp);
876                 }
877         } else
878                 rc = bnx2x_nvram_write(bp, eeprom->offset, eebuf, eeprom->len);
879
880         return rc;
881 }
882 static int bnx2x_get_coalesce(struct net_device *dev,
883                               struct ethtool_coalesce *coal)
884 {
885         struct bnx2x *bp = netdev_priv(dev);
886
887         memset(coal, 0, sizeof(struct ethtool_coalesce));
888
889         coal->rx_coalesce_usecs = bp->rx_ticks;
890         coal->tx_coalesce_usecs = bp->tx_ticks;
891
892         return 0;
893 }
894
895 static int bnx2x_set_coalesce(struct net_device *dev,
896                               struct ethtool_coalesce *coal)
897 {
898         struct bnx2x *bp = netdev_priv(dev);
899
900         bp->rx_ticks = (u16)coal->rx_coalesce_usecs;
901         if (bp->rx_ticks > BNX2X_MAX_COALESCE_TOUT)
902                 bp->rx_ticks = BNX2X_MAX_COALESCE_TOUT;
903
904         bp->tx_ticks = (u16)coal->tx_coalesce_usecs;
905         if (bp->tx_ticks > BNX2X_MAX_COALESCE_TOUT)
906                 bp->tx_ticks = BNX2X_MAX_COALESCE_TOUT;
907
908         if (netif_running(dev))
909                 bnx2x_update_coalesce(bp);
910
911         return 0;
912 }
913
914 static void bnx2x_get_ringparam(struct net_device *dev,
915                                 struct ethtool_ringparam *ering)
916 {
917         struct bnx2x *bp = netdev_priv(dev);
918
919         ering->rx_max_pending = MAX_RX_AVAIL;
920         ering->rx_mini_max_pending = 0;
921         ering->rx_jumbo_max_pending = 0;
922
923         ering->rx_pending = bp->rx_ring_size;
924         ering->rx_mini_pending = 0;
925         ering->rx_jumbo_pending = 0;
926
927         ering->tx_max_pending = MAX_TX_AVAIL;
928         ering->tx_pending = bp->tx_ring_size;
929 }
930
931 static int bnx2x_set_ringparam(struct net_device *dev,
932                                struct ethtool_ringparam *ering)
933 {
934         struct bnx2x *bp = netdev_priv(dev);
935         int rc = 0;
936
937         if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
938                 printk(KERN_ERR "Handling parity error recovery. Try again later\n");
939                 return -EAGAIN;
940         }
941
942         if ((ering->rx_pending > MAX_RX_AVAIL) ||
943             (ering->tx_pending > MAX_TX_AVAIL) ||
944             (ering->tx_pending <= MAX_SKB_FRAGS + 4))
945                 return -EINVAL;
946
947         bp->rx_ring_size = ering->rx_pending;
948         bp->tx_ring_size = ering->tx_pending;
949
950         if (netif_running(dev)) {
951                 bnx2x_nic_unload(bp, UNLOAD_NORMAL);
952                 rc = bnx2x_nic_load(bp, LOAD_NORMAL);
953         }
954
955         return rc;
956 }
957
958 static void bnx2x_get_pauseparam(struct net_device *dev,
959                                  struct ethtool_pauseparam *epause)
960 {
961         struct bnx2x *bp = netdev_priv(dev);
962
963         epause->autoneg = (bp->link_params.req_flow_ctrl ==
964                            BNX2X_FLOW_CTRL_AUTO) &&
965                           (bp->link_params.req_line_speed == SPEED_AUTO_NEG);
966
967         epause->rx_pause = ((bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_RX) ==
968                             BNX2X_FLOW_CTRL_RX);
969         epause->tx_pause = ((bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_TX) ==
970                             BNX2X_FLOW_CTRL_TX);
971
972         DP(NETIF_MSG_LINK, "ethtool_pauseparam: cmd %d\n"
973            DP_LEVEL "  autoneg %d  rx_pause %d  tx_pause %d\n",
974            epause->cmd, epause->autoneg, epause->rx_pause, epause->tx_pause);
975 }
976
977 static int bnx2x_set_pauseparam(struct net_device *dev,
978                                 struct ethtool_pauseparam *epause)
979 {
980         struct bnx2x *bp = netdev_priv(dev);
981
982         if (IS_E1HMF(bp))
983                 return 0;
984
985         DP(NETIF_MSG_LINK, "ethtool_pauseparam: cmd %d\n"
986            DP_LEVEL "  autoneg %d  rx_pause %d  tx_pause %d\n",
987            epause->cmd, epause->autoneg, epause->rx_pause, epause->tx_pause);
988
989         bp->link_params.req_flow_ctrl = BNX2X_FLOW_CTRL_AUTO;
990
991         if (epause->rx_pause)
992                 bp->link_params.req_flow_ctrl |= BNX2X_FLOW_CTRL_RX;
993
994         if (epause->tx_pause)
995                 bp->link_params.req_flow_ctrl |= BNX2X_FLOW_CTRL_TX;
996
997         if (bp->link_params.req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO)
998                 bp->link_params.req_flow_ctrl = BNX2X_FLOW_CTRL_NONE;
999
1000         if (epause->autoneg) {
1001                 if (!(bp->port.supported & SUPPORTED_Autoneg)) {
1002                         DP(NETIF_MSG_LINK, "autoneg not supported\n");
1003                         return -EINVAL;
1004                 }
1005
1006                 if (bp->link_params.req_line_speed == SPEED_AUTO_NEG)
1007                         bp->link_params.req_flow_ctrl = BNX2X_FLOW_CTRL_AUTO;
1008         }
1009
1010         DP(NETIF_MSG_LINK,
1011            "req_flow_ctrl 0x%x\n", bp->link_params.req_flow_ctrl);
1012
1013         if (netif_running(dev)) {
1014                 bnx2x_stats_handle(bp, STATS_EVENT_STOP);
1015                 bnx2x_link_set(bp);
1016         }
1017
1018         return 0;
1019 }
1020
1021 static int bnx2x_set_flags(struct net_device *dev, u32 data)
1022 {
1023         struct bnx2x *bp = netdev_priv(dev);
1024         int changed = 0;
1025         int rc = 0;
1026
1027         if (data & ~(ETH_FLAG_LRO | ETH_FLAG_RXHASH))
1028                 return -EINVAL;
1029
1030         if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
1031                 printk(KERN_ERR "Handling parity error recovery. Try again later\n");
1032                 return -EAGAIN;
1033         }
1034
1035         /* TPA requires Rx CSUM offloading */
1036         if ((data & ETH_FLAG_LRO) && bp->rx_csum) {
1037                 if (!bp->disable_tpa) {
1038                         if (!(dev->features & NETIF_F_LRO)) {
1039                                 dev->features |= NETIF_F_LRO;
1040                                 bp->flags |= TPA_ENABLE_FLAG;
1041                                 changed = 1;
1042                         }
1043                 } else
1044                         rc = -EINVAL;
1045         } else if (dev->features & NETIF_F_LRO) {
1046                 dev->features &= ~NETIF_F_LRO;
1047                 bp->flags &= ~TPA_ENABLE_FLAG;
1048                 changed = 1;
1049         }
1050
1051         if (data & ETH_FLAG_RXHASH)
1052                 dev->features |= NETIF_F_RXHASH;
1053         else
1054                 dev->features &= ~NETIF_F_RXHASH;
1055
1056         if (changed && netif_running(dev)) {
1057                 bnx2x_nic_unload(bp, UNLOAD_NORMAL);
1058                 rc = bnx2x_nic_load(bp, LOAD_NORMAL);
1059         }
1060
1061         return rc;
1062 }
1063
1064 static u32 bnx2x_get_rx_csum(struct net_device *dev)
1065 {
1066         struct bnx2x *bp = netdev_priv(dev);
1067
1068         return bp->rx_csum;
1069 }
1070
1071 static int bnx2x_set_rx_csum(struct net_device *dev, u32 data)
1072 {
1073         struct bnx2x *bp = netdev_priv(dev);
1074         int rc = 0;
1075
1076         if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
1077                 printk(KERN_ERR "Handling parity error recovery. Try again later\n");
1078                 return -EAGAIN;
1079         }
1080
1081         bp->rx_csum = data;
1082
1083         /* Disable TPA, when Rx CSUM is disabled. Otherwise all
1084            TPA'ed packets will be discarded due to wrong TCP CSUM */
1085         if (!data) {
1086                 u32 flags = ethtool_op_get_flags(dev);
1087
1088                 rc = bnx2x_set_flags(dev, (flags & ~ETH_FLAG_LRO));
1089         }
1090
1091         return rc;
1092 }
1093
1094 static int bnx2x_set_tso(struct net_device *dev, u32 data)
1095 {
1096         if (data) {
1097                 dev->features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
1098                 dev->features |= NETIF_F_TSO6;
1099         } else {
1100                 dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO_ECN);
1101                 dev->features &= ~NETIF_F_TSO6;
1102         }
1103
1104         return 0;
1105 }
1106
1107 static const struct {
1108         char string[ETH_GSTRING_LEN];
1109 } bnx2x_tests_str_arr[BNX2X_NUM_TESTS] = {
1110         { "register_test (offline)" },
1111         { "memory_test (offline)" },
1112         { "loopback_test (offline)" },
1113         { "nvram_test (online)" },
1114         { "interrupt_test (online)" },
1115         { "link_test (online)" },
1116         { "idle check (online)" }
1117 };
1118
1119 static int bnx2x_test_registers(struct bnx2x *bp)
1120 {
1121         int idx, i, rc = -ENODEV;
1122         u32 wr_val = 0;
1123         int port = BP_PORT(bp);
1124         static const struct {
1125                 u32 offset0;
1126                 u32 offset1;
1127                 u32 mask;
1128         } reg_tbl[] = {
1129 /* 0 */         { BRB1_REG_PAUSE_LOW_THRESHOLD_0,      4, 0x000003ff },
1130                 { DORQ_REG_DB_ADDR0,                   4, 0xffffffff },
1131                 { HC_REG_AGG_INT_0,                    4, 0x000003ff },
1132                 { PBF_REG_MAC_IF0_ENABLE,              4, 0x00000001 },
1133                 { PBF_REG_P0_INIT_CRD,                 4, 0x000007ff },
1134                 { PRS_REG_CID_PORT_0,                  4, 0x00ffffff },
1135                 { PXP2_REG_PSWRQ_CDU0_L2P,             4, 0x000fffff },
1136                 { PXP2_REG_RQ_CDU0_EFIRST_MEM_ADDR,    8, 0x0003ffff },
1137                 { PXP2_REG_PSWRQ_TM0_L2P,              4, 0x000fffff },
1138                 { PXP2_REG_RQ_USDM0_EFIRST_MEM_ADDR,   8, 0x0003ffff },
1139 /* 10 */        { PXP2_REG_PSWRQ_TSDM0_L2P,            4, 0x000fffff },
1140                 { QM_REG_CONNNUM_0,                    4, 0x000fffff },
1141                 { TM_REG_LIN0_MAX_ACTIVE_CID,          4, 0x0003ffff },
1142                 { SRC_REG_KEYRSS0_0,                  40, 0xffffffff },
1143                 { SRC_REG_KEYRSS0_7,                  40, 0xffffffff },
1144                 { XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 4, 0x00000001 },
1145                 { XCM_REG_WU_DA_CNT_CMD00,             4, 0x00000003 },
1146                 { XCM_REG_GLB_DEL_ACK_MAX_CNT_0,       4, 0x000000ff },
1147                 { NIG_REG_LLH0_T_BIT,                  4, 0x00000001 },
1148                 { NIG_REG_EMAC0_IN_EN,                 4, 0x00000001 },
1149 /* 20 */        { NIG_REG_BMAC0_IN_EN,                 4, 0x00000001 },
1150                 { NIG_REG_XCM0_OUT_EN,                 4, 0x00000001 },
1151                 { NIG_REG_BRB0_OUT_EN,                 4, 0x00000001 },
1152                 { NIG_REG_LLH0_XCM_MASK,               4, 0x00000007 },
1153                 { NIG_REG_LLH0_ACPI_PAT_6_LEN,        68, 0x000000ff },
1154                 { NIG_REG_LLH0_ACPI_PAT_0_CRC,        68, 0xffffffff },
1155                 { NIG_REG_LLH0_DEST_MAC_0_0,         160, 0xffffffff },
1156                 { NIG_REG_LLH0_DEST_IP_0_1,          160, 0xffffffff },
1157                 { NIG_REG_LLH0_IPV4_IPV6_0,          160, 0x00000001 },
1158                 { NIG_REG_LLH0_DEST_UDP_0,           160, 0x0000ffff },
1159 /* 30 */        { NIG_REG_LLH0_DEST_TCP_0,           160, 0x0000ffff },
1160                 { NIG_REG_LLH0_VLAN_ID_0,            160, 0x00000fff },
1161                 { NIG_REG_XGXS_SERDES0_MODE_SEL,       4, 0x00000001 },
1162                 { NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0, 4, 0x00000001 },
1163                 { NIG_REG_STATUS_INTERRUPT_PORT0,      4, 0x07ffffff },
1164                 { NIG_REG_XGXS0_CTRL_EXTREMOTEMDIOST, 24, 0x00000001 },
1165                 { NIG_REG_SERDES0_CTRL_PHY_ADDR,      16, 0x0000001f },
1166
1167                 { 0xffffffff, 0, 0x00000000 }
1168         };
1169
1170         if (!netif_running(bp->dev))
1171                 return rc;
1172
1173         /* Repeat the test twice:
1174            First by writing 0x00000000, second by writing 0xffffffff */
1175         for (idx = 0; idx < 2; idx++) {
1176
1177                 switch (idx) {
1178                 case 0:
1179                         wr_val = 0;
1180                         break;
1181                 case 1:
1182                         wr_val = 0xffffffff;
1183                         break;
1184                 }
1185
1186                 for (i = 0; reg_tbl[i].offset0 != 0xffffffff; i++) {
1187                         u32 offset, mask, save_val, val;
1188
1189                         offset = reg_tbl[i].offset0 + port*reg_tbl[i].offset1;
1190                         mask = reg_tbl[i].mask;
1191
1192                         save_val = REG_RD(bp, offset);
1193
1194                         REG_WR(bp, offset, (wr_val & mask));
1195                         val = REG_RD(bp, offset);
1196
1197                         /* Restore the original register's value */
1198                         REG_WR(bp, offset, save_val);
1199
1200                         /* verify value is as expected */
1201                         if ((val & mask) != (wr_val & mask)) {
1202                                 DP(NETIF_MSG_PROBE,
1203                                    "offset 0x%x: val 0x%x != 0x%x mask 0x%x\n",
1204                                    offset, val, wr_val, mask);
1205                                 goto test_reg_exit;
1206                         }
1207                 }
1208         }
1209
1210         rc = 0;
1211
1212 test_reg_exit:
1213         return rc;
1214 }
1215
1216 static int bnx2x_test_memory(struct bnx2x *bp)
1217 {
1218         int i, j, rc = -ENODEV;
1219         u32 val;
1220         static const struct {
1221                 u32 offset;
1222                 int size;
1223         } mem_tbl[] = {
1224                 { CCM_REG_XX_DESCR_TABLE,   CCM_REG_XX_DESCR_TABLE_SIZE },
1225                 { CFC_REG_ACTIVITY_COUNTER, CFC_REG_ACTIVITY_COUNTER_SIZE },
1226                 { CFC_REG_LINK_LIST,        CFC_REG_LINK_LIST_SIZE },
1227                 { DMAE_REG_CMD_MEM,         DMAE_REG_CMD_MEM_SIZE },
1228                 { TCM_REG_XX_DESCR_TABLE,   TCM_REG_XX_DESCR_TABLE_SIZE },
1229                 { UCM_REG_XX_DESCR_TABLE,   UCM_REG_XX_DESCR_TABLE_SIZE },
1230                 { XCM_REG_XX_DESCR_TABLE,   XCM_REG_XX_DESCR_TABLE_SIZE },
1231
1232                 { 0xffffffff, 0 }
1233         };
1234         static const struct {
1235                 char *name;
1236                 u32 offset;
1237                 u32 e1_mask;
1238                 u32 e1h_mask;
1239         } prty_tbl[] = {
1240                 { "CCM_PRTY_STS",  CCM_REG_CCM_PRTY_STS,   0x3ffc0, 0 },
1241                 { "CFC_PRTY_STS",  CFC_REG_CFC_PRTY_STS,   0x2,     0x2 },
1242                 { "DMAE_PRTY_STS", DMAE_REG_DMAE_PRTY_STS, 0,       0 },
1243                 { "TCM_PRTY_STS",  TCM_REG_TCM_PRTY_STS,   0x3ffc0, 0 },
1244                 { "UCM_PRTY_STS",  UCM_REG_UCM_PRTY_STS,   0x3ffc0, 0 },
1245                 { "XCM_PRTY_STS",  XCM_REG_XCM_PRTY_STS,   0x3ffc1, 0 },
1246
1247                 { NULL, 0xffffffff, 0, 0 }
1248         };
1249
1250         if (!netif_running(bp->dev))
1251                 return rc;
1252
1253         /* Go through all the memories */
1254         for (i = 0; mem_tbl[i].offset != 0xffffffff; i++)
1255                 for (j = 0; j < mem_tbl[i].size; j++)
1256                         REG_RD(bp, mem_tbl[i].offset + j*4);
1257
1258         /* Check the parity status */
1259         for (i = 0; prty_tbl[i].offset != 0xffffffff; i++) {
1260                 val = REG_RD(bp, prty_tbl[i].offset);
1261                 if ((CHIP_IS_E1(bp) && (val & ~(prty_tbl[i].e1_mask))) ||
1262                     (CHIP_IS_E1H(bp) && (val & ~(prty_tbl[i].e1h_mask)))) {
1263                         DP(NETIF_MSG_HW,
1264                            "%s is 0x%x\n", prty_tbl[i].name, val);
1265                         goto test_mem_exit;
1266                 }
1267         }
1268
1269         rc = 0;
1270
1271 test_mem_exit:
1272         return rc;
1273 }
1274
1275 static void bnx2x_wait_for_link(struct bnx2x *bp, u8 link_up)
1276 {
1277         int cnt = 1000;
1278
1279         if (link_up)
1280                 while (bnx2x_link_test(bp) && cnt--)
1281                         msleep(10);
1282 }
1283
1284 static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up)
1285 {
1286         unsigned int pkt_size, num_pkts, i;
1287         struct sk_buff *skb;
1288         unsigned char *packet;
1289         struct bnx2x_fastpath *fp_rx = &bp->fp[0];
1290         struct bnx2x_fastpath *fp_tx = &bp->fp[0];
1291         u16 tx_start_idx, tx_idx;
1292         u16 rx_start_idx, rx_idx;
1293         u16 pkt_prod, bd_prod;
1294         struct sw_tx_bd *tx_buf;
1295         struct eth_tx_start_bd *tx_start_bd;
1296         struct eth_tx_parse_bd *pbd = NULL;
1297         dma_addr_t mapping;
1298         union eth_rx_cqe *cqe;
1299         u8 cqe_fp_flags;
1300         struct sw_rx_bd *rx_buf;
1301         u16 len;
1302         int rc = -ENODEV;
1303
1304         /* check the loopback mode */
1305         switch (loopback_mode) {
1306         case BNX2X_PHY_LOOPBACK:
1307                 if (bp->link_params.loopback_mode != LOOPBACK_XGXS_10)
1308                         return -EINVAL;
1309                 break;
1310         case BNX2X_MAC_LOOPBACK:
1311                 bp->link_params.loopback_mode = LOOPBACK_BMAC;
1312                 bnx2x_phy_init(&bp->link_params, &bp->link_vars);
1313                 break;
1314         default:
1315                 return -EINVAL;
1316         }
1317
1318         /* prepare the loopback packet */
1319         pkt_size = (((bp->dev->mtu < ETH_MAX_PACKET_SIZE) ?
1320                      bp->dev->mtu : ETH_MAX_PACKET_SIZE) + ETH_HLEN);
1321         skb = netdev_alloc_skb(bp->dev, bp->rx_buf_size);
1322         if (!skb) {
1323                 rc = -ENOMEM;
1324                 goto test_loopback_exit;
1325         }
1326         packet = skb_put(skb, pkt_size);
1327         memcpy(packet, bp->dev->dev_addr, ETH_ALEN);
1328         memset(packet + ETH_ALEN, 0, ETH_ALEN);
1329         memset(packet + 2*ETH_ALEN, 0x77, (ETH_HLEN - 2*ETH_ALEN));
1330         for (i = ETH_HLEN; i < pkt_size; i++)
1331                 packet[i] = (unsigned char) (i & 0xff);
1332
1333         /* send the loopback packet */
1334         num_pkts = 0;
1335         tx_start_idx = le16_to_cpu(*fp_tx->tx_cons_sb);
1336         rx_start_idx = le16_to_cpu(*fp_rx->rx_cons_sb);
1337
1338         pkt_prod = fp_tx->tx_pkt_prod++;
1339         tx_buf = &fp_tx->tx_buf_ring[TX_BD(pkt_prod)];
1340         tx_buf->first_bd = fp_tx->tx_bd_prod;
1341         tx_buf->skb = skb;
1342         tx_buf->flags = 0;
1343
1344         bd_prod = TX_BD(fp_tx->tx_bd_prod);
1345         tx_start_bd = &fp_tx->tx_desc_ring[bd_prod].start_bd;
1346         mapping = dma_map_single(&bp->pdev->dev, skb->data,
1347                                  skb_headlen(skb), DMA_TO_DEVICE);
1348         tx_start_bd->addr_hi = cpu_to_le32(U64_HI(mapping));
1349         tx_start_bd->addr_lo = cpu_to_le32(U64_LO(mapping));
1350         tx_start_bd->nbd = cpu_to_le16(2); /* start + pbd */
1351         tx_start_bd->nbytes = cpu_to_le16(skb_headlen(skb));
1352         tx_start_bd->vlan = cpu_to_le16(pkt_prod);
1353         tx_start_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_START_BD;
1354         tx_start_bd->general_data = ((UNICAST_ADDRESS <<
1355                                 ETH_TX_START_BD_ETH_ADDR_TYPE_SHIFT) | 1);
1356
1357         /* turn on parsing and get a BD */
1358         bd_prod = TX_BD(NEXT_TX_IDX(bd_prod));
1359         pbd = &fp_tx->tx_desc_ring[bd_prod].parse_bd;
1360
1361         memset(pbd, 0, sizeof(struct eth_tx_parse_bd));
1362
1363         wmb();
1364
1365         fp_tx->tx_db.data.prod += 2;
1366         barrier();
1367         DOORBELL(bp, fp_tx->index, fp_tx->tx_db.raw);
1368
1369         mmiowb();
1370
1371         num_pkts++;
1372         fp_tx->tx_bd_prod += 2; /* start + pbd */
1373
1374         udelay(100);
1375
1376         tx_idx = le16_to_cpu(*fp_tx->tx_cons_sb);
1377         if (tx_idx != tx_start_idx + num_pkts)
1378                 goto test_loopback_exit;
1379
1380         rx_idx = le16_to_cpu(*fp_rx->rx_cons_sb);
1381         if (rx_idx != rx_start_idx + num_pkts)
1382                 goto test_loopback_exit;
1383
1384         cqe = &fp_rx->rx_comp_ring[RCQ_BD(fp_rx->rx_comp_cons)];
1385         cqe_fp_flags = cqe->fast_path_cqe.type_error_flags;
1386         if (CQE_TYPE(cqe_fp_flags) || (cqe_fp_flags & ETH_RX_ERROR_FALGS))
1387                 goto test_loopback_rx_exit;
1388
1389         len = le16_to_cpu(cqe->fast_path_cqe.pkt_len);
1390         if (len != pkt_size)
1391                 goto test_loopback_rx_exit;
1392
1393         rx_buf = &fp_rx->rx_buf_ring[RX_BD(fp_rx->rx_bd_cons)];
1394         skb = rx_buf->skb;
1395         skb_reserve(skb, cqe->fast_path_cqe.placement_offset);
1396         for (i = ETH_HLEN; i < pkt_size; i++)
1397                 if (*(skb->data + i) != (unsigned char) (i & 0xff))
1398                         goto test_loopback_rx_exit;
1399
1400         rc = 0;
1401
1402 test_loopback_rx_exit:
1403
1404         fp_rx->rx_bd_cons = NEXT_RX_IDX(fp_rx->rx_bd_cons);
1405         fp_rx->rx_bd_prod = NEXT_RX_IDX(fp_rx->rx_bd_prod);
1406         fp_rx->rx_comp_cons = NEXT_RCQ_IDX(fp_rx->rx_comp_cons);
1407         fp_rx->rx_comp_prod = NEXT_RCQ_IDX(fp_rx->rx_comp_prod);
1408
1409         /* Update producers */
1410         bnx2x_update_rx_prod(bp, fp_rx, fp_rx->rx_bd_prod, fp_rx->rx_comp_prod,
1411                              fp_rx->rx_sge_prod);
1412
1413 test_loopback_exit:
1414         bp->link_params.loopback_mode = LOOPBACK_NONE;
1415
1416         return rc;
1417 }
1418
1419 static int bnx2x_test_loopback(struct bnx2x *bp, u8 link_up)
1420 {
1421         int rc = 0, res;
1422
1423         if (BP_NOMCP(bp))
1424                 return rc;
1425
1426         if (!netif_running(bp->dev))
1427                 return BNX2X_LOOPBACK_FAILED;
1428
1429         bnx2x_netif_stop(bp, 1);
1430         bnx2x_acquire_phy_lock(bp);
1431
1432         res = bnx2x_run_loopback(bp, BNX2X_PHY_LOOPBACK, link_up);
1433         if (res) {
1434                 DP(NETIF_MSG_PROBE, "  PHY loopback failed  (res %d)\n", res);
1435                 rc |= BNX2X_PHY_LOOPBACK_FAILED;
1436         }
1437
1438         res = bnx2x_run_loopback(bp, BNX2X_MAC_LOOPBACK, link_up);
1439         if (res) {
1440                 DP(NETIF_MSG_PROBE, "  MAC loopback failed  (res %d)\n", res);
1441                 rc |= BNX2X_MAC_LOOPBACK_FAILED;
1442         }
1443
1444         bnx2x_release_phy_lock(bp);
1445         bnx2x_netif_start(bp);
1446
1447         return rc;
1448 }
1449
1450 #define CRC32_RESIDUAL                  0xdebb20e3
1451
1452 static int bnx2x_test_nvram(struct bnx2x *bp)
1453 {
1454         static const struct {
1455                 int offset;
1456                 int size;
1457         } nvram_tbl[] = {
1458                 {     0,  0x14 }, /* bootstrap */
1459                 {  0x14,  0xec }, /* dir */
1460                 { 0x100, 0x350 }, /* manuf_info */
1461                 { 0x450,  0xf0 }, /* feature_info */
1462                 { 0x640,  0x64 }, /* upgrade_key_info */
1463                 { 0x6a4,  0x64 },
1464                 { 0x708,  0x70 }, /* manuf_key_info */
1465                 { 0x778,  0x70 },
1466                 {     0,     0 }
1467         };
1468         __be32 buf[0x350 / 4];
1469         u8 *data = (u8 *)buf;
1470         int i, rc;
1471         u32 magic, crc;
1472
1473         if (BP_NOMCP(bp))
1474                 return 0;
1475
1476         rc = bnx2x_nvram_read(bp, 0, data, 4);
1477         if (rc) {
1478                 DP(NETIF_MSG_PROBE, "magic value read (rc %d)\n", rc);
1479                 goto test_nvram_exit;
1480         }
1481
1482         magic = be32_to_cpu(buf[0]);
1483         if (magic != 0x669955aa) {
1484                 DP(NETIF_MSG_PROBE, "magic value (0x%08x)\n", magic);
1485                 rc = -ENODEV;
1486                 goto test_nvram_exit;
1487         }
1488
1489         for (i = 0; nvram_tbl[i].size; i++) {
1490
1491                 rc = bnx2x_nvram_read(bp, nvram_tbl[i].offset, data,
1492                                       nvram_tbl[i].size);
1493                 if (rc) {
1494                         DP(NETIF_MSG_PROBE,
1495                            "nvram_tbl[%d] read data (rc %d)\n", i, rc);
1496                         goto test_nvram_exit;
1497                 }
1498
1499                 crc = ether_crc_le(nvram_tbl[i].size, data);
1500                 if (crc != CRC32_RESIDUAL) {
1501                         DP(NETIF_MSG_PROBE,
1502                            "nvram_tbl[%d] crc value (0x%08x)\n", i, crc);
1503                         rc = -ENODEV;
1504                         goto test_nvram_exit;
1505                 }
1506         }
1507
1508 test_nvram_exit:
1509         return rc;
1510 }
1511
1512 static int bnx2x_test_intr(struct bnx2x *bp)
1513 {
1514         struct mac_configuration_cmd *config = bnx2x_sp(bp, mac_config);
1515         int i, rc;
1516
1517         if (!netif_running(bp->dev))
1518                 return -ENODEV;
1519
1520         config->hdr.length = 0;
1521         if (CHIP_IS_E1(bp))
1522                 /* use last unicast entries */
1523                 config->hdr.offset = (BP_PORT(bp) ? 63 : 31);
1524         else
1525                 config->hdr.offset = BP_FUNC(bp);
1526         config->hdr.client_id = bp->fp->cl_id;
1527         config->hdr.reserved1 = 0;
1528
1529         bp->set_mac_pending++;
1530         smp_wmb();
1531         rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0,
1532                            U64_HI(bnx2x_sp_mapping(bp, mac_config)),
1533                            U64_LO(bnx2x_sp_mapping(bp, mac_config)), 0);
1534         if (rc == 0) {
1535                 for (i = 0; i < 10; i++) {
1536                         if (!bp->set_mac_pending)
1537                                 break;
1538                         smp_rmb();
1539                         msleep_interruptible(10);
1540                 }
1541                 if (i == 10)
1542                         rc = -ENODEV;
1543         }
1544
1545         return rc;
1546 }
1547
1548 static void bnx2x_self_test(struct net_device *dev,
1549                             struct ethtool_test *etest, u64 *buf)
1550 {
1551         struct bnx2x *bp = netdev_priv(dev);
1552
1553         if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
1554                 printk(KERN_ERR "Handling parity error recovery. Try again later\n");
1555                 etest->flags |= ETH_TEST_FL_FAILED;
1556                 return;
1557         }
1558
1559         memset(buf, 0, sizeof(u64) * BNX2X_NUM_TESTS);
1560
1561         if (!netif_running(dev))
1562                 return;
1563
1564         /* offline tests are not supported in MF mode */
1565         if (IS_E1HMF(bp))
1566                 etest->flags &= ~ETH_TEST_FL_OFFLINE;
1567
1568         if (etest->flags & ETH_TEST_FL_OFFLINE) {
1569                 int port = BP_PORT(bp);
1570                 u32 val;
1571                 u8 link_up;
1572
1573                 /* save current value of input enable for TX port IF */
1574                 val = REG_RD(bp, NIG_REG_EGRESS_UMP0_IN_EN + port*4);
1575                 /* disable input for TX port IF */
1576                 REG_WR(bp, NIG_REG_EGRESS_UMP0_IN_EN + port*4, 0);
1577
1578                 link_up = (bnx2x_link_test(bp) == 0);
1579                 bnx2x_nic_unload(bp, UNLOAD_NORMAL);
1580                 bnx2x_nic_load(bp, LOAD_DIAG);
1581                 /* wait until link state is restored */
1582                 bnx2x_wait_for_link(bp, link_up);
1583
1584                 if (bnx2x_test_registers(bp) != 0) {
1585                         buf[0] = 1;
1586                         etest->flags |= ETH_TEST_FL_FAILED;
1587                 }
1588                 if (bnx2x_test_memory(bp) != 0) {
1589                         buf[1] = 1;
1590                         etest->flags |= ETH_TEST_FL_FAILED;
1591                 }
1592                 buf[2] = bnx2x_test_loopback(bp, link_up);
1593                 if (buf[2] != 0)
1594                         etest->flags |= ETH_TEST_FL_FAILED;
1595
1596                 bnx2x_nic_unload(bp, UNLOAD_NORMAL);
1597
1598                 /* restore input for TX port IF */
1599                 REG_WR(bp, NIG_REG_EGRESS_UMP0_IN_EN + port*4, val);
1600
1601                 bnx2x_nic_load(bp, LOAD_NORMAL);
1602                 /* wait until link state is restored */
1603                 bnx2x_wait_for_link(bp, link_up);
1604         }
1605         if (bnx2x_test_nvram(bp) != 0) {
1606                 buf[3] = 1;
1607                 etest->flags |= ETH_TEST_FL_FAILED;
1608         }
1609         if (bnx2x_test_intr(bp) != 0) {
1610                 buf[4] = 1;
1611                 etest->flags |= ETH_TEST_FL_FAILED;
1612         }
1613         if (bp->port.pmf)
1614                 if (bnx2x_link_test(bp) != 0) {
1615                         buf[5] = 1;
1616                         etest->flags |= ETH_TEST_FL_FAILED;
1617                 }
1618
1619 #ifdef BNX2X_EXTRA_DEBUG
1620         bnx2x_panic_dump(bp);
1621 #endif
1622 }
1623
1624 static const struct {
1625         long offset;
1626         int size;
1627         u8 string[ETH_GSTRING_LEN];
1628 } bnx2x_q_stats_arr[BNX2X_NUM_Q_STATS] = {
1629 /* 1 */ { Q_STATS_OFFSET32(total_bytes_received_hi), 8, "[%d]: rx_bytes" },
1630         { Q_STATS_OFFSET32(error_bytes_received_hi),
1631                                                 8, "[%d]: rx_error_bytes" },
1632         { Q_STATS_OFFSET32(total_unicast_packets_received_hi),
1633                                                 8, "[%d]: rx_ucast_packets" },
1634         { Q_STATS_OFFSET32(total_multicast_packets_received_hi),
1635                                                 8, "[%d]: rx_mcast_packets" },
1636         { Q_STATS_OFFSET32(total_broadcast_packets_received_hi),
1637                                                 8, "[%d]: rx_bcast_packets" },
1638         { Q_STATS_OFFSET32(no_buff_discard_hi), 8, "[%d]: rx_discards" },
1639         { Q_STATS_OFFSET32(rx_err_discard_pkt),
1640                                          4, "[%d]: rx_phy_ip_err_discards"},
1641         { Q_STATS_OFFSET32(rx_skb_alloc_failed),
1642                                          4, "[%d]: rx_skb_alloc_discard" },
1643         { Q_STATS_OFFSET32(hw_csum_err), 4, "[%d]: rx_csum_offload_errors" },
1644
1645 /* 10 */{ Q_STATS_OFFSET32(total_bytes_transmitted_hi), 8, "[%d]: tx_bytes" },
1646         { Q_STATS_OFFSET32(total_unicast_packets_transmitted_hi),
1647                                                 8, "[%d]: tx_ucast_packets" },
1648         { Q_STATS_OFFSET32(total_multicast_packets_transmitted_hi),
1649                                                 8, "[%d]: tx_mcast_packets" },
1650         { Q_STATS_OFFSET32(total_broadcast_packets_transmitted_hi),
1651                                                 8, "[%d]: tx_bcast_packets" }
1652 };
1653
1654 static const struct {
1655         long offset;
1656         int size;
1657         u32 flags;
1658 #define STATS_FLAGS_PORT                1
1659 #define STATS_FLAGS_FUNC                2
1660 #define STATS_FLAGS_BOTH                (STATS_FLAGS_FUNC | STATS_FLAGS_PORT)
1661         u8 string[ETH_GSTRING_LEN];
1662 } bnx2x_stats_arr[BNX2X_NUM_STATS] = {
1663 /* 1 */ { STATS_OFFSET32(total_bytes_received_hi),
1664                                 8, STATS_FLAGS_BOTH, "rx_bytes" },
1665         { STATS_OFFSET32(error_bytes_received_hi),
1666                                 8, STATS_FLAGS_BOTH, "rx_error_bytes" },
1667         { STATS_OFFSET32(total_unicast_packets_received_hi),
1668                                 8, STATS_FLAGS_BOTH, "rx_ucast_packets" },
1669         { STATS_OFFSET32(total_multicast_packets_received_hi),
1670                                 8, STATS_FLAGS_BOTH, "rx_mcast_packets" },
1671         { STATS_OFFSET32(total_broadcast_packets_received_hi),
1672                                 8, STATS_FLAGS_BOTH, "rx_bcast_packets" },
1673         { STATS_OFFSET32(rx_stat_dot3statsfcserrors_hi),
1674                                 8, STATS_FLAGS_PORT, "rx_crc_errors" },
1675         { STATS_OFFSET32(rx_stat_dot3statsalignmenterrors_hi),
1676                                 8, STATS_FLAGS_PORT, "rx_align_errors" },
1677         { STATS_OFFSET32(rx_stat_etherstatsundersizepkts_hi),
1678                                 8, STATS_FLAGS_PORT, "rx_undersize_packets" },
1679         { STATS_OFFSET32(etherstatsoverrsizepkts_hi),
1680                                 8, STATS_FLAGS_PORT, "rx_oversize_packets" },
1681 /* 10 */{ STATS_OFFSET32(rx_stat_etherstatsfragments_hi),
1682                                 8, STATS_FLAGS_PORT, "rx_fragments" },
1683         { STATS_OFFSET32(rx_stat_etherstatsjabbers_hi),
1684                                 8, STATS_FLAGS_PORT, "rx_jabbers" },
1685         { STATS_OFFSET32(no_buff_discard_hi),
1686                                 8, STATS_FLAGS_BOTH, "rx_discards" },
1687         { STATS_OFFSET32(mac_filter_discard),
1688                                 4, STATS_FLAGS_PORT, "rx_filtered_packets" },
1689         { STATS_OFFSET32(xxoverflow_discard),
1690                                 4, STATS_FLAGS_PORT, "rx_fw_discards" },
1691         { STATS_OFFSET32(brb_drop_hi),
1692                                 8, STATS_FLAGS_PORT, "rx_brb_discard" },
1693         { STATS_OFFSET32(brb_truncate_hi),
1694                                 8, STATS_FLAGS_PORT, "rx_brb_truncate" },
1695         { STATS_OFFSET32(pause_frames_received_hi),
1696                                 8, STATS_FLAGS_PORT, "rx_pause_frames" },
1697         { STATS_OFFSET32(rx_stat_maccontrolframesreceived_hi),
1698                                 8, STATS_FLAGS_PORT, "rx_mac_ctrl_frames" },
1699         { STATS_OFFSET32(nig_timer_max),
1700                         4, STATS_FLAGS_PORT, "rx_constant_pause_events" },
1701 /* 20 */{ STATS_OFFSET32(rx_err_discard_pkt),
1702                                 4, STATS_FLAGS_BOTH, "rx_phy_ip_err_discards"},
1703         { STATS_OFFSET32(rx_skb_alloc_failed),
1704                                 4, STATS_FLAGS_BOTH, "rx_skb_alloc_discard" },
1705         { STATS_OFFSET32(hw_csum_err),
1706                                 4, STATS_FLAGS_BOTH, "rx_csum_offload_errors" },
1707
1708         { STATS_OFFSET32(total_bytes_transmitted_hi),
1709                                 8, STATS_FLAGS_BOTH, "tx_bytes" },
1710         { STATS_OFFSET32(tx_stat_ifhcoutbadoctets_hi),
1711                                 8, STATS_FLAGS_PORT, "tx_error_bytes" },
1712         { STATS_OFFSET32(total_unicast_packets_transmitted_hi),
1713                                 8, STATS_FLAGS_BOTH, "tx_ucast_packets" },
1714         { STATS_OFFSET32(total_multicast_packets_transmitted_hi),
1715                                 8, STATS_FLAGS_BOTH, "tx_mcast_packets" },
1716         { STATS_OFFSET32(total_broadcast_packets_transmitted_hi),
1717                                 8, STATS_FLAGS_BOTH, "tx_bcast_packets" },
1718         { STATS_OFFSET32(tx_stat_dot3statsinternalmactransmiterrors_hi),
1719                                 8, STATS_FLAGS_PORT, "tx_mac_errors" },
1720         { STATS_OFFSET32(rx_stat_dot3statscarriersenseerrors_hi),
1721                                 8, STATS_FLAGS_PORT, "tx_carrier_errors" },
1722 /* 30 */{ STATS_OFFSET32(tx_stat_dot3statssinglecollisionframes_hi),
1723                                 8, STATS_FLAGS_PORT, "tx_single_collisions" },
1724         { STATS_OFFSET32(tx_stat_dot3statsmultiplecollisionframes_hi),
1725                                 8, STATS_FLAGS_PORT, "tx_multi_collisions" },
1726         { STATS_OFFSET32(tx_stat_dot3statsdeferredtransmissions_hi),
1727                                 8, STATS_FLAGS_PORT, "tx_deferred" },
1728         { STATS_OFFSET32(tx_stat_dot3statsexcessivecollisions_hi),
1729                                 8, STATS_FLAGS_PORT, "tx_excess_collisions" },
1730         { STATS_OFFSET32(tx_stat_dot3statslatecollisions_hi),
1731                                 8, STATS_FLAGS_PORT, "tx_late_collisions" },
1732         { STATS_OFFSET32(tx_stat_etherstatscollisions_hi),
1733                                 8, STATS_FLAGS_PORT, "tx_total_collisions" },
1734         { STATS_OFFSET32(tx_stat_etherstatspkts64octets_hi),
1735                                 8, STATS_FLAGS_PORT, "tx_64_byte_packets" },
1736         { STATS_OFFSET32(tx_stat_etherstatspkts65octetsto127octets_hi),
1737                         8, STATS_FLAGS_PORT, "tx_65_to_127_byte_packets" },
1738         { STATS_OFFSET32(tx_stat_etherstatspkts128octetsto255octets_hi),
1739                         8, STATS_FLAGS_PORT, "tx_128_to_255_byte_packets" },
1740         { STATS_OFFSET32(tx_stat_etherstatspkts256octetsto511octets_hi),
1741                         8, STATS_FLAGS_PORT, "tx_256_to_511_byte_packets" },
1742 /* 40 */{ STATS_OFFSET32(tx_stat_etherstatspkts512octetsto1023octets_hi),
1743                         8, STATS_FLAGS_PORT, "tx_512_to_1023_byte_packets" },
1744         { STATS_OFFSET32(etherstatspkts1024octetsto1522octets_hi),
1745                         8, STATS_FLAGS_PORT, "tx_1024_to_1522_byte_packets" },
1746         { STATS_OFFSET32(etherstatspktsover1522octets_hi),
1747                         8, STATS_FLAGS_PORT, "tx_1523_to_9022_byte_packets" },
1748         { STATS_OFFSET32(pause_frames_sent_hi),
1749                                 8, STATS_FLAGS_PORT, "tx_pause_frames" }
1750 };
1751
1752 #define IS_PORT_STAT(i) \
1753         ((bnx2x_stats_arr[i].flags & STATS_FLAGS_BOTH) == STATS_FLAGS_PORT)
1754 #define IS_FUNC_STAT(i)         (bnx2x_stats_arr[i].flags & STATS_FLAGS_FUNC)
1755 #define IS_E1HMF_MODE_STAT(bp) \
1756                         (IS_E1HMF(bp) && !(bp->msg_enable & BNX2X_MSG_STATS))
1757
1758 static int bnx2x_get_sset_count(struct net_device *dev, int stringset)
1759 {
1760         struct bnx2x *bp = netdev_priv(dev);
1761         int i, num_stats;
1762
1763         switch (stringset) {
1764         case ETH_SS_STATS:
1765                 if (is_multi(bp)) {
1766                         num_stats = BNX2X_NUM_Q_STATS * bp->num_queues;
1767                         if (!IS_E1HMF_MODE_STAT(bp))
1768                                 num_stats += BNX2X_NUM_STATS;
1769                 } else {
1770                         if (IS_E1HMF_MODE_STAT(bp)) {
1771                                 num_stats = 0;
1772                                 for (i = 0; i < BNX2X_NUM_STATS; i++)
1773                                         if (IS_FUNC_STAT(i))
1774                                                 num_stats++;
1775                         } else
1776                                 num_stats = BNX2X_NUM_STATS;
1777                 }
1778                 return num_stats;
1779
1780         case ETH_SS_TEST:
1781                 return BNX2X_NUM_TESTS;
1782
1783         default:
1784                 return -EINVAL;
1785         }
1786 }
1787
1788 static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
1789 {
1790         struct bnx2x *bp = netdev_priv(dev);
1791         int i, j, k;
1792
1793         switch (stringset) {
1794         case ETH_SS_STATS:
1795                 if (is_multi(bp)) {
1796                         k = 0;
1797                         for_each_queue(bp, i) {
1798                                 for (j = 0; j < BNX2X_NUM_Q_STATS; j++)
1799                                         sprintf(buf + (k + j)*ETH_GSTRING_LEN,
1800                                                 bnx2x_q_stats_arr[j].string, i);
1801                                 k += BNX2X_NUM_Q_STATS;
1802                         }
1803                         if (IS_E1HMF_MODE_STAT(bp))
1804                                 break;
1805                         for (j = 0; j < BNX2X_NUM_STATS; j++)
1806                                 strcpy(buf + (k + j)*ETH_GSTRING_LEN,
1807                                        bnx2x_stats_arr[j].string);
1808                 } else {
1809                         for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) {
1810                                 if (IS_E1HMF_MODE_STAT(bp) && IS_PORT_STAT(i))
1811                                         continue;
1812                                 strcpy(buf + j*ETH_GSTRING_LEN,
1813                                        bnx2x_stats_arr[i].string);
1814                                 j++;
1815                         }
1816                 }
1817                 break;
1818
1819         case ETH_SS_TEST:
1820                 memcpy(buf, bnx2x_tests_str_arr, sizeof(bnx2x_tests_str_arr));
1821                 break;
1822         }
1823 }
1824
1825 static void bnx2x_get_ethtool_stats(struct net_device *dev,
1826                                     struct ethtool_stats *stats, u64 *buf)
1827 {
1828         struct bnx2x *bp = netdev_priv(dev);
1829         u32 *hw_stats, *offset;
1830         int i, j, k;
1831
1832         if (is_multi(bp)) {
1833                 k = 0;
1834                 for_each_queue(bp, i) {
1835                         hw_stats = (u32 *)&bp->fp[i].eth_q_stats;
1836                         for (j = 0; j < BNX2X_NUM_Q_STATS; j++) {
1837                                 if (bnx2x_q_stats_arr[j].size == 0) {
1838                                         /* skip this counter */
1839                                         buf[k + j] = 0;
1840                                         continue;
1841                                 }
1842                                 offset = (hw_stats +
1843                                           bnx2x_q_stats_arr[j].offset);
1844                                 if (bnx2x_q_stats_arr[j].size == 4) {
1845                                         /* 4-byte counter */
1846                                         buf[k + j] = (u64) *offset;
1847                                         continue;
1848                                 }
1849                                 /* 8-byte counter */
1850                                 buf[k + j] = HILO_U64(*offset, *(offset + 1));
1851                         }
1852                         k += BNX2X_NUM_Q_STATS;
1853                 }
1854                 if (IS_E1HMF_MODE_STAT(bp))
1855                         return;
1856                 hw_stats = (u32 *)&bp->eth_stats;
1857                 for (j = 0; j < BNX2X_NUM_STATS; j++) {
1858                         if (bnx2x_stats_arr[j].size == 0) {
1859                                 /* skip this counter */
1860                                 buf[k + j] = 0;
1861                                 continue;
1862                         }
1863                         offset = (hw_stats + bnx2x_stats_arr[j].offset);
1864                         if (bnx2x_stats_arr[j].size == 4) {
1865                                 /* 4-byte counter */
1866                                 buf[k + j] = (u64) *offset;
1867                                 continue;
1868                         }
1869                         /* 8-byte counter */
1870                         buf[k + j] = HILO_U64(*offset, *(offset + 1));
1871                 }
1872         } else {
1873                 hw_stats = (u32 *)&bp->eth_stats;
1874                 for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) {
1875                         if (IS_E1HMF_MODE_STAT(bp) && IS_PORT_STAT(i))
1876                                 continue;
1877                         if (bnx2x_stats_arr[i].size == 0) {
1878                                 /* skip this counter */
1879                                 buf[j] = 0;
1880                                 j++;
1881                                 continue;
1882                         }
1883                         offset = (hw_stats + bnx2x_stats_arr[i].offset);
1884                         if (bnx2x_stats_arr[i].size == 4) {
1885                                 /* 4-byte counter */
1886                                 buf[j] = (u64) *offset;
1887                                 j++;
1888                                 continue;
1889                         }
1890                         /* 8-byte counter */
1891                         buf[j] = HILO_U64(*offset, *(offset + 1));
1892                         j++;
1893                 }
1894         }
1895 }
1896
1897 static int bnx2x_phys_id(struct net_device *dev, u32 data)
1898 {
1899         struct bnx2x *bp = netdev_priv(dev);
1900         int i;
1901
1902         if (!netif_running(dev))
1903                 return 0;
1904
1905         if (!bp->port.pmf)
1906                 return 0;
1907
1908         if (data == 0)
1909                 data = 2;
1910
1911         for (i = 0; i < (data * 2); i++) {
1912                 if ((i % 2) == 0)
1913                         bnx2x_set_led(&bp->link_params, LED_MODE_OPER,
1914                                       SPEED_1000);
1915                 else
1916                         bnx2x_set_led(&bp->link_params, LED_MODE_OFF, 0);
1917
1918                 msleep_interruptible(500);
1919                 if (signal_pending(current))
1920                         break;
1921         }
1922
1923         if (bp->link_vars.link_up)
1924                 bnx2x_set_led(&bp->link_params, LED_MODE_OPER,
1925                               bp->link_vars.line_speed);
1926
1927         return 0;
1928 }
1929
1930 static const struct ethtool_ops bnx2x_ethtool_ops = {
1931         .get_settings           = bnx2x_get_settings,
1932         .set_settings           = bnx2x_set_settings,
1933         .get_drvinfo            = bnx2x_get_drvinfo,
1934         .get_regs_len           = bnx2x_get_regs_len,
1935         .get_regs               = bnx2x_get_regs,
1936         .get_wol                = bnx2x_get_wol,
1937         .set_wol                = bnx2x_set_wol,
1938         .get_msglevel           = bnx2x_get_msglevel,
1939         .set_msglevel           = bnx2x_set_msglevel,
1940         .nway_reset             = bnx2x_nway_reset,
1941         .get_link               = bnx2x_get_link,
1942         .get_eeprom_len         = bnx2x_get_eeprom_len,
1943         .get_eeprom             = bnx2x_get_eeprom,
1944         .set_eeprom             = bnx2x_set_eeprom,
1945         .get_coalesce           = bnx2x_get_coalesce,
1946         .set_coalesce           = bnx2x_set_coalesce,
1947         .get_ringparam          = bnx2x_get_ringparam,
1948         .set_ringparam          = bnx2x_set_ringparam,
1949         .get_pauseparam         = bnx2x_get_pauseparam,
1950         .set_pauseparam         = bnx2x_set_pauseparam,
1951         .get_rx_csum            = bnx2x_get_rx_csum,
1952         .set_rx_csum            = bnx2x_set_rx_csum,
1953         .get_tx_csum            = ethtool_op_get_tx_csum,
1954         .set_tx_csum            = ethtool_op_set_tx_hw_csum,
1955         .set_flags              = bnx2x_set_flags,
1956         .get_flags              = ethtool_op_get_flags,
1957         .get_sg                 = ethtool_op_get_sg,
1958         .set_sg                 = ethtool_op_set_sg,
1959         .get_tso                = ethtool_op_get_tso,
1960         .set_tso                = bnx2x_set_tso,
1961         .self_test              = bnx2x_self_test,
1962         .get_sset_count         = bnx2x_get_sset_count,
1963         .get_strings            = bnx2x_get_strings,
1964         .phys_id                = bnx2x_phys_id,
1965         .get_ethtool_stats      = bnx2x_get_ethtool_stats,
1966 };
1967
1968 void bnx2x_set_ethtool_ops(struct net_device *netdev)
1969 {
1970         SET_ETHTOOL_OPS(netdev, &bnx2x_ethtool_ops);
1971 }