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