Skip to content

Commit

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

====================
qlcnic: Refactoring and enhancements

This patch series includes follwing changes

* Refactor DCBX code. Do not allow DCBX operations for VFs
* Issue INIT_NIC mailbox command only once
* Refactor initialize nic code path
* Allow configuration for single TX/RX queue
* VLAN enhancement for 84xx adapters
* Support for 16 virtual NIC functions for 84XX series adapters

Please apply to net-next
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Dec 17, 2013
2 parents baf9573 + c100bb2 commit 5c509a2
Show file tree
Hide file tree
Showing 17 changed files with 635 additions and 302 deletions.
45 changes: 38 additions & 7 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 3
#define _QLCNIC_LINUX_SUBVERSION 52
#define QLCNIC_LINUX_VERSIONID "5.3.52"
#define _QLCNIC_LINUX_SUBVERSION 53
#define QLCNIC_LINUX_VERSIONID "5.3.53"
#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 @@ -115,6 +115,10 @@ enum qlcnic_queue_type {
#define QLCNIC_VNIC_MODE 0xFF
#define QLCNIC_DEFAULT_MODE 0x0

/* Virtual NIC function count */
#define QLC_DEFAULT_VNIC_COUNT 8
#define QLC_84XX_VNIC_COUNT 16

/*
* Following are the states of the Phantom. Phantom will set them and
* Host will read to check if the fields are correct.
Expand Down Expand Up @@ -374,7 +378,7 @@ struct qlcnic_rx_buffer {

#define QLCNIC_INTR_DEFAULT 0x04
#define QLCNIC_CONFIG_INTR_COALESCE 3
#define QLCNIC_DEV_INFO_SIZE 1
#define QLCNIC_DEV_INFO_SIZE 2

struct qlcnic_nic_intr_coalesce {
u8 type;
Expand Down Expand Up @@ -462,8 +466,10 @@ struct qlcnic_hardware_context {
u16 max_rx_ques;
u16 max_mtu;
u32 msg_enable;
u16 act_pci_func;
u16 total_nic_func;
u16 max_pci_func;
u32 max_vnic_func;
u32 total_pci_func;

u32 capabilities;
u32 extra_capability[3];
Expand Down Expand Up @@ -788,9 +794,10 @@ struct qlcnic_cardrsp_tx_ctx {
#define QLCNIC_MAC_VLAN_ADD 3
#define QLCNIC_MAC_VLAN_DEL 4

struct qlcnic_mac_list_s {
struct qlcnic_mac_vlan_list {
struct list_head list;
uint8_t mac_addr[ETH_ALEN+2];
u16 vlan_id;
};

/* MAC Learn */
Expand Down Expand Up @@ -856,7 +863,7 @@ struct qlcnic_mac_list_s {
#define QLCNIC_FW_CAP2_HW_LRO_IPV6 BIT_3
#define QLCNIC_FW_CAPABILITY_SET_DRV_VER BIT_5
#define QLCNIC_FW_CAPABILITY_2_BEACON BIT_7
#define QLCNIC_FW_CAPABILITY_2_PER_PORT_ESWITCH_CFG BIT_8
#define QLCNIC_FW_CAPABILITY_2_PER_PORT_ESWITCH_CFG BIT_9

/* module types */
#define LINKEVENT_MODULE_NOT_PRESENT 1
Expand Down Expand Up @@ -1637,7 +1644,9 @@ int qlcnic_setup_netdev(struct qlcnic_adapter *, struct net_device *, int);
void qlcnic_set_netdev_features(struct qlcnic_adapter *,
struct qlcnic_esw_func_cfg *);
void qlcnic_sriov_vf_schedule_multi(struct net_device *);
void qlcnic_vf_add_mc_list(struct net_device *, u16);
int qlcnic_is_valid_nic_func(struct qlcnic_adapter *, u8);
int qlcnic_get_pci_func_type(struct qlcnic_adapter *, u16, u16 *, u16 *,
u16 *);

/*
* QLOGIC Board information
Expand Down Expand Up @@ -2136,4 +2145,26 @@ static inline bool qlcnic_sriov_vf_check(struct qlcnic_adapter *adapter)

return status;
}

static inline bool qlcnic_83xx_pf_check(struct qlcnic_adapter *adapter)
{
unsigned short device = adapter->pdev->device;

return (device == PCI_DEVICE_ID_QLOGIC_QLE834X) ? true : false;
}

static inline bool qlcnic_83xx_vf_check(struct qlcnic_adapter *adapter)
{
unsigned short device = adapter->pdev->device;

return (device == PCI_DEVICE_ID_QLOGIC_VF_QLE834X) ? true : false;
}

static inline u32 qlcnic_get_vnic_func_count(struct qlcnic_adapter *adapter)
{
if (qlcnic_84xx_check(adapter))
return QLC_84XX_VNIC_COUNT;
else
return QLC_DEFAULT_VNIC_COUNT;
}
#endif /* __QLCNIC_H_ */
78 changes: 58 additions & 20 deletions drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

#define RSS_HASHTYPE_IP_TCP 0x3
#define QLC_83XX_FW_MBX_CMD 0
#define QLC_SKIP_INACTIVE_PCI_REGS 7

static const struct qlcnic_mailbox_metadata qlcnic_83xx_mbx_tbl[] = {
{QLCNIC_CMD_CONFIGURE_IP_ADDR, 6, 1},
Expand All @@ -34,7 +35,7 @@ static const struct qlcnic_mailbox_metadata qlcnic_83xx_mbx_tbl[] = {
{QLCNIC_CMD_READ_MAX_MTU, 4, 2},
{QLCNIC_CMD_READ_MAX_LRO, 4, 2},
{QLCNIC_CMD_MAC_ADDRESS, 4, 3},
{QLCNIC_CMD_GET_PCI_INFO, 1, 66},
{QLCNIC_CMD_GET_PCI_INFO, 1, 129},
{QLCNIC_CMD_GET_NIC_INFO, 2, 19},
{QLCNIC_CMD_SET_NIC_INFO, 32, 1},
{QLCNIC_CMD_GET_ESWITCH_CAPABILITY, 4, 3},
Expand Down Expand Up @@ -68,7 +69,7 @@ static const struct qlcnic_mailbox_metadata qlcnic_83xx_mbx_tbl[] = {
{QLCNIC_CMD_CONFIG_VPORT, 4, 4},
{QLCNIC_CMD_BC_EVENT_SETUP, 2, 1},
{QLCNIC_CMD_DCB_QUERY_CAP, 1, 2},
{QLCNIC_CMD_DCB_QUERY_PARAM, 2, 50},
{QLCNIC_CMD_DCB_QUERY_PARAM, 1, 50},
};

const u32 qlcnic_83xx_ext_reg_tbl[] = {
Expand Down Expand Up @@ -289,6 +290,7 @@ int qlcnic_83xx_setup_intr(struct qlcnic_adapter *adapter)
if (qlcnic_sriov_vf_check(adapter))
return -EINVAL;
num_msix = 1;
adapter->drv_tx_rings = QLCNIC_SINGLE_RING;
}
/* setup interrupt mapping table for fw */
ahw->intr_tbl = vzalloc(num_msix *
Expand Down Expand Up @@ -636,7 +638,7 @@ int qlcnic_83xx_get_port_info(struct qlcnic_adapter *adapter)
void qlcnic_83xx_set_mac_filter_count(struct qlcnic_adapter *adapter)
{
struct qlcnic_hardware_context *ahw = adapter->ahw;
u16 act_pci_fn = ahw->act_pci_func;
u16 act_pci_fn = ahw->total_nic_func;
u16 count;

ahw->max_mc_count = QLC_83XX_MAX_MC_COUNT;
Expand Down Expand Up @@ -1518,30 +1520,29 @@ int qlcnic_83xx_set_led(struct net_device *netdev,
return err;
}

void qlcnic_83xx_register_nic_idc_func(struct qlcnic_adapter *adapter,
int enable)
void qlcnic_83xx_initialize_nic(struct qlcnic_adapter *adapter, int enable)
{
struct qlcnic_cmd_args cmd;
int status;

if (qlcnic_sriov_vf_check(adapter))
return;

if (enable) {
if (enable)
status = qlcnic_alloc_mbx_args(&cmd, adapter,
QLCNIC_CMD_INIT_NIC_FUNC);
if (status)
return;

cmd.req.arg[1] = BIT_0 | BIT_31;
} else {
else
status = qlcnic_alloc_mbx_args(&cmd, adapter,
QLCNIC_CMD_STOP_NIC_FUNC);
if (status)
return;

cmd.req.arg[1] = BIT_0 | BIT_31;
}
if (status)
return;

cmd.req.arg[1] = QLC_REGISTER_LB_IDC | QLC_INIT_FW_RESOURCES;

if (adapter->dcb)
cmd.req.arg[1] |= QLC_REGISTER_DCB_AEN;

status = qlcnic_issue_cmd(adapter, &cmd);
if (status)
dev_err(&adapter->pdev->dev,
Expand Down Expand Up @@ -1637,7 +1638,7 @@ int qlcnic_83xx_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode)

cmd->type = QLC_83XX_MBX_CMD_NO_WAIT;
qlcnic_83xx_set_interface_id_promisc(adapter, &temp);
cmd->req.arg[1] = (mode ? 1 : 0) | temp;
cmd->req.arg[1] = mode | temp;
err = qlcnic_issue_cmd(adapter, cmd);
if (!err)
return err;
Expand Down Expand Up @@ -2293,11 +2294,37 @@ int qlcnic_83xx_get_nic_info(struct qlcnic_adapter *adapter,
return err;
}

int qlcnic_get_pci_func_type(struct qlcnic_adapter *adapter, u16 type,
u16 *nic, u16 *fcoe, u16 *iscsi)
{
struct device *dev = &adapter->pdev->dev;
int err = 0;

switch (type) {
case QLCNIC_TYPE_NIC:
(*nic)++;
break;
case QLCNIC_TYPE_FCOE:
(*fcoe)++;
break;
case QLCNIC_TYPE_ISCSI:
(*iscsi)++;
break;
default:
dev_err(dev, "%s: Unknown PCI type[%x]\n",
__func__, type);
err = -EIO;
}

return err;
}

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;
u16 nic = 0, fcoe = 0, iscsi = 0;
struct qlcnic_cmd_args cmd;
int i, err = 0, j = 0;
u32 temp;
Expand All @@ -2308,16 +2335,20 @@ int qlcnic_83xx_get_pci_info(struct qlcnic_adapter *adapter,

err = qlcnic_issue_cmd(adapter, &cmd);

ahw->act_pci_func = 0;
ahw->total_nic_func = 0;
if (err == QLCNIC_RCODE_SUCCESS) {
ahw->max_pci_func = cmd.rsp.arg[1] & 0xFF;
for (i = 2, j = 0; j < QLCNIC_MAX_PCI_FUNC; j++, pci_info++) {
for (i = 2, j = 0; j < ahw->max_vnic_func; j++, pci_info++) {
pci_info->id = cmd.rsp.arg[i] & 0xFFFF;
pci_info->active = (cmd.rsp.arg[i] & 0xFFFF0000) >> 16;
i++;
if (!pci_info->active) {
i += QLC_SKIP_INACTIVE_PCI_REGS;
continue;
}
pci_info->type = cmd.rsp.arg[i] & 0xFFFF;
if (pci_info->type == QLCNIC_TYPE_NIC)
ahw->act_pci_func++;
err = qlcnic_get_pci_func_type(adapter, pci_info->type,
&nic, &fcoe, &iscsi);
temp = (cmd.rsp.arg[i] & 0xFFFF0000) >> 16;
pci_info->default_port = temp;
i++;
Expand All @@ -2335,6 +2366,13 @@ int qlcnic_83xx_get_pci_info(struct qlcnic_adapter *adapter,
err = -EIO;
}

ahw->total_nic_func = nic;
ahw->total_pci_func = nic + fcoe + iscsi;
if (ahw->total_nic_func == 0 || ahw->total_pci_func == 0) {
dev_err(dev, "%s: Invalid function count: total nic func[%x], total pci func[%x]\n",
__func__, ahw->total_nic_func, ahw->total_pci_func);
err = -EIO;
}
qlcnic_free_mbx_args(&cmd);

return err;
Expand Down
12 changes: 11 additions & 1 deletion drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,11 @@ struct qlc_83xx_idc {
char **name;
};

enum qlcnic_vlan_operations {
QLC_VLAN_ADD = 0,
QLC_VLAN_DELETE
};

/* Device States */
enum qlcnic_83xx_states {
QLC_83XX_IDC_DEV_UNKNOWN,
Expand Down Expand Up @@ -518,6 +523,11 @@ enum qlc_83xx_ext_regs {
QLC_83XX_ASIC_TEMP,
};

/* Initialize/Stop NIC command bit definitions */
#define QLC_REGISTER_DCB_AEN BIT_1
#define QLC_REGISTER_LB_IDC BIT_0
#define QLC_INIT_FW_RESOURCES BIT_31

/* 83xx funcitons */
int qlcnic_83xx_get_fw_version(struct qlcnic_adapter *);
int qlcnic_83xx_issue_cmd(struct qlcnic_adapter *, struct qlcnic_cmd_args *);
Expand All @@ -542,7 +552,7 @@ int qlcnic_83xx_config_intr_coalesce(struct qlcnic_adapter *);
void qlcnic_83xx_change_l2_filter(struct qlcnic_adapter *, u64 *, u16);
int qlcnic_83xx_get_pci_info(struct qlcnic_adapter *, struct qlcnic_pci_info *);
int qlcnic_83xx_set_nic_info(struct qlcnic_adapter *, struct qlcnic_info *);
void qlcnic_83xx_register_nic_idc_func(struct qlcnic_adapter *, int);
void qlcnic_83xx_initialize_nic(struct qlcnic_adapter *, int);

int qlcnic_83xx_napi_add(struct qlcnic_adapter *, struct net_device *);
void qlcnic_83xx_napi_del(struct qlcnic_adapter *);
Expand Down
14 changes: 3 additions & 11 deletions drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -614,8 +614,7 @@ int qlcnic_83xx_idc_reattach_driver(struct qlcnic_adapter *adapter)
qlcnic_83xx_reinit_mbx_work(adapter->ahw->mailbox);
qlcnic_83xx_enable_mbx_interrupt(adapter);

/* register for NIC IDC AEN Events */
qlcnic_83xx_register_nic_idc_func(adapter, 1);
qlcnic_83xx_initialize_nic(adapter, 1);

err = qlcnic_sriov_pf_reinit(adapter);
if (err)
Expand Down Expand Up @@ -2198,7 +2197,6 @@ static void qlcnic_83xx_init_rings(struct qlcnic_adapter *adapter)
int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac)
{
struct qlcnic_hardware_context *ahw = adapter->ahw;
struct qlcnic_dcb *dcb;
int err = 0;

ahw->msix_supported = !!qlcnic_use_msi_x;
Expand Down Expand Up @@ -2250,8 +2248,7 @@ int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac)

INIT_DELAYED_WORK(&adapter->idc_aen_work, qlcnic_83xx_idc_aen_work);

/* register for NIC IDC AEN Events */
qlcnic_83xx_register_nic_idc_func(adapter, 1);
qlcnic_83xx_initialize_nic(adapter, 1);

/* Configure default, SR-IOV or Virtual NIC mode of operation */
err = qlcnic_83xx_configure_opmode(adapter);
Expand All @@ -2264,11 +2261,6 @@ int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac)
if (err)
goto disable_mbx_intr;

dcb = adapter->dcb;

if (dcb && qlcnic_dcb_attach(dcb))
qlcnic_clear_dcb_ops(dcb);

/* Periodically monitor device status */
qlcnic_83xx_idc_poll_dev_state(&adapter->fw_work.work);
return 0;
Expand Down Expand Up @@ -2299,7 +2291,7 @@ void qlcnic_83xx_aer_stop_poll_work(struct qlcnic_adapter *adapter)
qlcnic_83xx_disable_vnic_mode(adapter, 1);

qlcnic_83xx_idc_detach_driver(adapter);
qlcnic_83xx_register_nic_idc_func(adapter, 0);
qlcnic_83xx_initialize_nic(adapter, 0);

cancel_delayed_work_sync(&adapter->idc_aen_work);
}
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,15 +107,15 @@ static int qlcnic_83xx_init_mgmt_vnic(struct qlcnic_adapter *adapter)

npar = adapter->npars;

for (i = 0; i < ahw->act_pci_func; i++, npar++) {
for (i = 0; i < ahw->total_nic_func; i++, npar++) {
dev_info(dev, "id:%d active:%d type:%d port:%d min_bw:%d max_bw:%d mac_addr:%pM\n",
npar->pci_func, npar->active, npar->type,
npar->phy_port, npar->min_bw, npar->max_bw,
npar->mac);
}

dev_info(dev, "Max functions = %d, active functions = %d\n",
ahw->max_pci_func, ahw->act_pci_func);
ahw->max_pci_func, ahw->total_nic_func);

if (qlcnic_83xx_set_vnic_opmode(adapter))
return err;
Expand Down
Loading

0 comments on commit 5c509a2

Please sign in to comment.