Skip to content

Commit

Permalink
Merge branch 'qlcnic'
Browse files Browse the repository at this point in the history
Shahed Shaikh says:

====================
This patch series includes following changes:
* Support for spoof check configuration per VF using
  iproute2 tool.
* Set HW mask for 8300 adapter in INT-x mode to stop generating
  interrupts.
* Updated IRQ name for 8200 and 8300 Series adapter as per
  format used by other multiqueue drivers.
* Remove qlcnic_config_npars module parameter.
* Initialize trans_work and idc_aen_work at VF probe.
* Convert netsted if-else into switch-case statement.
* Change in diagnostics routine.
* Modify reset recovery path in diag mode by providing diagnostics
  routines enough time to unwind before proceeding with reset recovery.
* Implement GET_LED_STATUS command for 82xx adapter and refactor
  qlcnic_store_beacon() to split 8200 and 8300 specific calls.
* Some cleanup and log enhancements
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed May 25, 2013
2 parents f2068b8 + 6a531b7 commit 6e2842f
Show file tree
Hide file tree
Showing 13 changed files with 324 additions and 168 deletions.
27 changes: 24 additions & 3 deletions drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@

#define _QLCNIC_LINUX_MAJOR 5
#define _QLCNIC_LINUX_MINOR 2
#define _QLCNIC_LINUX_SUBVERSION 42
#define QLCNIC_LINUX_VERSIONID "5.2.42"
#define _QLCNIC_LINUX_SUBVERSION 43
#define QLCNIC_LINUX_VERSIONID "5.2.43"
#define QLCNIC_DRV_IDC_VER 0x01
#define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\
(_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION))
Expand Down Expand Up @@ -303,7 +303,6 @@ extern int qlcnic_use_msi;
extern int qlcnic_use_msi_x;
extern int qlcnic_auto_fw_reset;
extern int qlcnic_load_fw_file;
extern int qlcnic_config_npars;

