|
@@ -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_del(struct net_device *, u16);
|
|
|
|
|
|
+#define QLCNIC_IS_TSO_CAPABLE(adapter) \
|
|
|
+ ((adapter)->ahw->capabilities & QLCNIC_FW_CAPABILITY_TSO)
|
|
|
+
|
|
|
/* PCI Device ID Table */
|
|
|
#define ENTRY(device) \
|
|
|
{PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, (device)), \
|
|
@@ -369,19 +372,25 @@ qlcnic_cleanup_pci_map(struct qlcnic_adapter *adapter)
|
|
|
iounmap(adapter->ahw->pci_base0);
|
|
|
}
|
|
|
|
|
|
-static int
|
|
|
-qlcnic_init_pci_info(struct qlcnic_adapter *adapter)
|
|
|
+static int qlcnic_init_pci_info(struct qlcnic_adapter *adapter)
|
|
|
{
|
|
|
struct qlcnic_pci_info *pci_info;
|
|
|
- int i, ret = 0;
|
|
|
+ int i, ret = 0, j = 0;
|
|
|
+ u16 act_pci_func;
|
|
|
u8 pfn;
|
|
|
|
|
|
pci_info = kcalloc(QLCNIC_MAX_PCI_FUNC, sizeof(*pci_info), GFP_KERNEL);
|
|
|
if (!pci_info)
|
|
|
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) *
|
|
|
- QLCNIC_MAX_PCI_FUNC, GFP_KERNEL);
|
|
|
+ act_pci_func, GFP_KERNEL);
|
|
|
if (!adapter->npars) {
|
|
|
ret = -ENOMEM;
|
|
|
goto err_pci_info;
|
|
@@ -394,21 +403,25 @@ qlcnic_init_pci_info(struct qlcnic_adapter *adapter)
|
|
|
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++) {
|
|
|
pfn = pci_info[i].id;
|
|
|
+
|
|
|
if (pfn >= QLCNIC_MAX_PCI_FUNC) {
|
|
|
ret = QL_STATUS_INVALID_PARAM;
|
|
|
goto err_eswitch;
|
|
|
}
|
|
|
- adapter->npars[pfn].active = (u8)pci_info[i].active;
|
|
|
- adapter->npars[pfn].type = (u8)pci_info[i].type;
|
|
|
- adapter->npars[pfn].phy_port = (u8)pci_info[i].default_port;
|
|
|
- adapter->npars[pfn].min_bw = pci_info[i].tx_min_bw;
|
|
|
- adapter->npars[pfn].max_bw = pci_info[i].tx_max_bw;
|
|
|
+
|
|
|
+ if (!pci_info[i].active ||
|
|
|
+ (pci_info[i].type != QLCNIC_TYPE_NIC))
|
|
|
+ continue;
|
|
|
+
|
|
|
+ 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++)
|
|
@@ -436,7 +449,7 @@ qlcnic_set_function_modes(struct qlcnic_adapter *adapter)
|
|
|
u32 ref_count;
|
|
|
int i, ret = 1;
|
|
|
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 */
|
|
|
ref_count = QLCRD32(adapter, QLCNIC_CRB_DRV_ACTIVE);
|
|
@@ -445,21 +458,20 @@ qlcnic_set_function_modes(struct qlcnic_adapter *adapter)
|
|
|
goto err_lock;
|
|
|
|
|
|
if (qlcnic_config_npars) {
|
|
|
- for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
|
|
|
- id = i;
|
|
|
- if (adapter->npars[i].type != QLCNIC_TYPE_NIC ||
|
|
|
- id == adapter->ahw->pci_func)
|
|
|
+ for (i = 0; i < ahw->act_pci_func; i++) {
|
|
|
+ id = adapter->npars[i].pci_func;
|
|
|
+ if (id == ahw->pci_func)
|
|
|
continue;
|
|
|
data |= (qlcnic_config_npars &
|
|
|
QLC_DEV_SET_DRV(0xf, id));
|
|
|
}
|
|
|
} else {
|
|
|
- data = readl(priv_op);
|
|
|
- data = (data & ~QLC_DEV_SET_DRV(0xf, adapter->ahw->pci_func)) |
|
|
|
+ data = QLCRD32(adapter, QLCNIC_DRV_OP_MODE);
|
|
|
+ data = (data & ~QLC_DEV_SET_DRV(0xf, ahw->pci_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);
|
|
|
err_lock:
|
|
|
return ret;
|
|
@@ -632,6 +644,7 @@ qlcnic_initialize_nic(struct qlcnic_adapter *adapter)
|
|
|
int err;
|
|
|
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);
|
|
|
if (err)
|
|
|
return err;
|
|
@@ -798,8 +811,7 @@ qlcnic_check_eswitch_mode(struct qlcnic_adapter *adapter)
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
-static int
|
|
|
-qlcnic_set_default_offload_settings(struct qlcnic_adapter *adapter)
|
|
|
+static int qlcnic_set_default_offload_settings(struct qlcnic_adapter *adapter)
|
|
|
{
|
|
|
struct qlcnic_esw_func_cfg esw_cfg;
|
|
|
struct qlcnic_npar_info *npar;
|
|
@@ -808,16 +820,16 @@ qlcnic_set_default_offload_settings(struct qlcnic_adapter *adapter)
|
|
|
if (adapter->need_fw_reset)
|
|
|
return 0;
|
|
|
|
|
|
- for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
|
|
|
- if (adapter->npars[i].type != QLCNIC_TYPE_NIC)
|
|
|
- continue;
|
|
|
+ for (i = 0; i < adapter->ahw->act_pci_func; i++) {
|
|
|
memset(&esw_cfg, 0, sizeof(struct qlcnic_esw_func_cfg));
|
|
|
- esw_cfg.pci_func = i;
|
|
|
- esw_cfg.offload_flags = BIT_0;
|
|
|
+ esw_cfg.pci_func = adapter->npars[i].pci_func;
|
|
|
esw_cfg.mac_override = BIT_0;
|
|
|
esw_cfg.promisc_mode = BIT_0;
|
|
|
- if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_TSO)
|
|
|
- esw_cfg.offload_flags |= (BIT_1 | BIT_2);
|
|
|
+ if (qlcnic_82xx_check(adapter)) {
|
|
|
+ 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))
|
|
|
return -EIO;
|
|
|
npar = &adapter->npars[i];
|
|
@@ -855,22 +867,24 @@ qlcnic_reset_eswitch_config(struct qlcnic_adapter *adapter,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static int
|
|
|
-qlcnic_reset_npar_config(struct qlcnic_adapter *adapter)
|
|
|
+static int qlcnic_reset_npar_config(struct qlcnic_adapter *adapter)
|
|
|
{
|
|
|
int i, err;
|
|
|
struct qlcnic_npar_info *npar;
|
|
|
struct qlcnic_info nic_info;
|
|
|
+ u8 pci_func;
|
|
|
|
|
|
- if (!adapter->need_fw_reset)
|
|
|
- return 0;
|
|
|
+ if (qlcnic_82xx_check(adapter))
|
|
|
+ if (!adapter->need_fw_reset)
|
|
|
+ return 0;
|
|
|
|
|
|
/* 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];
|
|
|
- if (npar->type != QLCNIC_TYPE_NIC)
|
|
|
- continue;
|
|
|
- err = qlcnic_get_nic_info(adapter, &nic_info, i);
|
|
|
+ pci_func = npar->pci_func;
|
|
|
+ memset(&nic_info, 0, sizeof(struct qlcnic_info));
|
|
|
+ err = qlcnic_get_nic_info(adapter,
|
|
|
+ &nic_info, pci_func);
|
|
|
if (err)
|
|
|
return err;
|
|
|
nic_info.min_tx_bw = npar->min_bw;
|
|
@@ -881,11 +895,12 @@ qlcnic_reset_npar_config(struct qlcnic_adapter *adapter)
|
|
|
|
|
|
if (npar->enable_pm) {
|
|
|
err = qlcnic_config_port_mirroring(adapter,
|
|
|
- npar->dest_npar, 1, i);
|
|
|
+ npar->dest_npar, 1,
|
|
|
+ pci_func);
|
|
|
if (err)
|
|
|
return err;
|
|
|
}
|
|
|
- err = qlcnic_reset_eswitch_config(adapter, npar, i);
|
|
|
+ err = qlcnic_reset_eswitch_config(adapter, npar, pci_func);
|
|
|
if (err)
|
|
|
return err;
|
|
|
}
|