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