/* Number of status descriptors to handle per interrupt */
#define MAX_STATUS_HANDLE (64)
Expand Down Expand Up @@ -443,6 +442,7 @@ struct qlcnic_hardware_context {
u16 max_mtu;
u32 msg_enable;
u16 act_pci_func;
u16 max_pci_func;

u32 capabilities;
u32 capabilities2;
Expand Down Expand Up @@ -816,6 +816,7 @@ struct qlcnic_mac_list_s {
#define QLCNIC_FW_CAPABILITY_2_LRO_MAX_TCP_SEG BIT_2
#define QLCNIC_FW_CAP2_HW_LRO_IPV6 BIT_3
#define QLCNIC_FW_CAPABILITY_2_OCBB BIT_5
#define QLCNIC_FW_CAPABILITY_2_BEACON BIT_7

/* module types */
#define LINKEVENT_MODULE_NOT_PRESENT 1
Expand Down Expand Up @@ -913,6 +914,9 @@ struct qlcnic_ipaddr {
#define QLCNIC_IS_TSO_CAPABLE(adapter) \
((adapter)->ahw->capabilities & QLCNIC_FW_CAPABILITY_TSO)

#define QLCNIC_BEACON_EANBLE 0xC
#define QLCNIC_BEACON_DISABLE 0xD

#define QLCNIC_DEF_NUM_STS_DESC_RINGS 4
#define QLCNIC_MSIX_TBL_SPACE 8192
#define QLCNIC_PCI_REG_MSIX_TBL 0x44
Expand All @@ -932,6 +936,7 @@ struct qlcnic_ipaddr {
#define __QLCNIC_SRIOV_ENABLE 10
#define __QLCNIC_SRIOV_CAPABLE 11
#define __QLCNIC_MBX_POLL_ENABLE 12
#define __QLCNIC_DIAG_MODE 13

#define QLCNIC_INTERRUPT_TEST 1
#define QLCNIC_LOOPBACK_TEST 2
Expand Down Expand Up @@ -1543,6 +1548,7 @@ int qlcnic_set_default_offload_settings(struct qlcnic_adapter *);
int qlcnic_reset_npar_config(struct qlcnic_adapter *);
int qlcnic_set_eswitch_port_config(struct qlcnic_adapter *);
void qlcnic_add_lb_filter(struct qlcnic_adapter *, struct sk_buff *, int, u16);
int qlcnic_get_beacon_state(struct qlcnic_adapter *, u8 *);
int qlcnic_83xx_configure_opmode(struct qlcnic_adapter *adapter);
int qlcnic_read_mac_addr(struct qlcnic_adapter *);
int qlcnic_setup_netdev(struct qlcnic_adapter *, struct net_device *, int);
Expand Down Expand Up @@ -1886,6 +1892,21 @@ static inline void qlcnic_enable_int(struct qlcnic_host_sds_ring *sds_ring)
writel(0xfbff, adapter->tgt_mask_reg);
}

static inline int qlcnic_get_diag_lock(struct qlcnic_adapter *adapter)
{
return test_and_set_bit(__QLCNIC_DIAG_MODE, &adapter->state);
}

static inline void qlcnic_release_diag_lock(struct qlcnic_adapter *adapter)
{
clear_bit(__QLCNIC_DIAG_MODE, &adapter->state);
}

static inline int qlcnic_check_diag_status(struct qlcnic_adapter *adapter)
{
return test_bit(__QLCNIC_DIAG_MODE, &adapter->state);
}

extern const struct ethtool_ops qlcnic_sriov_vf_ethtool_ops;
extern const struct ethtool_ops qlcnic_ethtool_ops;
extern const struct ethtool_ops qlcnic_ethtool_failed_ops;
Expand Down
77 changes: 47 additions & 30 deletions drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,11 @@ inline void qlcnic_83xx_clear_legacy_intr_mask(struct qlcnic_adapter *adapter)
writel(0, adapter->tgt_mask_reg);
}

inline void qlcnic_83xx_set_legacy_intr_mask(struct qlcnic_adapter *adapter)
{
writel(1, adapter->tgt_mask_reg);
}

/* Enable MSI-x and INT-x interrupts */
void qlcnic_83xx_enable_intr(struct qlcnic_adapter *adapter,
struct qlcnic_host_sds_ring *sds_ring)
Expand Down Expand Up @@ -458,6 +463,9 @@ void qlcnic_83xx_free_mbx_intr(struct qlcnic_adapter *adapter)
{
u32 num_msix;

if (!(adapter->flags & QLCNIC_MSIX_ENABLED))
qlcnic_83xx_set_legacy_intr_mask(adapter);

qlcnic_83xx_disable_mbx_intr(adapter);

if (adapter->flags & QLCNIC_MSIX_ENABLED)
Expand All @@ -474,7 +482,6 @@ int qlcnic_83xx_setup_mbx_intr(struct qlcnic_adapter *adapter)
{
irq_handler_t handler;
u32 val;
char name[32];
int err = 0;
unsigned long flags = 0;

Expand All @@ -485,9 +492,7 @@ int qlcnic_83xx_setup_mbx_intr(struct qlcnic_adapter *adapter)
if (adapter->flags & QLCNIC_MSIX_ENABLED) {
handler = qlcnic_83xx_handle_aen;
val = adapter->msix_entries[adapter->ahw->num_msix - 1].vector;
snprintf(name, (IFNAMSIZ + 4),
"%s[%s]", "qlcnic", "aen");
err = request_irq(val, handler, flags, name, adapter);
err = request_irq(val, handler, flags, "qlcnic-MB", adapter);
if (err) {
dev_err(&adapter->pdev->dev,
"failed to register MBX interrupt\n");
Expand Down Expand Up @@ -1588,16 +1593,24 @@ int qlcnic_83xx_loopback_test(struct net_device *netdev, u8 mode)
struct qlcnic_hardware_context *ahw = adapter->ahw;
int ret = 0, loop = 0, max_sds_rings = adapter->max_sds_rings;

QLCDB(adapter, DRV, "%s loopback test in progress\n",
mode == QLCNIC_ILB_MODE ? "internal" : "external");
if (ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
dev_warn(&adapter->pdev->dev,
"Loopback test not supported for non privilege function\n");
netdev_warn(netdev,
"Loopback test not supported in non privileged mode\n");
return ret;
}

if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
netdev_info(netdev, "Device is resetting\n");
return -EBUSY;
}

if (qlcnic_get_diag_lock(adapter)) {
netdev_info(netdev, "Device is in diagnostics mode\n");
return -EBUSY;
}

netdev_info(netdev, "%s loopback test in progress\n",
mode == QLCNIC_ILB_MODE ? "internal" : "external");

ret = qlcnic_83xx_diag_alloc_res(netdev, QLCNIC_LOOPBACK_TEST,
max_sds_rings);
Expand Down Expand Up @@ -1638,7 +1651,7 @@ int qlcnic_83xx_loopback_test(struct net_device *netdev, u8 mode)

fail_diag_alloc:
adapter->max_sds_rings = max_sds_rings;
clear_bit(__QLCNIC_RESETTING, &adapter->state);
qlcnic_release_diag_lock(adapter);
return ret;
}

Expand Down Expand Up @@ -2121,26 +2134,25 @@ int qlcnic_83xx_get_nic_info(struct qlcnic_adapter *adapter,
int qlcnic_83xx_get_pci_info(struct qlcnic_adapter *adapter,
struct qlcnic_pci_info *pci_info)
{
struct qlcnic_hardware_context *ahw = adapter->ahw;
struct device *dev = &adapter->pdev->dev;
struct qlcnic_cmd_args cmd;
int i, err = 0, j = 0;
u32 temp;
struct qlcnic_cmd_args cmd;

qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_PCI_INFO);
err = qlcnic_issue_cmd(adapter, &cmd);

adapter->ahw->act_pci_func = 0;
ahw->act_pci_func = 0;
if (err == QLCNIC_RCODE_SUCCESS) {
pci_info->func_count = cmd.rsp.arg[1] & 0xFF;
dev_info(&adapter->pdev->dev,
"%s: total functions = %d\n",
__func__, pci_info->func_count);
ahw->max_pci_func = cmd.rsp.arg[1] & 0xFF;
for (i = 2, j = 0; j < QLCNIC_MAX_PCI_FUNC; j++, pci_info++) {
pci_info->id = cmd.rsp.arg[i] & 0xFFFF;
pci_info->active = (cmd.rsp.arg[i] & 0xFFFF0000) >> 16;
i++;
pci_info->type = cmd.rsp.arg[i] & 0xFFFF;
if (pci_info->type == QLCNIC_TYPE_NIC)
adapter->ahw->act_pci_func++;
ahw->act_pci_func++;
temp = (cmd.rsp.arg[i] & 0xFFFF0000) >> 16;
pci_info->default_port = temp;
i++;
Expand All @@ -2152,18 +2164,21 @@ int qlcnic_83xx_get_pci_info(struct qlcnic_adapter *adapter,
i++;
memcpy(pci_info->mac + sizeof(u32), &cmd.rsp.arg[i], 2);
i = i + 3;

dev_info(&adapter->pdev->dev, "%s:\n"
"\tid = %d active = %d type = %d\n"
"\tport = %d min bw = %d max bw = %d\n"
"\tmac_addr = %pM\n", __func__,
pci_info->id, pci_info->active, pci_info->type,
pci_info->default_port, pci_info->tx_min_bw,
pci_info->tx_max_bw, pci_info->mac);
if (ahw->op_mode == QLCNIC_MGMT_FUNC)
dev_info(dev, "id = %d active = %d type = %d\n"
"\tport = %d min bw = %d max bw = %d\n"
"\tmac_addr = %pM\n", pci_info->id,
pci_info->active, pci_info->type,
pci_info->default_port,
pci_info->tx_min_bw,
pci_info->tx_max_bw, pci_info->mac);
}
if (ahw->op_mode == QLCNIC_MGMT_FUNC)
dev_info(dev, "Max vNIC functions = %d, active vNIC functions = %d\n",
ahw->max_pci_func, ahw->act_pci_func);

} else {
dev_err(&adapter->pdev->dev, "Failed to get PCI Info%d\n",
err);
dev_err(dev, "Failed to get PCI Info, error = %d\n", err);
err = -EIO;
}

Expand Down Expand Up @@ -3113,8 +3128,10 @@ int qlcnic_83xx_interrupt_test(struct net_device *netdev)
u8 val;
int ret, max_sds_rings = adapter->max_sds_rings;

if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
return -EIO;
if (qlcnic_get_diag_lock(adapter)) {
netdev_info(netdev, "Device in diagnostics mode\n");
return -EBUSY;
}

ret = qlcnic_83xx_diag_alloc_res(netdev, QLCNIC_INTERRUPT_TEST,
max_sds_rings);
Expand Down Expand Up @@ -3156,7 +3173,7 @@ int qlcnic_83xx_interrupt_test(struct net_device *netdev)

fail_diag_irq:
adapter->max_sds_rings = max_sds_rings;
clear_bit(__QLCNIC_RESETTING, &adapter->state);
qlcnic_release_diag_lock(adapter);
return ret;
}

Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,7 @@ struct qlc_83xx_idc {
u8 vnic_state;
u8 vnic_wait_limit;
u8 quiesce_req;
u8 delay_reset;
char **name;
};

Expand Down
35 changes: 28 additions & 7 deletions drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -649,6 +649,7 @@ static void qlcnic_83xx_idc_update_idc_params(struct qlcnic_adapter *adapter)
ahw->idc.collect_dump = 0;
ahw->reset_context = 0;
adapter->tx_timeo_cnt = 0;
ahw->idc.delay_reset = 0;

clear_bit(__QLCNIC_RESETTING, &adapter->state);
}
Expand Down Expand Up @@ -883,21 +884,41 @@ static int qlcnic_83xx_idc_need_reset_state(struct qlcnic_adapter *adapter)
int ret = 0;

if (adapter->ahw->idc.prev_state != QLC_83XX_IDC_DEV_NEED_RESET) {
qlcnic_83xx_idc_update_drv_ack_reg(adapter, 1, 1);
qlcnic_83xx_idc_update_audit_reg(adapter, 0, 1);
set_bit(__QLCNIC_RESETTING, &adapter->state);
clear_bit(QLC_83XX_MBX_READY, &adapter->ahw->idc.status);
if (adapter->ahw->nic_mode == QLC_83XX_VIRTUAL_NIC_MODE)
qlcnic_83xx_disable_vnic_mode(adapter, 1);
qlcnic_83xx_idc_detach_driver(adapter);

if (qlcnic_check_diag_status(adapter)) {
dev_info(&adapter->pdev->dev,
"%s: Wait for diag completion\n", __func__);
adapter->ahw->idc.delay_reset = 1;
return 0;
} else {
qlcnic_83xx_idc_update_drv_ack_reg(adapter, 1, 1);
qlcnic_83xx_idc_detach_driver(adapter);
}
}

/* Check ACK from other functions */
ret = qlcnic_83xx_idc_check_reset_ack_reg(adapter);
if (ret) {
if (qlcnic_check_diag_status(adapter)) {
dev_info(&adapter->pdev->dev,
"%s: Waiting for reset ACK\n", __func__);
return 0;
"%s: Wait for diag completion\n", __func__);
return -1;
} else {
if (adapter->ahw->idc.delay_reset) {
qlcnic_83xx_idc_update_drv_ack_reg(adapter, 1, 1);
qlcnic_83xx_idc_detach_driver(adapter);
adapter->ahw->idc.delay_reset = 0;
}

/* Check for ACK from other functions */
ret = qlcnic_83xx_idc_check_reset_ack_reg(adapter);
if (ret) {
dev_info(&adapter->pdev->dev,
"%s: Waiting for reset ACK\n", __func__);
return -1;
}
}

/* Transit to INIT state and restart the HW */
Expand Down
39 changes: 17 additions & 22 deletions drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,27 +42,18 @@ int qlcnic_83xx_disable_vnic_mode(struct qlcnic_adapter *adapter, int lock)
static int qlcnic_83xx_set_vnic_opmode(struct qlcnic_adapter *adapter)
{
u8 id;
int i, ret = -EBUSY;
int ret = -EBUSY;
u32 data = QLCNIC_MGMT_FUNC;
struct qlcnic_hardware_context *ahw = adapter->ahw;

if (qlcnic_83xx_lock_driver(adapter))
return ret;

if (qlcnic_config_npars) {
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_83XX_SET_FUNC_OPMODE(0x3, id);
}
} else {
data = QLCRDX(adapter->ahw, QLC_83XX_DRV_OP_MODE);
data = (data & ~QLC_83XX_SET_FUNC_OPMODE(0x3, ahw->pci_func)) |
QLC_83XX_SET_FUNC_OPMODE(QLCNIC_MGMT_FUNC,
ahw->pci_func);
}
id = ahw->pci_func;
data = QLCRDX(adapter->ahw, QLC_83XX_DRV_OP_MODE);
data = (data & ~QLC_83XX_SET_FUNC_OPMODE(0x3, id)) |
QLC_83XX_SET_FUNC_OPMODE(QLCNIC_MGMT_FUNC, id);

QLCWRX(adapter->ahw, QLC_83XX_DRV_OP_MODE, data);

qlcnic_83xx_unlock_driver(adapter);
Expand Down Expand Up @@ -196,20 +187,24 @@ int qlcnic_83xx_config_vnic_opmode(struct qlcnic_adapter *adapter)
else
priv_level = QLC_83XX_GET_FUNC_PRIVILEGE(op_mode,
ahw->pci_func);

if (priv_level == QLCNIC_NON_PRIV_FUNC) {
switch (priv_level) {
case QLCNIC_NON_PRIV_FUNC:
ahw->op_mode = QLCNIC_NON_PRIV_FUNC;
ahw->idc.state_entry = qlcnic_83xx_idc_ready_state_entry;
nic_ops->init_driver = qlcnic_83xx_init_non_privileged_vnic;
} else if (priv_level == QLCNIC_PRIV_FUNC) {
break;
case QLCNIC_PRIV_FUNC:
ahw->op_mode = QLCNIC_PRIV_FUNC;
ahw->idc.state_entry = qlcnic_83xx_idc_vnic_pf_entry;
nic_ops->init_driver = qlcnic_83xx_init_privileged_vnic;
} else if (priv_level == QLCNIC_MGMT_FUNC) {
break;
case QLCNIC_MGMT_FUNC:
ahw->op_mode = QLCNIC_MGMT_FUNC;
ahw->idc.state_entry = qlcnic_83xx_idc_ready_state_entry;
nic_ops->init_driver = qlcnic_83xx_init_mgmt_vnic;
} else {
break;
default:
dev_err(&adapter->pdev->dev, "Invalid Virtual NIC opmode\n");
return -EIO;
}

Expand All @@ -218,8 +213,8 @@ int qlcnic_83xx_config_vnic_opmode(struct qlcnic_adapter *adapter)
else
adapter->flags &= ~QLCNIC_ESWITCH_ENABLED;

adapter->ahw->idc.vnic_state = QLCNIC_DEV_NPAR_NON_OPER;
adapter->ahw->idc.vnic_wait_limit = QLCNIC_DEV_NPAR_OPER_TIMEO;
ahw->idc.vnic_state = QLCNIC_DEV_NPAR_NON_OPER;
ahw->idc.vnic_wait_limit = QLCNIC_DEV_NPAR_OPER_TIMEO;

return 0;
}
Loading

0 comments on commit 6e2842f

Please sign in to comment.