root/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. qlcnic_82xx_statistics
  2. qlcnic_83xx_statistics
  3. qlcnic_dev_statistics_len
  4. qlcnic_get_ring_regs_len
  5. qlcnic_get_regs_len
  6. qlcnic_get_eeprom_len
  7. qlcnic_get_drvinfo
  8. qlcnic_82xx_get_link_ksettings
  9. qlcnic_get_link_ksettings
  10. qlcnic_set_port_config
  11. qlcnic_set_link_ksettings
  12. qlcnic_82xx_get_registers
  13. qlcnic_get_regs
  14. qlcnic_test_link
  15. qlcnic_get_eeprom
  16. qlcnic_get_ringparam
  17. qlcnic_validate_ringparam
  18. qlcnic_set_ringparam
  19. qlcnic_validate_ring_count
  20. qlcnic_get_channels
  21. qlcnic_set_channels
  22. qlcnic_get_pauseparam
  23. qlcnic_set_pauseparam
  24. qlcnic_reg_test
  25. qlcnic_eeprom_test
  26. qlcnic_get_sset_count
  27. qlcnic_irq_test
  28. qlcnic_create_loopback_buff
  29. qlcnic_check_loopback_buff
  30. qlcnic_do_lb_test
  31. qlcnic_loopback_test
  32. qlcnic_diag_test
  33. qlcnic_get_strings
  34. qlcnic_fill_stats
  35. qlcnic_update_stats
  36. qlcnic_fill_tx_queue_stats
  37. qlcnic_get_ethtool_stats
  38. qlcnic_set_led
  39. qlcnic_get_wol
  40. qlcnic_set_wol
  41. qlcnic_set_intr_coalesce
  42. qlcnic_get_intr_coalesce
  43. qlcnic_get_msglevel
  44. qlcnic_set_msglevel
  45. qlcnic_enable_fw_dump_state
  46. qlcnic_disable_fw_dump_state
  47. qlcnic_check_fw_dump_state
  48. qlcnic_get_dump_flag
  49. qlcnic_get_dump_data
  50. qlcnic_set_dump_mask
  51. qlcnic_set_dump

   1 /*
   2  * QLogic qlcnic NIC Driver
   3  * Copyright (c) 2009-2013 QLogic Corporation
   4  *
   5  * See LICENSE.qlcnic for copyright and licensing details.
   6  */
   7 
   8 #include <linux/types.h>
   9 #include <linux/delay.h>
  10 #include <linux/pci.h>
  11 #include <linux/io.h>
  12 #include <linux/netdevice.h>
  13 #include <linux/ethtool.h>
  14 
  15 #include "qlcnic.h"
  16 
  17 struct qlcnic_stats {
  18         char stat_string[ETH_GSTRING_LEN];
  19         int sizeof_stat;
  20         int stat_offset;
  21 };
  22 
  23 #define QLC_SIZEOF(m) FIELD_SIZEOF(struct qlcnic_adapter, m)
  24 #define QLC_OFF(m) offsetof(struct qlcnic_adapter, m)
  25 static const u32 qlcnic_fw_dump_level[] = {
  26         0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff
  27 };
  28 
  29 static const struct qlcnic_stats qlcnic_gstrings_stats[] = {
  30         {"xmit_on", QLC_SIZEOF(stats.xmit_on), QLC_OFF(stats.xmit_on)},
  31         {"xmit_off", QLC_SIZEOF(stats.xmit_off), QLC_OFF(stats.xmit_off)},
  32         {"xmit_called", QLC_SIZEOF(stats.xmitcalled),
  33          QLC_OFF(stats.xmitcalled)},
  34         {"xmit_finished", QLC_SIZEOF(stats.xmitfinished),
  35          QLC_OFF(stats.xmitfinished)},
  36         {"tx dma map error", QLC_SIZEOF(stats.tx_dma_map_error),
  37          QLC_OFF(stats.tx_dma_map_error)},
  38         {"tx_bytes", QLC_SIZEOF(stats.txbytes), QLC_OFF(stats.txbytes)},
  39         {"tx_dropped", QLC_SIZEOF(stats.txdropped), QLC_OFF(stats.txdropped)},
  40         {"rx dma map error", QLC_SIZEOF(stats.rx_dma_map_error),
  41          QLC_OFF(stats.rx_dma_map_error)},
  42         {"rx_pkts", QLC_SIZEOF(stats.rx_pkts), QLC_OFF(stats.rx_pkts)},
  43         {"rx_bytes", QLC_SIZEOF(stats.rxbytes), QLC_OFF(stats.rxbytes)},
  44         {"rx_dropped", QLC_SIZEOF(stats.rxdropped), QLC_OFF(stats.rxdropped)},
  45         {"null rxbuf", QLC_SIZEOF(stats.null_rxbuf), QLC_OFF(stats.null_rxbuf)},
  46         {"csummed", QLC_SIZEOF(stats.csummed), QLC_OFF(stats.csummed)},
  47         {"lro_pkts", QLC_SIZEOF(stats.lro_pkts), QLC_OFF(stats.lro_pkts)},
  48         {"lrobytes", QLC_SIZEOF(stats.lrobytes), QLC_OFF(stats.lrobytes)},
  49         {"lso_frames", QLC_SIZEOF(stats.lso_frames), QLC_OFF(stats.lso_frames)},
  50         {"encap_lso_frames", QLC_SIZEOF(stats.encap_lso_frames),
  51          QLC_OFF(stats.encap_lso_frames)},
  52         {"encap_tx_csummed", QLC_SIZEOF(stats.encap_tx_csummed),
  53          QLC_OFF(stats.encap_tx_csummed)},
  54         {"encap_rx_csummed", QLC_SIZEOF(stats.encap_rx_csummed),
  55          QLC_OFF(stats.encap_rx_csummed)},
  56         {"skb_alloc_failure", QLC_SIZEOF(stats.skb_alloc_failure),
  57          QLC_OFF(stats.skb_alloc_failure)},
  58         {"mac_filter_limit_overrun", QLC_SIZEOF(stats.mac_filter_limit_overrun),
  59          QLC_OFF(stats.mac_filter_limit_overrun)},
  60         {"spurious intr", QLC_SIZEOF(stats.spurious_intr),
  61          QLC_OFF(stats.spurious_intr)},
  62         {"mbx spurious intr", QLC_SIZEOF(stats.mbx_spurious_intr),
  63          QLC_OFF(stats.mbx_spurious_intr)},
  64 };
  65 
  66 static const char qlcnic_device_gstrings_stats[][ETH_GSTRING_LEN] = {
  67         "tx unicast frames",
  68         "tx multicast frames",
  69         "tx broadcast frames",
  70         "tx dropped frames",
  71         "tx errors",
  72         "tx local frames",
  73         "tx numbytes",
  74         "rx unicast frames",
  75         "rx multicast frames",
  76         "rx broadcast frames",
  77         "rx dropped frames",
  78         "rx errors",
  79         "rx local frames",
  80         "rx numbytes",
  81 };
  82 
  83 static const char qlcnic_83xx_tx_stats_strings[][ETH_GSTRING_LEN] = {
  84         "ctx_tx_bytes",
  85         "ctx_tx_pkts",
  86         "ctx_tx_errors",
  87         "ctx_tx_dropped_pkts",
  88         "ctx_tx_num_buffers",
  89 };
  90 
  91 static const char qlcnic_83xx_mac_stats_strings[][ETH_GSTRING_LEN] = {
  92         "mac_tx_frames",
  93         "mac_tx_bytes",
  94         "mac_tx_mcast_pkts",
  95         "mac_tx_bcast_pkts",
  96         "mac_tx_pause_cnt",
  97         "mac_tx_ctrl_pkt",
  98         "mac_tx_lt_64b_pkts",
  99         "mac_tx_lt_127b_pkts",
 100         "mac_tx_lt_255b_pkts",
 101         "mac_tx_lt_511b_pkts",
 102         "mac_tx_lt_1023b_pkts",
 103         "mac_tx_lt_1518b_pkts",
 104         "mac_tx_gt_1518b_pkts",
 105         "mac_rx_frames",
 106         "mac_rx_bytes",
 107         "mac_rx_mcast_pkts",
 108         "mac_rx_bcast_pkts",
 109         "mac_rx_pause_cnt",
 110         "mac_rx_ctrl_pkt",
 111         "mac_rx_lt_64b_pkts",
 112         "mac_rx_lt_127b_pkts",
 113         "mac_rx_lt_255b_pkts",
 114         "mac_rx_lt_511b_pkts",
 115         "mac_rx_lt_1023b_pkts",
 116         "mac_rx_lt_1518b_pkts",
 117         "mac_rx_gt_1518b_pkts",
 118         "mac_rx_length_error",
 119         "mac_rx_length_small",
 120         "mac_rx_length_large",
 121         "mac_rx_jabber",
 122         "mac_rx_dropped",
 123         "mac_crc_error",
 124         "mac_align_error",
 125         "eswitch_frames",
 126         "eswitch_bytes",
 127         "eswitch_multicast_frames",
 128         "eswitch_broadcast_frames",
 129         "eswitch_unicast_frames",
 130         "eswitch_error_free_frames",
 131         "eswitch_error_free_bytes",
 132 };
 133 
 134 #define QLCNIC_STATS_LEN        ARRAY_SIZE(qlcnic_gstrings_stats)
 135 
 136 static const char qlcnic_tx_queue_stats_strings[][ETH_GSTRING_LEN] = {
 137         "xmit_on",
 138         "xmit_off",
 139         "xmit_called",
 140         "xmit_finished",
 141         "tx_bytes",
 142 };
 143 
 144 #define QLCNIC_TX_STATS_LEN     ARRAY_SIZE(qlcnic_tx_queue_stats_strings)
 145 
 146 static const char qlcnic_83xx_rx_stats_strings[][ETH_GSTRING_LEN] = {
 147         "ctx_rx_bytes",
 148         "ctx_rx_pkts",
 149         "ctx_lro_pkt_cnt",
 150         "ctx_ip_csum_error",
 151         "ctx_rx_pkts_wo_ctx",
 152         "ctx_rx_pkts_drop_wo_sds_on_card",
 153         "ctx_rx_pkts_drop_wo_sds_on_host",
 154         "ctx_rx_osized_pkts",
 155         "ctx_rx_pkts_dropped_wo_rds",
 156         "ctx_rx_unexpected_mcast_pkts",
 157         "ctx_invalid_mac_address",
 158         "ctx_rx_rds_ring_prim_attempted",
 159         "ctx_rx_rds_ring_prim_success",
 160         "ctx_num_lro_flows_added",
 161         "ctx_num_lro_flows_removed",
 162         "ctx_num_lro_flows_active",
 163         "ctx_pkts_dropped_unknown",
 164 };
 165 
 166 static const char qlcnic_gstrings_test[][ETH_GSTRING_LEN] = {
 167         "Register_Test_on_offline",
 168         "Link_Test_on_offline",
 169         "Interrupt_Test_offline",
 170         "Internal_Loopback_offline",
 171         "External_Loopback_offline",
 172         "EEPROM_Test_offline"
 173 };
 174 
 175 #define QLCNIC_TEST_LEN ARRAY_SIZE(qlcnic_gstrings_test)
 176 
 177 static inline int qlcnic_82xx_statistics(struct qlcnic_adapter *adapter)
 178 {
 179         return ARRAY_SIZE(qlcnic_gstrings_stats) +
 180                ARRAY_SIZE(qlcnic_83xx_mac_stats_strings) +
 181                QLCNIC_TX_STATS_LEN * adapter->drv_tx_rings;
 182 }
 183 
 184 static inline int qlcnic_83xx_statistics(struct qlcnic_adapter *adapter)
 185 {
 186         return ARRAY_SIZE(qlcnic_gstrings_stats) +
 187                ARRAY_SIZE(qlcnic_83xx_tx_stats_strings) +
 188                ARRAY_SIZE(qlcnic_83xx_mac_stats_strings) +
 189                ARRAY_SIZE(qlcnic_83xx_rx_stats_strings) +
 190                QLCNIC_TX_STATS_LEN * adapter->drv_tx_rings;
 191 }
 192 
 193 static int qlcnic_dev_statistics_len(struct qlcnic_adapter *adapter)
 194 {
 195         int len = -1;
 196 
 197         if (qlcnic_82xx_check(adapter)) {
 198                 len = qlcnic_82xx_statistics(adapter);
 199                 if (adapter->flags & QLCNIC_ESWITCH_ENABLED)
 200                         len += ARRAY_SIZE(qlcnic_device_gstrings_stats);
 201         } else if (qlcnic_83xx_check(adapter)) {
 202                 len = qlcnic_83xx_statistics(adapter);
 203         }
 204 
 205         return len;
 206 }
 207 
 208 #define QLCNIC_TX_INTR_NOT_CONFIGURED   0X78563412
 209 
 210 #define QLCNIC_MAX_EEPROM_LEN   1024
 211 
 212 static const u32 diag_registers[] = {
 213         QLCNIC_CMDPEG_STATE,
 214         QLCNIC_RCVPEG_STATE,
 215         QLCNIC_FW_CAPABILITIES,
 216         QLCNIC_CRB_DRV_ACTIVE,
 217         QLCNIC_CRB_DEV_STATE,
 218         QLCNIC_CRB_DRV_STATE,
 219         QLCNIC_CRB_DRV_SCRATCH,
 220         QLCNIC_CRB_DEV_PARTITION_INFO,
 221         QLCNIC_CRB_DRV_IDC_VER,
 222         QLCNIC_PEG_ALIVE_COUNTER,
 223         QLCNIC_PEG_HALT_STATUS1,
 224         QLCNIC_PEG_HALT_STATUS2,
 225         -1
 226 };
 227 
 228 
 229 static const u32 ext_diag_registers[] = {
 230         CRB_XG_STATE_P3P,
 231         ISR_INT_STATE_REG,
 232         QLCNIC_CRB_PEG_NET_0+0x3c,
 233         QLCNIC_CRB_PEG_NET_1+0x3c,
 234         QLCNIC_CRB_PEG_NET_2+0x3c,
 235         QLCNIC_CRB_PEG_NET_4+0x3c,
 236         -1
 237 };
 238 
 239 #define QLCNIC_MGMT_API_VERSION 3
 240 #define QLCNIC_ETHTOOL_REGS_VER 4
 241 
 242 static inline int qlcnic_get_ring_regs_len(struct qlcnic_adapter *adapter)
 243 {
 244         int ring_regs_cnt = (adapter->drv_tx_rings * 5) +
 245                             (adapter->max_rds_rings * 2) +
 246                             (adapter->drv_sds_rings * 3) + 5;
 247         return ring_regs_cnt * sizeof(u32);
 248 }
 249 
 250 static int qlcnic_get_regs_len(struct net_device *dev)
 251 {
 252         struct qlcnic_adapter *adapter = netdev_priv(dev);
 253         u32 len;
 254 
 255         if (qlcnic_83xx_check(adapter))
 256                 len = qlcnic_83xx_get_regs_len(adapter);
 257         else
 258                 len = sizeof(ext_diag_registers) + sizeof(diag_registers);
 259 
 260         len += ((QLCNIC_DEV_INFO_SIZE + 2) * sizeof(u32));
 261         len += qlcnic_get_ring_regs_len(adapter);
 262         return len;
 263 }
 264 
 265 static int qlcnic_get_eeprom_len(struct net_device *dev)
 266 {
 267         return QLCNIC_FLASH_TOTAL_SIZE;
 268 }
 269 
 270 static void
 271 qlcnic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
 272 {
 273         struct qlcnic_adapter *adapter = netdev_priv(dev);
 274         u32 fw_major, fw_minor, fw_build;
 275         fw_major = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_MAJOR);
 276         fw_minor = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_MINOR);
 277         fw_build = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_SUB);
 278         snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
 279                 "%d.%d.%d", fw_major, fw_minor, fw_build);
 280 
 281         strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
 282                 sizeof(drvinfo->bus_info));
 283         strlcpy(drvinfo->driver, qlcnic_driver_name, sizeof(drvinfo->driver));
 284         strlcpy(drvinfo->version, QLCNIC_LINUX_VERSIONID,
 285                 sizeof(drvinfo->version));
 286 }
 287 
 288 static int qlcnic_82xx_get_link_ksettings(struct qlcnic_adapter *adapter,
 289                                           struct ethtool_link_ksettings *ecmd)
 290 {
 291         struct qlcnic_hardware_context *ahw = adapter->ahw;
 292         u32 speed, reg;
 293         int check_sfp_module = 0, err = 0;
 294         u16 pcifn = ahw->pci_func;
 295         u32 supported, advertising;
 296 
 297         /* read which mode */
 298         if (adapter->ahw->port_type == QLCNIC_GBE) {
 299                 supported = (SUPPORTED_10baseT_Half |
 300                                    SUPPORTED_10baseT_Full |
 301                                    SUPPORTED_100baseT_Half |
 302                                    SUPPORTED_100baseT_Full |
 303                                    SUPPORTED_1000baseT_Half |
 304                                    SUPPORTED_1000baseT_Full);
 305 
 306                 advertising = (ADVERTISED_100baseT_Half |
 307                                      ADVERTISED_100baseT_Full |
 308                                      ADVERTISED_1000baseT_Half |
 309                                      ADVERTISED_1000baseT_Full);
 310 
 311                 ecmd->base.speed = adapter->ahw->link_speed;
 312                 ecmd->base.duplex = adapter->ahw->link_duplex;
 313                 ecmd->base.autoneg = adapter->ahw->link_autoneg;
 314 
 315         } else if (adapter->ahw->port_type == QLCNIC_XGBE) {
 316                 u32 val = 0;
 317                 val = QLCRD32(adapter, QLCNIC_PORT_MODE_ADDR, &err);
 318 
 319                 if (val == QLCNIC_PORT_MODE_802_3_AP) {
 320                         supported = SUPPORTED_1000baseT_Full;
 321                         advertising = ADVERTISED_1000baseT_Full;
 322                 } else {
 323                         supported = SUPPORTED_10000baseT_Full;
 324                         advertising = ADVERTISED_10000baseT_Full;
 325                 }
 326 
 327                 if (netif_running(adapter->netdev) && ahw->has_link_events) {
 328                         if (ahw->linkup) {
 329                                 reg = QLCRD32(adapter,
 330                                               P3P_LINK_SPEED_REG(pcifn), &err);
 331                                 speed = P3P_LINK_SPEED_VAL(pcifn, reg);
 332                                 ahw->link_speed = speed * P3P_LINK_SPEED_MHZ;
 333                         }
 334 
 335                         ecmd->base.speed = ahw->link_speed;
 336                         ecmd->base.autoneg = ahw->link_autoneg;
 337                         ecmd->base.duplex = ahw->link_duplex;
 338                         goto skip;
 339                 }
 340 
 341                 ecmd->base.speed = SPEED_UNKNOWN;
 342                 ecmd->base.duplex = DUPLEX_UNKNOWN;
 343                 ecmd->base.autoneg = AUTONEG_DISABLE;
 344         } else
 345                 return -EIO;
 346 
 347 skip:
 348         ecmd->base.phy_address = adapter->ahw->physical_port;
 349 
 350         switch (adapter->ahw->board_type) {
 351         case QLCNIC_BRDTYPE_P3P_REF_QG:
 352         case QLCNIC_BRDTYPE_P3P_4_GB:
 353         case QLCNIC_BRDTYPE_P3P_4_GB_MM:
 354                 supported |= SUPPORTED_Autoneg;
 355                 advertising |= ADVERTISED_Autoneg;
 356                 /* fall through */
 357         case QLCNIC_BRDTYPE_P3P_10G_CX4:
 358         case QLCNIC_BRDTYPE_P3P_10G_CX4_LP:
 359         case QLCNIC_BRDTYPE_P3P_10000_BASE_T:
 360                 supported |= SUPPORTED_TP;
 361                 advertising |= ADVERTISED_TP;
 362                 ecmd->base.port = PORT_TP;
 363                 ecmd->base.autoneg =  adapter->ahw->link_autoneg;
 364                 break;
 365         case QLCNIC_BRDTYPE_P3P_IMEZ:
 366         case QLCNIC_BRDTYPE_P3P_XG_LOM:
 367         case QLCNIC_BRDTYPE_P3P_HMEZ:
 368                 supported |= SUPPORTED_MII;
 369                 advertising |= ADVERTISED_MII;
 370                 ecmd->base.port = PORT_MII;
 371                 ecmd->base.autoneg = AUTONEG_DISABLE;
 372                 break;
 373         case QLCNIC_BRDTYPE_P3P_10G_SFP_PLUS:
 374         case QLCNIC_BRDTYPE_P3P_10G_SFP_CT:
 375         case QLCNIC_BRDTYPE_P3P_10G_SFP_QT:
 376                 advertising |= ADVERTISED_TP;
 377                 supported |= SUPPORTED_TP;
 378                 check_sfp_module = netif_running(adapter->netdev) &&
 379                                    ahw->has_link_events;
 380                 /* fall through */
 381         case QLCNIC_BRDTYPE_P3P_10G_XFP:
 382                 supported |= SUPPORTED_FIBRE;
 383                 advertising |= ADVERTISED_FIBRE;
 384                 ecmd->base.port = PORT_FIBRE;
 385                 ecmd->base.autoneg = AUTONEG_DISABLE;
 386                 break;
 387         case QLCNIC_BRDTYPE_P3P_10G_TP:
 388                 if (adapter->ahw->port_type == QLCNIC_XGBE) {
 389                         ecmd->base.autoneg = AUTONEG_DISABLE;
 390                         supported |= (SUPPORTED_FIBRE | SUPPORTED_TP);
 391                         advertising |=
 392                                 (ADVERTISED_FIBRE | ADVERTISED_TP);
 393                         ecmd->base.port = PORT_FIBRE;
 394                         check_sfp_module = netif_running(adapter->netdev) &&
 395                                            ahw->has_link_events;
 396                 } else {
 397                         ecmd->base.autoneg = AUTONEG_ENABLE;
 398                         supported |= (SUPPORTED_TP | SUPPORTED_Autoneg);
 399                         advertising |=
 400                                 (ADVERTISED_TP | ADVERTISED_Autoneg);
 401                         ecmd->base.port = PORT_TP;
 402                 }
 403                 break;
 404         default:
 405                 dev_err(&adapter->pdev->dev, "Unsupported board model %d\n",
 406                         adapter->ahw->board_type);
 407                 return -EIO;
 408         }
 409 
 410         if (check_sfp_module) {
 411                 switch (adapter->ahw->module_type) {
 412                 case LINKEVENT_MODULE_OPTICAL_UNKNOWN:
 413                 case LINKEVENT_MODULE_OPTICAL_SRLR:
 414                 case LINKEVENT_MODULE_OPTICAL_LRM:
 415                 case LINKEVENT_MODULE_OPTICAL_SFP_1G:
 416                         ecmd->base.port = PORT_FIBRE;
 417                         break;
 418                 case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE:
 419                 case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN:
 420                 case LINKEVENT_MODULE_TWINAX:
 421                         ecmd->base.port = PORT_TP;
 422                         break;
 423                 default:
 424                         ecmd->base.port = PORT_OTHER;
 425                 }
 426         }
 427 
 428         ethtool_convert_legacy_u32_to_link_mode(ecmd->link_modes.supported,
 429                                                 supported);
 430         ethtool_convert_legacy_u32_to_link_mode(ecmd->link_modes.advertising,
 431                                                 advertising);
 432 
 433         return 0;
 434 }
 435 
 436 static int qlcnic_get_link_ksettings(struct net_device *dev,
 437                                      struct ethtool_link_ksettings *ecmd)
 438 {
 439         struct qlcnic_adapter *adapter = netdev_priv(dev);
 440 
 441         if (qlcnic_82xx_check(adapter))
 442                 return qlcnic_82xx_get_link_ksettings(adapter, ecmd);
 443         else if (qlcnic_83xx_check(adapter))
 444                 return qlcnic_83xx_get_link_ksettings(adapter, ecmd);
 445 
 446         return -EIO;
 447 }
 448 
 449 
 450 static int qlcnic_set_port_config(struct qlcnic_adapter *adapter,
 451                                   const struct ethtool_link_ksettings *ecmd)
 452 {
 453         u32 ret = 0, config = 0;
 454         /* read which mode */
 455         if (ecmd->base.duplex)
 456                 config |= 0x1;
 457 
 458         if (ecmd->base.autoneg)
 459                 config |= 0x2;
 460 
 461         switch (ecmd->base.speed) {
 462         case SPEED_10:
 463                 config |= (0 << 8);
 464                 break;
 465         case SPEED_100:
 466                 config |= (1 << 8);
 467                 break;
 468         case SPEED_1000:
 469                 config |= (10 << 8);
 470                 break;
 471         default:
 472                 return -EIO;
 473         }
 474 
 475         ret = qlcnic_fw_cmd_set_port(adapter, config);
 476 
 477         if (ret == QLCNIC_RCODE_NOT_SUPPORTED)
 478                 return -EOPNOTSUPP;
 479         else if (ret)
 480                 return -EIO;
 481         return ret;
 482 }
 483 
 484 static int qlcnic_set_link_ksettings(struct net_device *dev,
 485                                      const struct ethtool_link_ksettings *ecmd)
 486 {
 487         u32 ret = 0;
 488         struct qlcnic_adapter *adapter = netdev_priv(dev);
 489 
 490         if (qlcnic_83xx_check(adapter))
 491                 qlcnic_83xx_get_port_type(adapter);
 492 
 493         if (adapter->ahw->port_type != QLCNIC_GBE)
 494                 return -EOPNOTSUPP;
 495 
 496         if (qlcnic_83xx_check(adapter))
 497                 ret = qlcnic_83xx_set_link_ksettings(adapter, ecmd);
 498         else
 499                 ret = qlcnic_set_port_config(adapter, ecmd);
 500 
 501         if (!ret)
 502                 return ret;
 503 
 504         adapter->ahw->link_speed = ecmd->base.speed;
 505         adapter->ahw->link_duplex = ecmd->base.duplex;
 506         adapter->ahw->link_autoneg = ecmd->base.autoneg;
 507 
 508         if (!netif_running(dev))
 509                 return 0;
 510 
 511         dev->netdev_ops->ndo_stop(dev);
 512         return dev->netdev_ops->ndo_open(dev);
 513 }
 514 
 515 static int qlcnic_82xx_get_registers(struct qlcnic_adapter *adapter,
 516                                      u32 *regs_buff)
 517 {
 518         int i, j = 0, err = 0;
 519 
 520         for (i = QLCNIC_DEV_INFO_SIZE + 1; diag_registers[j] != -1; j++, i++)
 521                 regs_buff[i] = QLC_SHARED_REG_RD32(adapter, diag_registers[j]);
 522         j = 0;
 523         while (ext_diag_registers[j] != -1)
 524                 regs_buff[i++] = QLCRD32(adapter, ext_diag_registers[j++],
 525                                          &err);
 526         return i;
 527 }
 528 
 529 static void
 530 qlcnic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
 531 {
 532         struct qlcnic_adapter *adapter = netdev_priv(dev);
 533         struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
 534         struct qlcnic_host_sds_ring *sds_ring;
 535         struct qlcnic_host_rds_ring *rds_rings;
 536         struct qlcnic_host_tx_ring *tx_ring;
 537         u32 *regs_buff = p;
 538         int ring, i = 0;
 539 
 540         memset(p, 0, qlcnic_get_regs_len(dev));
 541 
 542         regs->version = (QLCNIC_ETHTOOL_REGS_VER << 24) |
 543                 (adapter->ahw->revision_id << 16) | (adapter->pdev)->device;
 544 
 545         regs_buff[0] = (0xcafe0000 | (QLCNIC_DEV_INFO_SIZE & 0xffff));
 546         regs_buff[1] = QLCNIC_MGMT_API_VERSION;
 547 
 548         if (adapter->ahw->capabilities & QLC_83XX_ESWITCH_CAPABILITY)
 549                 regs_buff[2] = adapter->ahw->max_vnic_func;
 550 
 551         if (qlcnic_82xx_check(adapter))
 552                 i = qlcnic_82xx_get_registers(adapter, regs_buff);
 553         else
 554                 i = qlcnic_83xx_get_registers(adapter, regs_buff);
 555 
 556         if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
 557                 return;
 558 
 559         /* Marker btw regs and TX ring count */
 560         regs_buff[i++] = 0xFFEFCDAB;
 561 
 562         regs_buff[i++] = adapter->drv_tx_rings; /* No. of TX ring */
 563         for (ring = 0; ring < adapter->drv_tx_rings; ring++) {
 564                 tx_ring = &adapter->tx_ring[ring];
 565                 regs_buff[i++] = le32_to_cpu(*(tx_ring->hw_consumer));
 566                 regs_buff[i++] = tx_ring->sw_consumer;
 567                 regs_buff[i++] = readl(tx_ring->crb_cmd_producer);
 568                 regs_buff[i++] = tx_ring->producer;
 569                 if (tx_ring->crb_intr_mask)
 570                         regs_buff[i++] = readl(tx_ring->crb_intr_mask);
 571                 else
 572                         regs_buff[i++] = QLCNIC_TX_INTR_NOT_CONFIGURED;
 573         }
 574 
 575         regs_buff[i++] = adapter->max_rds_rings; /* No. of RX ring */
 576         for (ring = 0; ring < adapter->max_rds_rings; ring++) {
 577                 rds_rings = &recv_ctx->rds_rings[ring];
 578                 regs_buff[i++] = readl(rds_rings->crb_rcv_producer);
 579                 regs_buff[i++] = rds_rings->producer;
 580         }
 581 
 582         regs_buff[i++] = adapter->drv_sds_rings; /* No. of SDS ring */
 583         for (ring = 0; ring < adapter->drv_sds_rings; ring++) {
 584                 sds_ring = &(recv_ctx->sds_rings[ring]);
 585                 regs_buff[i++] = readl(sds_ring->crb_sts_consumer);
 586                 regs_buff[i++] = sds_ring->consumer;
 587                 regs_buff[i++] = readl(sds_ring->crb_intr_mask);
 588         }
 589 }
 590 
 591 static u32 qlcnic_test_link(struct net_device *dev)
 592 {
 593         struct qlcnic_adapter *adapter = netdev_priv(dev);
 594         int err = 0;
 595         u32 val;
 596 
 597         if (qlcnic_83xx_check(adapter)) {
 598                 val = qlcnic_83xx_test_link(adapter);
 599                 return (val & 1) ? 0 : 1;
 600         }
 601         val = QLCRD32(adapter, CRB_XG_STATE_P3P, &err);
 602         if (err == -EIO)
 603                 return err;
 604         val = XG_LINK_STATE_P3P(adapter->ahw->pci_func, val);
 605         return (val == XG_LINK_UP_P3P) ? 0 : 1;
 606 }
 607 
 608 static int
 609 qlcnic_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
 610                       u8 *bytes)
 611 {
 612         struct qlcnic_adapter *adapter = netdev_priv(dev);
 613         int offset;
 614         int ret = -1;
 615 
 616         if (qlcnic_83xx_check(adapter))
 617                 return 0;
 618         if (eeprom->len == 0)
 619                 return -EINVAL;
 620 
 621         eeprom->magic = (adapter->pdev)->vendor |
 622                         ((adapter->pdev)->device << 16);
 623         offset = eeprom->offset;
 624 
 625         if (qlcnic_82xx_check(adapter))
 626                 ret = qlcnic_rom_fast_read_words(adapter, offset, bytes,
 627                                                  eeprom->len);
 628         if (ret < 0)
 629                 return ret;
 630 
 631         return 0;
 632 }
 633 
 634 static void
 635 qlcnic_get_ringparam(struct net_device *dev,
 636                 struct ethtool_ringparam *ring)
 637 {
 638         struct qlcnic_adapter *adapter = netdev_priv(dev);
 639 
 640         ring->rx_pending = adapter->num_rxd;
 641         ring->rx_jumbo_pending = adapter->num_jumbo_rxd;
 642         ring->tx_pending = adapter->num_txd;
 643 
 644         ring->rx_max_pending = adapter->max_rxd;
 645         ring->rx_jumbo_max_pending = adapter->max_jumbo_rxd;
 646         ring->tx_max_pending = MAX_CMD_DESCRIPTORS;
 647 }
 648 
 649 static u32
 650 qlcnic_validate_ringparam(u32 val, u32 min, u32 max, char *r_name)
 651 {
 652         u32 num_desc;
 653         num_desc = max(val, min);
 654         num_desc = min(num_desc, max);
 655         num_desc = roundup_pow_of_two(num_desc);
 656 
 657         if (val != num_desc) {
 658                 printk(KERN_INFO "%s: setting %s ring size %d instead of %d\n",
 659                        qlcnic_driver_name, r_name, num_desc, val);
 660         }
 661 
 662         return num_desc;
 663 }
 664 
 665 static int
 666 qlcnic_set_ringparam(struct net_device *dev,
 667                 struct ethtool_ringparam *ring)
 668 {
 669         struct qlcnic_adapter *adapter = netdev_priv(dev);
 670         u16 num_rxd, num_jumbo_rxd, num_txd;
 671 
 672         if (ring->rx_mini_pending)
 673                 return -EOPNOTSUPP;
 674 
 675         num_rxd = qlcnic_validate_ringparam(ring->rx_pending,
 676                         MIN_RCV_DESCRIPTORS, adapter->max_rxd, "rx");
 677 
 678         num_jumbo_rxd = qlcnic_validate_ringparam(ring->rx_jumbo_pending,
 679                         MIN_JUMBO_DESCRIPTORS, adapter->max_jumbo_rxd,
 680                                                 "rx jumbo");
 681 
 682         num_txd = qlcnic_validate_ringparam(ring->tx_pending,
 683                         MIN_CMD_DESCRIPTORS, MAX_CMD_DESCRIPTORS, "tx");
 684 
 685         if (num_rxd == adapter->num_rxd && num_txd == adapter->num_txd &&
 686                         num_jumbo_rxd == adapter->num_jumbo_rxd)
 687                 return 0;
 688 
 689         adapter->num_rxd = num_rxd;
 690         adapter->num_jumbo_rxd = num_jumbo_rxd;
 691         adapter->num_txd = num_txd;
 692 
 693         return qlcnic_reset_context(adapter);
 694 }
 695 
 696 static int qlcnic_validate_ring_count(struct qlcnic_adapter *adapter,
 697                                       u8 rx_ring, u8 tx_ring)
 698 {
 699         if (rx_ring == 0 || tx_ring == 0)
 700                 return -EINVAL;
 701 
 702         if (rx_ring != 0) {
 703                 if (rx_ring > adapter->max_sds_rings) {
 704                         netdev_err(adapter->netdev,
 705                                    "Invalid ring count, SDS ring count %d should not be greater than max %d driver sds rings.\n",
 706                                    rx_ring, adapter->max_sds_rings);
 707                         return -EINVAL;
 708                 }
 709         }
 710 
 711          if (tx_ring != 0) {
 712                 if (tx_ring > adapter->max_tx_rings) {
 713                         netdev_err(adapter->netdev,
 714                                    "Invalid ring count, Tx ring count %d should not be greater than max %d driver Tx rings.\n",
 715                                    tx_ring, adapter->max_tx_rings);
 716                         return -EINVAL;
 717                 }
 718         }
 719 
 720         return 0;
 721 }
 722 
 723 static void qlcnic_get_channels(struct net_device *dev,
 724                 struct ethtool_channels *channel)
 725 {
 726         struct qlcnic_adapter *adapter = netdev_priv(dev);
 727 
 728         channel->max_rx = adapter->max_sds_rings;
 729         channel->max_tx = adapter->max_tx_rings;
 730         channel->rx_count = adapter->drv_sds_rings;
 731         channel->tx_count = adapter->drv_tx_rings;
 732 }
 733 
 734 static int qlcnic_set_channels(struct net_device *dev,
 735                                struct ethtool_channels *channel)
 736 {
 737         struct qlcnic_adapter *adapter = netdev_priv(dev);
 738         int err;
 739 
 740         if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) {
 741                 netdev_err(dev, "No RSS/TSS support in non MSI-X mode\n");
 742                 return -EINVAL;
 743         }
 744 
 745         if (channel->other_count || channel->combined_count)
 746                 return -EINVAL;
 747 
 748         err = qlcnic_validate_ring_count(adapter, channel->rx_count,
 749                                          channel->tx_count);
 750         if (err)
 751                 return err;
 752 
 753         if (adapter->drv_sds_rings != channel->rx_count) {
 754                 err = qlcnic_validate_rings(adapter, channel->rx_count,
 755                                             QLCNIC_RX_QUEUE);
 756                 if (err) {
 757                         netdev_err(dev, "Unable to configure %u SDS rings\n",
 758                                    channel->rx_count);
 759                         return err;
 760                 }
 761                 adapter->drv_rss_rings = channel->rx_count;
 762         }
 763 
 764         if (adapter->drv_tx_rings != channel->tx_count) {
 765                 err = qlcnic_validate_rings(adapter, channel->tx_count,
 766                                             QLCNIC_TX_QUEUE);
 767                 if (err) {
 768                         netdev_err(dev, "Unable to configure %u Tx rings\n",
 769                                    channel->tx_count);
 770                         return err;
 771                 }
 772                 adapter->drv_tss_rings = channel->tx_count;
 773         }
 774 
 775         adapter->flags |= QLCNIC_TSS_RSS;
 776 
 777         err = qlcnic_setup_rings(adapter);
 778         netdev_info(dev, "Allocated %d SDS rings and %d Tx rings\n",
 779                     adapter->drv_sds_rings, adapter->drv_tx_rings);
 780 
 781         return err;
 782 }
 783 
 784 static void
 785 qlcnic_get_pauseparam(struct net_device *netdev,
 786                           struct ethtool_pauseparam *pause)
 787 {
 788         struct qlcnic_adapter *adapter = netdev_priv(netdev);
 789         int port = adapter->ahw->physical_port;
 790         int err = 0;
 791         __u32 val;
 792 
 793         if (qlcnic_83xx_check(adapter)) {
 794                 qlcnic_83xx_get_pauseparam(adapter, pause);
 795                 return;
 796         }
 797         if (adapter->ahw->port_type == QLCNIC_GBE) {
 798                 if ((port < 0) || (port > QLCNIC_NIU_MAX_GBE_PORTS))
 799                         return;
 800                 /* get flow control settings */
 801                 val = QLCRD32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port), &err);
 802                 if (err == -EIO)
 803                         return;
 804                 pause->rx_pause = qlcnic_gb_get_rx_flowctl(val);
 805                 val = QLCRD32(adapter, QLCNIC_NIU_GB_PAUSE_CTL, &err);
 806                 if (err == -EIO)
 807                         return;
 808                 switch (port) {
 809                 case 0:
 810                         pause->tx_pause = !(qlcnic_gb_get_gb0_mask(val));
 811                         break;
 812                 case 1:
 813                         pause->tx_pause = !(qlcnic_gb_get_gb1_mask(val));
 814                         break;
 815                 case 2:
 816                         pause->tx_pause = !(qlcnic_gb_get_gb2_mask(val));
 817                         break;
 818                 case 3:
 819                 default:
 820                         pause->tx_pause = !(qlcnic_gb_get_gb3_mask(val));
 821                         break;
 822                 }
 823         } else if (adapter->ahw->port_type == QLCNIC_XGBE) {
 824                 if ((port < 0) || (port > QLCNIC_NIU_MAX_XG_PORTS))
 825                         return;
 826                 pause->rx_pause = 1;
 827                 val = QLCRD32(adapter, QLCNIC_NIU_XG_PAUSE_CTL, &err);
 828                 if (err == -EIO)
 829                         return;
 830                 if (port == 0)
 831                         pause->tx_pause = !(qlcnic_xg_get_xg0_mask(val));
 832                 else
 833                         pause->tx_pause = !(qlcnic_xg_get_xg1_mask(val));
 834         } else {
 835                 dev_err(&netdev->dev, "Unknown board type: %x\n",
 836                                         adapter->ahw->port_type);
 837         }
 838 }
 839 
 840 static int
 841 qlcnic_set_pauseparam(struct net_device *netdev,
 842                           struct ethtool_pauseparam *pause)
 843 {
 844         struct qlcnic_adapter *adapter = netdev_priv(netdev);
 845         int port = adapter->ahw->physical_port;
 846         int err = 0;
 847         __u32 val;
 848 
 849         if (qlcnic_83xx_check(adapter))
 850                 return qlcnic_83xx_set_pauseparam(adapter, pause);
 851 
 852         /* read mode */
 853         if (adapter->ahw->port_type == QLCNIC_GBE) {
 854                 if ((port < 0) || (port > QLCNIC_NIU_MAX_GBE_PORTS))
 855                         return -EIO;
 856                 /* set flow control */
 857                 val = QLCRD32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port), &err);
 858                 if (err == -EIO)
 859                         return err;
 860 
 861                 if (pause->rx_pause)
 862                         qlcnic_gb_rx_flowctl(val);
 863                 else
 864                         qlcnic_gb_unset_rx_flowctl(val);
 865 
 866                 QLCWR32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port),
 867                                 val);
 868                 QLCWR32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port), val);
 869                 /* set autoneg */
 870                 val = QLCRD32(adapter, QLCNIC_NIU_GB_PAUSE_CTL, &err);
 871                 if (err == -EIO)
 872                         return err;
 873                 switch (port) {
 874                 case 0:
 875                         if (pause->tx_pause)
 876                                 qlcnic_gb_unset_gb0_mask(val);
 877                         else
 878                                 qlcnic_gb_set_gb0_mask(val);
 879                         break;
 880                 case 1:
 881                         if (pause->tx_pause)
 882                                 qlcnic_gb_unset_gb1_mask(val);
 883                         else
 884                                 qlcnic_gb_set_gb1_mask(val);
 885                         break;
 886                 case 2:
 887                         if (pause->tx_pause)
 888                                 qlcnic_gb_unset_gb2_mask(val);
 889                         else
 890                                 qlcnic_gb_set_gb2_mask(val);
 891                         break;
 892                 case 3:
 893                 default:
 894                         if (pause->tx_pause)
 895                                 qlcnic_gb_unset_gb3_mask(val);
 896                         else
 897                                 qlcnic_gb_set_gb3_mask(val);
 898                         break;
 899                 }
 900                 QLCWR32(adapter, QLCNIC_NIU_GB_PAUSE_CTL, val);
 901         } else if (adapter->ahw->port_type == QLCNIC_XGBE) {
 902                 if (!pause->rx_pause || pause->autoneg)
 903                         return -EOPNOTSUPP;
 904 
 905                 if ((port < 0) || (port > QLCNIC_NIU_MAX_XG_PORTS))
 906                         return -EIO;
 907 
 908                 val = QLCRD32(adapter, QLCNIC_NIU_XG_PAUSE_CTL, &err);
 909                 if (err == -EIO)
 910                         return err;
 911                 if (port == 0) {
 912                         if (pause->tx_pause)
 913                                 qlcnic_xg_unset_xg0_mask(val);
 914                         else
 915                                 qlcnic_xg_set_xg0_mask(val);
 916                 } else {
 917                         if (pause->tx_pause)
 918                                 qlcnic_xg_unset_xg1_mask(val);
 919                         else
 920                                 qlcnic_xg_set_xg1_mask(val);
 921                 }
 922                 QLCWR32(adapter, QLCNIC_NIU_XG_PAUSE_CTL, val);
 923         } else {
 924                 dev_err(&netdev->dev, "Unknown board type: %x\n",
 925                                 adapter->ahw->port_type);
 926         }
 927         return 0;
 928 }
 929 
 930 static int qlcnic_reg_test(struct net_device *dev)
 931 {
 932         struct qlcnic_adapter *adapter = netdev_priv(dev);
 933         u32 data_read;
 934         int err = 0;
 935 
 936         if (qlcnic_83xx_check(adapter))
 937                 return qlcnic_83xx_reg_test(adapter);
 938 
 939         data_read = QLCRD32(adapter, QLCNIC_PCIX_PH_REG(0), &err);
 940         if (err == -EIO)
 941                 return err;
 942         if ((data_read & 0xffff) != adapter->pdev->vendor)
 943                 return 1;
 944 
 945         return 0;
 946 }
 947 
 948 static int qlcnic_eeprom_test(struct net_device *dev)
 949 {
 950         struct qlcnic_adapter *adapter = netdev_priv(dev);
 951 
 952         if (qlcnic_82xx_check(adapter))
 953                 return 0;
 954 
 955         return qlcnic_83xx_flash_test(adapter);
 956 }
 957 
 958 static int qlcnic_get_sset_count(struct net_device *dev, int sset)
 959 {
 960 
 961         struct qlcnic_adapter *adapter = netdev_priv(dev);
 962         switch (sset) {
 963         case ETH_SS_TEST:
 964                 return QLCNIC_TEST_LEN;
 965         case ETH_SS_STATS:
 966                 return qlcnic_dev_statistics_len(adapter);
 967         default:
 968                 return -EOPNOTSUPP;
 969         }
 970 }
 971 
 972 static int qlcnic_irq_test(struct net_device *netdev)
 973 {
 974         struct qlcnic_adapter *adapter = netdev_priv(netdev);
 975         struct qlcnic_hardware_context *ahw = adapter->ahw;
 976         struct qlcnic_cmd_args cmd;
 977         int ret, drv_sds_rings = adapter->drv_sds_rings;
 978         int drv_tx_rings = adapter->drv_tx_rings;
 979 
 980         if (qlcnic_83xx_check(adapter))
 981                 return qlcnic_83xx_interrupt_test(netdev);
 982 
 983         if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
 984                 return -EIO;
 985 
 986         ret = qlcnic_diag_alloc_res(netdev, QLCNIC_INTERRUPT_TEST);
 987         if (ret)
 988                 goto clear_diag_irq;
 989 
 990         ahw->diag_cnt = 0;
 991         ret = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_INTRPT_TEST);
 992         if (ret)
 993                 goto free_diag_res;
 994 
 995         cmd.req.arg[1] = ahw->pci_func;
 996         ret = qlcnic_issue_cmd(adapter, &cmd);
 997         if (ret)
 998                 goto done;
 999 
