Skip to content

Commit

Permalink
qlcnic: Fix a bug in setting up NIC partitioning mode
Browse files Browse the repository at this point in the history
The driver was not detecting the presence of NIC partitioning capability of the
firmware properly. Now, it checks the eswitch set bit in the FW capabilities
register and accordingly sets the driver mode as NPAR capable or not.

Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Anirban Chakraborty authored and David S. Miller committed Jun 16, 2010
1 parent 8c76368 commit 0e33c66
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 52 deletions.
2 changes: 1 addition & 1 deletion drivers/net/qlcnic/qlcnic.h
Original file line number Diff line number Diff line change
Expand Up @@ -891,7 +891,7 @@ struct qlcnic_mac_req {
#define QLCNIC_LRO_ENABLED 0x08
#define QLCNIC_BRIDGE_ENABLED 0X10
#define QLCNIC_DIAG_ENABLED 0x20
#define QLCNIC_NPAR_ENABLED 0x40
#define QLCNIC_ESWITCH_ENABLED 0x40
#define QLCNIC_IS_MSI_FAMILY(adapter) \
((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED))

Expand Down
5 changes: 5 additions & 0 deletions drivers/net/qlcnic/qlcnic_ctx.c
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,11 @@ int qlcnic_get_nic_info(struct qlcnic_adapter *adapter, u8 func_id)
adapter->capabilities = le32_to_cpu(nic_info->capabilities);
adapter->max_mac_filters = nic_info->max_mac_filters;

if (adapter->capabilities & BIT_6)
adapter->flags |= QLCNIC_ESWITCH_ENABLED;
else
adapter->flags &= ~QLCNIC_ESWITCH_ENABLED;

dev_info(&adapter->pdev->dev,
"phy port: %d switch_mode: %d,\n"
"\tmax_tx_q: %d max_rx_q: %d min_tx_bw: 0x%x,\n"
Expand Down
82 changes: 31 additions & 51 deletions drivers/net/qlcnic/qlcnic_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -502,39 +502,28 @@ qlcnic_set_function_modes(struct qlcnic_adapter *adapter)
if (QLC_DEV_CLR_REF_CNT(ref_count, adapter->ahw.pci_func))
goto err_npar;

for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
id = adapter->npars[i].id;
if (adapter->npars[i].type != QLCNIC_TYPE_NIC ||
id == adapter->ahw.pci_func)
continue;
data |= (qlcnic_config_npars & QLC_DEV_SET_DRV(0xf, id));
if (qlcnic_config_npars) {
for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
id = adapter->npars[i].id;
if (adapter->npars[i].type != QLCNIC_TYPE_NIC ||
id == adapter->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)) |
(QLC_DEV_SET_DRV(QLCNIC_MGMT_FUNC,
adapter->ahw.pci_func));
}
writel(data, priv_op);

err_npar:
qlcnic_api_unlock(adapter);
err_lock:
return ret;
}

static u8
qlcnic_set_mgmt_driver(struct qlcnic_adapter *adapter)
{
u8 i, ret = 0;

if (qlcnic_get_pci_info(adapter))
return ret;
/* Set the eswitch */
for (i = 0; i < QLCNIC_NIU_MAX_XG_PORTS; i++) {
if (!qlcnic_get_eswitch_capabilities(adapter, i,
&adapter->eswitch[i])) {
ret++;
qlcnic_toggle_eswitch(adapter, i, ret);
}
}
return ret;
}

