static int qlcnic_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) { struct qlcnic_adapter *adapter = netdev_priv(dev); u32 wol_cfg; if (qlcnic_83xx_check(adapter)) return -EOPNOTSUPP; if (wol->wolopts & ~WAKE_MAGIC) return -EINVAL; wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG_NV); if (!(wol_cfg & (1 << adapter->portnum))) return -EOPNOTSUPP; wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG); if (wol->wolopts & WAKE_MAGIC) wol_cfg |= 1UL << adapter->portnum; else wol_cfg &= ~(1UL << adapter->portnum); QLCWR32(adapter, QLCNIC_WOL_CONFIG, wol_cfg); return 0; }
static void qlcnic_get_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause) { struct qlcnic_adapter *adapter = netdev_priv(netdev); int port = adapter->ahw->physical_port; int err = 0; __u32 val; if (qlcnic_83xx_check(adapter)) { qlcnic_83xx_get_pauseparam(adapter, pause); return; } if (adapter->ahw->port_type == QLCNIC_GBE) { if ((port < 0) || (port > QLCNIC_NIU_MAX_GBE_PORTS)) return; /* get flow control settings */ val = QLCRD32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port), &err); if (err == -EIO) return; pause->rx_pause = qlcnic_gb_get_rx_flowctl(val); val = QLCRD32(adapter, QLCNIC_NIU_GB_PAUSE_CTL, &err); if (err == -EIO) return; switch (port) { case 0: pause->tx_pause = !(qlcnic_gb_get_gb0_mask(val)); break; case 1: pause->tx_pause = !(qlcnic_gb_get_gb1_mask(val)); break; case 2: pause->tx_pause = !(qlcnic_gb_get_gb2_mask(val)); break; case 3: default: pause->tx_pause = !(qlcnic_gb_get_gb3_mask(val)); break; } } else if (adapter->ahw->port_type == QLCNIC_XGBE) { if ((port < 0) || (port > QLCNIC_NIU_MAX_XG_PORTS)) return; pause->rx_pause = 1; val = QLCRD32(adapter, QLCNIC_NIU_XG_PAUSE_CTL, &err); if (err == -EIO) return; if (port == 0) pause->tx_pause = !(qlcnic_xg_get_xg0_mask(val)); else pause->tx_pause = !(qlcnic_xg_get_xg1_mask(val)); } else { dev_err(&netdev->dev, "Unknown board type: %x\n", adapter->ahw->port_type); } }
static void qlcnic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo) { struct qlcnic_adapter *adapter = netdev_priv(dev); u32 fw_major, fw_minor, fw_build; fw_major = QLCRD32(adapter, QLCNIC_FW_VERSION_MAJOR); fw_minor = QLCRD32(adapter, QLCNIC_FW_VERSION_MINOR); fw_build = QLCRD32(adapter, QLCNIC_FW_VERSION_SUB); sprintf(drvinfo->fw_version, "%d.%d.%d", fw_major, fw_minor, fw_build); strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), 32); strlcpy(drvinfo->driver, qlcnic_driver_name, 32); strlcpy(drvinfo->version, QLCNIC_LINUX_VERSIONID, 32); }
static void qlcnic_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) { struct qlcnic_adapter *adapter = netdev_priv(dev); u32 wol_cfg; wol->supported = 0; wol->wolopts = 0; wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG_NV); if (wol_cfg & (1UL << adapter->portnum)) wol->supported |= WAKE_MAGIC; wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG); if (wol_cfg & (1UL << adapter->portnum)) wol->wolopts |= WAKE_MAGIC; }
static u32 qlcnic_test_link(struct net_device *dev) { struct qlcnic_adapter *adapter = netdev_priv(dev); u32 val; val = QLCRD32(adapter, CRB_XG_STATE_P3P); val = XG_LINK_STATE_P3P(adapter->ahw.pci_func, val); return (val == XG_LINK_UP_P3P) ? 0 : 1; }
static int qlcnic_reg_test(struct net_device *dev) { struct qlcnic_adapter *adapter = netdev_priv(dev); u32 data_read; data_read = QLCRD32(adapter, QLCNIC_PCIX_PH_REG(0)); if ((data_read & 0xffff) != adapter->pdev->vendor) return 1; return 0; }
static int qlcnic_82xx_get_registers(struct qlcnic_adapter *adapter, u32 *regs_buff) { int i, j = 0; for (i = QLCNIC_DEV_INFO_SIZE + 1; diag_registers[j] != -1; j++, i++) regs_buff[i] = QLC_SHARED_REG_RD32(adapter, diag_registers[j]); j = 0; while (ext_diag_registers[j] != -1) regs_buff[i++] = QLCRD32(adapter, ext_diag_registers[j++]); return i; }
static void qlcnic_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) { struct qlcnic_adapter *adapter = netdev_priv(dev); u32 wol_cfg; int err = 0; if (qlcnic_83xx_check(adapter)) return; wol->supported = 0; wol->wolopts = 0; wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG_NV, &err); if (err == -EIO) return; if (wol_cfg & (1UL << adapter->portnum)) wol->supported |= WAKE_MAGIC; wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG, &err); if (wol_cfg & (1UL << adapter->portnum)) wol->wolopts |= WAKE_MAGIC; }
static u32 qlcnic_test_link(struct net_device *dev) { struct qlcnic_adapter *adapter = netdev_priv(dev); u32 val; if (qlcnic_83xx_check(adapter)) { val = qlcnic_83xx_test_link(adapter); return (val & 1) ? 0 : 1; } val = QLCRD32(adapter, CRB_XG_STATE_P3P); val = XG_LINK_STATE_P3P(adapter->ahw->pci_func, val); return (val == XG_LINK_UP_P3P) ? 0 : 1; }
/* Get eSwitch Capabilities */ int qlcnic_get_eswitch_capabilities(struct qlcnic_adapter *adapter, u8 port, struct qlcnic_eswitch *eswitch) { int err = -EIO; u32 arg1, arg2; if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) return err; err = qlcnic_issue_cmd(adapter, adapter->ahw.pci_func, adapter->fw_hal_version, port, 0, 0, QLCNIC_CDRP_CMD_GET_ESWITCH_CAPABILITY); if (err == QLCNIC_RCODE_SUCCESS) { arg1 = QLCRD32(adapter, QLCNIC_ARG1_CRB_OFFSET); arg2 = QLCRD32(adapter, QLCNIC_ARG2_CRB_OFFSET); eswitch->port = arg1 & 0xf; eswitch->active_vports = LSB(arg2); eswitch->max_ucast_filters = MSB(arg2); eswitch->max_active_vlans = LSB(MSW(arg2)); if (arg1 & BIT_6) eswitch->flags |= QLCNIC_SWITCH_VLAN_FILTERING; if (arg1 & BIT_7) eswitch->flags |= QLCNIC_SWITCH_PROMISC_MODE; if (arg1 & BIT_8) eswitch->flags |= QLCNIC_SWITCH_PORT_MIRRORING; } else { dev_err(&adapter->pdev->dev, "Failed to get eswitch capabilities%d\n", err); } return err; }
static int qlcnic_reg_test(struct net_device *dev) { struct qlcnic_adapter *adapter = netdev_priv(dev); u32 data_read; int err = 0; if (qlcnic_83xx_check(adapter)) return qlcnic_83xx_reg_test(adapter); data_read = QLCRD32(adapter, QLCNIC_PCIX_PH_REG(0), &err); if (err == -EIO) return err; if ((data_read & 0xffff) != adapter->pdev->vendor) return 1; return 0; }
int qlcnic_fw_cmd_query_phy(struct qlcnic_adapter *adapter, u32 reg, u32 *val) { if (qlcnic_issue_cmd(adapter, adapter->ahw.pci_func, adapter->fw_hal_version, reg, 0, 0, QLCNIC_CDRP_CMD_READ_PHY)) { return -EIO; } return QLCRD32(adapter, QLCNIC_ARG1_CRB_OFFSET); }
static u32 qlcnic_poll_rsp(struct qlcnic_adapter *adapter) { u32 rsp; int timeout = 0; do { /* give atleast 1ms for firmware to respond */ msleep(1); if (++timeout > QLCNIC_OS_CRB_RETRY_COUNT) return QLCNIC_CDRP_RSP_TIMEOUT; rsp = QLCRD32(adapter, QLCNIC_CDRP_CRB_OFFSET); } while (!QLCNIC_CDRP_IS_RSP(rsp)); return rsp; }
static void qlcnic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p) { struct qlcnic_adapter *adapter = netdev_priv(dev); struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx; struct qlcnic_host_sds_ring *sds_ring; u32 *regs_buff = p; int ring, i = 0, j = 0; memset(p, 0, qlcnic_get_regs_len(dev)); regs->version = (QLCNIC_ETHTOOL_REGS_VER << 24) | (adapter->ahw.revision_id << 16) | (adapter->pdev)->device; regs_buff[0] = (0xcafe0000 | (QLCNIC_DEV_INFO_SIZE & 0xffff)); regs_buff[1] = QLCNIC_MGMT_API_VERSION; for (i = QLCNIC_DEV_INFO_SIZE + 1; diag_registers[j] != -1; j++, i++) regs_buff[i] = QLCRD32(adapter, diag_registers[j]); if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) return; regs_buff[i++] = 0xFFEFCDAB; /* Marker btw regs and ring count*/ regs_buff[i++] = 1; /* No. of tx ring */ regs_buff[i++] = le32_to_cpu(*(adapter->tx_ring->hw_consumer)); regs_buff[i++] = readl(adapter->tx_ring->crb_cmd_producer); regs_buff[i++] = 2; /* No. of rx ring */ regs_buff[i++] = readl(recv_ctx->rds_rings[0].crb_rcv_producer); regs_buff[i++] = readl(recv_ctx->rds_rings[1].crb_rcv_producer); regs_buff[i++] = adapter->max_sds_rings; for (ring = 0; ring < adapter->max_sds_rings; ring++) { sds_ring = &(recv_ctx->sds_rings[ring]); regs_buff[i++] = readl(sds_ring->crb_sts_consumer); } }
u32 qlcnic_issue_cmd(struct qlcnic_adapter *adapter, u32 pci_fn, u32 version, u32 arg1, u32 arg2, u32 arg3, u32 cmd) { u32 rsp; u32 signature; u32 rcode = QLCNIC_RCODE_SUCCESS; struct pci_dev *pdev = adapter->pdev; signature = QLCNIC_CDRP_SIGNATURE_MAKE(pci_fn, version); /* Acquire semaphore before accessing CRB */ if (qlcnic_api_lock(adapter)) return QLCNIC_RCODE_TIMEOUT; QLCWR32(adapter, QLCNIC_SIGN_CRB_OFFSET, signature); QLCWR32(adapter, QLCNIC_ARG1_CRB_OFFSET, arg1); QLCWR32(adapter, QLCNIC_ARG2_CRB_OFFSET, arg2); QLCWR32(adapter, QLCNIC_ARG3_CRB_OFFSET, arg3); QLCWR32(adapter, QLCNIC_CDRP_CRB_OFFSET, QLCNIC_CDRP_FORM_CMD(cmd)); rsp = qlcnic_poll_rsp(adapter); if (rsp == QLCNIC_CDRP_RSP_TIMEOUT) { dev_err(&pdev->dev, "card response timeout.\n"); rcode = QLCNIC_RCODE_TIMEOUT; } else if (rsp == QLCNIC_CDRP_RSP_FAIL) { rcode = QLCRD32(adapter, QLCNIC_ARG1_CRB_OFFSET); dev_err(&pdev->dev, "failed card response code:0x%x\n", rcode); } /* Release semaphore */ qlcnic_api_unlock(adapter); return rcode; }
static void qlcnic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p) { struct qlcnic_adapter *adapter = netdev_priv(dev); struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx; struct qlcnic_host_sds_ring *sds_ring; u32 *regs_buff = p; int ring, i = 0; memset(p, 0, qlcnic_get_regs_len(dev)); regs->version = (1 << 24) | (adapter->ahw.revision_id << 16) | (adapter->pdev)->device; for (i = 0; diag_registers[i] != -1; i++) regs_buff[i] = QLCRD32(adapter, diag_registers[i]); if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC) return; regs_buff[i++] = 0xFFEFCDAB; /* Marker btw regs and ring count*/ regs_buff[i++] = 1; /* No. of tx ring */ regs_buff[i++] = le32_to_cpu(*(adapter->tx_ring->hw_consumer)); regs_buff[i++] = readl(adapter->tx_ring->crb_cmd_producer); regs_buff[i++] = 2; /* No. of rx ring */ regs_buff[i++] = readl(recv_ctx->rds_rings[0].crb_rcv_producer); regs_buff[i++] = readl(recv_ctx->rds_rings[1].crb_rcv_producer); regs_buff[i++] = adapter->max_sds_rings; for (ring = 0; ring < adapter->max_sds_rings; ring++) { sds_ring = &(recv_ctx->sds_rings[ring]); regs_buff[i++] = readl(sds_ring->crb_sts_consumer); } }
static int qlcnic_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause) { struct qlcnic_adapter *adapter = netdev_priv(netdev); int port = adapter->ahw->physical_port; __u32 val; if (qlcnic_83xx_check(adapter)) return qlcnic_83xx_set_pauseparam(adapter, pause); /* read mode */ if (adapter->ahw->port_type == QLCNIC_GBE) { if ((port < 0) || (port > QLCNIC_NIU_MAX_GBE_PORTS)) return -EIO; /* set flow control */ val = QLCRD32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port)); if (pause->rx_pause) qlcnic_gb_rx_flowctl(val); else qlcnic_gb_unset_rx_flowctl(val); QLCWR32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port), val); QLCWR32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port), val); /* set autoneg */ val = QLCRD32(adapter, QLCNIC_NIU_GB_PAUSE_CTL); switch (port) { case 0: if (pause->tx_pause) qlcnic_gb_unset_gb0_mask(val); else qlcnic_gb_set_gb0_mask(val); break; case 1: if (pause->tx_pause) qlcnic_gb_unset_gb1_mask(val); else qlcnic_gb_set_gb1_mask(val); break; case 2: if (pause->tx_pause) qlcnic_gb_unset_gb2_mask(val); else qlcnic_gb_set_gb2_mask(val); break; case 3: default: if (pause->tx_pause) qlcnic_gb_unset_gb3_mask(val); else qlcnic_gb_set_gb3_mask(val); break; } QLCWR32(adapter, QLCNIC_NIU_GB_PAUSE_CTL, val); } else if (adapter->ahw->port_type == QLCNIC_XGBE) { if (!pause->rx_pause || pause->autoneg) return -EOPNOTSUPP; if ((port < 0) || (port > QLCNIC_NIU_MAX_XG_PORTS)) return -EIO; val = QLCRD32(adapter, QLCNIC_NIU_XG_PAUSE_CTL); if (port == 0) { if (pause->tx_pause) qlcnic_xg_unset_xg0_mask(val); else qlcnic_xg_set_xg0_mask(val); } else { if (pause->tx_pause) qlcnic_xg_unset_xg1_mask(val); else qlcnic_xg_set_xg1_mask(val); } QLCWR32(adapter, QLCNIC_NIU_XG_PAUSE_CTL, val); } else { dev_err(&netdev->dev, "Unknown board type: %x\n", adapter->ahw->port_type); } return 0; }
int qlcnic_82xx_get_settings(struct qlcnic_adapter *adapter, struct ethtool_cmd *ecmd) { struct qlcnic_hardware_context *ahw = adapter->ahw; u32 speed, reg; int check_sfp_module = 0; u16 pcifn = ahw->pci_func; /* read which mode */ if (adapter->ahw->port_type == QLCNIC_GBE) { ecmd->supported = (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full); ecmd->advertising = (ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full); ethtool_cmd_speed_set(ecmd, adapter->ahw->link_speed); ecmd->duplex = adapter->ahw->link_duplex; ecmd->autoneg = adapter->ahw->link_autoneg; } else if (adapter->ahw->port_type == QLCNIC_XGBE) { u32 val = 0; val = QLCRD32(adapter, QLCNIC_PORT_MODE_ADDR); if (val == QLCNIC_PORT_MODE_802_3_AP) { ecmd->supported = SUPPORTED_1000baseT_Full; ecmd->advertising = ADVERTISED_1000baseT_Full; } else { ecmd->supported = SUPPORTED_10000baseT_Full; ecmd->advertising = ADVERTISED_10000baseT_Full; } if (netif_running(adapter->netdev) && ahw->has_link_events) { reg = QLCRD32(adapter, P3P_LINK_SPEED_REG(pcifn)); speed = P3P_LINK_SPEED_VAL(pcifn, reg); ahw->link_speed = speed * P3P_LINK_SPEED_MHZ; ethtool_cmd_speed_set(ecmd, ahw->link_speed); ecmd->autoneg = ahw->link_autoneg; ecmd->duplex = ahw->link_duplex; goto skip; } ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN); ecmd->duplex = DUPLEX_UNKNOWN; ecmd->autoneg = AUTONEG_DISABLE; } else return -EIO; skip: ecmd->phy_address = adapter->ahw->physical_port; ecmd->transceiver = XCVR_EXTERNAL; switch (adapter->ahw->board_type) { case QLCNIC_BRDTYPE_P3P_REF_QG: case QLCNIC_BRDTYPE_P3P_4_GB: case QLCNIC_BRDTYPE_P3P_4_GB_MM: ecmd->supported |= SUPPORTED_Autoneg; ecmd->advertising |= ADVERTISED_Autoneg; case QLCNIC_BRDTYPE_P3P_10G_CX4: case QLCNIC_BRDTYPE_P3P_10G_CX4_LP: case QLCNIC_BRDTYPE_P3P_10000_BASE_T: ecmd->supported |= SUPPORTED_TP; ecmd->advertising |= ADVERTISED_TP; ecmd->port = PORT_TP; ecmd->autoneg = adapter->ahw->link_autoneg; break; case QLCNIC_BRDTYPE_P3P_IMEZ: case QLCNIC_BRDTYPE_P3P_XG_LOM: case QLCNIC_BRDTYPE_P3P_HMEZ: ecmd->supported |= SUPPORTED_MII; ecmd->advertising |= ADVERTISED_MII; ecmd->port = PORT_MII; ecmd->autoneg = AUTONEG_DISABLE; break; case QLCNIC_BRDTYPE_P3P_10G_SFP_PLUS: case QLCNIC_BRDTYPE_P3P_10G_SFP_CT: case QLCNIC_BRDTYPE_P3P_10G_SFP_QT: ecmd->advertising |= ADVERTISED_TP; ecmd->supported |= SUPPORTED_TP; check_sfp_module = netif_running(adapter->netdev) && ahw->has_link_events; case QLCNIC_BRDTYPE_P3P_10G_XFP: ecmd->supported |= SUPPORTED_FIBRE; ecmd->advertising |= ADVERTISED_FIBRE; ecmd->port = PORT_FIBRE; ecmd->autoneg = AUTONEG_DISABLE; break; case QLCNIC_BRDTYPE_P3P_10G_TP: if (adapter->ahw->port_type == QLCNIC_XGBE) { ecmd->autoneg = AUTONEG_DISABLE; ecmd->supported |= (SUPPORTED_FIBRE | SUPPORTED_TP); ecmd->advertising |= (ADVERTISED_FIBRE | ADVERTISED_TP); ecmd->port = PORT_FIBRE; check_sfp_module = netif_running(adapter->netdev) && ahw->has_link_events; } else { ecmd->autoneg = AUTONEG_ENABLE; ecmd->supported |= (SUPPORTED_TP | SUPPORTED_Autoneg); ecmd->advertising |= (ADVERTISED_TP | ADVERTISED_Autoneg); ecmd->port = PORT_TP; } break; default: dev_err(&adapter->pdev->dev, "Unsupported board model %d\n", adapter->ahw->board_type); return -EIO; } if (check_sfp_module) { switch (adapter->ahw->module_type) { case LINKEVENT_MODULE_OPTICAL_UNKNOWN: case LINKEVENT_MODULE_OPTICAL_SRLR: case LINKEVENT_MODULE_OPTICAL_LRM: case LINKEVENT_MODULE_OPTICAL_SFP_1G: ecmd->port = PORT_FIBRE; break; case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE: case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN: case LINKEVENT_MODULE_TWINAX: ecmd->port = PORT_TP; break; default: ecmd->port = PORT_OTHER; } } return 0; }
static int qlcnic_set_dump(struct net_device *netdev, struct ethtool_dump *val) { int i; struct qlcnic_adapter *adapter = netdev_priv(netdev); struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump; u32 state; switch (val->flag) { case QLCNIC_FORCE_FW_DUMP_KEY: if (!fw_dump->tmpl_hdr) { netdev_err(netdev, "FW dump not supported\n"); return -ENOTSUPP; } if (!fw_dump->enable) { netdev_info(netdev, "FW dump not enabled\n"); return 0; } if (fw_dump->clr) { netdev_info(netdev, "Previous dump not cleared, not forcing dump\n"); return 0; } netdev_info(netdev, "Forcing a FW dump\n"); qlcnic_dev_request_reset(adapter, val->flag); break; case QLCNIC_DISABLE_FW_DUMP: if (fw_dump->enable && fw_dump->tmpl_hdr) { netdev_info(netdev, "Disabling FW dump\n"); fw_dump->enable = 0; } return 0; case QLCNIC_ENABLE_FW_DUMP: if (!fw_dump->tmpl_hdr) { netdev_err(netdev, "FW dump not supported\n"); return -ENOTSUPP; } if (!fw_dump->enable) { netdev_info(netdev, "Enabling FW dump\n"); fw_dump->enable = 1; } return 0; case QLCNIC_FORCE_FW_RESET: netdev_info(netdev, "Forcing a FW reset\n"); qlcnic_dev_request_reset(adapter, val->flag); adapter->flags &= ~QLCNIC_FW_RESET_OWNER; return 0; case QLCNIC_SET_QUIESCENT: case QLCNIC_RESET_QUIESCENT: state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); if (state == QLCNIC_DEV_FAILED || (state == QLCNIC_DEV_BADBAD)) netdev_info(netdev, "Device in FAILED state\n"); return 0; default: if (!fw_dump->tmpl_hdr) { netdev_err(netdev, "FW dump not supported\n"); return -ENOTSUPP; } for (i = 0; i < ARRAY_SIZE(qlcnic_fw_dump_level); i++) { if (val->flag == qlcnic_fw_dump_level[i]) { fw_dump->tmpl_hdr->drv_cap_mask = val->flag; netdev_info(netdev, "Driver mask changed to: 0x%x\n", fw_dump->tmpl_hdr->drv_cap_mask); return 0; } } netdev_info(netdev, "Invalid dump level: 0x%x\n", val->flag); return -EINVAL; } return 0; }