1000         usleep_range(1000, 12000);
1001         ret = !ahw->diag_cnt;
1002 
1003 done:
1004         qlcnic_free_mbx_args(&cmd);
1005 
1006 free_diag_res:
1007         qlcnic_diag_free_res(netdev, drv_sds_rings);
1008 
1009 clear_diag_irq:
1010         adapter->drv_sds_rings = drv_sds_rings;
1011         adapter->drv_tx_rings = drv_tx_rings;
1012         clear_bit(__QLCNIC_RESETTING, &adapter->state);
1013 
1014         return ret;
1015 }
1016 
1017 #define QLCNIC_ILB_PKT_SIZE             64
1018 #define QLCNIC_NUM_ILB_PKT              16
1019 #define QLCNIC_ILB_MAX_RCV_LOOP         10
1020 #define QLCNIC_LB_PKT_POLL_DELAY_MSEC   1
1021 #define QLCNIC_LB_PKT_POLL_COUNT        20
1022 
1023 static void qlcnic_create_loopback_buff(unsigned char *data, u8 mac[])
1024 {
1025         unsigned char random_data[] = {0xa8, 0x06, 0x45, 0x00};
1026 
1027         memset(data, 0x4e, QLCNIC_ILB_PKT_SIZE);
1028 
1029         memcpy(data, mac, ETH_ALEN);
1030         memcpy(data + ETH_ALEN, mac, ETH_ALEN);
1031 
1032         memcpy(data + 2 * ETH_ALEN, random_data, sizeof(random_data));
1033 }
1034 
1035 int qlcnic_check_loopback_buff(unsigned char *data, u8 mac[])
1036 {
1037         unsigned char buff[QLCNIC_ILB_PKT_SIZE];
1038         qlcnic_create_loopback_buff(buff, mac);
1039         return memcmp(data, buff, QLCNIC_ILB_PKT_SIZE);
1040 }
1041 
1042 int qlcnic_do_lb_test(struct qlcnic_adapter *adapter, u8 mode)
1043 {
1044         struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
1045         struct qlcnic_host_sds_ring *sds_ring = &recv_ctx->sds_rings[0];
1046         struct sk_buff *skb;
1047         int i, loop, cnt = 0;
1048 
1049         for (i = 0; i < QLCNIC_NUM_ILB_PKT; i++) {
1050                 skb = netdev_alloc_skb(adapter->netdev, QLCNIC_ILB_PKT_SIZE);
1051                 if (!skb)
1052                         break;
1053                 qlcnic_create_loopback_buff(skb->data, adapter->mac_addr);
1054                 skb_put(skb, QLCNIC_ILB_PKT_SIZE);
1055                 adapter->ahw->diag_cnt = 0;
1056                 qlcnic_xmit_frame(skb, adapter->netdev);
1057                 loop = 0;
1058 
1059                 do {
1060                         msleep(QLCNIC_LB_PKT_POLL_DELAY_MSEC);
1061                         qlcnic_process_rcv_ring_diag(sds_ring);
1062                         if (loop++ > QLCNIC_LB_PKT_POLL_COUNT)
1063                                 break;
1064                 } while (!adapter->ahw->diag_cnt);
1065 
1066                 dev_kfree_skb_any(skb);
1067 
1068                 if (!adapter->ahw->diag_cnt)
1069                         dev_warn(&adapter->pdev->dev,
1070                                  "LB Test: packet #%d was not received\n",
1071                                  i + 1);
1072                 else
1073                         cnt++;
1074         }
1075         if (cnt != i) {
1076                 dev_err(&adapter->pdev->dev,
1077                         "LB Test: failed, TX[%d], RX[%d]\n", i, cnt);
1078                 if (mode != QLCNIC_ILB_MODE)
1079                         dev_warn(&adapter->pdev->dev,
1080                                  "WARNING: Please check loopback cable\n");
1081                 return -1;
1082         }
1083         return 0;
1084 }
1085 
1086 static int qlcnic_loopback_test(struct net_device *netdev, u8 mode)
1087 {
1088         struct qlcnic_adapter *adapter = netdev_priv(netdev);
1089         int drv_tx_rings = adapter->drv_tx_rings;
1090         int drv_sds_rings = adapter->drv_sds_rings;
1091         struct qlcnic_host_sds_ring *sds_ring;
1092         struct qlcnic_hardware_context *ahw = adapter->ahw;
1093         int loop = 0;
1094         int ret;
1095 
1096         if (qlcnic_83xx_check(adapter))
1097                 return qlcnic_83xx_loopback_test(netdev, mode);
1098 
1099         if (!(ahw->capabilities & QLCNIC_FW_CAPABILITY_MULTI_LOOPBACK)) {
1100                 dev_info(&adapter->pdev->dev,
1101                          "Firmware do not support loopback test\n");
1102                 return -EOPNOTSUPP;
1103         }
1104 
1105         dev_warn(&adapter->pdev->dev, "%s loopback test in progress\n",
1106                  mode == QLCNIC_ILB_MODE ? "internal" : "external");
1107         if (ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
1108                 dev_warn(&adapter->pdev->dev,
1109                          "Loopback test not supported in nonprivileged mode\n");
1110                 return 0;
1111         }
1112 
1113         if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
1114                 return -EBUSY;
1115 
1116         ret = qlcnic_diag_alloc_res(netdev, QLCNIC_LOOPBACK_TEST);
1117         if (ret)
1118                 goto clear_it;
1119 
1120         sds_ring = &adapter->recv_ctx->sds_rings[0];
1121         ret = qlcnic_set_lb_mode(adapter, mode);
1122         if (ret)
1123                 goto free_res;
1124 
1125         ahw->diag_cnt = 0;
1126         do {
1127                 msleep(500);
1128                 qlcnic_process_rcv_ring_diag(sds_ring);
1129                 if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP) {
1130                         netdev_info(netdev,
1131                                     "Firmware didn't sent link up event to loopback request\n");
1132                         ret = -ETIMEDOUT;
1133                         goto free_res;
1134                 } else if (adapter->ahw->diag_cnt) {
1135                         ret = adapter->ahw->diag_cnt;
1136                         goto free_res;
1137                 }
1138         } while (!QLCNIC_IS_LB_CONFIGURED(ahw->loopback_state));
1139 
1140         ret = qlcnic_do_lb_test(adapter, mode);
1141 
1142         qlcnic_clear_lb_mode(adapter, mode);
1143 
1144  free_res:
1145         qlcnic_diag_free_res(netdev, drv_sds_rings);
1146 
1147  clear_it:
1148         adapter->drv_sds_rings = drv_sds_rings;
1149         adapter->drv_tx_rings = drv_tx_rings;
1150         clear_bit(__QLCNIC_RESETTING, &adapter->state);
1151         return ret;
1152 }
1153 
1154 static void
1155 qlcnic_diag_test(struct net_device *dev, struct ethtool_test *eth_test,
1156                      u64 *data)
1157 {
1158         memset(data, 0, sizeof(u64) * QLCNIC_TEST_LEN);
1159 
1160         data[0] = qlcnic_reg_test(dev);
1161         if (data[0])
1162                 eth_test->flags |= ETH_TEST_FL_FAILED;
1163 
1164         data[1] = (u64) qlcnic_test_link(dev);
1165         if (data[1])
1166                 eth_test->flags |= ETH_TEST_FL_FAILED;
1167 
1168         if (eth_test->flags & ETH_TEST_FL_OFFLINE) {
1169                 data[2] = qlcnic_irq_test(dev);
1170                 if (data[2])
1171                         eth_test->flags |= ETH_TEST_FL_FAILED;
1172 
1173                 data[3] = qlcnic_loopback_test(dev, QLCNIC_ILB_MODE);
1174                 if (data[3])
1175                         eth_test->flags |= ETH_TEST_FL_FAILED;
1176 
1177                 if (eth_test->flags & ETH_TEST_FL_EXTERNAL_LB) {
1178                         data[4] = qlcnic_loopback_test(dev, QLCNIC_ELB_MODE);
1179                         if (data[4])
1180                                 eth_test->flags |= ETH_TEST_FL_FAILED;
1181                         eth_test->flags |= ETH_TEST_FL_EXTERNAL_LB_DONE;
1182                 }
1183 
1184                 data[5] = qlcnic_eeprom_test(dev);
1185                 if (data[5])
1186                         eth_test->flags |= ETH_TEST_FL_FAILED;
1187         }
1188 }
1189 
1190 static void
1191 qlcnic_get_strings(struct net_device *dev, u32 stringset, u8 *data)
1192 {
1193         struct qlcnic_adapter *adapter = netdev_priv(dev);
1194         int index, i, num_stats;
1195 
1196         switch (stringset) {
1197         case ETH_SS_TEST:
1198                 memcpy(data, *qlcnic_gstrings_test,
1199                        QLCNIC_TEST_LEN * ETH_GSTRING_LEN);
1200                 break;
1201         case ETH_SS_STATS:
1202                 num_stats = ARRAY_SIZE(qlcnic_tx_queue_stats_strings);
1203                 for (i = 0; i < adapter->drv_tx_rings; i++) {
1204                         for (index = 0; index < num_stats; index++) {
1205                                 sprintf(data, "tx_queue_%d %s", i,
1206                                         qlcnic_tx_queue_stats_strings[index]);
1207                                 data += ETH_GSTRING_LEN;
1208                         }
1209                 }
1210 
1211                 for (index = 0; index < QLCNIC_STATS_LEN; index++) {
1212                         memcpy(data + index * ETH_GSTRING_LEN,
1213                                qlcnic_gstrings_stats[index].stat_string,
1214                                ETH_GSTRING_LEN);
1215                 }
1216 
1217                 if (qlcnic_83xx_check(adapter)) {
1218                         num_stats = ARRAY_SIZE(qlcnic_83xx_tx_stats_strings);
1219                         for (i = 0; i < num_stats; i++, index++)
1220                                 memcpy(data + index * ETH_GSTRING_LEN,
1221                                        qlcnic_83xx_tx_stats_strings[i],
1222                                        ETH_GSTRING_LEN);
1223                         num_stats = ARRAY_SIZE(qlcnic_83xx_mac_stats_strings);
1224                         for (i = 0; i < num_stats; i++, index++)
1225                                 memcpy(data + index * ETH_GSTRING_LEN,
1226                                        qlcnic_83xx_mac_stats_strings[i],
1227                                        ETH_GSTRING_LEN);
1228                         num_stats = ARRAY_SIZE(qlcnic_83xx_rx_stats_strings);
1229                         for (i = 0; i < num_stats; i++, index++)
1230                                 memcpy(data + index * ETH_GSTRING_LEN,
1231                                        qlcnic_83xx_rx_stats_strings[i],
1232                                        ETH_GSTRING_LEN);
1233                         return;
1234                 } else {
1235                         num_stats = ARRAY_SIZE(qlcnic_83xx_mac_stats_strings);
1236                         for (i = 0; i < num_stats; i++, index++)
1237                                 memcpy(data + index * ETH_GSTRING_LEN,
1238                                        qlcnic_83xx_mac_stats_strings[i],
1239                                        ETH_GSTRING_LEN);
1240                 }
1241                 if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
1242                         return;
1243                 num_stats = ARRAY_SIZE(qlcnic_device_gstrings_stats);
1244                 for (i = 0; i < num_stats; index++, i++) {
1245                         memcpy(data + index * ETH_GSTRING_LEN,
1246                                qlcnic_device_gstrings_stats[i],
1247                                ETH_GSTRING_LEN);
1248                 }
1249         }
1250 }
1251 
1252 static u64 *qlcnic_fill_stats(u64 *data, void *stats, int type)
1253 {
1254         if (type == QLCNIC_MAC_STATS) {
1255                 struct qlcnic_mac_statistics *mac_stats =
1256                                         (struct qlcnic_mac_statistics *)stats;
1257                 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_frames);
1258                 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_bytes);
1259                 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_mcast_pkts);
1260                 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_bcast_pkts);
1261                 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_pause_cnt);
1262                 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_ctrl_pkt);
1263                 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_64b_pkts);
1264                 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_127b_pkts);
1265                 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_255b_pkts);
1266                 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_511b_pkts);
1267                 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_1023b_pkts);
1268                 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_1518b_pkts);
1269                 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_gt_1518b_pkts);
1270                 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_frames);
1271                 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_bytes);
1272                 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_mcast_pkts);
1273                 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_bcast_pkts);
1274                 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_pause_cnt);
1275                 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_ctrl_pkt);
1276                 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_64b_pkts);
1277                 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_127b_pkts);
1278                 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_255b_pkts);
1279                 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_511b_pkts);
1280                 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_1023b_pkts);
1281                 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_1518b_pkts);
1282                 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_gt_1518b_pkts);
1283                 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_length_error);
1284                 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_length_small);
1285                 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_length_large);
1286                 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_jabber);
1287                 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_dropped);
1288                 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_crc_error);
1289                 *data++ = QLCNIC_FILL_STATS(mac_stats->mac_align_error);
1290         } else if (type == QLCNIC_ESW_STATS) {
1291                 struct __qlcnic_esw_statistics *esw_stats =
1292                                 (struct __qlcnic_esw_statistics *)stats;
1293                 *data++ = QLCNIC_FILL_STATS(esw_stats->unicast_frames);
1294                 *data++ = QLCNIC_FILL_STATS(esw_stats->multicast_frames);
1295                 *data++ = QLCNIC_FILL_STATS(esw_stats->broadcast_frames);
1296                 *data++ = QLCNIC_FILL_STATS(esw_stats->dropped_frames);
1297                 *data++ = QLCNIC_FILL_STATS(esw_stats->errors);
1298                 *data++ = QLCNIC_FILL_STATS(esw_stats->local_frames);
1299                 *data++ = QLCNIC_FILL_STATS(esw_stats->numbytes);
1300         }
1301         return data;
1302 }
1303 
1304 void qlcnic_update_stats(struct qlcnic_adapter *adapter)
1305 {
1306         struct qlcnic_tx_queue_stats tx_stats;
1307         struct qlcnic_host_tx_ring *tx_ring;
1308         int ring;
1309 
1310         memset(&tx_stats, 0, sizeof(tx_stats));
1311         for (ring = 0; ring < adapter->drv_tx_rings; ring++) {
1312                 tx_ring = &adapter->tx_ring[ring];
1313                 tx_stats.xmit_on += tx_ring->tx_stats.xmit_on;
1314                 tx_stats.xmit_off += tx_ring->tx_stats.xmit_off;
1315                 tx_stats.xmit_called += tx_ring->tx_stats.xmit_called;
1316                 tx_stats.xmit_finished += tx_ring->tx_stats.xmit_finished;
1317                 tx_stats.tx_bytes += tx_ring->tx_stats.tx_bytes;
1318         }
1319 
1320         adapter->stats.xmit_on = tx_stats.xmit_on;
1321         adapter->stats.xmit_off = tx_stats.xmit_off;
1322         adapter->stats.xmitcalled = tx_stats.xmit_called;
1323         adapter->stats.xmitfinished = tx_stats.xmit_finished;
1324         adapter->stats.txbytes = tx_stats.tx_bytes;
1325 }
1326 
1327 static u64 *qlcnic_fill_tx_queue_stats(u64 *data, void *stats)
1328 {
1329         struct qlcnic_host_tx_ring *tx_ring;
1330 
1331         tx_ring = (struct qlcnic_host_tx_ring *)stats;
1332 
1333         *data++ = QLCNIC_FILL_STATS(tx_ring->tx_stats.xmit_on);
1334         *data++ = QLCNIC_FILL_STATS(tx_ring->tx_stats.xmit_off);
1335         *data++ = QLCNIC_FILL_STATS(tx_ring->tx_stats.xmit_called);
1336         *data++ = QLCNIC_FILL_STATS(tx_ring->tx_stats.xmit_finished);
1337         *data++ = QLCNIC_FILL_STATS(tx_ring->tx_stats.tx_bytes);
1338 
1339         return data;
1340 }
1341 
1342 static void qlcnic_get_ethtool_stats(struct net_device *dev,
1343                                      struct ethtool_stats *stats, u64 *data)
1344 {
1345         struct qlcnic_adapter *adapter = netdev_priv(dev);
1346         struct qlcnic_host_tx_ring *tx_ring;
1347         struct qlcnic_esw_statistics port_stats;
1348         struct qlcnic_mac_statistics mac_stats;
1349         int index, ret, length, size, ring;
1350         char *p;
1351 
1352         memset(data, 0, stats->n_stats * sizeof(u64));
1353 
1354         for (ring = 0, index = 0; ring < adapter->drv_tx_rings; ring++) {
1355                 if (adapter->is_up == QLCNIC_ADAPTER_UP_MAGIC) {
1356                         tx_ring = &adapter->tx_ring[ring];
1357                         data = qlcnic_fill_tx_queue_stats(data, tx_ring);
1358                         qlcnic_update_stats(adapter);
1359                 } else {
1360                         data += QLCNIC_TX_STATS_LEN;
1361                 }
1362         }
1363 
1364         length = QLCNIC_STATS_LEN;
1365         for (index = 0; index < length; index++) {
1366                 p = (char *)adapter + qlcnic_gstrings_stats[index].stat_offset;
1367                 size = qlcnic_gstrings_stats[index].sizeof_stat;
1368                 *data++ = (size == sizeof(u64)) ? (*(u64 *)p) : ((*(u32 *)p));
1369         }
1370 
1371         if (qlcnic_83xx_check(adapter)) {
1372                 if (adapter->ahw->linkup)
1373                         qlcnic_83xx_get_stats(adapter, data);
1374                 return;
1375         } else {
1376                 /* Retrieve MAC statistics from firmware */
1377                 memset(&mac_stats, 0, sizeof(struct qlcnic_mac_statistics));
1378                 qlcnic_get_mac_stats(adapter, &mac_stats);
1379                 data = qlcnic_fill_stats(data, &mac_stats, QLCNIC_MAC_STATS);
1380         }
1381 
1382         if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
1383                 return;
1384 
1385         memset(&port_stats, 0, sizeof(struct qlcnic_esw_statistics));
1386         ret = qlcnic_get_port_stats(adapter, adapter->ahw->pci_func,
1387                         QLCNIC_QUERY_RX_COUNTER, &port_stats.rx);
1388         if (ret)
1389                 return;
1390 
1391         data = qlcnic_fill_stats(data, &port_stats.rx, QLCNIC_ESW_STATS);
1392         ret = qlcnic_get_port_stats(adapter, adapter->ahw->pci_func,
1393                         QLCNIC_QUERY_TX_COUNTER, &port_stats.tx);
1394         if (ret)
1395                 return;
1396 
1397         qlcnic_fill_stats(data, &port_stats.tx, QLCNIC_ESW_STATS);
1398 }
1399 
1400 static int qlcnic_set_led(struct net_device *dev,
1401                           enum ethtool_phys_id_state state)
1402 {
1403         struct qlcnic_adapter *adapter = netdev_priv(dev);
1404         int drv_sds_rings = adapter->drv_sds_rings;
1405         int err = -EIO, active = 1;
1406 
1407         if (qlcnic_83xx_check(adapter))
1408                 return qlcnic_83xx_set_led(dev, state);
1409 
1410         if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
1411                 netdev_warn(dev, "LED test not supported for non "
1412                                 "privilege function\n");
1413                 return -EOPNOTSUPP;
1414         }
1415 
1416         switch (state) {
1417         case ETHTOOL_ID_ACTIVE:
1418                 if (test_and_set_bit(__QLCNIC_LED_ENABLE, &adapter->state))
1419                         return -EBUSY;
1420 
1421                 if (test_bit(__QLCNIC_RESETTING, &adapter->state))
1422                         break;
1423 
1424                 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
1425                         if (qlcnic_diag_alloc_res(dev, QLCNIC_LED_TEST))
1426                                 break;
1427                         set_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state);
1428                 }
1429 
1430                 if (adapter->nic_ops->config_led(adapter, 1, 0xf) == 0) {
1431                         err = 0;
1432                         break;
1433                 }
1434 
1435                 dev_err(&adapter->pdev->dev,
1436                         "Failed to set LED blink state.\n");
1437                 break;
1438 
1439         case ETHTOOL_ID_INACTIVE:
1440                 active = 0;
1441 
1442                 if (test_bit(__QLCNIC_RESETTING, &adapter->state))
1443                         break;
1444 
1445                 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
1446                         if (qlcnic_diag_alloc_res(dev, QLCNIC_LED_TEST))
1447                                 break;
1448                         set_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state);
1449                 }
1450 
1451                 if (adapter->nic_ops->config_led(adapter, 0, 0xf))
1452                         dev_err(&adapter->pdev->dev,
1453                                 "Failed to reset LED blink state.\n");
1454 
1455                 break;
1456 
1457         default:
1458                 return -EINVAL;
1459         }
1460 
1461         if (test_and_clear_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state))
1462                 qlcnic_diag_free_res(dev, drv_sds_rings);
1463 
1464         if (!active || err)
1465                 clear_bit(__QLCNIC_LED_ENABLE, &adapter->state);
1466 
1467         return err;
1468 }
1469 
1470 static void
1471 qlcnic_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
1472 {
1473         struct qlcnic_adapter *adapter = netdev_priv(dev);
1474         u32 wol_cfg;
1475         int err = 0;
1476 
1477         if (qlcnic_83xx_check(adapter))
1478                 return;
1479         wol->supported = 0;
1480         wol->wolopts = 0;
1481 
1482         wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG_NV, &err);
1483         if (err == -EIO)
1484                 return;
1485         if (wol_cfg & (1UL << adapter->portnum))
1486                 wol->supported |= WAKE_MAGIC;
1487 
1488         wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG, &err);
1489         if (wol_cfg & (1UL << adapter->portnum))
1490                 wol->wolopts |= WAKE_MAGIC;
1491 }
1492 
1493 static int
1494 qlcnic_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
1495 {
1496         struct qlcnic_adapter *adapter = netdev_priv(dev);
1497         u32 wol_cfg;
1498         int err = 0;
1499 
1500         if (qlcnic_83xx_check(adapter))
1501                 return -EOPNOTSUPP;
1502         if (wol->wolopts & ~WAKE_MAGIC)
1503                 return -EINVAL;
1504 
1505         wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG_NV, &err);
1506         if (err == -EIO)
1507                 return err;
1508         if (!(wol_cfg & (1 << adapter->portnum)))
1509                 return -EOPNOTSUPP;
1510 
1511         wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG, &err);
1512         if (err == -EIO)
1513                 return err;
1514         if (wol->wolopts & WAKE_MAGIC)
1515                 wol_cfg |= 1UL << adapter->portnum;
1516         else
1517                 wol_cfg &= ~(1UL << adapter->portnum);
1518 
1519         QLCWR32(adapter, QLCNIC_WOL_CONFIG, wol_cfg);
1520 
1521         return 0;
1522 }
1523 
1524 /*
1525  * Set the coalescing parameters. Currently only normal is supported.
1526  * If rx_coalesce_usecs == 0 or rx_max_coalesced_frames == 0 then set the
1527  * firmware coalescing to default.
1528  */
1529 static int qlcnic_set_intr_coalesce(struct net_device *netdev,
1530                         struct ethtool_coalesce *ethcoal)
1531 {
1532         struct qlcnic_adapter *adapter = netdev_priv(netdev);
1533         int err;
1534 
1535         if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
1536                 return -EINVAL;
1537 
1538         /*
1539         * Return Error if unsupported values or
1540         * unsupported parameters are set.
1541         */
1542         if (ethcoal->rx_coalesce_usecs > 0xffff ||
1543             ethcoal->rx_max_coalesced_frames > 0xffff ||
1544             ethcoal->tx_coalesce_usecs > 0xffff ||
1545             ethcoal->tx_max_coalesced_frames > 0xffff ||
1546             ethcoal->rx_coalesce_usecs_irq ||
1547             ethcoal->rx_max_coalesced_frames_irq ||
1548             ethcoal->tx_coalesce_usecs_irq ||
1549             ethcoal->tx_max_coalesced_frames_irq ||
1550             ethcoal->stats_block_coalesce_usecs ||
1551             ethcoal->use_adaptive_rx_coalesce ||
1552             ethcoal->use_adaptive_tx_coalesce ||
1553             ethcoal->pkt_rate_low ||
1554             ethcoal->rx_coalesce_usecs_low ||
1555             ethcoal->rx_max_coalesced_frames_low ||
1556             ethcoal->tx_coalesce_usecs_low ||
1557             ethcoal->tx_max_coalesced_frames_low ||
1558             ethcoal->pkt_rate_high ||
1559             ethcoal->rx_coalesce_usecs_high ||
1560             ethcoal->rx_max_coalesced_frames_high ||
1561             ethcoal->tx_coalesce_usecs_high ||
1562             ethcoal->tx_max_coalesced_frames_high)
1563                 return -EINVAL;
1564 
1565         err = qlcnic_config_intr_coalesce(adapter, ethcoal);
1566 
1567         return err;
1568 }
1569 
1570 static int qlcnic_get_intr_coalesce(struct net_device *netdev,
1571                         struct ethtool_coalesce *ethcoal)
1572 {
1573         struct qlcnic_adapter *adapter = netdev_priv(netdev);
1574 
1575         if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
1576                 return -EINVAL;
1577 
1578         ethcoal->rx_coalesce_usecs = adapter->ahw->coal.rx_time_us;
1579         ethcoal->rx_max_coalesced_frames = adapter->ahw->coal.rx_packets;
1580         ethcoal->tx_coalesce_usecs = adapter->ahw->coal.tx_time_us;
1581         ethcoal->tx_max_coalesced_frames = adapter->ahw->coal.tx_packets;
1582 
1583         return 0;
1584 }
1585 
1586 static u32 qlcnic_get_msglevel(struct net_device *netdev)
1587 {
1588         struct qlcnic_adapter *adapter = netdev_priv(netdev);
1589 
1590         return adapter->ahw->msg_enable;
1591 }
1592 
1593 static void qlcnic_set_msglevel(struct net_device *netdev, u32 msglvl)
1594 {
1595         struct qlcnic_adapter *adapter = netdev_priv(netdev);
1596 
1597         adapter->ahw->msg_enable = msglvl;
1598 }
1599 
1600 int qlcnic_enable_fw_dump_state(struct qlcnic_adapter *adapter)
1601 {
1602         struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1603         u32 val;
1604 
1605         if (qlcnic_84xx_check(adapter)) {
1606                 if (qlcnic_83xx_lock_driver(adapter))
1607                         return -EBUSY;
1608 
1609                 val = QLCRDX(adapter->ahw, QLC_83XX_IDC_CTRL);
1610                 val &= ~QLC_83XX_IDC_DISABLE_FW_DUMP;
1611                 QLCWRX(adapter->ahw, QLC_83XX_IDC_CTRL, val);
1612 
1613                 qlcnic_83xx_unlock_driver(adapter);
1614         } else {
1615                 fw_dump->enable = true;
1616         }
1617 
1618         dev_info(&adapter->pdev->dev, "FW dump enabled\n");
1619 
1620         return 0;
1621 }
1622 
1623 static int qlcnic_disable_fw_dump_state(struct qlcnic_adapter *adapter)
1624 {
1625         struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1626         u32 val;
1627 
1628         if (qlcnic_84xx_check(adapter)) {
1629                 if (qlcnic_83xx_lock_driver(adapter))
1630                         return -EBUSY;
1631 
1632                 val = QLCRDX(adapter->ahw, QLC_83XX_IDC_CTRL);
1633                 val |= QLC_83XX_IDC_DISABLE_FW_DUMP;
1634                 QLCWRX(adapter->ahw, QLC_83XX_IDC_CTRL, val);
1635 
1636                 qlcnic_83xx_unlock_driver(adapter);
1637         } else {
1638                 fw_dump->enable = false;
1639         }
1640 
1641         dev_info(&adapter->pdev->dev, "FW dump disabled\n");
1642 
1643         return 0;
1644 }
1645 
1646 bool qlcnic_check_fw_dump_state(struct qlcnic_adapter *adapter)
1647 {
1648         struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1649         bool state;
1650         u32 val;
1651 
1652         if (qlcnic_84xx_check(adapter)) {
1653                 val = QLCRDX(adapter->ahw, QLC_83XX_IDC_CTRL);
1654                 state = (val & QLC_83XX_IDC_DISABLE_FW_DUMP) ? false : true;
1655         } else {
1656                 state = fw_dump->enable;
1657         }
1658 
1659         return state;
1660 }
1661 
1662 static int
1663 qlcnic_get_dump_flag(struct net_device *netdev, struct ethtool_dump *dump)
1664 {
1665         struct qlcnic_adapter *adapter = netdev_priv(netdev);
1666         struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1667 
1668         if (!fw_dump->tmpl_hdr) {
1669                 netdev_err(adapter->netdev, "FW Dump not supported\n");
1670                 return -ENOTSUPP;
1671         }
1672 
1673         if (fw_dump->clr)
1674                 dump->len = fw_dump->tmpl_hdr_size + fw_dump->size;
1675         else
1676                 dump->len = 0;
1677 
1678         if (!qlcnic_check_fw_dump_state(adapter))
1679                 dump->flag = ETH_FW_DUMP_DISABLE;
1680         else
1681                 dump->flag = fw_dump->cap_mask;
1682 
1683         dump->version = adapter->fw_version;
1684         return 0;
1685 }
1686 
1687 static int
1688 qlcnic_get_dump_data(struct net_device *netdev, struct ethtool_dump *dump,
1689                         void *buffer)
1690 {
1691         int i, copy_sz;
1692         u32 *hdr_ptr;
1693         __le32 *data;
1694         struct qlcnic_adapter *adapter = netdev_priv(netdev);
1695         struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1696 
1697         if (!fw_dump->tmpl_hdr) {
1698                 netdev_err(netdev, "FW Dump not supported\n");
1699                 return -ENOTSUPP;
1700         }
1701 
1702         if (!fw_dump->clr) {
1703                 netdev_info(netdev, "Dump not available\n");
1704                 return -EINVAL;
1705         }
1706 
1707         /* Copy template header first */
1708         copy_sz = fw_dump->tmpl_hdr_size;
1709         hdr_ptr = (u32 *)fw_dump->tmpl_hdr;
1710         data = buffer;
1711         for (i = 0; i < copy_sz/sizeof(u32); i++)
1712                 *data++ = cpu_to_le32(*hdr_ptr++);
1713 
1714         /* Copy captured dump data */
1715         memcpy(buffer + copy_sz, fw_dump->data, fw_dump->size);
1716         dump->len = copy_sz + fw_dump->size;
1717         dump->flag = fw_dump->cap_mask;
1718 
1719         /* Free dump area once data has been captured */
1720         vfree(fw_dump->data);
1721         fw_dump->data = NULL;
1722         fw_dump->clr = 0;
1723         netdev_info(netdev, "extracted the FW dump Successfully\n");
1724         return 0;
1725 }
1726 
1727 static int qlcnic_set_dump_mask(struct qlcnic_adapter *adapter, u32 mask)
1728 {
1729         struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1730         struct net_device *netdev = adapter->netdev;
1731 
1732         if (!qlcnic_check_fw_dump_state(adapter)) {
1733                 netdev_info(netdev,
1734                             "Can not change driver mask to 0x%x. FW dump not enabled\n",
1735                             mask);
1736                 return -EOPNOTSUPP;
1737         }
1738 
1739         fw_dump->cap_mask = mask;
1740 
1741         /* Store new capture mask in template header as well*/
1742         qlcnic_store_cap_mask(adapter, fw_dump->tmpl_hdr, mask);
1743 
1744         netdev_info(netdev, "Driver mask changed to: 0x%x\n", mask);
1745         return 0;
1746 }
1747 
1748 static int
1749 qlcnic_set_dump(struct net_device *netdev, struct ethtool_dump *val)
1750 {
1751         struct qlcnic_adapter *adapter = netdev_priv(netdev);
1752         struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1753         bool valid_mask = false;
1754         int i, ret = 0;
1755 
1756         switch (val->flag) {
1757         case QLCNIC_FORCE_FW_DUMP_KEY:
1758                 if (!fw_dump->tmpl_hdr) {
1759                         netdev_err(netdev, "FW dump not supported\n");
1760                         ret = -EOPNOTSUPP;
1761                         break;
1762                 }
1763 
1764                 if (!qlcnic_check_fw_dump_state(adapter)) {
1765                         netdev_info(netdev, "FW dump not enabled\n");
1766                         ret = -EOPNOTSUPP;
1767                         break;
1768                 }
1769 
1770                 if (fw_dump->clr) {
1771                         netdev_info(netdev,
1772                                     "Previous dump not cleared, not forcing dump\n");
1773                         break;
1774                 }
1775 
1776                 netdev_info(netdev, "Forcing a FW dump\n");
1777                 qlcnic_dev_request_reset(adapter, val->flag);
1778                 break;
1779         case QLCNIC_DISABLE_FW_DUMP:
1780                 if (!fw_dump->tmpl_hdr) {
1781                         netdev_err(netdev, "FW dump not supported\n");
1782                         ret = -EOPNOTSUPP;
1783                         break;
1784                 }
1785 
1786                 ret = qlcnic_disable_fw_dump_state(adapter);
1787                 break;
1788 
1789         case QLCNIC_ENABLE_FW_DUMP:
1790                 if (!fw_dump->tmpl_hdr) {
1791                         netdev_err(netdev, "FW dump not supported\n");
1792                         ret = -EOPNOTSUPP;
1793                         break;
1794                 }
1795 
1796                 ret = qlcnic_enable_fw_dump_state(adapter);
1797                 break;
1798 
1799         case QLCNIC_FORCE_FW_RESET:
1800                 netdev_info(netdev, "Forcing a FW reset\n");
1801                 qlcnic_dev_request_reset(adapter, val->flag);
1802                 adapter->flags &= ~QLCNIC_FW_RESET_OWNER;
1803                 break;
1804 
1805         case QLCNIC_SET_QUIESCENT:
1806         case QLCNIC_RESET_QUIESCENT:
1807                 if (test_bit(__QLCNIC_MAINTENANCE_MODE, &adapter->state))
1808                         netdev_info(netdev, "Device is in non-operational state\n");
1809                 break;
1810 
1811         default:
1812                 if (!fw_dump->tmpl_hdr) {
1813                         netdev_err(netdev, "FW dump not supported\n");
1814                         ret = -EOPNOTSUPP;
1815                         break;
1816                 }
1817 
1818                 for (i = 0; i < ARRAY_SIZE(qlcnic_fw_dump_level); i++) {
1819                         if (val->flag == qlcnic_fw_dump_level[i]) {
1820                                 valid_mask = true;
1821                                 break;
1822                         }
1823                 }
1824 
1825                 if (valid_mask) {
1826                         ret = qlcnic_set_dump_mask(adapter, val->flag);
1827                 } else {
1828                         netdev_info(netdev, "Invalid dump level: 0x%x\n",
1829                                     val->flag);
1830                         ret = -EINVAL;
1831                 }
1832         }
1833         return ret;
1834 }
1835 
1836 const struct ethtool_ops qlcnic_ethtool_ops = {
1837         .get_drvinfo = qlcnic_get_drvinfo,
1838         .get_regs_len = qlcnic_get_regs_len,
1839         .get_regs = qlcnic_get_regs,
1840         .get_link = ethtool_op_get_link,
1841         .get_eeprom_len = qlcnic_get_eeprom_len,
1842         .get_eeprom = qlcnic_get_eeprom,
1843         .get_ringparam = qlcnic_get_ringparam,
1844         .set_ringparam = qlcnic_set_ringparam,
1845         .get_channels = qlcnic_get_channels,
1846         .set_channels = qlcnic_set_channels,
1847         .get_pauseparam = qlcnic_get_pauseparam,
1848         .set_pauseparam = qlcnic_set_pauseparam,
1849         .get_wol = qlcnic_get_wol,
1850         .set_wol = qlcnic_set_wol,
1851         .self_test = qlcnic_diag_test,
1852         .get_strings = qlcnic_get_strings,
1853         .get_ethtool_stats = qlcnic_get_ethtool_stats,
1854         .get_sset_count = qlcnic_get_sset_count,
1855         .get_coalesce = qlcnic_get_intr_coalesce,
1856         .set_coalesce = qlcnic_set_intr_coalesce,
1857         .set_phys_id = qlcnic_set_led,
1858         .set_msglevel = qlcnic_set_msglevel,
1859         .get_msglevel = qlcnic_get_msglevel,
1860         .get_dump_flag = qlcnic_get_dump_flag,
1861         .get_dump_data = qlcnic_get_dump_data,
1862         .set_dump = qlcnic_set_dump,
1863         .get_link_ksettings = qlcnic_get_link_ksettings,
1864         .set_link_ksettings = qlcnic_set_link_ksettings,
1865 };
1866 
1867 const struct ethtool_ops qlcnic_sriov_vf_ethtool_ops = {
1868         .get_drvinfo            = qlcnic_get_drvinfo,
1869         .get_regs_len           = qlcnic_get_regs_len,
1870         .get_regs               = qlcnic_get_regs,
1871         .get_link               = ethtool_op_get_link,
1872         .get_eeprom_len         = qlcnic_get_eeprom_len,
1873         .get_eeprom             = qlcnic_get_eeprom,
1874         .get_ringparam          = qlcnic_get_ringparam,
1875         .set_ringparam          = qlcnic_set_ringparam,
1876         .get_channels           = qlcnic_get_channels,
1877         .get_pauseparam         = qlcnic_get_pauseparam,
1878         .get_wol                = qlcnic_get_wol,
1879         .get_strings            = qlcnic_get_strings,
1880         .get_ethtool_stats      = qlcnic_get_ethtool_stats,
1881         .get_sset_count         = qlcnic_get_sset_count,
1882         .get_coalesce           = qlcnic_get_intr_coalesce,
1883         .set_coalesce           = qlcnic_set_intr_coalesce,
1884         .set_msglevel           = qlcnic_set_msglevel,
1885         .get_msglevel           = qlcnic_get_msglevel,
1886         .get_link_ksettings     = qlcnic_get_link_ksettings,
1887 };
1888 
1889 const struct ethtool_ops qlcnic_ethtool_failed_ops = {
1890         .get_drvinfo            = qlcnic_get_drvinfo,
1891         .set_msglevel           = qlcnic_set_msglevel,
1892         .get_msglevel           = qlcnic_get_msglevel,
1893         .set_dump               = qlcnic_set_dump,
1894         .get_link_ksettings     = qlcnic_get_link_ksettings,
1895 };

/* [<][>][^][v][top][bottom][index][help] */