]> bbs.cooldavid.org Git - net-next-2.6.git/blob - drivers/net/bnx2x/bnx2x_ethtool.c
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
[net-next-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         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_E1HMF(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_E1HMF(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         ering->rx_pending = bp->rx_ring_size;
965         ering->rx_mini_pending = 0;
966         ering->rx_jumbo_pending = 0;
967
968         ering->tx_max_pending = MAX_TX_AVAIL;
969         ering->tx_pending = bp->tx_ring_size;
970 }
971
972 static int bnx2x_set_ringparam(struct net_device *dev,
973                                struct ethtool_ringparam *ering)
974 {
975         struct bnx2x *bp = netdev_priv(dev);
976         int rc = 0;
977
978         if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
979                 printk(KERN_ERR "Handling parity error recovery. Try again later\n");
980                 return -EAGAIN;
981         }
982
983         if ((ering->rx_pending > MAX_RX_AVAIL) ||
984             (ering->tx_pending > MAX_TX_AVAIL) ||
985             (ering->tx_pending <= MAX_SKB_FRAGS + 4))
986                 return -EINVAL;
987
988         bp->rx_ring_size = ering->rx_pending;
989         bp->tx_ring_size = ering->tx_pending;
990
991         if (netif_running(dev)) {
992                 bnx2x_nic_unload(bp, UNLOAD_NORMAL);
993                 rc = bnx2x_nic_load(bp, LOAD_NORMAL);
994         }
995
996         return rc;
997 }
998
999 static void bnx2x_get_pauseparam(struct net_device *dev,
1000                                  struct ethtool_pauseparam *epause)
1001 {
1002         struct bnx2x *bp = netdev_priv(dev);
1003         int cfg_idx = bnx2x_get_link_cfg_idx(bp);
1004         epause->autoneg = (bp->link_params.req_flow_ctrl[cfg_idx] ==
1005                            BNX2X_FLOW_CTRL_AUTO);
1006
1007         epause->rx_pause = ((bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_RX) ==
1008                             BNX2X_FLOW_CTRL_RX);
1009         epause->tx_pause = ((bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_TX) ==
1010                             BNX2X_FLOW_CTRL_TX);
1011
1012         DP(NETIF_MSG_LINK, "ethtool_pauseparam: cmd %d\n"
1013            DP_LEVEL "  autoneg %d  rx_pause %d  tx_pause %d\n",
1014            epause->cmd, epause->autoneg, epause->rx_pause, epause->tx_pause);
1015 }
1016
1017 static int bnx2x_set_pauseparam(struct net_device *dev,
1018                                 struct ethtool_pauseparam *epause)
1019 {
1020         struct bnx2x *bp = netdev_priv(dev);
1021         u32 cfg_idx = bnx2x_get_link_cfg_idx(bp);
1022         if (IS_E1HMF(bp))
1023                 return 0;
1024
1025         DP(NETIF_MSG_LINK, "ethtool_pauseparam: cmd %d\n"
1026            DP_LEVEL "  autoneg %d  rx_pause %d  tx_pause %d\n",
1027            epause->cmd, epause->autoneg, epause->rx_pause, epause->tx_pause);
1028
1029         bp->link_params.req_flow_ctrl[cfg_idx] = BNX2X_FLOW_CTRL_AUTO;
1030
1031         if (epause->rx_pause)
1032                 bp->link_params.req_flow_ctrl[cfg_idx] |= BNX2X_FLOW_CTRL_RX;
1033
1034         if (epause->tx_pause)
1035                 bp->link_params.req_flow_ctrl[cfg_idx] |= BNX2X_FLOW_CTRL_TX;
1036
1037         if (bp->link_params.req_flow_ctrl[cfg_idx] == BNX2X_FLOW_CTRL_AUTO)
1038                 bp->link_params.req_flow_ctrl[cfg_idx] = BNX2X_FLOW_CTRL_NONE;
1039
1040         if (epause->autoneg) {
1041                 if (!(bp->port.supported[cfg_idx] & SUPPORTED_Autoneg)) {
1042                         DP(NETIF_MSG_LINK, "autoneg not supported\n");
1043                         return -EINVAL;
1044                 }
1045
1046                 if (bp->link_params.req_line_speed[cfg_idx] == SPEED_AUTO_NEG) {
1047                         bp->link_params.req_flow_ctrl[cfg_idx] =
1048                                 BNX2X_FLOW_CTRL_AUTO;
1049                 }
1050         }
1051
1052         DP(NETIF_MSG_LINK,
1053            "req_flow_ctrl 0x%x\n", bp->link_params.req_flow_ctrl[cfg_idx]);
1054
1055         if (netif_running(dev)) {
1056                 bnx2x_stats_handle(bp, STATS_EVENT_STOP);
1057                 bnx2x_link_set(bp);
1058         }
1059
1060         return 0;
1061 }
1062
1063 static int bnx2x_set_flags(struct net_device *dev, u32 data)
1064 {
1065         struct bnx2x *bp = netdev_priv(dev);
1066         int changed = 0;
1067         int rc = 0;
1068
1069         if (data & ~(ETH_FLAG_LRO | ETH_FLAG_RXHASH))
1070                 return -EINVAL;
1071
1072         if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
1073                 printk(KERN_ERR "Handling parity error recovery. Try again later\n");
1074                 return -EAGAIN;
1075         }
1076
1077         /* TPA requires Rx CSUM offloading */
1078         if ((data & ETH_FLAG_LRO) && bp->rx_csum) {
1079                 if (!bp->disable_tpa) {
1080                         if (!(dev->features & NETIF_F_LRO)) {
1081                                 dev->features |= NETIF_F_LRO;
1082                                 bp->flags |= TPA_ENABLE_FLAG;
1083                                 changed = 1;
1084                         }
1085                 } else
1086                         rc = -EINVAL;
1087         } else if (dev->features & NETIF_F_LRO) {
1088                 dev->features &= ~NETIF_F_LRO;
1089                 bp->flags &= ~TPA_ENABLE_FLAG;
1090                 changed = 1;
1091         }
1092
1093         if (data & ETH_FLAG_RXHASH)
1094                 dev->features |= NETIF_F_RXHASH;
1095         else
1096                 dev->features &= ~NETIF_F_RXHASH;
1097
1098         if (changed && netif_running(dev)) {
1099                 bnx2x_nic_unload(bp, UNLOAD_NORMAL);
1100                 rc = bnx2x_nic_load(bp, LOAD_NORMAL);
1101         }
1102
1103         return rc;
1104 }
1105
1106 static u32 bnx2x_get_rx_csum(struct net_device *dev)
1107 {
1108         struct bnx2x *bp = netdev_priv(dev);
1109
1110         return bp->rx_csum;
1111 }
1112
1113 static int bnx2x_set_rx_csum(struct net_device *dev, u32 data)
1114 {
1115         struct bnx2x *bp = netdev_priv(dev);
1116         int rc = 0;
1117
1118         if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
1119                 printk(KERN_ERR "Handling parity error recovery. Try again later\n");
1120                 return -EAGAIN;
1121         }
1122
1123         bp->rx_csum = data;
1124
1125         /* Disable TPA, when Rx CSUM is disabled. Otherwise all
1126            TPA'ed packets will be discarded due to wrong TCP CSUM */
1127         if (!data) {
1128                 u32 flags = ethtool_op_get_flags(dev);
1129
1130                 rc = bnx2x_set_flags(dev, (flags & ~ETH_FLAG_LRO));
1131         }
1132
1133         return rc;
1134 }
1135
1136 static int bnx2x_set_tso(struct net_device *dev, u32 data)
1137 {
1138         if (data) {
1139                 dev->features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
1140                 dev->features |= NETIF_F_TSO6;
1141         } else {
1142                 dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO_ECN);
1143                 dev->features &= ~NETIF_F_TSO6;
1144         }
1145
1146         return 0;
1147 }
1148
1149 static const struct {
1150         char string[ETH_GSTRING_LEN];
1151 } bnx2x_tests_str_arr[BNX2X_NUM_TESTS] = {
1152         { "register_test (offline)" },
1153         { "memory_test (offline)" },
1154         { "loopback_test (offline)" },
1155         { "nvram_test (online)" },
1156         { "interrupt_test (online)" },
1157         { "link_test (online)" },
1158         { "idle check (online)" }
1159 };
1160
1161 static int bnx2x_test_registers(struct bnx2x *bp)
1162 {
1163         int idx, i, rc = -ENODEV;
1164         u32 wr_val = 0;
1165         int port = BP_PORT(bp);
1166         static const struct {
1167                 u32 offset0;
1168                 u32 offset1;
1169                 u32 mask;
1170         } reg_tbl[] = {
1171 /* 0 */         { BRB1_REG_PAUSE_LOW_THRESHOLD_0,      4, 0x000003ff },
1172                 { DORQ_REG_DB_ADDR0,                   4, 0xffffffff },
1173                 { HC_REG_AGG_INT_0,                    4, 0x000003ff },
1174                 { PBF_REG_MAC_IF0_ENABLE,              4, 0x00000001 },
1175                 { PBF_REG_P0_INIT_CRD,                 4, 0x000007ff },
1176                 { PRS_REG_CID_PORT_0,                  4, 0x00ffffff },
1177                 { PXP2_REG_PSWRQ_CDU0_L2P,             4, 0x000fffff },
1178                 { PXP2_REG_RQ_CDU0_EFIRST_MEM_ADDR,    8, 0x0003ffff },
1179                 { PXP2_REG_PSWRQ_TM0_L2P,              4, 0x000fffff },
1180                 { PXP2_REG_RQ_USDM0_EFIRST_MEM_ADDR,   8, 0x0003ffff },
1181 /* 10 */        { PXP2_REG_PSWRQ_TSDM0_L2P,            4, 0x000fffff },
1182                 { QM_REG_CONNNUM_0,                    4, 0x000fffff },
1183                 { TM_REG_LIN0_MAX_ACTIVE_CID,          4, 0x0003ffff },
1184                 { SRC_REG_KEYRSS0_0,                  40, 0xffffffff },
1185                 { SRC_REG_KEYRSS0_7,                  40, 0xffffffff },
1186                 { XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 4, 0x00000001 },
1187                 { XCM_REG_WU_DA_CNT_CMD00,             4, 0x00000003 },
1188                 { XCM_REG_GLB_DEL_ACK_MAX_CNT_0,       4, 0x000000ff },
1189                 { NIG_REG_LLH0_T_BIT,                  4, 0x00000001 },
1190                 { NIG_REG_EMAC0_IN_EN,                 4, 0x00000001 },
1191 /* 20 */        { NIG_REG_BMAC0_IN_EN,                 4, 0x00000001 },
1192                 { NIG_REG_XCM0_OUT_EN,                 4, 0x00000001 },
1193                 { NIG_REG_BRB0_OUT_EN,                 4, 0x00000001 },
1194                 { NIG_REG_LLH0_XCM_MASK,               4, 0x00000007 },
1195                 { NIG_REG_LLH0_ACPI_PAT_6_LEN,        68, 0x000000ff },
1196                 { NIG_REG_LLH0_ACPI_PAT_0_CRC,        68, 0xffffffff },
1197                 { NIG_REG_LLH0_DEST_MAC_0_0,         160, 0xffffffff },
1198                 { NIG_REG_LLH0_DEST_IP_0_1,          160, 0xffffffff },
1199                 { NIG_REG_LLH0_IPV4_IPV6_0,          160, 0x00000001 },
1200                 { NIG_REG_LLH0_DEST_UDP_0,           160, 0x0000ffff },
1201 /* 30 */        { NIG_REG_LLH0_DEST_TCP_0,           160, 0x0000ffff },
1202                 { NIG_REG_LLH0_VLAN_ID_0,            160, 0x00000fff },
1203                 { NIG_REG_XGXS_SERDES0_MODE_SEL,       4, 0x00000001 },
1204                 { NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0, 4, 0x00000001 },
1205                 { NIG_REG_STATUS_INTERRUPT_PORT0,      4, 0x07ffffff },
1206                 { NIG_REG_XGXS0_CTRL_EXTREMOTEMDIOST, 24, 0x00000001 },
1207                 { NIG_REG_SERDES0_CTRL_PHY_ADDR,      16, 0x0000001f },
1208
1209                 { 0xffffffff, 0, 0x00000000 }
1210         };
1211
1212         if (!netif_running(bp->dev))
1213                 return rc;
1214
1215         /* Repeat the test twice:
1216            First by writing 0x00000000, second by writing 0xffffffff */
1217         for (idx = 0; idx < 2; idx++) {
1218
1219                 switch (idx) {
1220                 case 0:
1221                         wr_val = 0;
1222                         break;
1223                 case 1:
1224                         wr_val = 0xffffffff;
1225                         break;
1226                 }
1227
1228                 for (i = 0; reg_tbl[i].offset0 != 0xffffffff; i++) {
1229                         u32 offset, mask, save_val, val;
1230
1231                         offset = reg_tbl[i].offset0 + port*reg_tbl[i].offset1;
1232                         mask = reg_tbl[i].mask;
1233
1234                         save_val = REG_RD(bp, offset);
1235
1236                         REG_WR(bp, offset, (wr_val & mask));
1237                         val = REG_RD(bp, offset);
1238
1239                         /* Restore the original register's value */
1240                         REG_WR(bp, offset, save_val);
1241
1242                         /* verify value is as expected */
1243                         if ((val & mask) != (wr_val & mask)) {
1244                                 DP(NETIF_MSG_PROBE,
1245                                    "offset 0x%x: val 0x%x != 0x%x mask 0x%x\n",
1246                                    offset, val, wr_val, mask);
1247                                 goto test_reg_exit;
1248                         }
1249                 }
1250         }
1251
1252         rc = 0;
1253
1254 test_reg_exit:
1255         return rc;
1256 }
1257
1258 static int bnx2x_test_memory(struct bnx2x *bp)
1259 {
1260         int i, j, rc = -ENODEV;
1261         u32 val;
1262         static const struct {
1263                 u32 offset;
1264                 int size;
1265         } mem_tbl[] = {
1266                 { CCM_REG_XX_DESCR_TABLE,   CCM_REG_XX_DESCR_TABLE_SIZE },
1267                 { CFC_REG_ACTIVITY_COUNTER, CFC_REG_ACTIVITY_COUNTER_SIZE },
1268                 { CFC_REG_LINK_LIST,        CFC_REG_LINK_LIST_SIZE },
1269                 { DMAE_REG_CMD_MEM,         DMAE_REG_CMD_MEM_SIZE },
1270                 { TCM_REG_XX_DESCR_TABLE,   TCM_REG_XX_DESCR_TABLE_SIZE },
1271                 { UCM_REG_XX_DESCR_TABLE,   UCM_REG_XX_DESCR_TABLE_SIZE },
1272                 { XCM_REG_XX_DESCR_TABLE,   XCM_REG_XX_DESCR_TABLE_SIZE },
1273
1274                 { 0xffffffff, 0 }
1275         };
1276         static const struct {
1277                 char *name;
1278                 u32 offset;
1279                 u32 e1_mask;
1280                 u32 e1h_mask;
1281         } prty_tbl[] = {
1282                 { "CCM_PRTY_STS",  CCM_REG_CCM_PRTY_STS,   0x3ffc0, 0 },
1283                 { "CFC_PRTY_STS",  CFC_REG_CFC_PRTY_STS,   0x2,     0x2 },
1284                 { "DMAE_PRTY_STS", DMAE_REG_DMAE_PRTY_STS, 0,       0 },
1285                 { "TCM_PRTY_STS",  TCM_REG_TCM_PRTY_STS,   0x3ffc0, 0 },
1286                 { "UCM_PRTY_STS",  UCM_REG_UCM_PRTY_STS,   0x3ffc0, 0 },
1287                 { "XCM_PRTY_STS",  XCM_REG_XCM_PRTY_STS,   0x3ffc1, 0 },
1288
1289                 { NULL, 0xffffffff, 0, 0 }
1290         };
1291
1292         if (!netif_running(bp->dev))
1293                 return rc;
1294
1295         /* Go through all the memories */
1296         for (i = 0; mem_tbl[i].offset != 0xffffffff; i++)
1297                 for (j = 0; j < mem_tbl[i].size; j++)
1298                         REG_RD(bp, mem_tbl[i].offset + j*4);
1299
1300         /* Check the parity status */
1301         for (i = 0; prty_tbl[i].offset != 0xffffffff; i++) {
1302                 val = REG_RD(bp, prty_tbl[i].offset);
1303                 if ((CHIP_IS_E1(bp) && (val & ~(prty_tbl[i].e1_mask))) ||
1304                     (CHIP_IS_E1H(bp) && (val & ~(prty_tbl[i].e1h_mask)))) {
1305                         DP(NETIF_MSG_HW,
1306                            "%s is 0x%x\n", prty_tbl[i].name, val);
1307                         goto test_mem_exit;
1308                 }
1309         }
1310
1311         rc = 0;
1312
1313 test_mem_exit:
1314         return rc;
1315 }
1316
1317 static void bnx2x_wait_for_link(struct bnx2x *bp, u8 link_up, u8 is_serdes)
1318 {
1319         int cnt = 1000;
1320
1321         if (link_up)
1322                 while (bnx2x_link_test(bp, is_serdes) && cnt--)
1323                         msleep(10);
1324 }
1325
1326 static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up)
1327 {
1328         unsigned int pkt_size, num_pkts, i;
1329         struct sk_buff *skb;
1330         unsigned char *packet;
1331         struct bnx2x_fastpath *fp_rx = &bp->fp[0];
1332         struct bnx2x_fastpath *fp_tx = &bp->fp[0];
1333         u16 tx_start_idx, tx_idx;
1334         u16 rx_start_idx, rx_idx;
1335         u16 pkt_prod, bd_prod;
1336         struct sw_tx_bd *tx_buf;
1337         struct eth_tx_start_bd *tx_start_bd;
1338         struct eth_tx_parse_bd *pbd = NULL;
1339         dma_addr_t mapping;
1340         union eth_rx_cqe *cqe;
1341         u8 cqe_fp_flags;
1342         struct sw_rx_bd *rx_buf;
1343         u16 len;
1344         int rc = -ENODEV;
1345
1346         /* check the loopback mode */
1347         switch (loopback_mode) {
1348         case BNX2X_PHY_LOOPBACK:
1349                 if (bp->link_params.loopback_mode != LOOPBACK_XGXS)
1350                         return -EINVAL;
1351                 break;
1352         case BNX2X_MAC_LOOPBACK:
1353                 bp->link_params.loopback_mode = LOOPBACK_BMAC;
1354                 bnx2x_phy_init(&bp->link_params, &bp->link_vars);
1355                 break;
1356         default:
1357                 return -EINVAL;
1358         }
1359
1360         /* prepare the loopback packet */
1361         pkt_size = (((bp->dev->mtu < ETH_MAX_PACKET_SIZE) ?
1362                      bp->dev->mtu : ETH_MAX_PACKET_SIZE) + ETH_HLEN);
1363         skb = netdev_alloc_skb(bp->dev, bp->rx_buf_size);
1364         if (!skb) {
1365                 rc = -ENOMEM;
1366                 goto test_loopback_exit;
1367         }
1368         packet = skb_put(skb, pkt_size);
1369         memcpy(packet, bp->dev->dev_addr, ETH_ALEN);
1370         memset(packet + ETH_ALEN, 0, ETH_ALEN);
1371         memset(packet + 2*ETH_ALEN, 0x77, (ETH_HLEN - 2*ETH_ALEN));
1372         for (i = ETH_HLEN; i < pkt_size; i++)
1373                 packet[i] = (unsigned char) (i & 0xff);
1374
1375         /* send the loopback packet */
1376         num_pkts = 0;
1377         tx_start_idx = le16_to_cpu(*fp_tx->tx_cons_sb);
1378         rx_start_idx = le16_to_cpu(*fp_rx->rx_cons_sb);
1379
1380         pkt_prod = fp_tx->tx_pkt_prod++;
1381         tx_buf = &fp_tx->tx_buf_ring[TX_BD(pkt_prod)];
1382         tx_buf->first_bd = fp_tx->tx_bd_prod;
1383         tx_buf->skb = skb;
1384         tx_buf->flags = 0;
1385
1386         bd_prod = TX_BD(fp_tx->tx_bd_prod);
1387         tx_start_bd = &fp_tx->tx_desc_ring[bd_prod].start_bd;
1388         mapping = dma_map_single(&bp->pdev->dev, skb->data,
1389                                  skb_headlen(skb), DMA_TO_DEVICE);
1390         tx_start_bd->addr_hi = cpu_to_le32(U64_HI(mapping));
1391         tx_start_bd->addr_lo = cpu_to_le32(U64_LO(mapping));
1392         tx_start_bd->nbd = cpu_to_le16(2); /* start + pbd */
1393         tx_start_bd->nbytes = cpu_to_le16(skb_headlen(skb));
1394         tx_start_bd->vlan = cpu_to_le16(pkt_prod);
1395         tx_start_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_START_BD;
1396         tx_start_bd->general_data = ((UNICAST_ADDRESS <<
1397                                 ETH_TX_START_BD_ETH_ADDR_TYPE_SHIFT) | 1);
1398
1399         /* turn on parsing and get a BD */
1400         bd_prod = TX_BD(NEXT_TX_IDX(bd_prod));
1401         pbd = &fp_tx->tx_desc_ring[bd_prod].parse_bd;
1402
1403         memset(pbd, 0, sizeof(struct eth_tx_parse_bd));
1404
1405         wmb();
1406
1407         fp_tx->tx_db.data.prod += 2;
1408         barrier();
1409         DOORBELL(bp, fp_tx->index, fp_tx->tx_db.raw);
1410
1411         mmiowb();
1412
1413         num_pkts++;
1414         fp_tx->tx_bd_prod += 2; /* start + pbd */
1415
1416         udelay(100);
1417
1418         tx_idx = le16_to_cpu(*fp_tx->tx_cons_sb);
1419         if (tx_idx != tx_start_idx + num_pkts)
1420                 goto test_loopback_exit;
1421
1422         rx_idx = le16_to_cpu(*fp_rx->rx_cons_sb);
1423         if (rx_idx != rx_start_idx + num_pkts)
1424                 goto test_loopback_exit;
1425
1426         cqe = &fp_rx->rx_comp_ring[RCQ_BD(fp_rx->rx_comp_cons)];
1427         cqe_fp_flags = cqe->fast_path_cqe.type_error_flags;
1428         if (CQE_TYPE(cqe_fp_flags) || (cqe_fp_flags & ETH_RX_ERROR_FALGS))
1429                 goto test_loopback_rx_exit;
1430
1431         len = le16_to_cpu(cqe->fast_path_cqe.pkt_len);
1432         if (len != pkt_size)
1433                 goto test_loopback_rx_exit;
1434
1435         rx_buf = &fp_rx->rx_buf_ring[RX_BD(fp_rx->rx_bd_cons)];
1436         skb = rx_buf->skb;
1437         skb_reserve(skb, cqe->fast_path_cqe.placement_offset);
1438         for (i = ETH_HLEN; i < pkt_size; i++)
1439                 if (*(skb->data + i) != (unsigned char) (i & 0xff))
1440                         goto test_loopback_rx_exit;
1441
1442         rc = 0;
1443
1444 test_loopback_rx_exit:
1445
1446         fp_rx->rx_bd_cons = NEXT_RX_IDX(fp_rx->rx_bd_cons);
1447         fp_rx->rx_bd_prod = NEXT_RX_IDX(fp_rx->rx_bd_prod);
1448         fp_rx->rx_comp_cons = NEXT_RCQ_IDX(fp_rx->rx_comp_cons);
1449         fp_rx->rx_comp_prod = NEXT_RCQ_IDX(fp_rx->rx_comp_prod);
1450
1451         /* Update producers */
1452         bnx2x_update_rx_prod(bp, fp_rx, fp_rx->rx_bd_prod, fp_rx->rx_comp_prod,
1453                              fp_rx->rx_sge_prod);
1454
1455 test_loopback_exit:
1456         bp->link_params.loopback_mode = LOOPBACK_NONE;
1457
1458         return rc;
1459 }
1460
1461 static int bnx2x_test_loopback(struct bnx2x *bp, u8 link_up)
1462 {
1463         int rc = 0, res;
1464
1465         if (BP_NOMCP(bp))
1466                 return rc;
1467
1468         if (!netif_running(bp->dev))
1469                 return BNX2X_LOOPBACK_FAILED;
1470
1471         bnx2x_netif_stop(bp, 1);
1472         bnx2x_acquire_phy_lock(bp);
1473
1474         res = bnx2x_run_loopback(bp, BNX2X_PHY_LOOPBACK, link_up);
1475         if (res) {
1476                 DP(NETIF_MSG_PROBE, "  PHY loopback failed  (res %d)\n", res);
1477                 rc |= BNX2X_PHY_LOOPBACK_FAILED;
1478         }
1479
1480         res = bnx2x_run_loopback(bp, BNX2X_MAC_LOOPBACK, link_up);
1481         if (res) {
1482                 DP(NETIF_MSG_PROBE, "  MAC loopback failed  (res %d)\n", res);
1483                 rc |= BNX2X_MAC_LOOPBACK_FAILED;
1484         }
1485
1486         bnx2x_release_phy_lock(bp);
1487         bnx2x_netif_start(bp);
1488
1489         return rc;
1490 }
1491
1492 #define CRC32_RESIDUAL                  0xdebb20e3
1493
1494 static int bnx2x_test_nvram(struct bnx2x *bp)
1495 {
1496         static const struct {
1497                 int offset;
1498                 int size;
1499         } nvram_tbl[] = {
1500                 {     0,  0x14 }, /* bootstrap */
1501                 {  0x14,  0xec }, /* dir */
1502                 { 0x100, 0x350 }, /* manuf_info */
1503                 { 0x450,  0xf0 }, /* feature_info */
1504                 { 0x640,  0x64 }, /* upgrade_key_info */
1505                 { 0x6a4,  0x64 },
1506                 { 0x708,  0x70 }, /* manuf_key_info */
1507                 { 0x778,  0x70 },
1508                 {     0,     0 }
1509         };
1510         __be32 buf[0x350 / 4];
1511         u8 *data = (u8 *)buf;
1512         int i, rc;
1513         u32 magic, crc;
1514
1515         if (BP_NOMCP(bp))
1516                 return 0;
1517
1518         rc = bnx2x_nvram_read(bp, 0, data, 4);
1519         if (rc) {
1520                 DP(NETIF_MSG_PROBE, "magic value read (rc %d)\n", rc);
1521                 goto test_nvram_exit;
1522         }
1523
1524         magic = be32_to_cpu(buf[0]);
1525         if (magic != 0x669955aa) {
1526                 DP(NETIF_MSG_PROBE, "magic value (0x%08x)\n", magic);
1527                 rc = -ENODEV;
1528                 goto test_nvram_exit;
1529         }
1530
1531         for (i = 0; nvram_tbl[i].size; i++) {
1532
1533                 rc = bnx2x_nvram_read(bp, nvram_tbl[i].offset, data,
1534                                       nvram_tbl[i].size);
1535                 if (rc) {
1536                         DP(NETIF_MSG_PROBE,
1537                            "nvram_tbl[%d] read data (rc %d)\n", i, rc);
1538                         goto test_nvram_exit;
1539                 }
1540
1541                 crc = ether_crc_le(nvram_tbl[i].size, data);
1542                 if (crc != CRC32_RESIDUAL) {
1543                         DP(NETIF_MSG_PROBE,
1544                            "nvram_tbl[%d] crc value (0x%08x)\n", i, crc);
1545                         rc = -ENODEV;
1546                         goto test_nvram_exit;
1547                 }
1548         }
1549
1550 test_nvram_exit:
1551         return rc;
1552 }
1553
1554 static int bnx2x_test_intr(struct bnx2x *bp)
1555 {
1556         struct mac_configuration_cmd *config = bnx2x_sp(bp, mac_config);
1557         int i, rc;
1558
1559         if (!netif_running(bp->dev))
1560                 return -ENODEV;
1561
1562         config->hdr.length = 0;
1563         if (CHIP_IS_E1(bp))
1564                 /* use last unicast entries */
1565                 config->hdr.offset = (BP_PORT(bp) ? 63 : 31);
1566         else
1567                 config->hdr.offset = BP_FUNC(bp);
1568         config->hdr.client_id = bp->fp->cl_id;
1569         config->hdr.reserved1 = 0;
1570
1571         bp->set_mac_pending++;
1572         smp_wmb();
1573         rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0,
1574                            U64_HI(bnx2x_sp_mapping(bp, mac_config)),
1575                            U64_LO(bnx2x_sp_mapping(bp, mac_config)), 0);
1576         if (rc == 0) {
1577                 for (i = 0; i < 10; i++) {
1578                         if (!bp->set_mac_pending)
1579                                 break;
1580                         smp_rmb();
1581                         msleep_interruptible(10);
1582                 }
1583                 if (i == 10)
1584                         rc = -ENODEV;
1585         }
1586
1587         return rc;
1588 }
1589
1590 static void bnx2x_self_test(struct net_device *dev,
1591                             struct ethtool_test *etest, u64 *buf)
1592 {
1593         struct bnx2x *bp = netdev_priv(dev);
1594         u8 is_serdes;
1595         if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
1596                 printk(KERN_ERR "Handling parity error recovery. Try again later\n");
1597                 etest->flags |= ETH_TEST_FL_FAILED;
1598                 return;
1599         }
1600
1601         memset(buf, 0, sizeof(u64) * BNX2X_NUM_TESTS);
1602
1603         if (!netif_running(dev))
1604                 return;
1605
1606         /* offline tests are not supported in MF mode */
1607         if (IS_E1HMF(bp))
1608                 etest->flags &= ~ETH_TEST_FL_OFFLINE;
1609         is_serdes = (bp->link_vars.link_status & LINK_STATUS_SERDES_LINK) > 0;
1610
1611         if (etest->flags & ETH_TEST_FL_OFFLINE) {
1612                 int port = BP_PORT(bp);
1613                 u32 val;
1614                 u8 link_up;
1615
1616                 /* save current value of input enable for TX port IF */
1617                 val = REG_RD(bp, NIG_REG_EGRESS_UMP0_IN_EN + port*4);
1618                 /* disable input for TX port IF */
1619                 REG_WR(bp, NIG_REG_EGRESS_UMP0_IN_EN + port*4, 0);
1620
1621                 link_up = bp->link_vars.link_up;
1622
1623                 bnx2x_nic_unload(bp, UNLOAD_NORMAL);
1624                 bnx2x_nic_load(bp, LOAD_DIAG);
1625                 /* wait until link state is restored */
1626                 bnx2x_wait_for_link(bp, link_up, is_serdes);
1627
1628                 if (bnx2x_test_registers(bp) != 0) {
1629                         buf[0] = 1;
1630                         etest->flags |= ETH_TEST_FL_FAILED;
1631                 }
1632                 if (bnx2x_test_memory(bp) != 0) {
1633                         buf[1] = 1;
1634                         etest->flags |= ETH_TEST_FL_FAILED;
1635                 }
1636                 buf[2] = bnx2x_test_loopback(bp, link_up);
1637                 if (buf[2] != 0)
1638                         etest->flags |= ETH_TEST_FL_FAILED;
1639
1640                 bnx2x_nic_unload(bp, UNLOAD_NORMAL);
1641
1642                 /* restore input for TX port IF */
1643                 REG_WR(bp, NIG_REG_EGRESS_UMP0_IN_EN + port*4, val);
1644
1645                 bnx2x_nic_load(bp, LOAD_NORMAL);
1646                 /* wait until link state is restored */
1647                 bnx2x_wait_for_link(bp, link_up, is_serdes);
1648         }
1649         if (bnx2x_test_nvram(bp) != 0) {
1650                 buf[3] = 1;
1651                 etest->flags |= ETH_TEST_FL_FAILED;
1652         }
1653         if (bnx2x_test_intr(bp) != 0) {
1654                 buf[4] = 1;
1655                 etest->flags |= ETH_TEST_FL_FAILED;
1656         }
1657         if (bp->port.pmf)
1658                 if (bnx2x_link_test(bp, is_serdes) != 0) {
1659                         buf[5] = 1;
1660                         etest->flags |= ETH_TEST_FL_FAILED;
1661                 }
1662
1663 #ifdef BNX2X_EXTRA_DEBUG
1664         bnx2x_panic_dump(bp);
1665 #endif
1666 }
1667
1668 static const struct {
1669         long offset;
1670         int size;
1671         u8 string[ETH_GSTRING_LEN];
1672 } bnx2x_q_stats_arr[BNX2X_NUM_Q_STATS] = {
1673 /* 1 */ { Q_STATS_OFFSET32(total_bytes_received_hi), 8, "[%d]: rx_bytes" },
1674         { Q_STATS_OFFSET32(error_bytes_received_hi),
1675                                                 8, "[%d]: rx_error_bytes" },
1676         { Q_STATS_OFFSET32(total_unicast_packets_received_hi),
1677                                                 8, "[%d]: rx_ucast_packets" },
1678         { Q_STATS_OFFSET32(total_multicast_packets_received_hi),
1679                                                 8, "[%d]: rx_mcast_packets" },
1680         { Q_STATS_OFFSET32(total_broadcast_packets_received_hi),
1681                                                 8, "[%d]: rx_bcast_packets" },
1682         { Q_STATS_OFFSET32(no_buff_discard_hi), 8, "[%d]: rx_discards" },
1683         { Q_STATS_OFFSET32(rx_err_discard_pkt),
1684                                          4, "[%d]: rx_phy_ip_err_discards"},
1685         { Q_STATS_OFFSET32(rx_skb_alloc_failed),
1686                                          4, "[%d]: rx_skb_alloc_discard" },
1687         { Q_STATS_OFFSET32(hw_csum_err), 4, "[%d]: rx_csum_offload_errors" },
1688
1689 /* 10 */{ Q_STATS_OFFSET32(total_bytes_transmitted_hi), 8, "[%d]: tx_bytes" },
1690         { Q_STATS_OFFSET32(total_unicast_packets_transmitted_hi),
1691                                                 8, "[%d]: tx_ucast_packets" },
1692         { Q_STATS_OFFSET32(total_multicast_packets_transmitted_hi),
1693                                                 8, "[%d]: tx_mcast_packets" },
1694         { Q_STATS_OFFSET32(total_broadcast_packets_transmitted_hi),
1695                                                 8, "[%d]: tx_bcast_packets" }
1696 };
1697
1698 static const struct {
1699         long offset;
1700         int size;
1701         u32 flags;
1702 #define STATS_FLAGS_PORT                1
1703 #define STATS_FLAGS_FUNC                2
1704 #define STATS_FLAGS_BOTH                (STATS_FLAGS_FUNC | STATS_FLAGS_PORT)
1705         u8 string[ETH_GSTRING_LEN];
1706 } bnx2x_stats_arr[BNX2X_NUM_STATS] = {
1707 /* 1 */ { STATS_OFFSET32(total_bytes_received_hi),
1708                                 8, STATS_FLAGS_BOTH, "rx_bytes" },
1709         { STATS_OFFSET32(error_bytes_received_hi),
1710                                 8, STATS_FLAGS_BOTH, "rx_error_bytes" },
1711         { STATS_OFFSET32(total_unicast_packets_received_hi),
1712                                 8, STATS_FLAGS_BOTH, "rx_ucast_packets" },
1713         { STATS_OFFSET32(total_multicast_packets_received_hi),
1714                                 8, STATS_FLAGS_BOTH, "rx_mcast_packets" },
1715         { STATS_OFFSET32(total_broadcast_packets_received_hi),
1716                                 8, STATS_FLAGS_BOTH, "rx_bcast_packets" },
1717         { STATS_OFFSET32(rx_stat_dot3statsfcserrors_hi),
1718                                 8, STATS_FLAGS_PORT, "rx_crc_errors" },
1719         { STATS_OFFSET32(rx_stat_dot3statsalignmenterrors_hi),
1720                                 8, STATS_FLAGS_PORT, "rx_align_errors" },
1721         { STATS_OFFSET32(rx_stat_etherstatsundersizepkts_hi),
1722                                 8, STATS_FLAGS_PORT, "rx_undersize_packets" },
1723         { STATS_OFFSET32(etherstatsoverrsizepkts_hi),
1724                                 8, STATS_FLAGS_PORT, "rx_oversize_packets" },
1725 /* 10 */{ STATS_OFFSET32(rx_stat_etherstatsfragments_hi),
1726                                 8, STATS_FLAGS_PORT, "rx_fragments" },
1727         { STATS_OFFSET32(rx_stat_etherstatsjabbers_hi),
1728                                 8, STATS_FLAGS_PORT, "rx_jabbers" },
1729         { STATS_OFFSET32(no_buff_discard_hi),
1730                                 8, STATS_FLAGS_BOTH, "rx_discards" },
1731         { STATS_OFFSET32(mac_filter_discard),
1732                                 4, STATS_FLAGS_PORT, "rx_filtered_packets" },
1733         { STATS_OFFSET32(xxoverflow_discard),
1734                                 4, STATS_FLAGS_PORT, "rx_fw_discards" },
1735         { STATS_OFFSET32(brb_drop_hi),
1736                                 8, STATS_FLAGS_PORT, "rx_brb_discard" },
1737         { STATS_OFFSET32(brb_truncate_hi),
1738                                 8, STATS_FLAGS_PORT, "rx_brb_truncate" },
1739         { STATS_OFFSET32(pause_frames_received_hi),
1740                                 8, STATS_FLAGS_PORT, "rx_pause_frames" },
1741         { STATS_OFFSET32(rx_stat_maccontrolframesreceived_hi),
1742                                 8, STATS_FLAGS_PORT, "rx_mac_ctrl_frames" },
1743         { STATS_OFFSET32(nig_timer_max),
1744                         4, STATS_FLAGS_PORT, "rx_constant_pause_events" },
1745 /* 20 */{ STATS_OFFSET32(rx_err_discard_pkt),
1746                                 4, STATS_FLAGS_BOTH, "rx_phy_ip_err_discards"},
1747         { STATS_OFFSET32(rx_skb_alloc_failed),
1748                                 4, STATS_FLAGS_BOTH, "rx_skb_alloc_discard" },
1749         { STATS_OFFSET32(hw_csum_err),
1750                                 4, STATS_FLAGS_BOTH, "rx_csum_offload_errors" },
1751
1752         { STATS_OFFSET32(total_bytes_transmitted_hi),
1753                                 8, STATS_FLAGS_BOTH, "tx_bytes" },
1754         { STATS_OFFSET32(tx_stat_ifhcoutbadoctets_hi),
1755                                 8, STATS_FLAGS_PORT, "tx_error_bytes" },
1756         { STATS_OFFSET32(total_unicast_packets_transmitted_hi),
1757                                 8, STATS_FLAGS_BOTH, "tx_ucast_packets" },
1758         { STATS_OFFSET32(total_multicast_packets_transmitted_hi),
1759                                 8, STATS_FLAGS_BOTH, "tx_mcast_packets" },
1760         { STATS_OFFSET32(total_broadcast_packets_transmitted_hi),
1761                                 8, STATS_FLAGS_BOTH, "tx_bcast_packets" },
1762         { STATS_OFFSET32(tx_stat_dot3statsinternalmactransmiterrors_hi),
1763                                 8, STATS_FLAGS_PORT, "tx_mac_errors" },
1764         { STATS_OFFSET32(rx_stat_dot3statscarriersenseerrors_hi),
1765                                 8, STATS_FLAGS_PORT, "tx_carrier_errors" },
1766 /* 30 */{ STATS_OFFSET32(tx_stat_dot3statssinglecollisionframes_hi),
1767                                 8, STATS_FLAGS_PORT, "tx_single_collisions" },
1768         { STATS_OFFSET32(tx_stat_dot3statsmultiplecollisionframes_hi),
1769                                 8, STATS_FLAGS_PORT, "tx_multi_collisions" },
1770         { STATS_OFFSET32(tx_stat_dot3statsdeferredtransmissions_hi),
1771                                 8, STATS_FLAGS_PORT, "tx_deferred" },
1772         { STATS_OFFSET32(tx_stat_dot3statsexcessivecollisions_hi),
1773                                 8, STATS_FLAGS_PORT, "tx_excess_collisions" },
1774         { STATS_OFFSET32(tx_stat_dot3statslatecollisions_hi),
1775                                 8, STATS_FLAGS_PORT, "tx_late_collisions" },
1776         { STATS_OFFSET32(tx_stat_etherstatscollisions_hi),
1777                                 8, STATS_FLAGS_PORT, "tx_total_collisions" },
1778         { STATS_OFFSET32(tx_stat_etherstatspkts64octets_hi),
1779                                 8, STATS_FLAGS_PORT, "tx_64_byte_packets" },
1780         { STATS_OFFSET32(tx_stat_etherstatspkts65octetsto127octets_hi),
1781                         8, STATS_FLAGS_PORT, "tx_65_to_127_byte_packets" },
1782         { STATS_OFFSET32(tx_stat_etherstatspkts128octetsto255octets_hi),
1783                         8, STATS_FLAGS_PORT, "tx_128_to_255_byte_packets" },
1784         { STATS_OFFSET32(tx_stat_etherstatspkts256octetsto511octets_hi),
1785                         8, STATS_FLAGS_PORT, "tx_256_to_511_byte_packets" },
1786 /* 40 */{ STATS_OFFSET32(tx_stat_etherstatspkts512octetsto1023octets_hi),
1787                         8, STATS_FLAGS_PORT, "tx_512_to_1023_byte_packets" },
1788         { STATS_OFFSET32(etherstatspkts1024octetsto1522octets_hi),
1789                         8, STATS_FLAGS_PORT, "tx_1024_to_1522_byte_packets" },
1790         { STATS_OFFSET32(etherstatspktsover1522octets_hi),
1791                         8, STATS_FLAGS_PORT, "tx_1523_to_9022_byte_packets" },
1792         { STATS_OFFSET32(pause_frames_sent_hi),
1793                                 8, STATS_FLAGS_PORT, "tx_pause_frames" }
1794 };
1795
1796 #define IS_PORT_STAT(i) \
1797         ((bnx2x_stats_arr[i].flags & STATS_FLAGS_BOTH) == STATS_FLAGS_PORT)
1798 #define IS_FUNC_STAT(i)         (bnx2x_stats_arr[i].flags & STATS_FLAGS_FUNC)
1799 #define IS_E1HMF_MODE_STAT(bp) \
1800                         (IS_E1HMF(bp) && !(bp->msg_enable & BNX2X_MSG_STATS))
1801
1802 static int bnx2x_get_sset_count(struct net_device *dev, int stringset)
1803 {
1804         struct bnx2x *bp = netdev_priv(dev);
1805         int i, num_stats;
1806
1807         switch (stringset) {
1808         case ETH_SS_STATS:
1809                 if (is_multi(bp)) {
1810                         num_stats = BNX2X_NUM_Q_STATS * bp->num_queues;
1811                         if (!IS_E1HMF_MODE_STAT(bp))
1812                                 num_stats += BNX2X_NUM_STATS;
1813                 } else {
1814                         if (IS_E1HMF_MODE_STAT(bp)) {
1815                                 num_stats = 0;
1816                                 for (i = 0; i < BNX2X_NUM_STATS; i++)
1817                                         if (IS_FUNC_STAT(i))
1818                                                 num_stats++;
1819                         } else
1820                                 num_stats = BNX2X_NUM_STATS;
1821                 }
1822                 return num_stats;
1823
1824         case ETH_SS_TEST:
1825                 return BNX2X_NUM_TESTS;
1826
1827         default:
1828                 return -EINVAL;
1829         }
1830 }
1831
1832 static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
1833 {
1834         struct bnx2x *bp = netdev_priv(dev);
1835         int i, j, k;
1836
1837         switch (stringset) {
1838         case ETH_SS_STATS:
1839                 if (is_multi(bp)) {
1840                         k = 0;
1841                         for_each_queue(bp, i) {
1842                                 for (j = 0; j < BNX2X_NUM_Q_STATS; j++)
1843                                         sprintf(buf + (k + j)*ETH_GSTRING_LEN,
1844                                                 bnx2x_q_stats_arr[j].string, i);
1845                                 k += BNX2X_NUM_Q_STATS;
1846                         }
1847                         if (IS_E1HMF_MODE_STAT(bp))
1848                                 break;
1849                         for (j = 0; j < BNX2X_NUM_STATS; j++)
1850                                 strcpy(buf + (k + j)*ETH_GSTRING_LEN,
1851                                        bnx2x_stats_arr[j].string);
1852                 } else {
1853                         for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) {
1854                                 if (IS_E1HMF_MODE_STAT(bp) && IS_PORT_STAT(i))
1855                                         continue;
1856                                 strcpy(buf + j*ETH_GSTRING_LEN,
1857                                        bnx2x_stats_arr[i].string);
1858                                 j++;
1859                         }
1860                 }
1861                 break;
1862
1863         case ETH_SS_TEST:
1864                 memcpy(buf, bnx2x_tests_str_arr, sizeof(bnx2x_tests_str_arr));
1865                 break;
1866         }
1867 }
1868
1869 static void bnx2x_get_ethtool_stats(struct net_device *dev,
1870                                     struct ethtool_stats *stats, u64 *buf)
1871 {
1872         struct bnx2x *bp = netdev_priv(dev);
1873         u32 *hw_stats, *offset;
1874         int i, j, k;
1875
1876         if (is_multi(bp)) {
1877                 k = 0;
1878                 for_each_queue(bp, i) {
1879                         hw_stats = (u32 *)&bp->fp[i].eth_q_stats;
1880                         for (j = 0; j < BNX2X_NUM_Q_STATS; j++) {
1881                                 if (bnx2x_q_stats_arr[j].size == 0) {
1882                                         /* skip this counter */
1883                                         buf[k + j] = 0;
1884                                         continue;
1885                                 }
1886                                 offset = (hw_stats +
1887                                           bnx2x_q_stats_arr[j].offset);
1888                                 if (bnx2x_q_stats_arr[j].size == 4) {
1889                                         /* 4-byte counter */
1890                                         buf[k + j] = (u64) *offset;
1891                                         continue;
1892                                 }
1893                                 /* 8-byte counter */
1894                                 buf[k + j] = HILO_U64(*offset, *(offset + 1));
1895                         }
1896                         k += BNX2X_NUM_Q_STATS;
1897                 }
1898                 if (IS_E1HMF_MODE_STAT(bp))
1899                         return;
1900                 hw_stats = (u32 *)&bp->eth_stats;
1901                 for (j = 0; j < BNX2X_NUM_STATS; j++) {
1902                         if (bnx2x_stats_arr[j].size == 0) {
1903                                 /* skip this counter */
1904                                 buf[k + j] = 0;
1905                                 continue;
1906                         }
1907                         offset = (hw_stats + bnx2x_stats_arr[j].offset);
1908                         if (bnx2x_stats_arr[j].size == 4) {
1909                                 /* 4-byte counter */
1910                                 buf[k + j] = (u64) *offset;
1911                                 continue;
1912                         }
1913                         /* 8-byte counter */
1914                         buf[k + j] = HILO_U64(*offset, *(offset + 1));
1915                 }
1916         } else {
1917                 hw_stats = (u32 *)&bp->eth_stats;
1918                 for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) {
1919                         if (IS_E1HMF_MODE_STAT(bp) && IS_PORT_STAT(i))
1920                                 continue;
1921                         if (bnx2x_stats_arr[i].size == 0) {
1922                                 /* skip this counter */
1923                                 buf[j] = 0;
1924                                 j++;
1925                                 continue;
1926                         }
1927                         offset = (hw_stats + bnx2x_stats_arr[i].offset);
1928                         if (bnx2x_stats_arr[i].size == 4) {
1929                                 /* 4-byte counter */
1930                                 buf[j] = (u64) *offset;
1931                                 j++;
1932                                 continue;
1933                         }
1934                         /* 8-byte counter */
1935                         buf[j] = HILO_U64(*offset, *(offset + 1));
1936                         j++;
1937                 }
1938         }
1939 }
1940
1941 static int bnx2x_phys_id(struct net_device *dev, u32 data)
1942 {
1943         struct bnx2x *bp = netdev_priv(dev);
1944         int i;
1945
1946         if (!netif_running(dev))
1947                 return 0;
1948
1949         if (!bp->port.pmf)
1950                 return 0;
1951
1952         if (data == 0)
1953                 data = 2;
1954
1955         for (i = 0; i < (data * 2); i++) {
1956                 if ((i % 2) == 0)
1957                         bnx2x_set_led(&bp->link_params, &bp->link_vars,
1958                                       LED_MODE_OPER, SPEED_1000);
1959                 else
1960                         bnx2x_set_led(&bp->link_params, &bp->link_vars,
1961                                       LED_MODE_OFF, 0);
1962
1963                 msleep_interruptible(500);
1964                 if (signal_pending(current))
1965                         break;
1966         }
1967
1968         if (bp->link_vars.link_up)
1969                 bnx2x_set_led(&bp->link_params, &bp->link_vars, LED_MODE_OPER,
1970                               bp->link_vars.line_speed);
1971
1972         return 0;
1973 }
1974
1975 static const struct ethtool_ops bnx2x_ethtool_ops = {
1976         .get_settings           = bnx2x_get_settings,
1977         .set_settings           = bnx2x_set_settings,
1978         .get_drvinfo            = bnx2x_get_drvinfo,
1979         .get_regs_len           = bnx2x_get_regs_len,
1980         .get_regs               = bnx2x_get_regs,
1981         .get_wol                = bnx2x_get_wol,
1982         .set_wol                = bnx2x_set_wol,
1983         .get_msglevel           = bnx2x_get_msglevel,
1984         .set_msglevel           = bnx2x_set_msglevel,
1985         .nway_reset             = bnx2x_nway_reset,
1986         .get_link               = bnx2x_get_link,
1987         .get_eeprom_len         = bnx2x_get_eeprom_len,
1988         .get_eeprom             = bnx2x_get_eeprom,
1989         .set_eeprom             = bnx2x_set_eeprom,
1990         .get_coalesce           = bnx2x_get_coalesce,
1991         .set_coalesce           = bnx2x_set_coalesce,
1992         .get_ringparam          = bnx2x_get_ringparam,
1993         .set_ringparam          = bnx2x_set_ringparam,
1994         .get_pauseparam         = bnx2x_get_pauseparam,
1995         .set_pauseparam         = bnx2x_set_pauseparam,
1996         .get_rx_csum            = bnx2x_get_rx_csum,
1997         .set_rx_csum            = bnx2x_set_rx_csum,
1998         .get_tx_csum            = ethtool_op_get_tx_csum,
1999         .set_tx_csum            = ethtool_op_set_tx_hw_csum,
2000         .set_flags              = bnx2x_set_flags,
2001         .get_flags              = ethtool_op_get_flags,
2002         .get_sg                 = ethtool_op_get_sg,
2003         .set_sg                 = ethtool_op_set_sg,
2004         .get_tso                = ethtool_op_get_tso,
2005         .set_tso                = bnx2x_set_tso,
2006         .self_test              = bnx2x_self_test,
2007         .get_sset_count         = bnx2x_get_sset_count,
2008         .get_strings            = bnx2x_get_strings,
2009         .phys_id                = bnx2x_phys_id,
2010         .get_ethtool_stats      = bnx2x_get_ethtool_stats,
2011 };
2012
2013 void bnx2x_set_ethtool_ops(struct net_device *netdev)
2014 {
2015         SET_ETHTOOL_OPS(netdev, &bnx2x_ethtool_ops);
2016 }