diff options
author | Jitendra Kalsaria <jitendra.kalsaria@qlogic.com> | 2013-12-17 18:01:54 +0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-12-18 02:09:44 +0400 |
commit | 2f514c5260d18722d03305c5849a59c4a6e7dcaf (patch) | |
tree | 238a5ec7e90de6abced967e95a4bedad4ad563ee /drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c | |
parent | 154d0c810c539cd4de84de07192930cce91b2565 (diff) | |
download | linux-2f514c5260d18722d03305c5849a59c4a6e7dcaf.tar.xz |
qlcnic: Support for 16 virtual NIC functions.
Extend virtual NIC functions from 8 to 16 for 84xx adapter.
Signed-off-by: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>
Signed-off-by: Manish Chopra <manish.chopra@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c')
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c | 118 |
1 files changed, 74 insertions, 44 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c index 1a9f8a400e50..b5296672c447 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c @@ -360,10 +360,28 @@ static ssize_t qlcnic_sysfs_write_mem(struct file *filp, struct kobject *kobj, 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; - 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) return i; } @@ -382,7 +400,6 @@ static int validate_pm_config(struct qlcnic_adapter *adapter, src_pci_func = pm_cfg[i].pci_func; dest_pci_func = pm_cfg[i].dest_npar; src_index = qlcnic_is_valid_nic_func(adapter, src_pci_func); - if (src_index < 0) return QL_STATUS_INVALID_PARAM; @@ -439,6 +456,8 @@ static ssize_t qlcnic_sysfs_write_pm_config(struct file *filp, for (i = 0; i < count; i++) { pci_func = pm_cfg[i].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; adapter->npars[index].enable_pm = !!pm_cfg[i].action; adapter->npars[index].dest_npar = id; @@ -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 qlcnic_adapter *adapter = dev_get_drvdata(dev); - struct qlcnic_pm_func_cfg pm_cfg[QLCNIC_MAX_PCI_FUNC]; - int i; + u32 pci_func_count = qlcnic_get_pci_func_count(adapter); + struct qlcnic_pm_func_cfg *pm_cfg; + int i, pm_cfg_size; 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; - memset(&pm_cfg, 0, - sizeof(struct qlcnic_pm_func_cfg) * QLCNIC_MAX_PCI_FUNC); + memset(buf, 0, pm_cfg_size); + 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; if (!adapter->npars[i].active) continue; @@ -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].pci_func = i; } - memcpy(buf, &pm_cfg, size); - return size; } static int validate_esw_config(struct qlcnic_adapter *adapter, 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; u8 pci_func; - int i, ret; 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 - 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++) { 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; if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC) @@ -600,6 +621,8 @@ static ssize_t qlcnic_sysfs_write_esw_config(struct file *file, for (i = 0; i < count; i++) { pci_func = esw_cfg[i].pci_func; index = qlcnic_is_valid_nic_func(adapter, pci_func); + if (index < 0) + return QL_STATUS_INVALID_PARAM; npar = &adapter->npars[index]; switch (esw_cfg[i].op_mode) { case QLCNIC_PORT_DEFAULTS: @@ -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 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; - if (size != sizeof(esw_cfg)) + esw_cfg_size = pci_func_count * sizeof(*esw_cfg); + if (size != esw_cfg_size) return QL_STATUS_INVALID_PARAM; - memset(&esw_cfg, 0, - sizeof(struct qlcnic_esw_func_cfg) * QLCNIC_MAX_PCI_FUNC); + memset(buf, 0, esw_cfg_size); + 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; if (!adapter->npars[i].active) continue; @@ -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])) return QL_STATUS_INVALID_PARAM; } - - memcpy(buf, &esw_cfg, size); - return size; } @@ -711,6 +734,8 @@ static ssize_t qlcnic_sysfs_write_npar_config(struct file *file, if (ret) return ret; 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].max_bw = nic_info.max_tx_bw; } @@ -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 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_npar_func_cfg np_cfg[QLCNIC_MAX_PCI_FUNC]; + size_t np_cfg_size; 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; memset(&nic_info, 0, sizeof(struct qlcnic_info)); - memset(&np_cfg, 0, - sizeof(struct qlcnic_npar_func_cfg) * QLCNIC_MAX_PCI_FUNC); + memset(buf, 0, np_cfg_size); + 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) continue; ret = qlcnic_get_nic_info(adapter, &nic_info, i); if (ret) return ret; - if (!adapter->npars[i].eswitch_status) continue; - np_cfg[i].pci_func = i; np_cfg[i].op_mode = (u8)nic_info.op_mode; np_cfg[i].port_num = nic_info.phys_port; @@ -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_rx_queues = nic_info.max_rx_ques; } - - memcpy(buf, &np_cfg, size); return size; } @@ -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 qlcnic_adapter *adapter = dev_get_drvdata(dev); + u32 pci_func_count = qlcnic_get_pci_func_count(adapter); struct qlcnic_esw_statistics port_stats; int ret; @@ -778,7 +803,7 @@ static ssize_t qlcnic_sysfs_get_port_stats(struct file *file, if (size != sizeof(struct qlcnic_esw_statistics)) return QL_STATUS_INVALID_PARAM; - if (offset >= QLCNIC_MAX_PCI_FUNC) + if (offset >= pci_func_count) return QL_STATUS_INVALID_PARAM; memset(&port_stats, 0, size); @@ -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 qlcnic_adapter *adapter = dev_get_drvdata(dev); + u32 pci_func_count = qlcnic_get_pci_func_count(adapter); int ret; if (qlcnic_83xx_check(adapter)) return QLC_STATUS_UNSUPPORTED_CMD; - if (offset >= QLCNIC_MAX_PCI_FUNC) + if (offset >= pci_func_count) return QL_STATUS_INVALID_PARAM; 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, { struct device *dev = container_of(kobj, struct device, kobj); 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; + size_t pci_info_sz, pci_cfg_sz; 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; - 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) 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); if (ret) { - kfree(pci_info); + vfree(pci_info); return ret; } - memset(&pci_cfg, 0, - sizeof(struct qlcnic_pci_func_cfg) * QLCNIC_MAX_PCI_FUNC); - - for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { + for (i = 0; i < pci_func_count; i++) { pci_cfg[i].pci_func = pci_info[i].id; pci_cfg[i].func_type = pci_info[i].type; 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, memcpy(&pci_cfg[i].def_mac_addr, &pci_info[i].mac, ETH_ALEN); } - memcpy(buf, &pci_cfg, size); - kfree(pci_info); + vfree(pci_info); return size; } |