static u32
qlcnic_get_driver_mode(struct qlcnic_adapter *adapter)
{
Expand All @@ -550,6 +539,7 @@ qlcnic_get_driver_mode(struct qlcnic_adapter *adapter)
adapter->nic_ops = &qlcnic_ops;
adapter->fw_hal_version = QLCNIC_FW_BASE;
adapter->ahw.pci_func = PCI_FUNC(adapter->pdev->devfn);
adapter->capabilities = QLCRD32(adapter, CRB_FW_CAPABILITIES_1);
dev_info(&adapter->pdev->dev,
"FW does not support nic partion\n");
return adapter->fw_hal_version;
Expand All @@ -562,29 +552,28 @@ qlcnic_get_driver_mode(struct qlcnic_adapter *adapter)
func = (func - msix_base)/QLCNIC_MSIX_TBL_PGSIZE;
adapter->ahw.pci_func = func;

qlcnic_get_nic_info(adapter, adapter->ahw.pci_func);

if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) {
adapter->nic_ops = &qlcnic_ops;
return adapter->fw_hal_version;
}

/* Determine function privilege level */
priv_op = adapter->ahw.pci_base0 + QLCNIC_DRV_OP_MODE;
op_mode = readl(priv_op);
if (op_mode == QLC_DEV_DRV_DEFAULT) {
if (op_mode == QLC_DEV_DRV_DEFAULT)
priv_level = QLCNIC_MGMT_FUNC;
if (qlcnic_api_lock(adapter))
return 0;
op_mode = (op_mode & ~QLC_DEV_SET_DRV(0xf, func)) |
(QLC_DEV_SET_DRV(QLCNIC_MGMT_FUNC, func));
writel(op_mode, priv_op);
qlcnic_api_unlock(adapter);

} else
else
priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw.pci_func);

switch (priv_level) {
case QLCNIC_MGMT_FUNC:
adapter->op_mode = QLCNIC_MGMT_FUNC;
adapter->nic_ops = &qlcnic_pf_ops;
qlcnic_get_pci_info(adapter);
/* Set privilege level for other functions */
if (qlcnic_config_npars)
qlcnic_set_function_modes(adapter);
qlcnic_dev_set_npar_ready(adapter);
qlcnic_set_function_modes(adapter);
dev_info(&adapter->pdev->dev,
"HAL Version: %d, Management function\n",
adapter->fw_hal_version);
Expand Down Expand Up @@ -716,11 +705,6 @@ qlcnic_check_options(struct qlcnic_adapter *adapter)
dev_info(&pdev->dev, "firmware v%d.%d.%d\n",
fw_major, fw_minor, fw_build);

if (adapter->fw_hal_version == QLCNIC_FW_NPAR)
qlcnic_get_nic_info(adapter, adapter->ahw.pci_func);
else
adapter->capabilities = QLCRD32(adapter, CRB_FW_CAPABILITIES_1);

adapter->flags &= ~QLCNIC_LRO_ENABLED;

if (adapter->ahw.port_type == QLCNIC_XGBE) {
Expand All @@ -731,6 +715,8 @@ qlcnic_check_options(struct qlcnic_adapter *adapter)
adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_1G;
}

qlcnic_get_nic_info(adapter, adapter->ahw.pci_func);

adapter->msix_supported = !!use_msi_x;
adapter->rss_supported = !!use_msi_x;

Expand Down Expand Up @@ -797,13 +783,11 @@ qlcnic_start_firmware(struct qlcnic_adapter *adapter)
QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_READY);
qlcnic_idc_debug_info(adapter, 1);

qlcnic_dev_set_npar_ready(adapter);

qlcnic_check_options(adapter);

if (adapter->fw_hal_version != QLCNIC_FW_BASE &&
adapter->op_mode == QLCNIC_MGMT_FUNC)
qlcnic_set_mgmt_driver(adapter);
if (adapter->flags & QLCNIC_ESWITCH_ENABLED &&
adapter->op_mode != QLCNIC_NON_PRIV_FUNC)
qlcnic_dev_set_npar_ready(adapter);

adapter->need_fw_reset = 0;

Expand Down Expand Up @@ -2449,10 +2433,6 @@ qlcnic_dev_set_npar_ready(struct qlcnic_adapter *adapter)
{
u32 state;

if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC ||
adapter->fw_hal_version == QLCNIC_FW_BASE)
return;

if (qlcnic_api_lock(adapter))
return;

Expand Down

0 comments on commit 0e33c66

Please sign in to comment.