1 /* 2 * QLogic qlcnic NIC Driver 3 * Copyright (c) 2009-2010 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 26 static const struct qlcnic_stats qlcnic_gstrings_stats[] = { 27 {"xmit_called", 28 QLC_SIZEOF(stats.xmitcalled), QLC_OFF(stats.xmitcalled)}, 29 {"xmit_finished", 30 QLC_SIZEOF(stats.xmitfinished), QLC_OFF(stats.xmitfinished)}, 31 {"rx_dropped", 32 QLC_SIZEOF(stats.rxdropped), QLC_OFF(stats.rxdropped)}, 33 {"tx_dropped", 34 QLC_SIZEOF(stats.txdropped), QLC_OFF(stats.txdropped)}, 35 {"csummed", 36 QLC_SIZEOF(stats.csummed), QLC_OFF(stats.csummed)}, 37 {"rx_pkts", 38 QLC_SIZEOF(stats.rx_pkts), QLC_OFF(stats.rx_pkts)}, 39 {"lro_pkts", 40 QLC_SIZEOF(stats.lro_pkts), QLC_OFF(stats.lro_pkts)}, 41 {"rx_bytes", 42 QLC_SIZEOF(stats.rxbytes), QLC_OFF(stats.rxbytes)}, 43 {"tx_bytes", 44 QLC_SIZEOF(stats.txbytes), QLC_OFF(stats.txbytes)}, 45 {"lrobytes", 46 QLC_SIZEOF(stats.lrobytes), QLC_OFF(stats.lrobytes)}, 47 {"lso_frames", 48 QLC_SIZEOF(stats.lso_frames), QLC_OFF(stats.lso_frames)}, 49 {"xmit_on", 50 QLC_SIZEOF(stats.xmit_on), QLC_OFF(stats.xmit_on)}, 51 {"xmit_off", 52 QLC_SIZEOF(stats.xmit_off), QLC_OFF(stats.xmit_off)}, 53 {"skb_alloc_failure", QLC_SIZEOF(stats.skb_alloc_failure), 54 QLC_OFF(stats.skb_alloc_failure)}, 55 {"null rxbuf", 56 QLC_SIZEOF(stats.null_rxbuf), QLC_OFF(stats.null_rxbuf)}, 57 {"rx dma map error", QLC_SIZEOF(stats.rx_dma_map_error), 58 QLC_OFF(stats.rx_dma_map_error)}, 59 {"tx dma map error", QLC_SIZEOF(stats.tx_dma_map_error), 60 QLC_OFF(stats.tx_dma_map_error)}, 61 62 }; 63 64 static const char qlcnic_device_gstrings_stats[][ETH_GSTRING_LEN] = { 65 "rx unicast frames", 66 "rx multicast frames", 67 "rx broadcast frames", 68 "rx dropped frames", 69 "rx errors", 70 "rx local frames", 71 "rx numbytes", 72 "tx unicast frames", 73 "tx multicast frames", 74 "tx broadcast frames", 75 "tx dropped frames", 76 "tx errors", 77 "tx local frames", 78 "tx numbytes", 79 }; 80 81 #define QLCNIC_STATS_LEN ARRAY_SIZE(qlcnic_gstrings_stats) 82 #define QLCNIC_DEVICE_STATS_LEN ARRAY_SIZE(qlcnic_device_gstrings_stats) 83 84 static const char qlcnic_gstrings_test[][ETH_GSTRING_LEN] = { 85 "Register_Test_on_offline", 86 "Link_Test_on_offline", 87 "Interrupt_Test_offline", 88 "Internal_Loopback_offline", 89 "External_Loopback_offline" 90 }; 91 92 #define QLCNIC_TEST_LEN ARRAY_SIZE(qlcnic_gstrings_test) 93 94 #define QLCNIC_RING_REGS_COUNT 20 95 #define QLCNIC_RING_REGS_LEN (QLCNIC_RING_REGS_COUNT * sizeof(u32)) 96 #define QLCNIC_MAX_EEPROM_LEN 1024 97 98 static const u32 diag_registers[] = { 99 CRB_CMDPEG_STATE, 100 CRB_RCVPEG_STATE, 101 CRB_XG_STATE_P3P, 102 CRB_FW_CAPABILITIES_1, 103 ISR_INT_STATE_REG, 104 QLCNIC_CRB_DRV_ACTIVE, 105 QLCNIC_CRB_DEV_STATE, 106 QLCNIC_CRB_DRV_STATE, 107 QLCNIC_CRB_DRV_SCRATCH, 108 QLCNIC_CRB_DEV_PARTITION_INFO, 109 QLCNIC_CRB_DRV_IDC_VER, 110 QLCNIC_PEG_ALIVE_COUNTER, 111 QLCNIC_PEG_HALT_STATUS1, 112 QLCNIC_PEG_HALT_STATUS2, 113 QLCNIC_CRB_PEG_NET_0+0x3c, 114 QLCNIC_CRB_PEG_NET_1+0x3c, 115 QLCNIC_CRB_PEG_NET_2+0x3c, 116 QLCNIC_CRB_PEG_NET_4+0x3c, 117 -1 118 }; 119 120 #define QLCNIC_MGMT_API_VERSION 2 121 #define QLCNIC_DEV_INFO_SIZE 1 122 #define QLCNIC_ETHTOOL_REGS_VER 2 123 static int qlcnic_get_regs_len(struct net_device *dev) 124 { 125 return sizeof(diag_registers) + QLCNIC_RING_REGS_LEN + 126 QLCNIC_DEV_INFO_SIZE + 1; 127 } 128 129 static int qlcnic_get_eeprom_len(struct net_device *dev) 130 { 131 return QLCNIC_FLASH_TOTAL_SIZE; 132 } 133 134 static void 135 qlcnic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo) 136 { 137 struct qlcnic_adapter *adapter = netdev_priv(dev); 138 u32 fw_major, fw_minor, fw_build; 139 140 fw_major = QLCRD32(adapter, QLCNIC_FW_VERSION_MAJOR); 141 fw_minor = QLCRD32(adapter, QLCNIC_FW_VERSION_MINOR); 142 fw_build = QLCRD32(adapter, QLCNIC_FW_VERSION_SUB); 143 snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), 144 "%d.%d.%d", fw_major, fw_minor, fw_build); 145 146 strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), 147 sizeof(drvinfo->bus_info)); 148 strlcpy(drvinfo->driver, qlcnic_driver_name, sizeof(drvinfo->driver)); 149 strlcpy(drvinfo->version, QLCNIC_LINUX_VERSIONID, 150 sizeof(drvinfo->version)); 151 } 152 153 static int 154 qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) 155 { 156 struct qlcnic_adapter *adapter = netdev_priv(dev); 157 int check_sfp_module = 0; 158 u16 pcifn = adapter->ahw->pci_func; 159 160 /* read which mode */ 161 if (adapter->ahw->port_type == QLCNIC_GBE) { 162 ecmd->supported = (SUPPORTED_10baseT_Half | 163 SUPPORTED_10baseT_Full | 164 SUPPORTED_100baseT_Half | 165 SUPPORTED_100baseT_Full | 166 SUPPORTED_1000baseT_Half | 167 SUPPORTED_1000baseT_Full); 168 169 ecmd->advertising = (ADVERTISED_100baseT_Half | 170 ADVERTISED_100baseT_Full | 171 ADVERTISED_1000baseT_Half | 172 ADVERTISED_1000baseT_Full); 173 174 ethtool_cmd_speed_set(ecmd, adapter->link_speed); 175 ecmd->duplex = adapter->link_duplex; 176 ecmd->autoneg = adapter->link_autoneg; 177 178 } else if (adapter->ahw->port_type == QLCNIC_XGBE) { 179 u32 val; 180 181 val = QLCRD32(adapter, QLCNIC_PORT_MODE_ADDR); 182 if (val == QLCNIC_PORT_MODE_802_3_AP) { 183 ecmd->supported = SUPPORTED_1000baseT_Full; 184 ecmd->advertising = ADVERTISED_1000baseT_Full; 185 } else { 186 ecmd->supported = SUPPORTED_10000baseT_Full; 187 ecmd->advertising = ADVERTISED_10000baseT_Full; 188 } 189 190 if (netif_running(dev) && adapter->has_link_events) { 191 ethtool_cmd_speed_set(ecmd, adapter->link_speed); 192 ecmd->autoneg = adapter->link_autoneg; 193 ecmd->duplex = adapter->link_duplex; 194 goto skip; 195 } 196 197 val = QLCRD32(adapter, P3P_LINK_SPEED_REG(pcifn)); 198 ethtool_cmd_speed_set(ecmd, P3P_LINK_SPEED_MHZ * 199 P3P_LINK_SPEED_VAL(pcifn, val)); 200 ecmd->duplex = DUPLEX_FULL; 201 ecmd->autoneg = AUTONEG_DISABLE; 202 } else 203 return -EIO; 204 205 skip: 206 ecmd->phy_address = adapter->physical_port; 207 ecmd->transceiver = XCVR_EXTERNAL; 208 209 switch (adapter->ahw->board_type) { 210 case QLCNIC_BRDTYPE_P3P_REF_QG: 211 case QLCNIC_BRDTYPE_P3P_4_GB: 212 case QLCNIC_BRDTYPE_P3P_4_GB_MM: 213 214 ecmd->supported |= SUPPORTED_Autoneg; 215 ecmd->advertising |= ADVERTISED_Autoneg; 216 case QLCNIC_BRDTYPE_P3P_10G_CX4: 217 case QLCNIC_BRDTYPE_P3P_10G_CX4_LP: 218 case QLCNIC_BRDTYPE_P3P_10000_BASE_T: 219 ecmd->supported |= SUPPORTED_TP; 220 ecmd->advertising |= ADVERTISED_TP; 221 ecmd->port = PORT_TP; 222 ecmd->autoneg = adapter->link_autoneg; 223 break; 224 case QLCNIC_BRDTYPE_P3P_IMEZ: 225 case QLCNIC_BRDTYPE_P3P_XG_LOM: 226 case QLCNIC_BRDTYPE_P3P_HMEZ: 227 ecmd->supported |= SUPPORTED_MII; 228 ecmd->advertising |= ADVERTISED_MII; 229 ecmd->port = PORT_MII; 230 ecmd->autoneg = AUTONEG_DISABLE; 231 break; 232 case QLCNIC_BRDTYPE_P3P_10G_SFP_PLUS: 233 case QLCNIC_BRDTYPE_P3P_10G_SFP_CT: 234 case QLCNIC_BRDTYPE_P3P_10G_SFP_QT: 235 ecmd->advertising |= ADVERTISED_TP; 236 ecmd->supported |= SUPPORTED_TP; 237 check_sfp_module = netif_running(dev) && 238 adapter->has_link_events; 239 case QLCNIC_BRDTYPE_P3P_10G_XFP: 240 ecmd->supported |= SUPPORTED_FIBRE; 241 ecmd->advertising |= ADVERTISED_FIBRE; 242 ecmd->port = PORT_FIBRE; 243 ecmd->autoneg = AUTONEG_DISABLE; 244 break; 245 case QLCNIC_BRDTYPE_P3P_10G_TP: 246 if (adapter->ahw->port_type == QLCNIC_XGBE) { 247 ecmd->autoneg = AUTONEG_DISABLE; 248 ecmd->supported |= (SUPPORTED_FIBRE | SUPPORTED_TP); 249 ecmd->advertising |= 250 (ADVERTISED_FIBRE | ADVERTISED_TP); 251 ecmd->port = PORT_FIBRE; 252 check_sfp_module = netif_running(dev) && 253 adapter->has_link_events; 254 } else { 255 ecmd->autoneg = AUTONEG_ENABLE; 256 ecmd->supported |= (SUPPORTED_TP | SUPPORTED_Autoneg); 257 ecmd->advertising |= 258 (ADVERTISED_TP | ADVERTISED_Autoneg); 259 ecmd->port = PORT_TP; 260 } 261 break; 262 default: 263 dev_err(&adapter->pdev->dev, "Unsupported board model %d\n", 264 adapter->ahw->board_type); 265 return -EIO; 266 } 267 268 if (check_sfp_module) { 269 switch (adapter->module_type) { 270 case LINKEVENT_MODULE_OPTICAL_UNKNOWN: 271 case LINKEVENT_MODULE_OPTICAL_SRLR: 272 case LINKEVENT_MODULE_OPTICAL_LRM: 273 case LINKEVENT_MODULE_OPTICAL_SFP_1G: 274 ecmd->port = PORT_FIBRE; 275 break; 276 case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE: 277 case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN: 278 case LINKEVENT_MODULE_TWINAX: 279 ecmd->port = PORT_TP; 280 break; 281 default: 282 ecmd->port = PORT_OTHER; 283 } 284 } 285 286 return 0; 287 } 288 289 static int 290 qlcnic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) 291 { 292 u32 config = 0; 293 u32 ret = 0; 294 struct qlcnic_adapter *adapter = netdev_priv(dev); 295 296 if (adapter->ahw->port_type != QLCNIC_GBE) 297 return -EOPNOTSUPP; 298 299 /* read which mode */ 300 if (ecmd->duplex) 301 config |= 0x1; 302 303 if (ecmd->autoneg) 304 config |= 0x2; 305 306 switch (ethtool_cmd_speed(ecmd)) { 307 case SPEED_10: 308 config |= (0 << 8); 309 break; 310 case SPEED_100: 311 config |= (1 << 8); 312 break; 313 case SPEED_1000: 314 config |= (10 << 8); 315 break; 316 default: 317 return -EIO; 318 } 319 320 ret = qlcnic_fw_cmd_set_port(adapter, config); 321 322 if (ret == QLCNIC_RCODE_NOT_SUPPORTED) 323 return -EOPNOTSUPP; 324 else if (ret) 325 return -EIO; 326 327 adapter->link_speed = ethtool_cmd_speed(ecmd); 328 adapter->link_duplex = ecmd->duplex; 329 adapter->link_autoneg = ecmd->autoneg; 330 331 if (!netif_running(dev)) 332 return 0; 333 334 dev->netdev_ops->ndo_stop(dev); 335 return dev->netdev_ops->ndo_open(dev); 336 } 337 338 static void 339 qlcnic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p) 340 { 341 struct qlcnic_adapter *adapter = netdev_priv(dev); 342 struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; 343 struct qlcnic_host_sds_ring *sds_ring; 344 u32 *regs_buff = p; 345 int ring, i = 0, j = 0; 346 347 memset(p, 0, qlcnic_get_regs_len(dev)); 348 regs->version = (QLCNIC_ETHTOOL_REGS_VER << 24) | 349 (adapter->ahw->revision_id << 16) | (adapter->pdev)->device; 350 351 regs_buff[0] = (0xcafe0000 | (QLCNIC_DEV_INFO_SIZE & 0xffff)); 352 regs_buff[1] = QLCNIC_MGMT_API_VERSION; 353 354 for (i = QLCNIC_DEV_INFO_SIZE + 1; diag_registers[j] != -1; j++, i++) 355 regs_buff[i] = QLCRD32(adapter, diag_registers[j]); 356 357 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) 358 return; 359 360 regs_buff[i++] = 0xFFEFCDAB; /* Marker btw regs and ring count*/ 361 362 regs_buff[i++] = 1; /* No. of tx ring */ 363 regs_buff[i++] = le32_to_cpu(*(adapter->tx_ring->hw_consumer)); 364 regs_buff[i++] = readl(adapter->tx_ring->crb_cmd_producer); 365 366 regs_buff[i++] = 2; /* No. of rx ring */ 367 regs_buff[i++] = readl(recv_ctx->rds_rings[0].crb_rcv_producer); 368 regs_buff[i++] = readl(recv_ctx->rds_rings[1].crb_rcv_producer); 369 370 regs_buff[i++] = adapter->max_sds_rings; 371 372 for (ring = 0; ring < adapter->max_sds_rings; ring++) { 373 sds_ring = &(recv_ctx->sds_rings[ring]); 374 regs_buff[i++] = readl(sds_ring->crb_sts_consumer); 375 } 376 } 377 378 static u32 qlcnic_test_link(struct net_device *dev) 379 { 380 struct qlcnic_adapter *adapter = netdev_priv(dev); 381 u32 val; 382 383 val = QLCRD32(adapter, CRB_XG_STATE_P3P); 384 val = XG_LINK_STATE_P3P(adapter->ahw->pci_func, val); 385 return (val == XG_LINK_UP_P3P) ? 0 : 1; 386 } 387 388 static int 389 qlcnic_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, 390 u8 *bytes) 391 { 392 struct qlcnic_adapter *adapter = netdev_priv(dev); 393 int offset; 394 int ret; 395 396 if (eeprom->len == 0) 397 return -EINVAL; 398 399 eeprom->magic = (adapter->pdev)->vendor | 400 ((adapter->pdev)->device << 16); 401 offset = eeprom->offset; 402 403 ret = qlcnic_rom_fast_read_words(adapter, offset, bytes, 404 eeprom->len); 405 if (ret < 0) 406 return ret; 407 408 return 0; 409 } 410 411 static void 412 qlcnic_get_ringparam(struct net_device *dev, 413 struct ethtool_ringparam *ring) 414 { 415 struct qlcnic_adapter *adapter = netdev_priv(dev); 416 417 ring->rx_pending = adapter->num_rxd; 418 ring->rx_jumbo_pending = adapter->num_jumbo_rxd; 419 ring->tx_pending = adapter->num_txd; 420 421 ring->rx_max_pending = adapter->max_rxd; 422 ring->rx_jumbo_max_pending = adapter->max_jumbo_rxd; 423 ring->tx_max_pending = MAX_CMD_DESCRIPTORS; 424 } 425 426 static u32 427 qlcnic_validate_ringparam(u32 val, u32 min, u32 max, char *r_name) 428 { 429 u32 num_desc; 430 num_desc = max(val, min); 431 num_desc = min(num_desc, max); 432 num_desc = roundup_pow_of_two(num_desc); 433 434 if (val != num_desc) { 435 printk(KERN_INFO "%s: setting %s ring size %d instead of %d\n", 436 qlcnic_driver_name, r_name, num_desc, val); 437 } 438 439 return num_desc; 440 } 441 442 static int 443 qlcnic_set_ringparam(struct net_device *dev, 444 struct ethtool_ringparam *ring) 445 { 446 struct qlcnic_adapter *adapter = netdev_priv(dev); 447 u16 num_rxd, num_jumbo_rxd, num_txd; 448 449 if (ring->rx_mini_pending) 450 return -EOPNOTSUPP; 451 452 num_rxd = qlcnic_validate_ringparam(ring->rx_pending, 453 MIN_RCV_DESCRIPTORS, adapter->max_rxd, "rx"); 454 455 num_jumbo_rxd = qlcnic_validate_ringparam(ring->rx_jumbo_pending, 456 MIN_JUMBO_DESCRIPTORS, adapter->max_jumbo_rxd, 457 "rx jumbo"); 458 459 num_txd = qlcnic_validate_ringparam(ring->tx_pending, 460 MIN_CMD_DESCRIPTORS, MAX_CMD_DESCRIPTORS, "tx"); 461 462 if (num_rxd == adapter->num_rxd && num_txd == adapter->num_txd && 463 num_jumbo_rxd == adapter->num_jumbo_rxd) 464 return 0; 465 466 adapter->num_rxd = num_rxd; 467 adapter->num_jumbo_rxd = num_jumbo_rxd; 468 adapter->num_txd = num_txd; 469 470 return qlcnic_reset_context(adapter); 471 } 472 473 static void qlcnic_get_channels(struct net_device *dev, 474 struct ethtool_channels *channel) 475 { 476 struct qlcnic_adapter *adapter = netdev_priv(dev); 477 478 channel->max_rx = rounddown_pow_of_two(min_t(int, 479 adapter->max_rx_ques, num_online_cpus())); 480 channel->max_tx = adapter->max_tx_ques; 481 482 channel->rx_count = adapter->max_sds_rings; 483 channel->tx_count = adapter->max_tx_ques; 484 } 485 486 static int qlcnic_set_channels(struct net_device *dev, 487 struct ethtool_channels *channel) 488 { 489 struct qlcnic_adapter *adapter = netdev_priv(dev); 490 int err; 491 492 if (channel->other_count || channel->combined_count || 493 channel->tx_count != channel->max_tx) 494 return -EINVAL; 495 496 err = qlcnic_validate_max_rss(dev, channel->max_rx, channel->rx_count); 497 if (err) 498 return err; 499 500 err = qlcnic_set_max_rss(adapter, channel->rx_count); 501 netdev_info(dev, "allocated 0x%x sds rings\n", 502 adapter->max_sds_rings); 503 return err; 504 } 505 506 static void 507 qlcnic_get_pauseparam(struct net_device *netdev, 508 struct ethtool_pauseparam *pause) 509 { 510 struct qlcnic_adapter *adapter = netdev_priv(netdev); 511 int port = adapter->physical_port; 512 __u32 val; 513 514 if (adapter->ahw->port_type == QLCNIC_GBE) { 515 if ((port < 0) || (port > QLCNIC_NIU_MAX_GBE_PORTS)) 516 return; 517 /* get flow control settings */ 518 val = QLCRD32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port)); 519 pause->rx_pause = qlcnic_gb_get_rx_flowctl(val); 520 val = QLCRD32(adapter, QLCNIC_NIU_GB_PAUSE_CTL); 521 switch (port) { 522 case 0: 523 pause->tx_pause = !(qlcnic_gb_get_gb0_mask(val)); 524 break; 525 case 1: 526 pause->tx_pause = !(qlcnic_gb_get_gb1_mask(val)); 527 break; 528 case 2: 529 pause->tx_pause = !(qlcnic_gb_get_gb2_mask(val)); 530 break; 531 case 3: 532 default: 533 pause->tx_pause = !(qlcnic_gb_get_gb3_mask(val)); 534 break; 535 } 536 } else if (adapter->ahw->port_type == QLCNIC_XGBE) { 537 if ((port < 0) || (port > QLCNIC_NIU_MAX_XG_PORTS)) 538 return; 539 pause->rx_pause = 1; 540 val = QLCRD32(adapter, QLCNIC_NIU_XG_PAUSE_CTL); 541 if (port == 0) 542 pause->tx_pause = !(qlcnic_xg_get_xg0_mask(val)); 543 else 544 pause->tx_pause = !(qlcnic_xg_get_xg1_mask(val)); 545 } else { 546 dev_err(&netdev->dev, "Unknown board type: %x\n", 547 adapter->ahw->port_type); 548 } 549 } 550 551 static int 552 qlcnic_set_pauseparam(struct net_device *netdev, 553 struct ethtool_pauseparam *pause) 554 { 555 struct qlcnic_adapter *adapter = netdev_priv(netdev); 556 int port = adapter->physical_port; 557 __u32 val; 558 559 /* read mode */ 560 if (adapter->ahw->port_type == QLCNIC_GBE) { 561 if ((port < 0) || (port > QLCNIC_NIU_MAX_GBE_PORTS)) 562 return -EIO; 563 /* set flow control */ 564 val = QLCRD32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port)); 565 566 if (pause->rx_pause) 567 qlcnic_gb_rx_flowctl(val); 568 else 569 qlcnic_gb_unset_rx_flowctl(val); 570 571 QLCWR32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port), 572 val); 573 /* set autoneg */ 574 val = QLCRD32(adapter, QLCNIC_NIU_GB_PAUSE_CTL); 575 switch (port) { 576 case 0: 577 if (pause->tx_pause) 578 qlcnic_gb_unset_gb0_mask(val); 579 else 580 qlcnic_gb_set_gb0_mask(val); 581 break; 582 case 1: 583 if (pause->tx_pause) 584 qlcnic_gb_unset_gb1_mask(val); 585 else 586 qlcnic_gb_set_gb1_mask(val); 587 break; 588 case 2: 589 if (pause->tx_pause) 590 qlcnic_gb_unset_gb2_mask(val); 591 else 592 qlcnic_gb_set_gb2_mask(val); 593 break; 594 case 3: 595 default: 596 if (pause->tx_pause) 597 qlcnic_gb_unset_gb3_mask(val); 598 else 599 qlcnic_gb_set_gb3_mask(val); 600 break; 601 } 602 QLCWR32(adapter, QLCNIC_NIU_GB_PAUSE_CTL, val); 603 } else if (adapter->ahw->port_type == QLCNIC_XGBE) { 604 if (!pause->rx_pause || pause->autoneg) 605 return -EOPNOTSUPP; 606 607 if ((port < 0) || (port > QLCNIC_NIU_MAX_XG_PORTS)) 608 return -EIO; 609 610 val = QLCRD32(adapter, QLCNIC_NIU_XG_PAUSE_CTL); 611 if (port == 0) { 612 if (pause->tx_pause) 613 qlcnic_xg_unset_xg0_mask(val); 614 else 615 qlcnic_xg_set_xg0_mask(val); 616 } else { 617 if (pause->tx_pause) 618 qlcnic_xg_unset_xg1_mask(val); 619 else 620 qlcnic_xg_set_xg1_mask(val); 621 } 622 QLCWR32(adapter, QLCNIC_NIU_XG_PAUSE_CTL, val); 623 } else { 624 dev_err(&netdev->dev, "Unknown board type: %x\n", 625 adapter->ahw->port_type); 626 } 627 return 0; 628 } 629 630 static int qlcnic_reg_test(struct net_device *dev) 631 { 632 struct qlcnic_adapter *adapter = netdev_priv(dev); 633 u32 data_read; 634 635 data_read = QLCRD32(adapter, QLCNIC_PCIX_PH_REG(0)); 636 if ((data_read & 0xffff) != adapter->pdev->vendor) 637 return 1; 638 639 return 0; 640 } 641 642 static int qlcnic_get_sset_count(struct net_device *dev, int sset) 643 { 644 struct qlcnic_adapter *adapter = netdev_priv(dev); 645 switch (sset) { 646 case ETH_SS_TEST: 647 return QLCNIC_TEST_LEN; 648 case ETH_SS_STATS: 649 if (adapter->flags & QLCNIC_ESWITCH_ENABLED) 650 return QLCNIC_STATS_LEN + QLCNIC_DEVICE_STATS_LEN; 651 return QLCNIC_STATS_LEN; 652 default: 653 return -EOPNOTSUPP; 654 } 655 } 656 657 static int qlcnic_irq_test(struct net_device *netdev) 658 { 659 struct qlcnic_adapter *adapter = netdev_priv(netdev); 660 int max_sds_rings = adapter->max_sds_rings; 661 int ret; 662 struct qlcnic_cmd_args cmd; 663 664 if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state)) 665 return -EIO; 666 667 ret = qlcnic_diag_alloc_res(netdev, QLCNIC_INTERRUPT_TEST); 668 if (ret) 669 goto clear_it; 670 671 adapter->diag_cnt = 0; 672 memset(&cmd, 0, sizeof(cmd)); 673 cmd.req.cmd = QLCNIC_CDRP_CMD_INTRPT_TEST; 674 cmd.req.arg1 = adapter->ahw->pci_func; 675 qlcnic_issue_cmd(adapter, &cmd); 676 ret = cmd.rsp.cmd; 677 678 if (ret) 679 goto done; 680 681 msleep(10); 682 683 ret = !adapter->diag_cnt; 684 685 done: 686 qlcnic_diag_free_res(netdev, max_sds_rings); 687 688 clear_it: 689 adapter->max_sds_rings = max_sds_rings; 690 clear_bit(__QLCNIC_RESETTING, &adapter->state); 691 return ret; 692 } 693 694 #define QLCNIC_ILB_PKT_SIZE 64 695 #define QLCNIC_NUM_ILB_PKT 16 696 #define QLCNIC_ILB_MAX_RCV_LOOP 10 697 698 static void qlcnic_create_loopback_buff(unsigned char *data, u8 mac[]) 699 { 700 unsigned char random_data[] = {0xa8, 0x06, 0x45, 0x00}; 701 702 memset(data, 0x4e, QLCNIC_ILB_PKT_SIZE); 703 704 memcpy(data, mac, ETH_ALEN); 705 memcpy(data + ETH_ALEN, mac, ETH_ALEN); 706 707 memcpy(data + 2 * ETH_ALEN, random_data, sizeof(random_data)); 708 } 709 710 int qlcnic_check_loopback_buff(unsigned char *data, u8 mac[]) 711 { 712 unsigned char buff[QLCNIC_ILB_PKT_SIZE]; 713 qlcnic_create_loopback_buff(buff, mac); 714 return memcmp(data, buff, QLCNIC_ILB_PKT_SIZE); 715 } 716 717 static int qlcnic_do_lb_test(struct qlcnic_adapter *adapter, u8 mode) 718 { 719 struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; 720 struct qlcnic_host_sds_ring *sds_ring = &recv_ctx->sds_rings[0]; 721 struct sk_buff *skb; 722 int i, loop, cnt = 0; 723 724 for (i = 0; i < QLCNIC_NUM_ILB_PKT; i++) { 725 skb = dev_alloc_skb(QLCNIC_ILB_PKT_SIZE); 726 qlcnic_create_loopback_buff(skb->data, adapter->mac_addr); 727 skb_put(skb, QLCNIC_ILB_PKT_SIZE); 728 729 adapter->diag_cnt = 0; 730 qlcnic_xmit_frame(skb, adapter->netdev); 731 732 loop = 0; 733 do { 734 msleep(1); 735 qlcnic_process_rcv_ring_diag(sds_ring); 736 if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP) 737 break; 738 } while (!adapter->diag_cnt); 739 740 dev_kfree_skb_any(skb); 741 742 if (!adapter->diag_cnt) 743 QLCDB(adapter, DRV, 744 "LB Test: packet #%d was not received\n", i + 1); 745 else 746 cnt++; 747 } 748 if (cnt != i) { 749 dev_warn(&adapter->pdev->dev, "LB Test failed\n"); 750 if (mode != QLCNIC_ILB_MODE) { 751 dev_warn(&adapter->pdev->dev, 752 "WARNING: Please make sure external" 753 "loopback connector is plugged in\n"); 754 } 755 return -1; 756 } 757 return 0; 758 } 759 760 static int qlcnic_loopback_test(struct net_device *netdev, u8 mode) 761 { 762 struct qlcnic_adapter *adapter = netdev_priv(netdev); 763 int max_sds_rings = adapter->max_sds_rings; 764 struct qlcnic_host_sds_ring *sds_ring; 765 int loop = 0; 766 int ret; 767 768 if (!(adapter->capabilities & QLCNIC_FW_CAPABILITY_MULTI_LOOPBACK)) { 769 netdev_info(netdev, "Firmware is not loopback test capable\n"); 770 return -EOPNOTSUPP; 771 } 772 773 QLCDB(adapter, DRV, "%s loopback test in progress\n", 774 mode == QLCNIC_ILB_MODE ? "internal" : "external"); 775 if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) { 776 netdev_warn(netdev, "Loopback test not supported for non " 777 "privilege function\n"); 778 return 0; 779 } 780 781 if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state)) 782 return -EBUSY; 783 784 ret = qlcnic_diag_alloc_res(netdev, QLCNIC_LOOPBACK_TEST); 785 if (ret) 786 goto clear_it; 787 788 sds_ring = &adapter->recv_ctx->sds_rings[0]; 789 790 ret = qlcnic_set_lb_mode(adapter, mode); 791 if (ret) 792 goto free_res; 793 794 adapter->diag_cnt = 0; 795 do { 796 msleep(500); 797 qlcnic_process_rcv_ring_diag(sds_ring); 798 if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP) { 799 netdev_info(netdev, "firmware didnt respond to loopback" 800 " configure request\n"); 801 ret = -QLCNIC_FW_NOT_RESPOND; 802 goto free_res; 803 } else if (adapter->diag_cnt) { 804 ret = adapter->diag_cnt; 805 goto free_res; 806 } 807 } while (!QLCNIC_IS_LB_CONFIGURED(adapter->ahw->loopback_state)); 808 809 ret = qlcnic_do_lb_test(adapter, mode); 810 811 qlcnic_clear_lb_mode(adapter); 812 813 free_res: 814 qlcnic_diag_free_res(netdev, max_sds_rings); 815 816 clear_it: 817 adapter->max_sds_rings = max_sds_rings; 818 clear_bit(__QLCNIC_RESETTING, &adapter->state); 819 return ret; 820 } 821 822 static void 823 qlcnic_diag_test(struct net_device *dev, struct ethtool_test *eth_test, 824 u64 *data) 825 { 826 memset(data, 0, sizeof(u64) * QLCNIC_TEST_LEN); 827 828 data[0] = qlcnic_reg_test(dev); 829 if (data[0]) 830 eth_test->flags |= ETH_TEST_FL_FAILED; 831 832 data[1] = (u64) qlcnic_test_link(dev); 833 if (data[1]) 834 eth_test->flags |= ETH_TEST_FL_FAILED; 835 836 if (eth_test->flags & ETH_TEST_FL_OFFLINE) { 837 data[2] = qlcnic_irq_test(dev); 838 if (data[2]) 839 eth_test->flags |= ETH_TEST_FL_FAILED; 840 841 data[3] = qlcnic_loopback_test(dev, QLCNIC_ILB_MODE); 842 if (data[3]) 843 eth_test->flags |= ETH_TEST_FL_FAILED; 844 if (eth_test->flags & ETH_TEST_FL_EXTERNAL_LB) { 845 data[4] = qlcnic_loopback_test(dev, QLCNIC_ELB_MODE); 846 if (data[4]) 847 eth_test->flags |= ETH_TEST_FL_FAILED; 848 eth_test->flags |= ETH_TEST_FL_EXTERNAL_LB_DONE; 849 } 850 } 851 } 852 853 static void 854 qlcnic_get_strings(struct net_device *dev, u32 stringset, u8 * data) 855 { 856 struct qlcnic_adapter *adapter = netdev_priv(dev); 857 int index, i; 858 859 switch (stringset) { 860 case ETH_SS_TEST: 861 memcpy(data, *qlcnic_gstrings_test, 862 QLCNIC_TEST_LEN * ETH_GSTRING_LEN); 863 break; 864 case ETH_SS_STATS: 865 for (index = 0; index < QLCNIC_STATS_LEN; index++) { 866 memcpy(data + index * ETH_GSTRING_LEN, 867 qlcnic_gstrings_stats[index].stat_string, 868 ETH_GSTRING_LEN); 869 } 870 if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) 871 return; 872 for (i = 0; i < QLCNIC_DEVICE_STATS_LEN; index++, i++) { 873 memcpy(data + index * ETH_GSTRING_LEN, 874 qlcnic_device_gstrings_stats[i], 875 ETH_GSTRING_LEN); 876 } 877 } 878 } 879 880 #define QLCNIC_FILL_ESWITCH_STATS(VAL1) \ 881 (((VAL1) == QLCNIC_ESW_STATS_NOT_AVAIL) ? 0 : VAL1) 882 883 static void 884 qlcnic_fill_device_stats(int *index, u64 *data, 885 struct __qlcnic_esw_statistics *stats) 886 { 887 int ind = *index; 888 889 data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->unicast_frames); 890 data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->multicast_frames); 891 data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->broadcast_frames); 892 data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->dropped_frames); 893 data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->errors); 894 data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->local_frames); 895 data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->numbytes); 896 897 *index = ind; 898 } 899 900 static void 901 qlcnic_get_ethtool_stats(struct net_device *dev, 902 struct ethtool_stats *stats, u64 * data) 903 { 904 struct qlcnic_adapter *adapter = netdev_priv(dev); 905 struct qlcnic_esw_statistics port_stats; 906 int index, ret; 907 908 for (index = 0; index < QLCNIC_STATS_LEN; index++) { 909 char *p = 910 (char *)adapter + 911 qlcnic_gstrings_stats[index].stat_offset; 912 data[index] = 913 (qlcnic_gstrings_stats[index].sizeof_stat == 914 sizeof(u64)) ? *(u64 *)p:(*(u32 *)p); 915 } 916 917 if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) 918 return; 919 920 memset(&port_stats, 0, sizeof(struct qlcnic_esw_statistics)); 921 ret = qlcnic_get_port_stats(adapter, adapter->ahw->pci_func, 922 QLCNIC_QUERY_RX_COUNTER, &port_stats.rx); 923 if (ret) 924 return; 925 926 qlcnic_fill_device_stats(&index, data, &port_stats.rx); 927 928 ret = qlcnic_get_port_stats(adapter, adapter->ahw->pci_func, 929 QLCNIC_QUERY_TX_COUNTER, &port_stats.tx); 930 if (ret) 931 return; 932 933 qlcnic_fill_device_stats(&index, data, &port_stats.tx); 934 } 935 936 static int qlcnic_set_led(struct net_device *dev, 937 enum ethtool_phys_id_state state) 938 { 939 struct qlcnic_adapter *adapter = netdev_priv(dev); 940 int max_sds_rings = adapter->max_sds_rings; 941 int err = -EIO, active = 1; 942 943 if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) { 944 netdev_warn(dev, "LED test not supported for non " 945 "privilege function\n"); 946 return -EOPNOTSUPP; 947 } 948 949 switch (state) { 950 case ETHTOOL_ID_ACTIVE: 951 if (test_and_set_bit(__QLCNIC_LED_ENABLE, &adapter->state)) 952 return -EBUSY; 953 954 if (test_bit(__QLCNIC_RESETTING, &adapter->state)) 955 break; 956 957 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) { 958 if (qlcnic_diag_alloc_res(dev, QLCNIC_LED_TEST)) 959 break; 960 set_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state); 961 } 962 963 if (adapter->nic_ops->config_led(adapter, 1, 0xf) == 0) { 964 err = 0; 965 break; 966 } 967 968 dev_err(&adapter->pdev->dev, 969 "Failed to set LED blink state.\n"); 970 break; 971 972 case ETHTOOL_ID_INACTIVE: 973 active = 0; 974 975 if (test_bit(__QLCNIC_RESETTING, &adapter->state)) 976 break; 977 978 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) { 979 if (qlcnic_diag_alloc_res(dev, QLCNIC_LED_TEST)) 980 break; 981 set_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state); 982 } 983 984 if (adapter->nic_ops->config_led(adapter, 0, 0xf)) 985 dev_err(&adapter->pdev->dev, 986 "Failed to reset LED blink state.\n"); 987 988 break; 989 990 default: 991 return -EINVAL; 992 } 993 994 if (test_and_clear_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state)) 995 qlcnic_diag_free_res(dev, max_sds_rings); 996 997 if (!active || err) 998 clear_bit(__QLCNIC_LED_ENABLE, &adapter->state); 999 1000 return err; 1001 } 1002 1003 static void 1004 qlcnic_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) 1005 { 1006 struct qlcnic_adapter *adapter = netdev_priv(dev); 1007 u32 wol_cfg; 1008 1009 wol->supported = 0; 1010 wol->wolopts = 0; 1011 1012 wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG_NV); 1013 if (wol_cfg & (1UL << adapter->portnum)) 1014 wol->supported |= WAKE_MAGIC; 1015 1016 wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG); 1017 if (wol_cfg & (1UL << adapter->portnum)) 1018 wol->wolopts |= WAKE_MAGIC; 1019 } 1020 1021 static int 1022 qlcnic_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) 1023 { 1024 struct qlcnic_adapter *adapter = netdev_priv(dev); 1025 u32 wol_cfg; 1026 1027 if (wol->wolopts & ~WAKE_MAGIC) 1028 return -EOPNOTSUPP; 1029 1030 wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG_NV); 1031 if (!(wol_cfg & (1 << adapter->portnum))) 1032 return -EOPNOTSUPP; 1033 1034 wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG); 1035 if (wol->wolopts & WAKE_MAGIC) 1036 wol_cfg |= 1UL << adapter->portnum; 1037 else 1038 wol_cfg &= ~(1UL << adapter->portnum); 1039 1040 QLCWR32(adapter, QLCNIC_WOL_CONFIG, wol_cfg); 1041 1042 return 0; 1043 } 1044 1045 /* 1046 * Set the coalescing parameters. Currently only normal is supported. 1047 * If rx_coalesce_usecs == 0 or rx_max_coalesced_frames == 0 then set the 1048 * firmware coalescing to default. 1049 */ 1050 static int qlcnic_set_intr_coalesce(struct net_device *netdev, 1051 struct ethtool_coalesce *ethcoal) 1052 { 1053 struct qlcnic_adapter *adapter = netdev_priv(netdev); 1054 1055 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) 1056 return -EINVAL; 1057 1058 /* 1059 * Return Error if unsupported values or 1060 * unsupported parameters are set. 1061 */ 1062 if (ethcoal->rx_coalesce_usecs > 0xffff || 1063 ethcoal->rx_max_coalesced_frames > 0xffff || 1064 ethcoal->tx_coalesce_usecs || 1065 ethcoal->tx_max_coalesced_frames || 1066 ethcoal->rx_coalesce_usecs_irq || 1067 ethcoal->rx_max_coalesced_frames_irq || 1068 ethcoal->tx_coalesce_usecs_irq || 1069 ethcoal->tx_max_coalesced_frames_irq || 1070 ethcoal->stats_block_coalesce_usecs || 1071 ethcoal->use_adaptive_rx_coalesce || 1072 ethcoal->use_adaptive_tx_coalesce || 1073 ethcoal->pkt_rate_low || 1074 ethcoal->rx_coalesce_usecs_low || 1075 ethcoal->rx_max_coalesced_frames_low || 1076 ethcoal->tx_coalesce_usecs_low || 1077 ethcoal->tx_max_coalesced_frames_low || 1078 ethcoal->pkt_rate_high || 1079 ethcoal->rx_coalesce_usecs_high || 1080 ethcoal->rx_max_coalesced_frames_high || 1081 ethcoal->tx_coalesce_usecs_high || 1082 ethcoal->tx_max_coalesced_frames_high) 1083 return -EINVAL; 1084 1085 if (!ethcoal->rx_coalesce_usecs || 1086 !ethcoal->rx_max_coalesced_frames) { 1087 adapter->ahw->coal.flag = QLCNIC_INTR_DEFAULT; 1088 adapter->ahw->coal.rx_time_us = 1089 QLCNIC_DEFAULT_INTR_COALESCE_RX_TIME_US; 1090 adapter->ahw->coal.rx_packets = 1091 QLCNIC_DEFAULT_INTR_COALESCE_RX_PACKETS; 1092 } else { 1093 adapter->ahw->coal.flag = 0; 1094 adapter->ahw->coal.rx_time_us = ethcoal->rx_coalesce_usecs; 1095 adapter->ahw->coal.rx_packets = 1096 ethcoal->rx_max_coalesced_frames; 1097 } 1098 1099 qlcnic_config_intr_coalesce(adapter); 1100 1101 return 0; 1102 } 1103 1104 static int qlcnic_get_intr_coalesce(struct net_device *netdev, 1105 struct ethtool_coalesce *ethcoal) 1106 { 1107 struct qlcnic_adapter *adapter = netdev_priv(netdev); 1108 1109 if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC) 1110 return -EINVAL; 1111 1112 ethcoal->rx_coalesce_usecs = adapter->ahw->coal.rx_time_us; 1113 ethcoal->rx_max_coalesced_frames = adapter->ahw->coal.rx_packets; 1114 1115 return 0; 1116 } 1117 1118 static u32 qlcnic_get_msglevel(struct net_device *netdev) 1119 { 1120 struct qlcnic_adapter *adapter = netdev_priv(netdev); 1121 1122 return adapter->msg_enable; 1123 } 1124 1125 static void qlcnic_set_msglevel(struct net_device *netdev, u32 msglvl) 1126 { 1127 struct qlcnic_adapter *adapter = netdev_priv(netdev); 1128 1129 adapter->msg_enable = msglvl; 1130 } 1131 1132 static int 1133 qlcnic_get_dump_flag(struct net_device *netdev, struct ethtool_dump *dump) 1134 { 1135 struct qlcnic_adapter *adapter = netdev_priv(netdev); 1136 struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump; 1137 1138 if (fw_dump->clr) 1139 dump->len = fw_dump->tmpl_hdr->size + fw_dump->size; 1140 else 1141 dump->len = 0; 1142 dump->flag = fw_dump->tmpl_hdr->drv_cap_mask; 1143 dump->version = adapter->fw_version; 1144 return 0; 1145 } 1146 1147 static int 1148 qlcnic_get_dump_data(struct net_device *netdev, struct ethtool_dump *dump, 1149 void *buffer) 1150 { 1151 int i, copy_sz; 1152 u32 *hdr_ptr, *data; 1153 struct qlcnic_adapter *adapter = netdev_priv(netdev); 1154 struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump; 1155 1156 if (!fw_dump->clr) { 1157 netdev_info(netdev, "Dump not available\n"); 1158 qlcnic_api_unlock(adapter); 1159 return -EINVAL; 1160 } 1161 /* Copy template header first */ 1162 copy_sz = fw_dump->tmpl_hdr->size; 1163 hdr_ptr = (u32 *) fw_dump->tmpl_hdr; 1164 data = buffer; 1165 for (i = 0; i < copy_sz/sizeof(u32); i++) 1166 *data++ = cpu_to_le32(*hdr_ptr++); 1167 1168 /* Copy captured dump data */ 1169 memcpy(buffer + copy_sz, fw_dump->data, fw_dump->size); 1170 dump->len = copy_sz + fw_dump->size; 1171 dump->flag = fw_dump->tmpl_hdr->drv_cap_mask; 1172 1173 /* Free dump area once data has been captured */ 1174 vfree(fw_dump->data); 1175 fw_dump->data = NULL; 1176 fw_dump->clr = 0; 1177 1178 return 0; 1179 } 1180 1181 static int 1182 qlcnic_set_dump(struct net_device *netdev, struct ethtool_dump *val) 1183 { 1184 int ret = 0; 1185 struct qlcnic_adapter *adapter = netdev_priv(netdev); 1186 struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump; 1187 1188 switch (val->flag) { 1189 case QLCNIC_FORCE_FW_DUMP_KEY: 1190 if (!fw_dump->enable) { 1191 netdev_info(netdev, "FW dump not enabled\n"); 1192 return ret; 1193 } 1194 if (fw_dump->clr) { 1195 dev_info(&adapter->pdev->dev, 1196 "Previous dump not cleared, not forcing dump\n"); 1197 return ret; 1198 } 1199 netdev_info(netdev, "Forcing a FW dump\n"); 1200 qlcnic_dev_request_reset(adapter); 1201 break; 1202 case QLCNIC_DISABLE_FW_DUMP: 1203 if (fw_dump->enable) { 1204 netdev_info(netdev, "Disabling FW dump\n"); 1205 fw_dump->enable = 0; 1206 } 1207 break; 1208 case QLCNIC_ENABLE_FW_DUMP: 1209 if (!fw_dump->enable && fw_dump->tmpl_hdr) { 1210 netdev_info(netdev, "Enabling FW dump\n"); 1211 fw_dump->enable = 1; 1212 } 1213 break; 1214 case QLCNIC_FORCE_FW_RESET: 1215 netdev_info(netdev, "Forcing a FW reset\n"); 1216 qlcnic_dev_request_reset(adapter); 1217 adapter->flags &= ~QLCNIC_FW_RESET_OWNER; 1218 break; 1219 default: 1220 if (val->flag > QLCNIC_DUMP_MASK_MAX || 1221 val->flag < QLCNIC_DUMP_MASK_MIN) { 1222 netdev_info(netdev, 1223 "Invalid dump level: 0x%x\n", val->flag); 1224 ret = -EINVAL; 1225 goto out; 1226 } 1227 fw_dump->tmpl_hdr->drv_cap_mask = val->flag & 0xff; 1228 netdev_info(netdev, "Driver mask changed to: 0x%x\n", 1229 fw_dump->tmpl_hdr->drv_cap_mask); 1230 } 1231 out: 1232 return ret; 1233 } 1234 1235 const struct ethtool_ops qlcnic_ethtool_ops = { 1236 .get_settings = qlcnic_get_settings, 1237 .set_settings = qlcnic_set_settings, 1238 .get_drvinfo = qlcnic_get_drvinfo, 1239 .get_regs_len = qlcnic_get_regs_len, 1240 .get_regs = qlcnic_get_regs, 1241 .get_link = ethtool_op_get_link, 1242 .get_eeprom_len = qlcnic_get_eeprom_len, 1243 .get_eeprom = qlcnic_get_eeprom, 1244 .get_ringparam = qlcnic_get_ringparam, 1245 .set_ringparam = qlcnic_set_ringparam, 1246 .get_channels = qlcnic_get_channels, 1247 .set_channels = qlcnic_set_channels, 1248 .get_pauseparam = qlcnic_get_pauseparam, 1249 .set_pauseparam = qlcnic_set_pauseparam, 1250 .get_wol = qlcnic_get_wol, 1251 .set_wol = qlcnic_set_wol, 1252 .self_test = qlcnic_diag_test, 1253 .get_strings = qlcnic_get_strings, 1254 .get_ethtool_stats = qlcnic_get_ethtool_stats, 1255 .get_sset_count = qlcnic_get_sset_count, 1256 .get_coalesce = qlcnic_get_intr_coalesce, 1257 .set_coalesce = qlcnic_set_intr_coalesce, 1258 .set_phys_id = qlcnic_set_led, 1259 .set_msglevel = qlcnic_set_msglevel, 1260 .get_msglevel = qlcnic_get_msglevel, 1261 .get_dump_flag = qlcnic_get_dump_flag, 1262 .get_dump_data = qlcnic_get_dump_data, 1263 .set_dump = qlcnic_set_dump, 1264 }; 1265