提交 bff57d8e 编写于 作者: S Sony Chacko 提交者: David S. Miller

qlcnic: update NIC partition interface routines

Refactor 82xx driver to support new adapter
Update routines to support variable number of NIC partitions
Signed-off-by: NRajesh Borundia <rajesh.borundia@qlogic.com>
Signed-off-by: NSony Chacko <sony.chacko@qlogic.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 22999798
...@@ -1051,6 +1051,7 @@ struct qlcnic_npar_info { ...@@ -1051,6 +1051,7 @@ struct qlcnic_npar_info {
u8 mac_anti_spoof; u8 mac_anti_spoof;
u8 promisc_mode; u8 promisc_mode;
u8 offload_flags; u8 offload_flags;
u8 pci_func;
}; };
struct qlcnic_eswitch { struct qlcnic_eswitch {
......
...@@ -7,6 +7,18 @@ ...@@ -7,6 +7,18 @@
#include "qlcnic.h" #include "qlcnic.h"
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)
{ {
...@@ -817,11 +829,14 @@ int qlcnic_get_pci_info(struct qlcnic_adapter *adapter, ...@@ -817,11 +829,14 @@ int qlcnic_get_pci_info(struct qlcnic_adapter *adapter,
qlcnic_issue_cmd(adapter, &cmd); qlcnic_issue_cmd(adapter, &cmd);
err = cmd.rsp.cmd; err = cmd.rsp.cmd;
adapter->ahw->act_pci_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 < QLCNIC_MAX_PCI_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);
pci_info->type = le16_to_cpu(npar->type); pci_info->type = le16_to_cpu(npar->type);
if (pci_info->type == QLCNIC_TYPE_NIC)
adapter->ahw->act_pci_func++;
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 =
...@@ -1016,12 +1031,13 @@ int qlcnic_get_eswitch_stats(struct qlcnic_adapter *adapter, const u8 eswitch, ...@@ -1016,12 +1031,13 @@ 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 < QLCNIC_MAX_PCI_FUNC; i++) { for (i = 0; i < adapter->ahw->act_pci_func; i++) {
if (adapter->npars[i].phy_port != eswitch) if (adapter->npars[i].phy_port != eswitch)
continue; continue;
memset(&port_stats, 0, sizeof(struct __qlcnic_esw_statistics)); memset(&port_stats, 0, sizeof(struct __qlcnic_esw_statistics));
if (qlcnic_get_port_stats(adapter, i, rx_tx, &port_stats)) if (qlcnic_get_port_stats(adapter, adapter->npars[i].pci_func,
rx_tx, &port_stats))
continue; continue;
esw_stats->size = port_stats.size; esw_stats->size = port_stats.size;
...@@ -1120,7 +1136,7 @@ op_type = 1 for port vlan_id ...@@ -1120,7 +1136,7 @@ op_type = 1 for port vlan_id
int qlcnic_config_switch_port(struct qlcnic_adapter *adapter, int qlcnic_config_switch_port(struct qlcnic_adapter *adapter,
struct qlcnic_esw_func_cfg *esw_cfg) struct qlcnic_esw_func_cfg *esw_cfg)
{ {
int err = -EIO; int err = -EIO, index;
u32 arg1, arg2 = 0; u32 arg1, arg2 = 0;
struct qlcnic_cmd_args cmd; struct qlcnic_cmd_args cmd;
u8 pci_func; u8 pci_func;
...@@ -1128,7 +1144,10 @@ int qlcnic_config_switch_port(struct qlcnic_adapter *adapter, ...@@ -1128,7 +1144,10 @@ int qlcnic_config_switch_port(struct qlcnic_adapter *adapter,
if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC) if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC)
return err; return err;
pci_func = esw_cfg->pci_func; pci_func = esw_cfg->pci_func;
arg1 = (adapter->npars[pci_func].phy_port & BIT_0); index = qlcnic_is_valid_nic_func(adapter, pci_func);
if (index < 0)
return err;
arg1 = (adapter->npars[index].phy_port & BIT_0);
arg1 |= (pci_func << 8); arg1 |= (pci_func << 8);
if (__qlcnic_get_eswitch_port_config(adapter, &arg1, &arg2)) if (__qlcnic_get_eswitch_port_config(adapter, &arg1, &arg2))
...@@ -1192,11 +1211,17 @@ qlcnic_get_eswitch_port_config(struct qlcnic_adapter *adapter, ...@@ -1192,11 +1211,17 @@ qlcnic_get_eswitch_port_config(struct qlcnic_adapter *adapter,
struct qlcnic_esw_func_cfg *esw_cfg) struct qlcnic_esw_func_cfg *esw_cfg)
{ {
u32 arg1, arg2; u32 arg1, arg2;
int index;
u8 phy_port; u8 phy_port;
if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC)
phy_port = adapter->npars[esw_cfg->pci_func].phy_port; if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC) {
else index = qlcnic_is_valid_nic_func(adapter, esw_cfg->pci_func);
if (index < 0)
return -EIO;
phy_port = adapter->npars[index].phy_port;
} else {
phy_port = adapter->ahw->physical_port; phy_port = adapter->ahw->physical_port;
}
arg1 = phy_port; arg1 = phy_port;
arg1 |= (esw_cfg->pci_func << 8); arg1 |= (esw_cfg->pci_func << 8);
if (__qlcnic_get_eswitch_port_config(adapter, &arg1, &arg2)) if (__qlcnic_get_eswitch_port_config(adapter, &arg1, &arg2))
......
...@@ -91,6 +91,9 @@ static void qlcnic_set_netdev_features(struct qlcnic_adapter *, ...@@ -91,6 +91,9 @@ static void qlcnic_set_netdev_features(struct qlcnic_adapter *,
static int qlcnic_vlan_rx_add(struct net_device *, u16); static int qlcnic_vlan_rx_add(struct net_device *, u16);
static int qlcnic_vlan_rx_del(struct net_device *, u16); static int qlcnic_vlan_rx_del(struct net_device *, u16);
#define QLCNIC_IS_TSO_CAPABLE(adapter) \
((adapter)->ahw->capabilities & QLCNIC_FW_CAPABILITY_TSO)
/* PCI Device ID Table */ /* PCI Device ID Table */
#define ENTRY(device) \ #define ENTRY(device) \
{PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, (device)), \ {PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, (device)), \
...@@ -369,19 +372,25 @@ qlcnic_cleanup_pci_map(struct qlcnic_adapter *adapter) ...@@ -369,19 +372,25 @@ qlcnic_cleanup_pci_map(struct qlcnic_adapter *adapter)
iounmap(adapter->ahw->pci_base0); iounmap(adapter->ahw->pci_base0);
} }
static int static int qlcnic_init_pci_info(struct qlcnic_adapter *adapter)
qlcnic_init_pci_info(struct qlcnic_adapter *adapter)
{ {
struct qlcnic_pci_info *pci_info; struct qlcnic_pci_info *pci_info;
int i, ret = 0; int i, ret = 0, j = 0;
u16 act_pci_func;
u8 pfn; u8 pfn;
pci_info = kcalloc(QLCNIC_MAX_PCI_FUNC, sizeof(*pci_info), GFP_KERNEL); pci_info = kcalloc(QLCNIC_MAX_PCI_FUNC, sizeof(*pci_info), GFP_KERNEL);
if (!pci_info) if (!pci_info)
return -ENOMEM; return -ENOMEM;
ret = qlcnic_get_pci_info(adapter, pci_info);
if (ret)
goto err_pci_info;
act_pci_func = adapter->ahw->act_pci_func;
adapter->npars = kzalloc(sizeof(struct qlcnic_npar_info) * adapter->npars = kzalloc(sizeof(struct qlcnic_npar_info) *
QLCNIC_MAX_PCI_FUNC, GFP_KERNEL); act_pci_func, GFP_KERNEL);
if (!adapter->npars) { if (!adapter->npars) {
ret = -ENOMEM; ret = -ENOMEM;
goto err_pci_info; goto err_pci_info;
...@@ -394,21 +403,25 @@ qlcnic_init_pci_info(struct qlcnic_adapter *adapter) ...@@ -394,21 +403,25 @@ qlcnic_init_pci_info(struct qlcnic_adapter *adapter)
goto err_npars; goto err_npars;
} }
ret = qlcnic_get_pci_info(adapter, pci_info);
if (ret)
goto err_eswitch;
for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
pfn = pci_info[i].id; pfn = pci_info[i].id;
if (pfn >= QLCNIC_MAX_PCI_FUNC) { if (pfn >= QLCNIC_MAX_PCI_FUNC) {
ret = QL_STATUS_INVALID_PARAM; ret = QL_STATUS_INVALID_PARAM;
goto err_eswitch; goto err_eswitch;
} }
adapter->npars[pfn].active = (u8)pci_info[i].active;
adapter->npars[pfn].type = (u8)pci_info[i].type; if (!pci_info[i].active ||
adapter->npars[pfn].phy_port = (u8)pci_info[i].default_port; (pci_info[i].type != QLCNIC_TYPE_NIC))
adapter->npars[pfn].min_bw = pci_info[i].tx_min_bw; continue;
adapter->npars[pfn].max_bw = pci_info[i].tx_max_bw;
adapter->npars[j].pci_func = pfn;
adapter->npars[j].active = (u8)pci_info[i].active;
adapter->npars[j].type = (u8)pci_info[i].type;
adapter->npars[j].phy_port = (u8)pci_info[i].default_port;
adapter->npars[j].min_bw = pci_info[i].tx_min_bw;
adapter->npars[j].max_bw = pci_info[i].tx_max_bw;
j++;
} }
for (i = 0; i < QLCNIC_NIU_MAX_XG_PORTS; i++) for (i = 0; i < QLCNIC_NIU_MAX_XG_PORTS; i++)
...@@ -436,7 +449,7 @@ qlcnic_set_function_modes(struct qlcnic_adapter *adapter) ...@@ -436,7 +449,7 @@ qlcnic_set_function_modes(struct qlcnic_adapter *adapter)
u32 ref_count; u32 ref_count;
int i, ret = 1; int i, ret = 1;
u32 data = QLCNIC_MGMT_FUNC; u32 data = QLCNIC_MGMT_FUNC;
void __iomem *priv_op = adapter->ahw->pci_base0 + QLCNIC_DRV_OP_MODE; struct qlcnic_hardware_context *ahw = adapter->ahw;
/* If other drivers are not in use set their privilege level */ /* If other drivers are not in use set their privilege level */
ref_count = QLCRD32(adapter, QLCNIC_CRB_DRV_ACTIVE); ref_count = QLCRD32(adapter, QLCNIC_CRB_DRV_ACTIVE);
...@@ -445,21 +458,20 @@ qlcnic_set_function_modes(struct qlcnic_adapter *adapter) ...@@ -445,21 +458,20 @@ qlcnic_set_function_modes(struct qlcnic_adapter *adapter)
goto err_lock; goto err_lock;
if (qlcnic_config_npars) { if (qlcnic_config_npars) {
for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { for (i = 0; i < ahw->act_pci_func; i++) {
id = i; id = adapter->npars[i].pci_func;
if (adapter->npars[i].type != QLCNIC_TYPE_NIC || if (id == ahw->pci_func)
id == adapter->ahw->pci_func)
continue; continue;
data |= (qlcnic_config_npars & data |= (qlcnic_config_npars &
QLC_DEV_SET_DRV(0xf, id)); QLC_DEV_SET_DRV(0xf, id));
} }
} else { } else {
data = readl(priv_op); data = QLCRD32(adapter, QLCNIC_DRV_OP_MODE);
data = (data & ~QLC_DEV_SET_DRV(0xf, adapter->ahw->pci_func)) | data = (data & ~QLC_DEV_SET_DRV(0xf, ahw->pci_func)) |
(QLC_DEV_SET_DRV(QLCNIC_MGMT_FUNC, (QLC_DEV_SET_DRV(QLCNIC_MGMT_FUNC,
adapter->ahw->pci_func)); ahw->pci_func));
} }
writel(data, priv_op); QLCWR32(adapter, QLCNIC_DRV_OP_MODE, data);
qlcnic_api_unlock(adapter); qlcnic_api_unlock(adapter);
err_lock: err_lock:
return ret; return ret;
...@@ -632,6 +644,7 @@ qlcnic_initialize_nic(struct qlcnic_adapter *adapter) ...@@ -632,6 +644,7 @@ qlcnic_initialize_nic(struct qlcnic_adapter *adapter)
int err; int err;
struct qlcnic_info nic_info; struct qlcnic_info nic_info;
memset(&nic_info, 0, sizeof(struct qlcnic_info));
err = qlcnic_get_nic_info(adapter, &nic_info, adapter->ahw->pci_func); err = qlcnic_get_nic_info(adapter, &nic_info, adapter->ahw->pci_func);
if (err) if (err)
return err; return err;
...@@ -798,8 +811,7 @@ qlcnic_check_eswitch_mode(struct qlcnic_adapter *adapter) ...@@ -798,8 +811,7 @@ qlcnic_check_eswitch_mode(struct qlcnic_adapter *adapter)
return err; return err;
} }
static int static int qlcnic_set_default_offload_settings(struct qlcnic_adapter *adapter)
qlcnic_set_default_offload_settings(struct qlcnic_adapter *adapter)
{ {
struct qlcnic_esw_func_cfg esw_cfg; struct qlcnic_esw_func_cfg esw_cfg;
struct qlcnic_npar_info *npar; struct qlcnic_npar_info *npar;
...@@ -808,16 +820,16 @@ qlcnic_set_default_offload_settings(struct qlcnic_adapter *adapter) ...@@ -808,16 +820,16 @@ 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 < QLCNIC_MAX_PCI_FUNC; i++) { for (i = 0; i < adapter->ahw->act_pci_func; i++) {
if (adapter->npars[i].type != QLCNIC_TYPE_NIC)
continue;
memset(&esw_cfg, 0, sizeof(struct qlcnic_esw_func_cfg)); memset(&esw_cfg, 0, sizeof(struct qlcnic_esw_func_cfg));
esw_cfg.pci_func = i; esw_cfg.pci_func = adapter->npars[i].pci_func;
esw_cfg.offload_flags = BIT_0;
esw_cfg.mac_override = BIT_0; esw_cfg.mac_override = BIT_0;
esw_cfg.promisc_mode = BIT_0; esw_cfg.promisc_mode = BIT_0;
if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_TSO) if (qlcnic_82xx_check(adapter)) {
esw_cfg.offload_flags |= (BIT_1 | BIT_2); esw_cfg.offload_flags = BIT_0;
if (QLCNIC_IS_TSO_CAPABLE(adapter))
esw_cfg.offload_flags |= (BIT_1 | BIT_2);
}
if (qlcnic_config_switch_port(adapter, &esw_cfg)) if (qlcnic_config_switch_port(adapter, &esw_cfg))
return -EIO; return -EIO;
npar = &adapter->npars[i]; npar = &adapter->npars[i];
...@@ -855,22 +867,24 @@ qlcnic_reset_eswitch_config(struct qlcnic_adapter *adapter, ...@@ -855,22 +867,24 @@ qlcnic_reset_eswitch_config(struct qlcnic_adapter *adapter,
return 0; return 0;
} }
static int static int qlcnic_reset_npar_config(struct qlcnic_adapter *adapter)
qlcnic_reset_npar_config(struct qlcnic_adapter *adapter)
{ {
int i, err; int i, err;
struct qlcnic_npar_info *npar; struct qlcnic_npar_info *npar;
struct qlcnic_info nic_info; struct qlcnic_info nic_info;
u8 pci_func;
if (!adapter->need_fw_reset) if (qlcnic_82xx_check(adapter))
return 0; if (!adapter->need_fw_reset)
return 0;
/* Set the NPAR config data after FW reset */ /* Set the NPAR config data after FW reset */
for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { for (i = 0; i < adapter->ahw->act_pci_func; i++) {
npar = &adapter->npars[i]; npar = &adapter->npars[i];
if (npar->type != QLCNIC_TYPE_NIC) pci_func = npar->pci_func;
continue; memset(&nic_info, 0, sizeof(struct qlcnic_info));
err = qlcnic_get_nic_info(adapter, &nic_info, i); err = qlcnic_get_nic_info(adapter,
&nic_info, pci_func);
if (err) if (err)
return err; return err;
nic_info.min_tx_bw = npar->min_bw; nic_info.min_tx_bw = npar->min_bw;
...@@ -881,11 +895,12 @@ qlcnic_reset_npar_config(struct qlcnic_adapter *adapter) ...@@ -881,11 +895,12 @@ qlcnic_reset_npar_config(struct qlcnic_adapter *adapter)
if (npar->enable_pm) { if (npar->enable_pm) {
err = qlcnic_config_port_mirroring(adapter, err = qlcnic_config_port_mirroring(adapter,
npar->dest_npar, 1, i); npar->dest_npar, 1,
pci_func);
if (err) if (err)
return err; return err;
} }
err = qlcnic_reset_eswitch_config(adapter, npar, i); err = qlcnic_reset_eswitch_config(adapter, npar, pci_func);
if (err) if (err)
return err; return err;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册