Commit 2f514c52 authored by Jitendra Kalsaria's avatar Jitendra Kalsaria Committed by David S. Miller

qlcnic: Support for 16 virtual NIC functions.

Extend virtual NIC functions from 8 to 16 for 84xx adapter.
Signed-off-by: default avatarJitendra Kalsaria <jitendra.kalsaria@qlogic.com>
Signed-off-by: default avatarManish Chopra <manish.chopra@qlogic.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 154d0c81
...@@ -115,6 +115,10 @@ enum qlcnic_queue_type { ...@@ -115,6 +115,10 @@ enum qlcnic_queue_type {
#define QLCNIC_VNIC_MODE 0xFF #define QLCNIC_VNIC_MODE 0xFF
#define QLCNIC_DEFAULT_MODE 0x0 #define QLCNIC_DEFAULT_MODE 0x0
/* Virtual NIC function count */
#define QLC_DEFAULT_VNIC_COUNT 8
#define QLC_84XX_VNIC_COUNT 16
/* /*
* Following are the states of the Phantom. Phantom will set them and * Following are the states of the Phantom. Phantom will set them and
* Host will read to check if the fields are correct. * Host will read to check if the fields are correct.
...@@ -374,7 +378,7 @@ struct qlcnic_rx_buffer { ...@@ -374,7 +378,7 @@ struct qlcnic_rx_buffer {
#define QLCNIC_INTR_DEFAULT 0x04 #define QLCNIC_INTR_DEFAULT 0x04
#define QLCNIC_CONFIG_INTR_COALESCE 3 #define QLCNIC_CONFIG_INTR_COALESCE 3
#define QLCNIC_DEV_INFO_SIZE 1 #define QLCNIC_DEV_INFO_SIZE 2
struct qlcnic_nic_intr_coalesce { struct qlcnic_nic_intr_coalesce {
u8 type; u8 type;
...@@ -462,8 +466,10 @@ struct qlcnic_hardware_context { ...@@ -462,8 +466,10 @@ struct qlcnic_hardware_context {
u16 max_rx_ques; u16 max_rx_ques;
u16 max_mtu; u16 max_mtu;
u32 msg_enable; u32 msg_enable;
u16 act_pci_func; u16 total_nic_func;
u16 max_pci_func; u16 max_pci_func;
u32 max_vnic_func;
u32 total_pci_func;
u32 capabilities; u32 capabilities;
u32 extra_capability[3]; u32 extra_capability[3];
...@@ -857,7 +863,7 @@ struct qlcnic_mac_vlan_list { ...@@ -857,7 +863,7 @@ struct qlcnic_mac_vlan_list {
#define QLCNIC_FW_CAP2_HW_LRO_IPV6 BIT_3 #define QLCNIC_FW_CAP2_HW_LRO_IPV6 BIT_3
#define QLCNIC_FW_CAPABILITY_SET_DRV_VER BIT_5 #define QLCNIC_FW_CAPABILITY_SET_DRV_VER BIT_5
#define QLCNIC_FW_CAPABILITY_2_BEACON BIT_7 #define QLCNIC_FW_CAPABILITY_2_BEACON BIT_7
#define QLCNIC_FW_CAPABILITY_2_PER_PORT_ESWITCH_CFG BIT_8 #define QLCNIC_FW_CAPABILITY_2_PER_PORT_ESWITCH_CFG BIT_9
/* module types */ /* module types */
#define LINKEVENT_MODULE_NOT_PRESENT 1 #define LINKEVENT_MODULE_NOT_PRESENT 1
...@@ -1638,6 +1644,9 @@ int qlcnic_setup_netdev(struct qlcnic_adapter *, struct net_device *, int); ...@@ -1638,6 +1644,9 @@ int qlcnic_setup_netdev(struct qlcnic_adapter *, struct net_device *, int);
void qlcnic_set_netdev_features(struct qlcnic_adapter *, void qlcnic_set_netdev_features(struct qlcnic_adapter *,
struct qlcnic_esw_func_cfg *); struct qlcnic_esw_func_cfg *);
void qlcnic_sriov_vf_schedule_multi(struct net_device *); void qlcnic_sriov_vf_schedule_multi(struct net_device *);
int qlcnic_is_valid_nic_func(struct qlcnic_adapter *, u8);
int qlcnic_get_pci_func_type(struct qlcnic_adapter *, u16, u16 *, u16 *,
u16 *);
/* /*
* QLOGIC Board information * QLOGIC Board information
...@@ -2150,4 +2159,12 @@ static inline bool qlcnic_83xx_vf_check(struct qlcnic_adapter *adapter) ...@@ -2150,4 +2159,12 @@ static inline bool qlcnic_83xx_vf_check(struct qlcnic_adapter *adapter)
return (device == PCI_DEVICE_ID_QLOGIC_VF_QLE834X) ? true : false; return (device == PCI_DEVICE_ID_QLOGIC_VF_QLE834X) ? true : false;
} }
static inline u32 qlcnic_get_vnic_func_count(struct qlcnic_adapter *adapter)
{
if (qlcnic_84xx_check(adapter))
return QLC_84XX_VNIC_COUNT;
else
return QLC_DEFAULT_VNIC_COUNT;
}
#endif /* __QLCNIC_H_ */ #endif /* __QLCNIC_H_ */
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#define RSS_HASHTYPE_IP_TCP 0x3 #define RSS_HASHTYPE_IP_TCP 0x3
#define QLC_83XX_FW_MBX_CMD 0 #define QLC_83XX_FW_MBX_CMD 0
#define QLC_SKIP_INACTIVE_PCI_REGS 7
static const struct qlcnic_mailbox_metadata qlcnic_83xx_mbx_tbl[] = { static const struct qlcnic_mailbox_metadata qlcnic_83xx_mbx_tbl[] = {
{QLCNIC_CMD_CONFIGURE_IP_ADDR, 6, 1}, {QLCNIC_CMD_CONFIGURE_IP_ADDR, 6, 1},
...@@ -34,7 +35,7 @@ static const struct qlcnic_mailbox_metadata qlcnic_83xx_mbx_tbl[] = { ...@@ -34,7 +35,7 @@ static const struct qlcnic_mailbox_metadata qlcnic_83xx_mbx_tbl[] = {
{QLCNIC_CMD_READ_MAX_MTU, 4, 2}, {QLCNIC_CMD_READ_MAX_MTU, 4, 2},
{QLCNIC_CMD_READ_MAX_LRO, 4, 2}, {QLCNIC_CMD_READ_MAX_LRO, 4, 2},
{QLCNIC_CMD_MAC_ADDRESS, 4, 3}, {QLCNIC_CMD_MAC_ADDRESS, 4, 3},
{QLCNIC_CMD_GET_PCI_INFO, 1, 66}, {QLCNIC_CMD_GET_PCI_INFO, 1, 129},
{QLCNIC_CMD_GET_NIC_INFO, 2, 19}, {QLCNIC_CMD_GET_NIC_INFO, 2, 19},
{QLCNIC_CMD_SET_NIC_INFO, 32, 1}, {QLCNIC_CMD_SET_NIC_INFO, 32, 1},
{QLCNIC_CMD_GET_ESWITCH_CAPABILITY, 4, 3}, {QLCNIC_CMD_GET_ESWITCH_CAPABILITY, 4, 3},
...@@ -637,7 +638,7 @@ int qlcnic_83xx_get_port_info(struct qlcnic_adapter *adapter) ...@@ -637,7 +638,7 @@ int qlcnic_83xx_get_port_info(struct qlcnic_adapter *adapter)
void qlcnic_83xx_set_mac_filter_count(struct qlcnic_adapter *adapter) void qlcnic_83xx_set_mac_filter_count(struct qlcnic_adapter *adapter)
{ {
struct qlcnic_hardware_context *ahw = adapter->ahw; struct qlcnic_hardware_context *ahw = adapter->ahw;
u16 act_pci_fn = ahw->act_pci_func; u16 act_pci_fn = ahw->total_nic_func;
u16 count; u16 count;
ahw->max_mc_count = QLC_83XX_MAX_MC_COUNT; ahw->max_mc_count = QLC_83XX_MAX_MC_COUNT;
...@@ -2293,11 +2294,37 @@ int qlcnic_83xx_get_nic_info(struct qlcnic_adapter *adapter, ...@@ -2293,11 +2294,37 @@ int qlcnic_83xx_get_nic_info(struct qlcnic_adapter *adapter,
return err; return err;
} }
int qlcnic_get_pci_func_type(struct qlcnic_adapter *adapter, u16 type,
u16 *nic, u16 *fcoe, u16 *iscsi)
{
struct device *dev = &adapter->pdev->dev;
int err = 0;
switch (type) {
case QLCNIC_TYPE_NIC:
(*nic)++;
break;
case QLCNIC_TYPE_FCOE:
(*fcoe)++;
break;
case QLCNIC_TYPE_ISCSI:
(*iscsi)++;
break;
default:
dev_err(dev, "%s: Unknown PCI type[%x]\n",
__func__, type);
err = -EIO;
}
return err;
}
int qlcnic_83xx_get_pci_info(struct qlcnic_adapter *adapter, int qlcnic_83xx_get_pci_info(struct qlcnic_adapter *adapter,
struct qlcnic_pci_info *pci_info) struct qlcnic_pci_info *pci_info)
{ {
struct qlcnic_hardware_context *ahw = adapter->ahw; struct qlcnic_hardware_context *ahw = adapter->ahw;
struct device *dev = &adapter->pdev->dev; struct device *dev = &adapter->pdev->dev;
u16 nic = 0, fcoe = 0, iscsi = 0;
struct qlcnic_cmd_args cmd; struct qlcnic_cmd_args cmd;
int i, err = 0, j = 0; int i, err = 0, j = 0;
u32 temp; u32 temp;
...@@ -2308,16 +2335,20 @@ int qlcnic_83xx_get_pci_info(struct qlcnic_adapter *adapter, ...@@ -2308,16 +2335,20 @@ int qlcnic_83xx_get_pci_info(struct qlcnic_adapter *adapter,
err = qlcnic_issue_cmd(adapter, &cmd); err = qlcnic_issue_cmd(adapter, &cmd);
ahw->act_pci_func = 0; ahw->total_nic_func = 0;
if (err == QLCNIC_RCODE_SUCCESS) { if (err == QLCNIC_RCODE_SUCCESS) {
ahw->max_pci_func = cmd.rsp.arg[1] & 0xFF; ahw->max_pci_func = cmd.rsp.arg[1] & 0xFF;
for (i = 2, j = 0; j < QLCNIC_MAX_PCI_FUNC; j++, pci_info++) { for (i = 2, j = 0; j < ahw->max_vnic_func; j++, pci_info++) {
pci_info->id = cmd.rsp.arg[i] & 0xFFFF; pci_info->id = cmd.rsp.arg[i] & 0xFFFF;
pci_info->active = (cmd.rsp.arg[i] & 0xFFFF0000) >> 16; pci_info->active = (cmd.rsp.arg[i] & 0xFFFF0000) >> 16;
i++; i++;
if (!pci_info->active) {
i += QLC_SKIP_INACTIVE_PCI_REGS;
continue;
}
pci_info->type = cmd.rsp.arg[i] & 0xFFFF; pci_info->type = cmd.rsp.arg[i] & 0xFFFF;
if (pci_info->type == QLCNIC_TYPE_NIC) err = qlcnic_get_pci_func_type(adapter, pci_info->type,
ahw->act_pci_func++; &nic, &fcoe, &iscsi);
temp = (cmd.rsp.arg[i] & 0xFFFF0000) >> 16; temp = (cmd.rsp.arg[i] & 0xFFFF0000) >> 16;
pci_info->default_port = temp; pci_info->default_port = temp;
i++; i++;
...@@ -2335,6 +2366,13 @@ int qlcnic_83xx_get_pci_info(struct qlcnic_adapter *adapter, ...@@ -2335,6 +2366,13 @@ int qlcnic_83xx_get_pci_info(struct qlcnic_adapter *adapter,
err = -EIO; err = -EIO;
} }
ahw->total_nic_func = nic;
ahw->total_pci_func = nic + fcoe + iscsi;
if (ahw->total_nic_func == 0 || ahw->total_pci_func == 0) {
dev_err(dev, "%s: Invalid function count: total nic func[%x], total pci func[%x]\n",
__func__, ahw->total_nic_func, ahw->total_pci_func);
err = -EIO;
}
qlcnic_free_mbx_args(&cmd); qlcnic_free_mbx_args(&cmd);
return err; return err;
......
...@@ -107,7 +107,7 @@ static int qlcnic_83xx_init_mgmt_vnic(struct qlcnic_adapter *adapter) ...@@ -107,7 +107,7 @@ static int qlcnic_83xx_init_mgmt_vnic(struct qlcnic_adapter *adapter)
npar = adapter->npars; npar = adapter->npars;
for (i = 0; i < ahw->act_pci_func; i++, npar++) { for (i = 0; i < ahw->total_nic_func; i++, npar++) {
dev_info(dev, "id:%d active:%d type:%d port:%d min_bw:%d max_bw:%d mac_addr:%pM\n", dev_info(dev, "id:%d active:%d type:%d port:%d min_bw:%d max_bw:%d mac_addr:%pM\n",
npar->pci_func, npar->active, npar->type, npar->pci_func, npar->active, npar->type,
npar->phy_port, npar->min_bw, npar->max_bw, npar->phy_port, npar->min_bw, npar->max_bw,
...@@ -115,7 +115,7 @@ static int qlcnic_83xx_init_mgmt_vnic(struct qlcnic_adapter *adapter) ...@@ -115,7 +115,7 @@ static int qlcnic_83xx_init_mgmt_vnic(struct qlcnic_adapter *adapter)
} }
dev_info(dev, "Max functions = %d, active functions = %d\n", dev_info(dev, "Max functions = %d, active functions = %d\n",
ahw->max_pci_func, ahw->act_pci_func); ahw->max_pci_func, ahw->total_nic_func);
if (qlcnic_83xx_set_vnic_opmode(adapter)) if (qlcnic_83xx_set_vnic_opmode(adapter))
return err; return err;
......
...@@ -91,18 +91,6 @@ void qlcnic_free_mbx_args(struct qlcnic_cmd_args *cmd) ...@@ -91,18 +91,6 @@ void qlcnic_free_mbx_args(struct qlcnic_cmd_args *cmd)
cmd->rsp.arg = NULL; cmd->rsp.arg = NULL;
} }
static int qlcnic_is_valid_nic_func(struct qlcnic_adapter *adapter, u8 pci_func)
{
int i;
for (i = 0; i < adapter->ahw->act_pci_func; i++) {
if (adapter->npars[i].pci_func == pci_func)
return i;
}
return -1;
}
static u32 static u32
qlcnic_poll_rsp(struct qlcnic_adapter *adapter) qlcnic_poll_rsp(struct qlcnic_adapter *adapter)
{ {
...@@ -966,13 +954,15 @@ int qlcnic_82xx_set_nic_info(struct qlcnic_adapter *adapter, ...@@ -966,13 +954,15 @@ int qlcnic_82xx_set_nic_info(struct qlcnic_adapter *adapter,
int qlcnic_82xx_get_pci_info(struct qlcnic_adapter *adapter, int qlcnic_82xx_get_pci_info(struct qlcnic_adapter *adapter,
struct qlcnic_pci_info *pci_info) struct qlcnic_pci_info *pci_info)
{ {
int err = 0, i; struct qlcnic_hardware_context *ahw = adapter->ahw;
size_t npar_size = sizeof(struct qlcnic_pci_info_le);
size_t pci_size = npar_size * ahw->max_vnic_func;
u16 nic = 0, fcoe = 0, iscsi = 0;
struct qlcnic_pci_info_le *npar;
struct qlcnic_cmd_args cmd; struct qlcnic_cmd_args cmd;
dma_addr_t pci_info_dma_t; dma_addr_t pci_info_dma_t;
struct qlcnic_pci_info_le *npar;
void *pci_info_addr; void *pci_info_addr;
size_t npar_size = sizeof(struct qlcnic_pci_info_le); int err = 0, i;
size_t pci_size = npar_size * QLCNIC_MAX_PCI_FUNC;
pci_info_addr = dma_zalloc_coherent(&adapter->pdev->dev, pci_size, pci_info_addr = dma_zalloc_coherent(&adapter->pdev->dev, pci_size,
&pci_info_dma_t, GFP_KERNEL); &pci_info_dma_t, GFP_KERNEL);
...@@ -989,14 +979,16 @@ int qlcnic_82xx_get_pci_info(struct qlcnic_adapter *adapter, ...@@ -989,14 +979,16 @@ int qlcnic_82xx_get_pci_info(struct qlcnic_adapter *adapter,
cmd.req.arg[3] = pci_size; cmd.req.arg[3] = pci_size;
err = qlcnic_issue_cmd(adapter, &cmd); err = qlcnic_issue_cmd(adapter, &cmd);
adapter->ahw->act_pci_func = 0; ahw->total_nic_func = 0;
if (err == QLCNIC_RCODE_SUCCESS) { if (err == QLCNIC_RCODE_SUCCESS) {
for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++, npar++, pci_info++) { for (i = 0; i < ahw->max_vnic_func; i++, npar++, pci_info++) {
pci_info->id = le16_to_cpu(npar->id); pci_info->id = le16_to_cpu(npar->id);
pci_info->active = le16_to_cpu(npar->active); pci_info->active = le16_to_cpu(npar->active);
if (!pci_info->active)
continue;
pci_info->type = le16_to_cpu(npar->type); pci_info->type = le16_to_cpu(npar->type);
if (pci_info->type == QLCNIC_TYPE_NIC) err = qlcnic_get_pci_func_type(adapter, pci_info->type,
adapter->ahw->act_pci_func++; &nic, &fcoe, &iscsi);
pci_info->default_port = pci_info->default_port =
le16_to_cpu(npar->default_port); le16_to_cpu(npar->default_port);
pci_info->tx_min_bw = pci_info->tx_min_bw =
...@@ -1011,6 +1003,14 @@ int qlcnic_82xx_get_pci_info(struct qlcnic_adapter *adapter, ...@@ -1011,6 +1003,14 @@ int qlcnic_82xx_get_pci_info(struct qlcnic_adapter *adapter,
err = -EIO; err = -EIO;
} }
ahw->total_nic_func = nic;
ahw->total_pci_func = nic + fcoe + iscsi;
if (ahw->total_nic_func == 0 || ahw->total_pci_func == 0) {
dev_err(&adapter->pdev->dev,
"%s: Invalid function count: total nic func[%x], total pci func[%x]\n",
__func__, ahw->total_nic_func, ahw->total_pci_func);
err = -EIO;
}
qlcnic_free_mbx_args(&cmd); qlcnic_free_mbx_args(&cmd);
out_free_dma: out_free_dma:
dma_free_coherent(&adapter->pdev->dev, pci_size, pci_info_addr, dma_free_coherent(&adapter->pdev->dev, pci_size, pci_info_addr,
...@@ -1203,7 +1203,7 @@ int qlcnic_get_eswitch_stats(struct qlcnic_adapter *adapter, const u8 eswitch, ...@@ -1203,7 +1203,7 @@ int qlcnic_get_eswitch_stats(struct qlcnic_adapter *adapter, const u8 eswitch,
esw_stats->numbytes = QLCNIC_STATS_NOT_AVAIL; esw_stats->numbytes = QLCNIC_STATS_NOT_AVAIL;
esw_stats->context_id = eswitch; esw_stats->context_id = eswitch;
for (i = 0; i < adapter->ahw->act_pci_func; i++) { for (i = 0; i < adapter->ahw->total_nic_func; i++) {
if (adapter->npars[i].phy_port != eswitch) if (adapter->npars[i].phy_port != eswitch)
continue; continue;
...@@ -1236,15 +1236,16 @@ int qlcnic_get_eswitch_stats(struct qlcnic_adapter *adapter, const u8 eswitch, ...@@ -1236,15 +1236,16 @@ int qlcnic_get_eswitch_stats(struct qlcnic_adapter *adapter, const u8 eswitch,
int qlcnic_clear_esw_stats(struct qlcnic_adapter *adapter, const u8 func_esw, int qlcnic_clear_esw_stats(struct qlcnic_adapter *adapter, const u8 func_esw,
const u8 port, const u8 rx_tx) const u8 port, const u8 rx_tx)
{ {
struct qlcnic_hardware_context *ahw = adapter->ahw;
struct qlcnic_cmd_args cmd;
int err; int err;
u32 arg1; u32 arg1;
struct qlcnic_cmd_args cmd;
if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC) if (ahw->op_mode != QLCNIC_MGMT_FUNC)
return -EIO; return -EIO;
if (func_esw == QLCNIC_STATS_PORT) { if (func_esw == QLCNIC_STATS_PORT) {
if (port >= QLCNIC_MAX_PCI_FUNC) if (port >= ahw->max_vnic_func)
goto err_ret; goto err_ret;
} else if (func_esw == QLCNIC_STATS_ESWITCH) { } else if (func_esw == QLCNIC_STATS_ESWITCH) {
if (port >= QLCNIC_NIU_MAX_XG_PORTS) if (port >= QLCNIC_NIU_MAX_XG_PORTS)
......
...@@ -221,7 +221,7 @@ static const u32 ext_diag_registers[] = { ...@@ -221,7 +221,7 @@ static const u32 ext_diag_registers[] = {
-1 -1
}; };
#define QLCNIC_MGMT_API_VERSION 2 #define QLCNIC_MGMT_API_VERSION 3
#define QLCNIC_ETHTOOL_REGS_VER 4 #define QLCNIC_ETHTOOL_REGS_VER 4
static inline int qlcnic_get_ring_regs_len(struct qlcnic_adapter *adapter) static inline int qlcnic_get_ring_regs_len(struct qlcnic_adapter *adapter)
...@@ -519,6 +519,9 @@ qlcnic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p) ...@@ -519,6 +519,9 @@ qlcnic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
regs_buff[0] = (0xcafe0000 | (QLCNIC_DEV_INFO_SIZE & 0xffff)); regs_buff[0] = (0xcafe0000 | (QLCNIC_DEV_INFO_SIZE & 0xffff));
regs_buff[1] = QLCNIC_MGMT_API_VERSION; regs_buff[1] = QLCNIC_MGMT_API_VERSION;
if (adapter->ahw->capabilities & QLC_83XX_ESWITCH_CAPABILITY)
regs_buff[2] = adapter->ahw->max_vnic_func;
if (qlcnic_82xx_check(adapter)) if (qlcnic_82xx_check(adapter))
i = qlcnic_82xx_get_registers(adapter, regs_buff); i = qlcnic_82xx_get_registers(adapter, regs_buff);
else else
......
...@@ -698,7 +698,6 @@ struct qlcnic_legacy_intr_set { ...@@ -698,7 +698,6 @@ struct qlcnic_legacy_intr_set {
}; };
#define QLCNIC_MSIX_BASE 0x132110 #define QLCNIC_MSIX_BASE 0x132110
#define QLCNIC_MAX_PCI_FUNC 8
#define QLCNIC_MAX_VLAN_FILTERS 64 #define QLCNIC_MAX_VLAN_FILTERS 64
#define FLASH_ROM_WINDOW 0x42110030 #define FLASH_ROM_WINDOW 0x42110030
......
...@@ -799,25 +799,26 @@ static void qlcnic_cleanup_pci_map(struct qlcnic_hardware_context *ahw) ...@@ -799,25 +799,26 @@ static void qlcnic_cleanup_pci_map(struct qlcnic_hardware_context *ahw)
static int qlcnic_get_act_pci_func(struct qlcnic_adapter *adapter) static int qlcnic_get_act_pci_func(struct qlcnic_adapter *adapter)
{ {
struct qlcnic_hardware_context *ahw = adapter->ahw;
struct qlcnic_pci_info *pci_info; struct qlcnic_pci_info *pci_info;
int ret; int ret;
if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) { if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) {
switch (adapter->ahw->port_type) { switch (ahw->port_type) {
case QLCNIC_GBE: case QLCNIC_GBE:
adapter->ahw->act_pci_func = QLCNIC_NIU_MAX_GBE_PORTS; ahw->total_nic_func = QLCNIC_NIU_MAX_GBE_PORTS;
break; break;
case QLCNIC_XGBE: case QLCNIC_XGBE:
adapter->ahw->act_pci_func = QLCNIC_NIU_MAX_XG_PORTS; ahw->total_nic_func = QLCNIC_NIU_MAX_XG_PORTS;
break; break;
} }
return 0; return 0;
} }
if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC) if (ahw->op_mode == QLCNIC_MGMT_FUNC)
return 0; return 0;
pci_info = kcalloc(QLCNIC_MAX_PCI_FUNC, sizeof(*pci_info), GFP_KERNEL); pci_info = kcalloc(ahw->max_vnic_func, sizeof(*pci_info), GFP_KERNEL);
if (!pci_info) if (!pci_info)
return -ENOMEM; return -ENOMEM;
...@@ -845,12 +846,13 @@ static bool qlcnic_port_eswitch_cfg_capability(struct qlcnic_adapter *adapter) ...@@ -845,12 +846,13 @@ static bool qlcnic_port_eswitch_cfg_capability(struct qlcnic_adapter *adapter)
int qlcnic_init_pci_info(struct qlcnic_adapter *adapter) int qlcnic_init_pci_info(struct qlcnic_adapter *adapter)
{ {
struct qlcnic_hardware_context *ahw = adapter->ahw;
struct qlcnic_pci_info *pci_info; struct qlcnic_pci_info *pci_info;
int i, id = 0, ret = 0, j = 0; int i, id = 0, ret = 0, j = 0;
u16 act_pci_func; u16 act_pci_func;
u8 pfn; u8 pfn;
pci_info = kcalloc(QLCNIC_MAX_PCI_FUNC, sizeof(*pci_info), GFP_KERNEL); pci_info = kcalloc(ahw->max_vnic_func, sizeof(*pci_info), GFP_KERNEL);
if (!pci_info) if (!pci_info)
return -ENOMEM; return -ENOMEM;
...@@ -858,7 +860,7 @@ int qlcnic_init_pci_info(struct qlcnic_adapter *adapter) ...@@ -858,7 +860,7 @@ int qlcnic_init_pci_info(struct qlcnic_adapter *adapter)
if (ret) if (ret)
goto err_pci_info; goto err_pci_info;
act_pci_func = adapter->ahw->act_pci_func; act_pci_func = ahw->total_nic_func;
adapter->npars = kzalloc(sizeof(struct qlcnic_npar_info) * adapter->npars = kzalloc(sizeof(struct qlcnic_npar_info) *
act_pci_func, GFP_KERNEL); act_pci_func, GFP_KERNEL);
...@@ -874,10 +876,10 @@ int qlcnic_init_pci_info(struct qlcnic_adapter *adapter) ...@@ -874,10 +876,10 @@ int qlcnic_init_pci_info(struct qlcnic_adapter *adapter)
goto err_npars; goto err_npars;
} }
for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { for (i = 0; i < ahw->max_vnic_func; i++) {
pfn = pci_info[i].id; pfn = pci_info[i].id;
if (pfn >= QLCNIC_MAX_PCI_FUNC) { if (pfn >= ahw->max_vnic_func) {
ret = QL_STATUS_INVALID_PARAM; ret = QL_STATUS_INVALID_PARAM;
goto err_eswitch; goto err_eswitch;
} }
...@@ -1344,7 +1346,7 @@ int qlcnic_set_default_offload_settings(struct qlcnic_adapter *adapter) ...@@ -1344,7 +1346,7 @@ int qlcnic_set_default_offload_settings(struct qlcnic_adapter *adapter)
if (adapter->need_fw_reset) if (adapter->need_fw_reset)
return 0; return 0;
for (i = 0; i < adapter->ahw->act_pci_func; i++) { for (i = 0; i < adapter->ahw->total_nic_func; i++) {
if (!adapter->npars[i].eswitch_status) if (!adapter->npars[i].eswitch_status)
continue; continue;
...@@ -1407,7 +1409,7 @@ int qlcnic_reset_npar_config(struct qlcnic_adapter *adapter) ...@@ -1407,7 +1409,7 @@ int qlcnic_reset_npar_config(struct qlcnic_adapter *adapter)
return 0; return 0;
/* Set the NPAR config data after FW reset */ /* Set the NPAR config data after FW reset */
for (i = 0; i < adapter->ahw->act_pci_func; i++) { for (i = 0; i < adapter->ahw->total_nic_func; i++) {
npar = &adapter->npars[i]; npar = &adapter->npars[i];
pci_func = npar->pci_func; pci_func = npar->pci_func;
if (!adapter->npars[i].eswitch_status) if (!adapter->npars[i].eswitch_status)
...@@ -2036,7 +2038,7 @@ qlcnic_reset_context(struct qlcnic_adapter *adapter) ...@@ -2036,7 +2038,7 @@ qlcnic_reset_context(struct qlcnic_adapter *adapter)
void qlcnic_82xx_set_mac_filter_count(struct qlcnic_adapter *adapter) void qlcnic_82xx_set_mac_filter_count(struct qlcnic_adapter *adapter)
{ {
struct qlcnic_hardware_context *ahw = adapter->ahw; struct qlcnic_hardware_context *ahw = adapter->ahw;
u16 act_pci_fn = ahw->act_pci_func; u16 act_pci_fn = ahw->total_nic_func;
u16 count; u16 count;
ahw->max_mc_count = QLCNIC_MAX_MC_COUNT; ahw->max_mc_count = QLCNIC_MAX_MC_COUNT;
...@@ -2288,7 +2290,8 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -2288,7 +2290,8 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_out_free_wq; goto err_out_free_wq;
adapter->dev_rst_time = jiffies; adapter->dev_rst_time = jiffies;
adapter->ahw->revision_id = pdev->revision; ahw->revision_id = pdev->revision;
ahw->max_vnic_func = qlcnic_get_vnic_func_count(adapter);
if (qlcnic_mac_learn == FDB_MAC_LEARN) if (qlcnic_mac_learn == FDB_MAC_LEARN)
adapter->fdb_mac_learn = true; adapter->fdb_mac_learn = true;
else if (qlcnic_mac_learn == DRV_MAC_LEARN) else if (qlcnic_mac_learn == DRV_MAC_LEARN)
...@@ -2638,7 +2641,7 @@ void qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter) ...@@ -2638,7 +2641,7 @@ void qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter)
if (adapter->fhash.fmax && adapter->fhash.fhead) if (adapter->fhash.fmax && adapter->fhash.fhead)
return; return;
act_pci_func = adapter->ahw->act_pci_func; act_pci_func = adapter->ahw->total_nic_func;
spin_lock_init(&adapter->mac_learn_lock); spin_lock_init(&adapter->mac_learn_lock);
spin_lock_init(&adapter->rx_mac_learn_lock); spin_lock_init(&adapter->rx_mac_learn_lock);
......
...@@ -360,10 +360,28 @@ static ssize_t qlcnic_sysfs_write_mem(struct file *filp, struct kobject *kobj, ...@@ -360,10 +360,28 @@ static ssize_t qlcnic_sysfs_write_mem(struct file *filp, struct kobject *kobj,
return size; return size;
} }
static int qlcnic_is_valid_nic_func(struct qlcnic_adapter *adapter, u8 pci_func) static u32 qlcnic_get_pci_func_count(struct qlcnic_adapter *adapter)
{ {
struct qlcnic_hardware_context *ahw = adapter->ahw;
u32 count = 0;
if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
return ahw->total_nic_func;
if (ahw->total_pci_func <= QLC_DEFAULT_VNIC_COUNT)
count = QLC_DEFAULT_VNIC_COUNT;
else
count = ahw->max_vnic_func;
return count;
}
int qlcnic_is_valid_nic_func(struct qlcnic_adapter *adapter, u8 pci_func)
{
u32 pci_func_count = qlcnic_get_pci_func_count(adapter);
int i; int i;
for (i = 0; i < adapter->ahw->act_pci_func; i++) {
for (i = 0; i < pci_func_count; i++) {
if (adapter->npars[i].pci_func == pci_func) if (adapter->npars[i].pci_func == pci_func)
return i; return i;
} }
...@@ -382,7 +400,6 @@ static int validate_pm_config(struct qlcnic_adapter *adapter, ...@@ -382,7 +400,6 @@ static int validate_pm_config(struct qlcnic_adapter *adapter,
src_pci_func = pm_cfg[i].pci_func; src_pci_func = pm_cfg[i].pci_func;
dest_pci_func = pm_cfg[i].dest_npar; dest_pci_func = pm_cfg[i].dest_npar;
src_index = qlcnic_is_valid_nic_func(adapter, src_pci_func); src_index = qlcnic_is_valid_nic_func(adapter, src_pci_func);
if (src_index < 0) if (src_index < 0)
return QL_STATUS_INVALID_PARAM; return QL_STATUS_INVALID_PARAM;
...@@ -439,6 +456,8 @@ static ssize_t qlcnic_sysfs_write_pm_config(struct file *filp, ...@@ -439,6 +456,8 @@ static ssize_t qlcnic_sysfs_write_pm_config(struct file *filp,
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
pci_func = pm_cfg[i].pci_func; pci_func = pm_cfg[i].pci_func;
index = qlcnic_is_valid_nic_func(adapter, pci_func); index = qlcnic_is_valid_nic_func(adapter, pci_func);
if (index < 0)
return QL_STATUS_INVALID_PARAM;
id = adapter->npars[index].phy_port; id = adapter->npars[index].phy_port;
adapter->npars[index].enable_pm = !!pm_cfg[i].action; adapter->npars[index].enable_pm = !!pm_cfg[i].action;
adapter->npars[index].dest_npar = id; adapter->npars[index].dest_npar = id;
...@@ -455,17 +474,19 @@ static ssize_t qlcnic_sysfs_read_pm_config(struct file *filp, ...@@ -455,17 +474,19 @@ static ssize_t qlcnic_sysfs_read_pm_config(struct file *filp,
{ {
struct device *dev = container_of(kobj, struct device, kobj); struct device *dev = container_of(kobj, struct device, kobj);
struct qlcnic_adapter *adapter = dev_get_drvdata(dev); struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
struct qlcnic_pm_func_cfg pm_cfg[QLCNIC_MAX_PCI_FUNC]; u32 pci_func_count = qlcnic_get_pci_func_count(adapter);
int i; struct qlcnic_pm_func_cfg *pm_cfg;
int i, pm_cfg_size;
u8 pci_func; u8 pci_func;
if (size != sizeof(pm_cfg)) pm_cfg_size = pci_func_count * sizeof(*pm_cfg);
if (size != pm_cfg_size)
return QL_STATUS_INVALID_PARAM; return QL_STATUS_INVALID_PARAM;
memset(&pm_cfg, 0, memset(buf, 0, pm_cfg_size);
sizeof(struct qlcnic_pm_func_cfg) * QLCNIC_MAX_PCI_FUNC); pm_cfg = (struct qlcnic_pm_func_cfg *)buf;
for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { for (i = 0; i < pci_func_count; i++) {
pci_func = adapter->npars[i].pci_func; pci_func = adapter->npars[i].pci_func;
if (!adapter->npars[i].active) if (!adapter->npars[i].active)
continue; continue;
...@@ -477,26 +498,26 @@ static ssize_t qlcnic_sysfs_read_pm_config(struct file *filp, ...@@ -477,26 +498,26 @@ static ssize_t qlcnic_sysfs_read_pm_config(struct file *filp,
pm_cfg[pci_func].dest_npar = 0; pm_cfg[pci_func].dest_npar = 0;
pm_cfg[pci_func].pci_func = i; pm_cfg[pci_func].pci_func = i;
} }
memcpy(buf, &pm_cfg, size);
return size; return size;
} }
static int validate_esw_config(struct qlcnic_adapter *adapter, static int validate_esw_config(struct qlcnic_adapter *adapter,
struct qlcnic_esw_func_cfg *esw_cfg, int count) struct qlcnic_esw_func_cfg *esw_cfg, int count)
{ {
u32 pci_func_count = qlcnic_get_pci_func_count(adapter);
struct qlcnic_hardware_context *ahw = adapter->ahw;
int i, ret;
u32 op_mode; u32 op_mode;
u8 pci_func; u8 pci_func;
int i, ret;
if (qlcnic_82xx_check(adapter)) if (qlcnic_82xx_check(adapter))
op_mode = readl(adapter->ahw->pci_base0 + QLCNIC_DRV_OP_MODE); op_mode = readl(ahw->pci_base0 + QLCNIC_DRV_OP_MODE);
else else
op_mode = QLCRDX(adapter->ahw, QLC_83XX_DRV_OP_MODE); op_mode = QLCRDX(ahw, QLC_83XX_DRV_OP_MODE);
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
pci_func = esw_cfg[i].pci_func; pci_func = esw_cfg[i].pci_func;
if (pci_func >= QLCNIC_MAX_PCI_FUNC) if (pci_func >= pci_func_count)
return QL_STATUS_INVALID_PARAM; return QL_STATUS_INVALID_PARAM;
if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC) if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC)
...@@ -600,6 +621,8 @@ static ssize_t qlcnic_sysfs_write_esw_config(struct file *file, ...@@ -600,6 +621,8 @@ static ssize_t qlcnic_sysfs_write_esw_config(struct file *file,
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
pci_func = esw_cfg[i].pci_func; pci_func = esw_cfg[i].pci_func;
index = qlcnic_is_valid_nic_func(adapter, pci_func); index = qlcnic_is_valid_nic_func(adapter, pci_func);
if (index < 0)
return QL_STATUS_INVALID_PARAM;
npar = &adapter->npars[index]; npar = &adapter->npars[index];
switch (esw_cfg[i].op_mode) { switch (esw_cfg[i].op_mode) {
case QLCNIC_PORT_DEFAULTS: case QLCNIC_PORT_DEFAULTS:
...@@ -629,16 +652,19 @@ static ssize_t qlcnic_sysfs_read_esw_config(struct file *file, ...@@ -629,16 +652,19 @@ static ssize_t qlcnic_sysfs_read_esw_config(struct file *file,
{ {
struct device *dev = container_of(kobj, struct device, kobj); struct device *dev = container_of(kobj, struct device, kobj);
struct qlcnic_adapter *adapter = dev_get_drvdata(dev); struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
struct qlcnic_esw_func_cfg esw_cfg[QLCNIC_MAX_PCI_FUNC]; u32 pci_func_count = qlcnic_get_pci_func_count(adapter);
struct qlcnic_esw_func_cfg *esw_cfg;
size_t esw_cfg_size;
u8 i, pci_func; u8 i, pci_func;
if (size != sizeof(esw_cfg)) esw_cfg_size = pci_func_count * sizeof(*esw_cfg);
if (size != esw_cfg_size)
return QL_STATUS_INVALID_PARAM; return QL_STATUS_INVALID_PARAM;
memset(&esw_cfg, 0, memset(buf, 0, esw_cfg_size);
sizeof(struct qlcnic_esw_func_cfg) * QLCNIC_MAX_PCI_FUNC); esw_cfg = (struct qlcnic_esw_func_cfg *)buf;
for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { for (i = 0; i < pci_func_count; i++) {
pci_func = adapter->npars[i].pci_func; pci_func = adapter->npars[i].pci_func;
if (!adapter->npars[i].active) if (!adapter->npars[i].active)
continue; continue;
...@@ -650,9 +676,6 @@ static ssize_t qlcnic_sysfs_read_esw_config(struct file *file, ...@@ -650,9 +676,6 @@ static ssize_t qlcnic_sysfs_read_esw_config(struct file *file,
if (qlcnic_get_eswitch_port_config(adapter, &esw_cfg[pci_func])) if (qlcnic_get_eswitch_port_config(adapter, &esw_cfg[pci_func]))
return QL_STATUS_INVALID_PARAM; return QL_STATUS_INVALID_PARAM;
} }
memcpy(buf, &esw_cfg, size);
return size; return size;
} }
...@@ -711,6 +734,8 @@ static ssize_t qlcnic_sysfs_write_npar_config(struct file *file, ...@@ -711,6 +734,8 @@ static ssize_t qlcnic_sysfs_write_npar_config(struct file *file,
if (ret) if (ret)
return ret; return ret;
index = qlcnic_is_valid_nic_func(adapter, pci_func); index = qlcnic_is_valid_nic_func(adapter, pci_func);
if (index < 0)
return QL_STATUS_INVALID_PARAM;
adapter->npars[index].min_bw = nic_info.min_tx_bw; adapter->npars[index].min_bw = nic_info.min_tx_bw;
adapter->npars[index].max_bw = nic_info.max_tx_bw; adapter->npars[index].max_bw = nic_info.max_tx_bw;
} }
...@@ -726,27 +751,28 @@ static ssize_t qlcnic_sysfs_read_npar_config(struct file *file, ...@@ -726,27 +751,28 @@ static ssize_t qlcnic_sysfs_read_npar_config(struct file *file,
{ {
struct device *dev = container_of(kobj, struct device, kobj); struct device *dev = container_of(kobj, struct device, kobj);
struct qlcnic_adapter *adapter = dev_get_drvdata(dev); struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
u32 pci_func_count = qlcnic_get_pci_func_count(adapter);
struct qlcnic_npar_func_cfg *np_cfg;
struct qlcnic_info nic_info; struct qlcnic_info nic_info;
struct qlcnic_npar_func_cfg np_cfg[QLCNIC_MAX_PCI_FUNC]; size_t np_cfg_size;
int i, ret; int i, ret;
if (size != sizeof(np_cfg)) np_cfg_size = pci_func_count * sizeof(*np_cfg);
if (size != np_cfg_size)
return QL_STATUS_INVALID_PARAM; return QL_STATUS_INVALID_PARAM;
memset(&nic_info, 0, sizeof(struct qlcnic_info)); memset(&nic_info, 0, sizeof(struct qlcnic_info));
memset(&np_cfg, 0, memset(buf, 0, np_cfg_size);
sizeof(struct qlcnic_npar_func_cfg) * QLCNIC_MAX_PCI_FUNC); np_cfg = (struct qlcnic_npar_func_cfg *)buf;
for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { for (i = 0; i < pci_func_count; i++) {
if (qlcnic_is_valid_nic_func(adapter, i) < 0) if (qlcnic_is_valid_nic_func(adapter, i) < 0)
continue; continue;
ret = qlcnic_get_nic_info(adapter, &nic_info, i); ret = qlcnic_get_nic_info(adapter, &nic_info, i);
if (ret) if (ret)
return ret; return ret;
if (!adapter->npars[i].eswitch_status) if (!adapter->npars[i].eswitch_status)
continue; continue;
np_cfg[i].pci_func = i; np_cfg[i].pci_func = i;
np_cfg[i].op_mode = (u8)nic_info.op_mode; np_cfg[i].op_mode = (u8)nic_info.op_mode;
np_cfg[i].port_num = nic_info.phys_port; np_cfg[i].port_num = nic_info.phys_port;
...@@ -756,8 +782,6 @@ static ssize_t qlcnic_sysfs_read_npar_config(struct file *file, ...@@ -756,8 +782,6 @@ static ssize_t qlcnic_sysfs_read_npar_config(struct file *file,
np_cfg[i].max_tx_queues = nic_info.max_tx_ques; np_cfg[i].max_tx_queues = nic_info.max_tx_ques;
np_cfg[i].max_rx_queues = nic_info.max_rx_ques; np_cfg[i].max_rx_queues = nic_info.max_rx_ques;
} }
memcpy(buf, &np_cfg, size);
return size; return size;
} }
...@@ -769,6 +793,7 @@ static ssize_t qlcnic_sysfs_get_port_stats(struct file *file, ...@@ -769,6 +793,7 @@ static ssize_t qlcnic_sysfs_get_port_stats(struct file *file,
{ {
struct device *dev = container_of(kobj, struct device, kobj); struct device *dev = container_of(kobj, struct device, kobj);
struct qlcnic_adapter *adapter = dev_get_drvdata(dev); struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
u32 pci_func_count = qlcnic_get_pci_func_count(adapter);
struct qlcnic_esw_statistics port_stats; struct qlcnic_esw_statistics port_stats;
int ret; int ret;
...@@ -778,7 +803,7 @@ static ssize_t qlcnic_sysfs_get_port_stats(struct file *file, ...@@ -778,7 +803,7 @@ static ssize_t qlcnic_sysfs_get_port_stats(struct file *file,
if (size != sizeof(struct qlcnic_esw_statistics)) if (size != sizeof(struct qlcnic_esw_statistics))
return QL_STATUS_INVALID_PARAM; return QL_STATUS_INVALID_PARAM;
if (offset >= QLCNIC_MAX_PCI_FUNC) if (offset >= pci_func_count)
return QL_STATUS_INVALID_PARAM; return QL_STATUS_INVALID_PARAM;
memset(&port_stats, 0, size); memset(&port_stats, 0, size);
...@@ -869,12 +894,13 @@ static ssize_t qlcnic_sysfs_clear_port_stats(struct file *file, ...@@ -869,12 +894,13 @@ static ssize_t qlcnic_sysfs_clear_port_stats(struct file *file,
struct device *dev = container_of(kobj, struct device, kobj); struct device *dev = container_of(kobj, struct device, kobj);
struct qlcnic_adapter *adapter = dev_get_drvdata(dev); struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
u32 pci_func_count = qlcnic_get_pci_func_count(adapter);
int ret; int ret;
if (qlcnic_83xx_check(adapter)) if (qlcnic_83xx_check(adapter))
return QLC_STATUS_UNSUPPORTED_CMD; return QLC_STATUS_UNSUPPORTED_CMD;
if (offset >= QLCNIC_MAX_PCI_FUNC) if (offset >= pci_func_count)
return QL_STATUS_INVALID_PARAM; return QL_STATUS_INVALID_PARAM;
ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_PORT, offset, ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_PORT, offset,
...@@ -898,27 +924,32 @@ static ssize_t qlcnic_sysfs_read_pci_config(struct file *file, ...@@ -898,27 +924,32 @@ static ssize_t qlcnic_sysfs_read_pci_config(struct file *file,
{ {
struct device *dev = container_of(kobj, struct device, kobj); struct device *dev = container_of(kobj, struct device, kobj);
struct qlcnic_adapter *adapter = dev_get_drvdata(dev); struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
struct qlcnic_pci_func_cfg pci_cfg[QLCNIC_MAX_PCI_FUNC]; u32 pci_func_count = qlcnic_get_pci_func_count(adapter);
struct qlcnic_pci_func_cfg *pci_cfg;
struct qlcnic_pci_info *pci_info; struct qlcnic_pci_info *pci_info;
size_t pci_info_sz, pci_cfg_sz;
int i, ret; int i, ret;
if (size != sizeof(pci_cfg)) pci_cfg_sz = pci_func_count * sizeof(*pci_cfg);
if (size != pci_cfg_sz)
return QL_STATUS_INVALID_PARAM; return QL_STATUS_INVALID_PARAM;
pci_info = kcalloc(QLCNIC_MAX_PCI_FUNC, sizeof(*pci_info), GFP_KERNEL); pci_info_sz = pci_func_count * sizeof(*pci_info);
pci_info = vmalloc(pci_info_sz);
if (!pci_info) if (!pci_info)
return -ENOMEM; return -ENOMEM;
memset(pci_info, 0, pci_info_sz);
memset(buf, 0, pci_cfg_sz);
pci_cfg = (struct qlcnic_pci_func_cfg *)buf;
ret = qlcnic_get_pci_info(adapter, pci_info); ret = qlcnic_get_pci_info(adapter, pci_info);
if (ret) { if (ret) {
kfree(pci_info); vfree(pci_info);
return ret; return ret;
} }
memset(&pci_cfg, 0, for (i = 0; i < pci_func_count; i++) {
sizeof(struct qlcnic_pci_func_cfg) * QLCNIC_MAX_PCI_FUNC);
for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
pci_cfg[i].pci_func = pci_info[i].id; pci_cfg[i].pci_func = pci_info[i].id;
pci_cfg[i].func_type = pci_info[i].type; pci_cfg[i].func_type = pci_info[i].type;
pci_cfg[i].port_num = pci_info[i].default_port; pci_cfg[i].port_num = pci_info[i].default_port;
...@@ -927,8 +958,7 @@ static ssize_t qlcnic_sysfs_read_pci_config(struct file *file, ...@@ -927,8 +958,7 @@ static ssize_t qlcnic_sysfs_read_pci_config(struct file *file,
memcpy(&pci_cfg[i].def_mac_addr, &pci_info[i].mac, ETH_ALEN); memcpy(&pci_cfg[i].def_mac_addr, &pci_info[i].mac, ETH_ALEN);
} }
memcpy(buf, &pci_cfg, size); vfree(pci_info);
kfree(pci_info);
return size; return size;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment