提交 5d6fa099 编写于 作者: D David S. Miller

Merge branch 'qlcnic'

Himanshu Madhani says:

====================
qlcnic: ethtool enhancements and code cleanup.

This patch series contains

o updates to ethtool for pause settings and enhance
  register dump to display mask and ring indices.
o cleanup in DCB code and remove redundant eSwitch enablement command.
o fixed firmware dump collection logic to skip unknown entries.

Changes from v3 -> v4
o Dropped patch for Tx queue validation to be submitted in net.

Changes from v2 -> v3

o Updated patch to print informational messages as per Joe Perches's comment.

Changes from v1 -> v2

o Dropped patch to register device if adapter is in FAILED state for more rework.
o Updated patch to display ring indices via ethtool per Ben Hutchings's comment.
o Update patch for DCB cleanup per Stephen Hemminger's comment.

Please apply to net-next.
====================
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
......@@ -38,8 +38,8 @@
#define _QLCNIC_LINUX_MAJOR 5
#define _QLCNIC_LINUX_MINOR 3
#define _QLCNIC_LINUX_SUBVERSION 50
#define QLCNIC_LINUX_VERSIONID "5.3.50"
#define _QLCNIC_LINUX_SUBVERSION 51
#define QLCNIC_LINUX_VERSIONID "5.3.51"
#define QLCNIC_DRV_IDC_VER 0x01
#define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\
(_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION))
......@@ -961,8 +961,6 @@ struct qlcnic_ipaddr {
#define __QLCNIC_SRIOV_CAPABLE 11
#define __QLCNIC_MBX_POLL_ENABLE 12
#define __QLCNIC_DIAG_MODE 13
#define __QLCNIC_DCB_STATE 14
#define __QLCNIC_DCB_IN_AEN 15
#define QLCNIC_INTERRUPT_TEST 1
#define QLCNIC_LOOPBACK_TEST 2
......@@ -1199,6 +1197,7 @@ struct qlcnic_npar_info {
u8 promisc_mode;
u8 offload_flags;
u8 pci_func;
u8 mac[ETH_ALEN];
};
struct qlcnic_eswitch {
......@@ -2115,98 +2114,4 @@ static inline bool qlcnic_sriov_vf_check(struct qlcnic_adapter *adapter)
return status;
}
static inline int qlcnic_dcb_get_hw_capability(struct qlcnic_adapter *adapter)
{
struct qlcnic_dcb *dcb = adapter->dcb;
if (dcb && dcb->ops->get_hw_capability)
return dcb->ops->get_hw_capability(adapter);
return 0;
}
static inline void qlcnic_dcb_free(struct qlcnic_adapter *adapter)
{
struct qlcnic_dcb *dcb = adapter->dcb;
if (dcb && dcb->ops->free)
dcb->ops->free(adapter);
}
static inline int qlcnic_dcb_attach(struct qlcnic_adapter *adapter)
{
struct qlcnic_dcb *dcb = adapter->dcb;
if (dcb && dcb->ops->attach)
return dcb->ops->attach(adapter);
return 0;
}
static inline int
qlcnic_dcb_query_hw_capability(struct qlcnic_adapter *adapter, char *buf)
{
struct qlcnic_dcb *dcb = adapter->dcb;
if (dcb && dcb->ops->query_hw_capability)
return dcb->ops->query_hw_capability(adapter, buf);
return 0;
}
static inline void qlcnic_dcb_get_info(struct qlcnic_adapter *adapter)
{
struct qlcnic_dcb *dcb = adapter->dcb;
if (dcb && dcb->ops->get_info)
dcb->ops->get_info(adapter);
}
static inline int
qlcnic_dcb_query_cee_param(struct qlcnic_adapter *adapter, char *buf, u8 type)
{
struct qlcnic_dcb *dcb = adapter->dcb;
if (dcb && dcb->ops->query_cee_param)
return dcb->ops->query_cee_param(adapter, buf, type);
return 0;
}
static inline int qlcnic_dcb_get_cee_cfg(struct qlcnic_adapter *adapter)
{
struct qlcnic_dcb *dcb = adapter->dcb;
if (dcb && dcb->ops->get_cee_cfg)
return dcb->ops->get_cee_cfg(adapter);
return 0;
}
static inline void
qlcnic_dcb_register_aen(struct qlcnic_adapter *adapter, u8 flag)
{
struct qlcnic_dcb *dcb = adapter->dcb;
if (dcb && dcb->ops->register_aen)
dcb->ops->register_aen(adapter, flag);
}
static inline void qlcnic_dcb_handle_aen(struct qlcnic_adapter *adapter,
void *msg)
{
struct qlcnic_dcb *dcb = adapter->dcb;
if (dcb && dcb->ops->handle_aen)
dcb->ops->handle_aen(adapter, msg);
}
static inline void qlcnic_dcb_init_dcbnl_ops(struct qlcnic_adapter *adapter)
{
struct qlcnic_dcb *dcb = adapter->dcb;
if (dcb && dcb->ops->init_dcbnl_ops)
dcb->ops->init_dcbnl_ops(adapter);
}
#endif /* __QLCNIC_H_ */
......@@ -902,7 +902,7 @@ void __qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter)
QLCNIC_MBX_RSP(event[0]));
break;
case QLCNIC_MBX_DCBX_CONFIG_CHANGE_EVENT:
qlcnic_dcb_handle_aen(adapter, (void *)&event[1]);
qlcnic_dcb_aen_handler(adapter->dcb, (void *)&event[1]);
break;
default:
dev_dbg(&adapter->pdev->dev, "Unsupported AEN:0x%x.\n",
......@@ -2321,19 +2321,7 @@ 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;
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 functions = %d, active functions = %d\n",
ahw->max_pci_func, ahw->act_pci_func);
} else {
dev_err(dev, "Failed to get PCI Info, error = %d\n", err);
err = -EIO;
......@@ -3279,12 +3267,12 @@ int qlcnic_83xx_reg_test(struct qlcnic_adapter *adapter)
return 0;
}
int qlcnic_83xx_get_regs_len(struct qlcnic_adapter *adapter)
inline int qlcnic_83xx_get_regs_len(struct qlcnic_adapter *adapter)
{
return (ARRAY_SIZE(qlcnic_83xx_ext_reg_tbl) *
sizeof(adapter->ahw->ext_reg_tbl)) +
(ARRAY_SIZE(qlcnic_83xx_reg_tbl) +
sizeof(adapter->ahw->reg_tbl));
sizeof(*adapter->ahw->ext_reg_tbl)) +
(ARRAY_SIZE(qlcnic_83xx_reg_tbl) *
sizeof(*adapter->ahw->reg_tbl));
}
int qlcnic_83xx_get_registers(struct qlcnic_adapter *adapter, u32 *regs_buff)
......@@ -3381,10 +3369,21 @@ void qlcnic_83xx_get_pauseparam(struct qlcnic_adapter *adapter,
}
config = ahw->port_config;
if (config & QLC_83XX_CFG_STD_PAUSE) {
if (config & QLC_83XX_CFG_STD_TX_PAUSE)
switch (MSW(config)) {
case QLC_83XX_TX_PAUSE:
pause->tx_pause = 1;
if (config & QLC_83XX_CFG_STD_RX_PAUSE)
break;
case QLC_83XX_RX_PAUSE:
pause->rx_pause = 1;
break;
case QLC_83XX_TX_RX_PAUSE:
default:
/* Backward compatibility for existing
* flash definitions
*/
pause->tx_pause = 1;
pause->rx_pause = 1;
}
}
if (QLC_83XX_AUTONEG(config))
......@@ -3427,7 +3426,8 @@ int qlcnic_83xx_set_pauseparam(struct qlcnic_adapter *adapter,
ahw->port_config &= ~QLC_83XX_CFG_STD_RX_PAUSE;
ahw->port_config |= QLC_83XX_CFG_STD_TX_PAUSE;
} else if (!pause->rx_pause && !pause->tx_pause) {
ahw->port_config &= ~QLC_83XX_CFG_STD_TX_RX_PAUSE;
ahw->port_config &= ~(QLC_83XX_CFG_STD_TX_RX_PAUSE |
QLC_83XX_CFG_STD_PAUSE);
}
status = qlcnic_83xx_set_port_config(adapter);
if (status) {
......
......@@ -363,6 +363,9 @@ enum qlcnic_83xx_states {
#define QLC_83XX_LINK_EEE(data) ((data) & BIT_13)
#define QLC_83XX_DCBX(data) (((data) >> 28) & 7)
#define QLC_83XX_AUTONEG(data) ((data) & BIT_15)
#define QLC_83XX_TX_PAUSE 0x10
#define QLC_83XX_RX_PAUSE 0x20
#define QLC_83XX_TX_RX_PAUSE 0x30
#define QLC_83XX_CFG_STD_PAUSE (1 << 5)
#define QLC_83XX_CFG_STD_TX_PAUSE (1 << 20)
#define QLC_83XX_CFG_STD_RX_PAUSE (2 << 20)
......@@ -626,7 +629,7 @@ int qlcnic_83xx_config_vnic_opmode(struct qlcnic_adapter *);
int qlcnic_83xx_get_vnic_vport_info(struct qlcnic_adapter *,
struct qlcnic_info *, u8);
int qlcnic_83xx_get_vnic_pf_info(struct qlcnic_adapter *, struct qlcnic_info *);
int qlcnic_83xx_enable_port_eswitch(struct qlcnic_adapter *, int);
int qlcnic_83xx_set_port_eswitch_status(struct qlcnic_adapter *, int, int *);
void qlcnic_83xx_get_minidump_template(struct qlcnic_adapter *);
void qlcnic_83xx_get_stats(struct qlcnic_adapter *adapter, u64 *data);
......
......@@ -636,7 +636,7 @@ int qlcnic_83xx_idc_reattach_driver(struct qlcnic_adapter *adapter)
if (adapter->portnum == 0)
qlcnic_set_drv_version(adapter);
qlcnic_dcb_get_info(adapter);
qlcnic_dcb_get_info(adapter->dcb);
qlcnic_83xx_idc_attach_driver(adapter);
return 0;
......@@ -818,6 +818,7 @@ static int qlcnic_83xx_idc_ready_state(struct qlcnic_adapter *adapter)
struct qlcnic_hardware_context *ahw = adapter->ahw;
struct qlcnic_mailbox *mbx = ahw->mailbox;
int ret = 0;
u32 owner;
u32 val;
/* Perform NIC configuration based ready state entry actions */
......@@ -846,6 +847,10 @@ static int qlcnic_83xx_idc_ready_state(struct qlcnic_adapter *adapter)
clear_bit(QLC_83XX_MBX_READY, &mbx->status);
set_bit(__QLCNIC_RESETTING, &adapter->state);
qlcnic_83xx_idc_enter_need_reset_state(adapter, 1);
} else {
owner = qlcnic_83xx_idc_find_reset_owner_id(adapter);
if (ahw->pci_func == owner)
qlcnic_dump_fw(adapter);
}
return -EIO;
}
......@@ -1058,6 +1063,12 @@ void qlcnic_83xx_idc_poll_dev_state(struct work_struct *work)
adapter->ahw->idc.prev_state = adapter->ahw->idc.curr_state;
qlcnic_83xx_periodic_tasks(adapter);
/* Do not reschedule if firmaware is in hanged state and auto
* recovery is disabled
*/
if ((adapter->flags & QLCNIC_FW_HANG) && !qlcnic_auto_fw_reset)
return;
/* Re-schedule the function */
if (test_bit(QLC_83XX_MODULE_LOADED, &adapter->ahw->idc.status))
qlcnic_schedule_work(adapter, qlcnic_83xx_idc_poll_dev_state,
......@@ -2163,6 +2174,7 @@ static int qlcnic_83xx_get_fw_info(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;
......@@ -2220,8 +2232,10 @@ int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac)
if (err)
goto disable_mbx_intr;
if (adapter->dcb && qlcnic_dcb_attach(adapter))
qlcnic_clear_dcb_ops(adapter);
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);
......
......@@ -94,13 +94,29 @@ qlcnic_83xx_config_vnic_buff_descriptors(struct qlcnic_adapter *adapter)
**/
static int qlcnic_83xx_init_mgmt_vnic(struct qlcnic_adapter *adapter)
{
int err = -EIO;
struct qlcnic_hardware_context *ahw = adapter->ahw;
struct device *dev = &adapter->pdev->dev;
struct qlcnic_npar_info *npar;
int i, err = -EIO;
qlcnic_83xx_get_minidump_template(adapter);
if (!(adapter->flags & QLCNIC_ADAPTER_INITIALIZED)) {
if (qlcnic_init_pci_info(adapter))
return err;
npar = adapter->npars;
for (i = 0; i < ahw->act_pci_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);
if (qlcnic_83xx_set_vnic_opmode(adapter))
return err;
......@@ -115,12 +131,12 @@ static int qlcnic_83xx_init_mgmt_vnic(struct qlcnic_adapter *adapter)
return err;
qlcnic_83xx_config_vnic_buff_descriptors(adapter);
adapter->ahw->msix_supported = !!qlcnic_use_msi_x;
ahw->msix_supported = qlcnic_use_msi_x ? 1 : 0;
adapter->flags |= QLCNIC_ADAPTER_INITIALIZED;
qlcnic_83xx_enable_vnic_mode(adapter, 1);
dev_info(&adapter->pdev->dev, "HAL Version: %d, Management function\n",
adapter->ahw->fw_hal_version);
dev_info(dev, "HAL Version: %d, Management function\n",
ahw->fw_hal_version);
return 0;
}
......@@ -240,8 +256,8 @@ int qlcnic_83xx_check_vnic_state(struct qlcnic_adapter *adapter)
return 0;
}
static int qlcnic_83xx_get_eswitch_port_info(struct qlcnic_adapter *adapter,
int func, int *port_id)
int qlcnic_83xx_set_port_eswitch_status(struct qlcnic_adapter *adapter,
int func, int *port_id)
{
struct qlcnic_info nic_info;
int err = 0;
......@@ -257,23 +273,8 @@ static int qlcnic_83xx_get_eswitch_port_info(struct qlcnic_adapter *adapter,
else
err = -EIO;
return err;
}
int qlcnic_83xx_enable_port_eswitch(struct qlcnic_adapter *adapter, int func)
{
int id, err = 0;
err = qlcnic_83xx_get_eswitch_port_info(adapter, func, &id);
if (err)
return err;
if (!(adapter->eswitch[id].flags & QLCNIC_SWITCH_ENABLE)) {
if (!qlcnic_enable_eswitch(adapter, id, 1))
adapter->eswitch[id].flags |= QLCNIC_SWITCH_ENABLE;
else
err = -EIO;
}
if (!err)
adapter->eswitch[*port_id].flags |= QLCNIC_SWITCH_ENABLE;
return err;
}
......@@ -57,22 +57,22 @@ static const struct dcbnl_rtnl_ops qlcnic_dcbnl_ops;
static void qlcnic_dcb_aen_work(struct work_struct *);
static void qlcnic_dcb_data_cee_param_map(struct qlcnic_adapter *);
static inline void __qlcnic_init_dcbnl_ops(struct qlcnic_adapter *);
static void __qlcnic_dcb_free(struct qlcnic_adapter *);
static int __qlcnic_dcb_attach(struct qlcnic_adapter *);
static int __qlcnic_dcb_query_hw_capability(struct qlcnic_adapter *, char *);
static void __qlcnic_dcb_get_info(struct qlcnic_adapter *);
static int qlcnic_82xx_dcb_get_hw_capability(struct qlcnic_adapter *);
static int qlcnic_82xx_dcb_query_cee_param(struct qlcnic_adapter *, char *, u8);
static int qlcnic_82xx_dcb_get_cee_cfg(struct qlcnic_adapter *);
static void qlcnic_82xx_dcb_handle_aen(struct qlcnic_adapter *, void *);
static int qlcnic_83xx_dcb_get_hw_capability(struct qlcnic_adapter *);
static int qlcnic_83xx_dcb_query_cee_param(struct qlcnic_adapter *, char *, u8);
static int qlcnic_83xx_dcb_get_cee_cfg(struct qlcnic_adapter *);
static int qlcnic_83xx_dcb_register_aen(struct qlcnic_adapter *, bool);
static void qlcnic_83xx_dcb_handle_aen(struct qlcnic_adapter *, void *);
static inline void __qlcnic_init_dcbnl_ops(struct qlcnic_dcb *);
static void __qlcnic_dcb_free(struct qlcnic_dcb *);
static int __qlcnic_dcb_attach(struct qlcnic_dcb *);
static int __qlcnic_dcb_query_hw_capability(struct qlcnic_dcb *, char *);
static void __qlcnic_dcb_get_info(struct qlcnic_dcb *);
static int qlcnic_82xx_dcb_get_hw_capability(struct qlcnic_dcb *);
static int qlcnic_82xx_dcb_query_cee_param(struct qlcnic_dcb *, char *, u8);
static int qlcnic_82xx_dcb_get_cee_cfg(struct qlcnic_dcb *);
static void qlcnic_82xx_dcb_aen_handler(struct qlcnic_dcb *, void *);
static int qlcnic_83xx_dcb_get_hw_capability(struct qlcnic_dcb *);
static int qlcnic_83xx_dcb_query_cee_param(struct qlcnic_dcb *, char *, u8);
static int qlcnic_83xx_dcb_get_cee_cfg(struct qlcnic_dcb *);
static int qlcnic_83xx_dcb_register_aen(struct qlcnic_dcb *, bool);
static void qlcnic_83xx_dcb_aen_handler(struct qlcnic_dcb *, void *);
struct qlcnic_dcb_capability {
bool tsa_capability;
......@@ -180,7 +180,7 @@ static struct qlcnic_dcb_ops qlcnic_83xx_dcb_ops = {
.query_cee_param = qlcnic_83xx_dcb_query_cee_param,
.get_cee_cfg = qlcnic_83xx_dcb_get_cee_cfg,
.register_aen = qlcnic_83xx_dcb_register_aen,
.handle_aen = qlcnic_83xx_dcb_handle_aen,
.aen_handler = qlcnic_83xx_dcb_aen_handler,
};
static struct qlcnic_dcb_ops qlcnic_82xx_dcb_ops = {
......@@ -193,7 +193,7 @@ static struct qlcnic_dcb_ops qlcnic_82xx_dcb_ops = {
.get_hw_capability = qlcnic_82xx_dcb_get_hw_capability,
.query_cee_param = qlcnic_82xx_dcb_query_cee_param,
.get_cee_cfg = qlcnic_82xx_dcb_get_cee_cfg,
.handle_aen = qlcnic_82xx_dcb_handle_aen,
.aen_handler = qlcnic_82xx_dcb_aen_handler,
};
static u8 qlcnic_dcb_get_num_app(struct qlcnic_adapter *adapter, u32 val)
......@@ -242,10 +242,10 @@ static int qlcnic_dcb_prio_count(u8 up_tc_map)
return j;
}
static inline void __qlcnic_init_dcbnl_ops(struct qlcnic_adapter *adapter)
static inline void __qlcnic_init_dcbnl_ops(struct qlcnic_dcb *dcb)
{
if (test_bit(__QLCNIC_DCB_STATE, &adapter->state))
adapter->netdev->dcbnl_ops = &qlcnic_dcbnl_ops;
if (test_bit(QLCNIC_DCB_STATE, &dcb->state))
dcb->adapter->netdev->dcbnl_ops = &qlcnic_dcbnl_ops;
}
static void qlcnic_set_dcb_ops(struct qlcnic_adapter *adapter)
......@@ -256,7 +256,7 @@ static void qlcnic_set_dcb_ops(struct qlcnic_adapter *adapter)
adapter->dcb->ops = &qlcnic_83xx_dcb_ops;
}
int __qlcnic_register_dcb(struct qlcnic_adapter *adapter)
int qlcnic_register_dcb(struct qlcnic_adapter *adapter)
{
struct qlcnic_dcb *dcb;
......@@ -267,20 +267,22 @@ int __qlcnic_register_dcb(struct qlcnic_adapter *adapter)
adapter->dcb = dcb;
dcb->adapter = adapter;
qlcnic_set_dcb_ops(adapter);
dcb->state = 0;
return 0;
}
static void __qlcnic_dcb_free(struct qlcnic_adapter *adapter)
static void __qlcnic_dcb_free(struct qlcnic_dcb *dcb)
{
struct qlcnic_dcb *dcb = adapter->dcb;
struct qlcnic_adapter *adapter;
if (!dcb)
return;
qlcnic_dcb_register_aen(adapter, 0);
adapter = dcb->adapter;
qlcnic_dcb_register_aen(dcb, 0);
while (test_bit(__QLCNIC_DCB_IN_AEN, &adapter->state))
while (test_bit(QLCNIC_DCB_AEN_MODE, &dcb->state))
usleep_range(10000, 11000);
cancel_delayed_work_sync(&dcb->aen_work);
......@@ -298,23 +300,22 @@ static void __qlcnic_dcb_free(struct qlcnic_adapter *adapter)
adapter->dcb = NULL;
}
static void __qlcnic_dcb_get_info(struct qlcnic_adapter *adapter)
static void __qlcnic_dcb_get_info(struct qlcnic_dcb *dcb)
{
qlcnic_dcb_get_hw_capability(adapter);
qlcnic_dcb_get_cee_cfg(adapter);
qlcnic_dcb_register_aen(adapter, 1);
qlcnic_dcb_get_hw_capability(dcb);
qlcnic_dcb_get_cee_cfg(dcb);
qlcnic_dcb_register_aen(dcb, 1);
}
static int __qlcnic_dcb_attach(struct qlcnic_adapter *adapter)
static int __qlcnic_dcb_attach(struct qlcnic_dcb *dcb)
{
struct qlcnic_dcb *dcb = adapter->dcb;
int err = 0;
INIT_DELAYED_WORK(&dcb->aen_work, qlcnic_dcb_aen_work);
dcb->wq = create_singlethread_workqueue("qlcnic-dcb");
if (!dcb->wq) {
dev_err(&adapter->pdev->dev,
dev_err(&dcb->adapter->pdev->dev,
"DCB workqueue allocation failed. DCB will be disabled\n");
return -1;
}
......@@ -331,7 +332,7 @@ static int __qlcnic_dcb_attach(struct qlcnic_adapter *adapter)
goto out_free_cfg;
}
qlcnic_dcb_get_info(adapter);
qlcnic_dcb_get_info(dcb);
return 0;
out_free_cfg:
......@@ -345,9 +346,9 @@ static int __qlcnic_dcb_attach(struct qlcnic_adapter *adapter)
return err;
}
static int __qlcnic_dcb_query_hw_capability(struct qlcnic_adapter *adapter,
char *buf)
static int __qlcnic_dcb_query_hw_capability(struct qlcnic_dcb *dcb, char *buf)
{
struct qlcnic_adapter *adapter = dcb->adapter;
struct qlcnic_cmd_args cmd;
u32 mbx_out;
int err;
......@@ -371,15 +372,15 @@ static int __qlcnic_dcb_query_hw_capability(struct qlcnic_adapter *adapter,
return err;
}
static int __qlcnic_dcb_get_capability(struct qlcnic_adapter *adapter, u32 *val)
static int __qlcnic_dcb_get_capability(struct qlcnic_dcb *dcb, u32 *val)
{
struct qlcnic_dcb_capability *cap = &adapter->dcb->cfg->capability;
struct qlcnic_dcb_capability *cap = &dcb->cfg->capability;
u32 mbx_out;
int err;
memset(cap, 0, sizeof(struct qlcnic_dcb_capability));
err = qlcnic_dcb_query_hw_capability(adapter, (char *)val);
err = qlcnic_dcb_query_hw_capability(dcb, (char *)val);
if (err)
return err;
......@@ -397,21 +398,21 @@ static int __qlcnic_dcb_get_capability(struct qlcnic_adapter *adapter, u32 *val)
if (cap->max_num_tc > QLC_DCB_MAX_TC ||
cap->max_ets_tc > cap->max_num_tc ||
cap->max_pfc_tc > cap->max_num_tc) {
dev_err(&adapter->pdev->dev, "Invalid DCB configuration\n");
dev_err(&dcb->adapter->pdev->dev, "Invalid DCB configuration\n");
return -EINVAL;
}
return err;
}
static int qlcnic_82xx_dcb_get_hw_capability(struct qlcnic_adapter *adapter)
static int qlcnic_82xx_dcb_get_hw_capability(struct qlcnic_dcb *dcb)
{
struct qlcnic_dcb_cfg *cfg = adapter->dcb->cfg;
struct qlcnic_dcb_cfg *cfg = dcb->cfg;
struct qlcnic_dcb_capability *cap;
u32 mbx_out;
int err;
err = __qlcnic_dcb_get_capability(adapter, &mbx_out);
err = __qlcnic_dcb_get_capability(dcb, &mbx_out);
if (err)
return err;
......@@ -419,15 +420,16 @@ static int qlcnic_82xx_dcb_get_hw_capability(struct qlcnic_adapter *adapter)
cap->dcb_capability = DCB_CAP_DCBX_VER_CEE | DCB_CAP_DCBX_LLD_MANAGED;
if (cap->dcb_capability && cap->tsa_capability && cap->ets_capability)
set_bit(__QLCNIC_DCB_STATE, &adapter->state);
set_bit(QLCNIC_DCB_STATE, &dcb->state);
return err;
}
static int qlcnic_82xx_dcb_query_cee_param(struct qlcnic_adapter *adapter,
static int qlcnic_82xx_dcb_query_cee_param(struct qlcnic_dcb *dcb,
char *buf, u8 type)
{
u16 size = sizeof(struct qlcnic_82xx_dcb_param_mbx_le);
struct qlcnic_adapter *adapter = dcb->adapter;
struct qlcnic_82xx_dcb_param_mbx_le *prsp_le;
struct device *dev = &adapter->pdev->dev;
dma_addr_t cardrsp_phys_addr;
......@@ -447,8 +449,7 @@ static int qlcnic_82xx_dcb_query_cee_param(struct qlcnic_adapter *adapter,
return -EINVAL;
}
addr = dma_alloc_coherent(&adapter->pdev->dev, size, &cardrsp_phys_addr,
GFP_KERNEL);
addr = dma_alloc_coherent(dev, size, &cardrsp_phys_addr, GFP_KERNEL);
if (addr == NULL)
return -ENOMEM;
......@@ -488,72 +489,67 @@ static int qlcnic_82xx_dcb_query_cee_param(struct qlcnic_adapter *adapter,
qlcnic_free_mbx_args(&cmd);
out_free_rsp:
dma_free_coherent(&adapter->pdev->dev, size, addr, cardrsp_phys_addr);
dma_free_coherent(dev, size, addr, cardrsp_phys_addr);
return err;
}
static int qlcnic_82xx_dcb_get_cee_cfg(struct qlcnic_adapter *adapter)
static int qlcnic_82xx_dcb_get_cee_cfg(struct qlcnic_dcb *dcb)
{
struct qlcnic_dcb_mbx_params *mbx;
int err;
mbx = adapter->dcb->param;
mbx = dcb->param;
if (!mbx)
return 0;
err = qlcnic_dcb_query_cee_param(adapter, (char *)&mbx->type[0],
err = qlcnic_dcb_query_cee_param(dcb, (char *)&mbx->type[0],
QLC_DCB_LOCAL_PARAM_FWID);
if (err)
return err;
err = qlcnic_dcb_query_cee_param(adapter, (char *)&mbx->type[1],
err = qlcnic_dcb_query_cee_param(dcb, (char *)&mbx->type[1],
QLC_DCB_OPER_PARAM_FWID);
if (err)
return err;
err = qlcnic_dcb_query_cee_param(adapter, (char *)&mbx->type[2],
err = qlcnic_dcb_query_cee_param(dcb, (char *)&mbx->type[2],
QLC_DCB_PEER_PARAM_FWID);
if (err)
return err;
mbx->prio_tc_map = QLC_82XX_DCB_PRIO_TC_MAP;
qlcnic_dcb_data_cee_param_map(adapter);
qlcnic_dcb_data_cee_param_map(dcb->adapter);
return err;
}
static void qlcnic_dcb_aen_work(struct work_struct *work)
{
struct qlcnic_adapter *adapter;
struct qlcnic_dcb *dcb;
dcb = container_of(work, struct qlcnic_dcb, aen_work.work);
adapter = dcb->adapter;
qlcnic_dcb_get_cee_cfg(adapter);
clear_bit(__QLCNIC_DCB_IN_AEN, &adapter->state);
qlcnic_dcb_get_cee_cfg(dcb);
clear_bit(QLCNIC_DCB_AEN_MODE, &dcb->state);
}
static void qlcnic_82xx_dcb_handle_aen(struct qlcnic_adapter *adapter,
void *data)
static void qlcnic_82xx_dcb_aen_handler(struct qlcnic_dcb *dcb, void *data)
{
struct qlcnic_dcb *dcb = adapter->dcb;
if (test_and_set_bit(__QLCNIC_DCB_IN_AEN, &adapter->state))
if (test_and_set_bit(QLCNIC_DCB_AEN_MODE, &dcb->state))
return;
queue_delayed_work(dcb->wq, &dcb->aen_work, 0);
}
static int qlcnic_83xx_dcb_get_hw_capability(struct qlcnic_adapter *adapter)
static int qlcnic_83xx_dcb_get_hw_capability(struct qlcnic_dcb *dcb)
{
struct qlcnic_dcb_capability *cap = &adapter->dcb->cfg->capability;
struct qlcnic_dcb_capability *cap = &dcb->cfg->capability;
u32 mbx_out;
int err;
err = __qlcnic_dcb_get_capability(adapter, &mbx_out);
err = __qlcnic_dcb_get_capability(dcb, &mbx_out);
if (err)
return err;
......@@ -565,14 +561,15 @@ static int qlcnic_83xx_dcb_get_hw_capability(struct qlcnic_adapter *adapter)
cap->dcb_capability |= DCB_CAP_DCBX_LLD_MANAGED;
if (cap->dcb_capability && cap->tsa_capability && cap->ets_capability)
set_bit(__QLCNIC_DCB_STATE, &adapter->state);
set_bit(QLCNIC_DCB_STATE, &dcb->state);
return err;
}
static int qlcnic_83xx_dcb_query_cee_param(struct qlcnic_adapter *adapter,
static int qlcnic_83xx_dcb_query_cee_param(struct qlcnic_dcb *dcb,
char *buf, u8 idx)
{
struct qlcnic_adapter *adapter = dcb->adapter;
struct qlcnic_dcb_mbx_params mbx_out;
int err, i, j, k, max_app, size;
struct qlcnic_dcb_param *each;
......@@ -632,24 +629,23 @@ static int qlcnic_83xx_dcb_query_cee_param(struct qlcnic_adapter *adapter,
return err;
}
static int qlcnic_83xx_dcb_get_cee_cfg(struct qlcnic_adapter *adapter)
static int qlcnic_83xx_dcb_get_cee_cfg(struct qlcnic_dcb *dcb)
{
struct qlcnic_dcb *dcb = adapter->dcb;
int err;
err = qlcnic_dcb_query_cee_param(adapter, (char *)dcb->param, 0);
err = qlcnic_dcb_query_cee_param(dcb, (char *)dcb->param, 0);
if (err)
return err;
qlcnic_dcb_data_cee_param_map(adapter);
qlcnic_dcb_data_cee_param_map(dcb->adapter);
return err;
}
static int qlcnic_83xx_dcb_register_aen(struct qlcnic_adapter *adapter,
bool flag)
static int qlcnic_83xx_dcb_register_aen(struct qlcnic_dcb *dcb, bool flag)
{
u8 val = (flag ? QLCNIC_CMD_INIT_NIC_FUNC : QLCNIC_CMD_STOP_NIC_FUNC);
struct qlcnic_adapter *adapter = dcb->adapter;
struct qlcnic_cmd_args cmd;
int err;
......@@ -669,19 +665,17 @@ static int qlcnic_83xx_dcb_register_aen(struct qlcnic_adapter *adapter,
return err;
}
static void qlcnic_83xx_dcb_handle_aen(struct qlcnic_adapter *adapter,
void *data)
static void qlcnic_83xx_dcb_aen_handler(struct qlcnic_dcb *dcb, void *data)
{
struct qlcnic_dcb *dcb = adapter->dcb;
u32 *val = data;
if (test_and_set_bit(__QLCNIC_DCB_IN_AEN, &adapter->state))
if (test_and_set_bit(QLCNIC_DCB_AEN_MODE, &dcb->state))
return;
if (*val & BIT_8)
set_bit(__QLCNIC_DCB_STATE, &adapter->state);
set_bit(QLCNIC_DCB_STATE, &dcb->state);
else
clear_bit(__QLCNIC_DCB_STATE, &adapter->state);
clear_bit(QLCNIC_DCB_STATE, &dcb->state);
queue_delayed_work(dcb->wq, &dcb->aen_work, 0);
}
......@@ -814,12 +808,12 @@ static u8 qlcnic_dcb_get_state(struct net_device *netdev)
{
struct qlcnic_adapter *adapter = netdev_priv(netdev);
return test_bit(__QLCNIC_DCB_STATE, &adapter->state);
return test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state);
}
static void qlcnic_dcb_get_perm_hw_addr(struct net_device *netdev, u8 *addr)
{
memcpy(addr, netdev->dev_addr, netdev->addr_len);
memcpy(addr, netdev->perm_addr, netdev->addr_len);
}
static void
......@@ -834,7 +828,7 @@ qlcnic_dcb_get_pg_tc_cfg_tx(struct net_device *netdev, int tc, u8 *prio,
type = &adapter->dcb->cfg->type[QLC_DCB_OPER_IDX];
*prio = *pgid = *bw_per = *up_tc_map = 0;
if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state) ||
if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state) ||
!type->tc_param_valid)
return;
......@@ -870,7 +864,7 @@ static void qlcnic_dcb_get_pg_bwg_cfg_tx(struct net_device *netdev, int pgid,
*bw_pct = 0;
type = &adapter->dcb->cfg->type[QLC_DCB_OPER_IDX];
if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state) ||
if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state) ||
!type->tc_param_valid)
return;
......@@ -896,7 +890,7 @@ static void qlcnic_dcb_get_pfc_cfg(struct net_device *netdev, int prio,
*setting = 0;
type = &adapter->dcb->cfg->type[QLC_DCB_OPER_IDX];
if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state) ||
if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state) ||
!type->pfc_mode_enable)
return;
......@@ -915,7 +909,7 @@ static u8 qlcnic_dcb_get_capability(struct net_device *netdev, int capid,
{
struct qlcnic_adapter *adapter = netdev_priv(netdev);
if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state))
return 0;
switch (capid) {
......@@ -944,7 +938,7 @@ static int qlcnic_dcb_get_num_tcs(struct net_device *netdev, int attr, u8 *num)
struct qlcnic_adapter *adapter = netdev_priv(netdev);
struct qlcnic_dcb_cfg *cfg = adapter->dcb->cfg;
if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state))
return -EINVAL;
switch (attr) {
......@@ -967,7 +961,7 @@ static u8 qlcnic_dcb_get_app(struct net_device *netdev, u8 idtype, u16 id)
.protocol = id,
};
if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state))
return 0;
return dcb_getapp(netdev, &app);
......@@ -978,7 +972,7 @@ static u8 qlcnic_dcb_get_pfc_state(struct net_device *netdev)
struct qlcnic_adapter *adapter = netdev_priv(netdev);
struct qlcnic_dcb *dcb = adapter->dcb;
if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
if (!test_bit(QLCNIC_DCB_STATE, &dcb->state))
return 0;
return dcb->cfg->type[QLC_DCB_OPER_IDX].pfc_mode_enable;
......@@ -989,7 +983,7 @@ static u8 qlcnic_dcb_get_dcbx(struct net_device *netdev)
struct qlcnic_adapter *adapter = netdev_priv(netdev);
struct qlcnic_dcb_cfg *cfg = adapter->dcb->cfg;
if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state))
return 0;
return cfg->capability.dcb_capability;
......@@ -1000,7 +994,7 @@ static u8 qlcnic_dcb_get_feat_cfg(struct net_device *netdev, int fid, u8 *flag)
struct qlcnic_adapter *adapter = netdev_priv(netdev);
struct qlcnic_dcb_cee *type;
if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state))
return 1;
type = &adapter->dcb->cfg->type[QLC_DCB_OPER_IDX];
......@@ -1055,7 +1049,7 @@ static int qlcnic_dcb_peer_app_info(struct net_device *netdev,
*app_count = 0;
if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state))
return 0;
peer = &adapter->dcb->cfg->type[QLC_DCB_PEER_IDX];
......@@ -1076,7 +1070,7 @@ static int qlcnic_dcb_peer_app_table(struct net_device *netdev,
struct qlcnic_dcb_app *app;
int i, j;
if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state))
return 0;
peer = &adapter->dcb->cfg->type[QLC_DCB_PEER_IDX];
......@@ -1101,7 +1095,7 @@ static int qlcnic_dcb_cee_peer_get_pg(struct net_device *netdev,
struct qlcnic_dcb_cee *peer;
u8 i, j, k, map;
if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state))
return 0;
peer = &adapter->dcb->cfg->type[QLC_DCB_PEER_IDX];
......@@ -1136,7 +1130,7 @@ static int qlcnic_dcb_cee_peer_get_pfc(struct net_device *netdev,
pfc->pfc_en = 0;
if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state))
return 0;
peer = &cfg->type[QLC_DCB_PEER_IDX];
......
......@@ -8,26 +8,29 @@
#ifndef __QLCNIC_DCBX_H
#define __QLCNIC_DCBX_H
void qlcnic_clear_dcb_ops(struct qlcnic_adapter *);
#define QLCNIC_DCB_STATE 0
#define QLCNIC_DCB_AEN_MODE 1
#ifdef CONFIG_QLCNIC_DCB
int __qlcnic_register_dcb(struct qlcnic_adapter *);
int qlcnic_register_dcb(struct qlcnic_adapter *);
#else
static inline int __qlcnic_register_dcb(struct qlcnic_adapter *adapter)
static inline int qlcnic_register_dcb(struct qlcnic_adapter *adapter)
{ return 0; }
#endif
struct qlcnic_dcb;
struct qlcnic_dcb_ops {
void (*init_dcbnl_ops) (struct qlcnic_adapter *);
void (*free) (struct qlcnic_adapter *);
int (*attach) (struct qlcnic_adapter *);
int (*query_hw_capability) (struct qlcnic_adapter *, char *);
int (*get_hw_capability) (struct qlcnic_adapter *);
void (*get_info) (struct qlcnic_adapter *);
int (*query_cee_param) (struct qlcnic_adapter *, char *, u8);
int (*get_cee_cfg) (struct qlcnic_adapter *);
int (*register_aen) (struct qlcnic_adapter *, bool);
void (*handle_aen) (struct qlcnic_adapter *, void *);
int (*query_hw_capability) (struct qlcnic_dcb *, char *);
int (*get_hw_capability) (struct qlcnic_dcb *);
int (*query_cee_param) (struct qlcnic_dcb *, char *, u8);
void (*init_dcbnl_ops) (struct qlcnic_dcb *);
int (*register_aen) (struct qlcnic_dcb *, bool);
void (*aen_handler) (struct qlcnic_dcb *, void *);
int (*get_cee_cfg) (struct qlcnic_dcb *);
void (*get_info) (struct qlcnic_dcb *);
int (*attach) (struct qlcnic_dcb *);
void (*free) (struct qlcnic_dcb *);
};
struct qlcnic_dcb {
......@@ -37,5 +40,85 @@ struct qlcnic_dcb {
struct workqueue_struct *wq;
struct qlcnic_dcb_ops *ops;
struct qlcnic_dcb_cfg *cfg;
unsigned long state;
};
static inline void qlcnic_clear_dcb_ops(struct qlcnic_dcb *dcb)
{
kfree(dcb);
dcb = NULL;
}
static inline int qlcnic_dcb_get_hw_capability(struct qlcnic_dcb *dcb)
{
if (dcb && dcb->ops->get_hw_capability)
return dcb->ops->get_hw_capability(dcb);
return 0;
}
static inline void qlcnic_dcb_free(struct qlcnic_dcb *dcb)
{
if (dcb && dcb->ops->free)
dcb->ops->free(dcb);
}
static inline int qlcnic_dcb_attach(struct qlcnic_dcb *dcb)
{
if (dcb && dcb->ops->attach)
return dcb->ops->attach(dcb);
return 0;
}
static inline int
qlcnic_dcb_query_hw_capability(struct qlcnic_dcb *dcb, char *buf)
{
if (dcb && dcb->ops->query_hw_capability)
return dcb->ops->query_hw_capability(dcb, buf);
return 0;
}
static inline void qlcnic_dcb_get_info(struct qlcnic_dcb *dcb)
{
if (dcb && dcb->ops->get_info)
dcb->ops->get_info(dcb);
}
static inline int
qlcnic_dcb_query_cee_param(struct qlcnic_dcb *dcb, char *buf, u8 type)
{
if (dcb && dcb->ops->query_cee_param)
return dcb->ops->query_cee_param(dcb, buf, type);
return 0;
}
static inline int qlcnic_dcb_get_cee_cfg(struct qlcnic_dcb *dcb)
{
if (dcb && dcb->ops->get_cee_cfg)
return dcb->ops->get_cee_cfg(dcb);
return 0;
}
static inline void
qlcnic_dcb_register_aen(struct qlcnic_dcb *dcb, u8 flag)
{
if (dcb && dcb->ops->register_aen)
dcb->ops->register_aen(dcb, flag);
}
static inline void qlcnic_dcb_aen_handler(struct qlcnic_dcb *dcb, void *msg)
{
if (dcb && dcb->ops->aen_handler)
dcb->ops->aen_handler(dcb, msg);
}
static inline void qlcnic_dcb_init_dcbnl_ops(struct qlcnic_dcb *dcb)
{
if (dcb && dcb->ops->init_dcbnl_ops)
dcb->ops->init_dcbnl_ops(dcb);
}
#endif
......@@ -187,8 +187,8 @@ static int qlcnic_dev_statistics_len(struct qlcnic_adapter *adapter)
return -1;
}
#define QLCNIC_RING_REGS_COUNT 20
#define QLCNIC_RING_REGS_LEN (QLCNIC_RING_REGS_COUNT * sizeof(u32))
#define QLCNIC_TX_INTR_NOT_CONFIGURED 0X78563412
#define QLCNIC_MAX_EEPROM_LEN 1024
static const u32 diag_registers[] = {
......@@ -219,7 +219,15 @@ static const u32 ext_diag_registers[] = {
};
#define QLCNIC_MGMT_API_VERSION 2
#define QLCNIC_ETHTOOL_REGS_VER 3
#define QLCNIC_ETHTOOL_REGS_VER 4
static inline int qlcnic_get_ring_regs_len(struct qlcnic_adapter *adapter)
{
int ring_regs_cnt = (adapter->max_drv_tx_rings * 5) +
(adapter->max_rds_rings * 2) +
(adapter->max_sds_rings * 3) + 5;
return ring_regs_cnt * sizeof(u32);
}
static int qlcnic_get_regs_len(struct net_device *dev)
{
......@@ -231,7 +239,9 @@ static int qlcnic_get_regs_len(struct net_device *dev)
else
len = sizeof(ext_diag_registers) + sizeof(diag_registers);
return QLCNIC_RING_REGS_LEN + len + QLCNIC_DEV_INFO_SIZE + 1;
len += ((QLCNIC_DEV_INFO_SIZE + 2) * sizeof(u32));
len += qlcnic_get_ring_regs_len(adapter);
return len;
}
static int qlcnic_get_eeprom_len(struct net_device *dev)
......@@ -493,6 +503,8 @@ qlcnic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
struct qlcnic_adapter *adapter = netdev_priv(dev);
struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
struct qlcnic_host_sds_ring *sds_ring;
struct qlcnic_host_rds_ring *rds_rings;
struct qlcnic_host_tx_ring *tx_ring;
u32 *regs_buff = p;
int ring, i = 0;
......@@ -512,21 +524,35 @@ qlcnic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
return;
regs_buff[i++] = 0xFFEFCDAB; /* Marker btw regs and ring count*/
regs_buff[i++] = 1; /* No. of tx ring */
regs_buff[i++] = le32_to_cpu(*(adapter->tx_ring->hw_consumer));
regs_buff[i++] = readl(adapter->tx_ring->crb_cmd_producer);
regs_buff[i++] = 2; /* No. of rx ring */
regs_buff[i++] = readl(recv_ctx->rds_rings[0].crb_rcv_producer);
regs_buff[i++] = readl(recv_ctx->rds_rings[1].crb_rcv_producer);
/* Marker btw regs and TX ring count */
regs_buff[i++] = 0xFFEFCDAB;
regs_buff[i++] = adapter->max_drv_tx_rings; /* No. of TX ring */
for (ring = 0; ring < adapter->max_drv_tx_rings; ring++) {
tx_ring = &adapter->tx_ring[ring];
regs_buff[i++] = le32_to_cpu(*(tx_ring->hw_consumer));
regs_buff[i++] = tx_ring->sw_consumer;
regs_buff[i++] = readl(tx_ring->crb_cmd_producer);
regs_buff[i++] = tx_ring->producer;
if (tx_ring->crb_intr_mask)
regs_buff[i++] = readl(tx_ring->crb_intr_mask);
else
regs_buff[i++] = QLCNIC_TX_INTR_NOT_CONFIGURED;
}
regs_buff[i++] = adapter->max_sds_rings;
regs_buff[i++] = adapter->max_rds_rings; /* No. of RX ring */
for (ring = 0; ring < adapter->max_rds_rings; ring++) {
rds_rings = &recv_ctx->rds_rings[ring];
regs_buff[i++] = readl(rds_rings->crb_rcv_producer);
regs_buff[i++] = rds_rings->producer;
}
regs_buff[i++] = adapter->max_sds_rings; /* No. of SDS ring */
for (ring = 0; ring < adapter->max_sds_rings; ring++) {
sds_ring = &(recv_ctx->sds_rings[ring]);
regs_buff[i++] = readl(sds_ring->crb_sts_consumer);
regs_buff[i++] = sds_ring->consumer;
regs_buff[i++] = readl(sds_ring->crb_intr_mask);
}
}
......
......@@ -1011,7 +1011,7 @@ static void qlcnic_handle_fw_message(int desc_cnt, int index,
}
break;
case QLCNIC_C2H_OPCODE_GET_DCB_AEN:
qlcnic_dcb_handle_aen(adapter, (void *)&msg);
qlcnic_dcb_aen_handler(adapter->dcb, (void *)&msg);
break;
default:
break;
......
......@@ -819,7 +819,7 @@ static bool qlcnic_port_eswitch_cfg_capability(struct qlcnic_adapter *adapter)
int qlcnic_init_pci_info(struct qlcnic_adapter *adapter)
{
struct qlcnic_pci_info *pci_info;
int i, ret = 0, j = 0;
int i, id = 0, ret = 0, j = 0;
u16 act_pci_func;
u8 pfn;
......@@ -860,7 +860,8 @@ int qlcnic_init_pci_info(struct qlcnic_adapter *adapter)
continue;
if (qlcnic_port_eswitch_cfg_capability(adapter)) {
if (!qlcnic_83xx_enable_port_eswitch(adapter, pfn))
if (!qlcnic_83xx_set_port_eswitch_status(adapter, pfn,
&id))
adapter->npars[j].eswitch_status = true;
else
continue;
......@@ -875,15 +876,16 @@ int qlcnic_init_pci_info(struct qlcnic_adapter *adapter)
adapter->npars[j].min_bw = pci_info[i].tx_min_bw;
adapter->npars[j].max_bw = pci_info[i].tx_max_bw;
memcpy(&adapter->npars[j].mac, &pci_info[i].mac, ETH_ALEN);
j++;
}
if (qlcnic_82xx_check(adapter)) {
/* Update eSwitch status for adapters without per port eSwitch
* configuration capability
*/
if (!qlcnic_port_eswitch_cfg_capability(adapter)) {
for (i = 0; i < QLCNIC_NIU_MAX_XG_PORTS; i++)
adapter->eswitch[i].flags |= QLCNIC_SWITCH_ENABLE;
} else if (!qlcnic_port_eswitch_cfg_capability(adapter)) {
for (i = 0; i < QLCNIC_NIU_MAX_XG_PORTS; i++)
qlcnic_enable_eswitch(adapter, i, 1);
}
kfree(pci_info);
......@@ -2069,7 +2071,7 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter, struct net_device *netdev,
return err;
}
qlcnic_dcb_init_dcbnl_ops(adapter);
qlcnic_dcb_init_dcbnl_ops(adapter->dcb);
return 0;
}
......@@ -2164,17 +2166,6 @@ void qlcnic_set_drv_version(struct qlcnic_adapter *adapter)
qlcnic_fw_cmd_set_drv_version(adapter, fw_cmd);
}
static int qlcnic_register_dcb(struct qlcnic_adapter *adapter)
{
return __qlcnic_register_dcb(adapter);
}
void qlcnic_clear_dcb_ops(struct qlcnic_adapter *adapter)
{
kfree(adapter->dcb);
adapter->dcb = NULL;
}
static int
qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
......@@ -2183,6 +2174,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
struct qlcnic_hardware_context *ahw;
int err, pci_using_dac = -1;
char board_name[QLCNIC_MAX_BOARD_NAME_LEN + 19]; /* MAC + ": " + name */
struct qlcnic_dcb *dcb;
if (pdev->is_virtfn)
return -ENODEV;
......@@ -2303,8 +2295,10 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
adapter->flags |= QLCNIC_NEED_FLR;
if (adapter->dcb && qlcnic_dcb_attach(adapter))
qlcnic_clear_dcb_ops(adapter);
dcb = adapter->dcb;
if (dcb && qlcnic_dcb_attach(dcb))
qlcnic_clear_dcb_ops(dcb);
} else if (qlcnic_83xx_check(adapter)) {
adapter->max_drv_tx_rings = 1;
......@@ -2449,7 +2443,7 @@ static void qlcnic_remove(struct pci_dev *pdev)
qlcnic_cancel_idc_work(adapter);
ahw = adapter->ahw;
qlcnic_dcb_free(adapter);
qlcnic_dcb_free(adapter->dcb);
unregister_netdev(netdev);
qlcnic_sriov_cleanup(adapter);
......@@ -3327,7 +3321,7 @@ qlcnic_attach_work(struct work_struct *work)
return;
}
attach:
qlcnic_dcb_get_info(adapter);
qlcnic_dcb_get_info(adapter->dcb);
if (netif_running(netdev)) {
if (qlcnic_up(adapter, netdev))
......@@ -3352,6 +3346,8 @@ qlcnic_attach_work(struct work_struct *work)
static int
qlcnic_check_health(struct qlcnic_adapter *adapter)
{
struct qlcnic_hardware_context *ahw = adapter->ahw;
struct qlcnic_fw_dump *fw_dump = &ahw->fw_dump;
u32 state = 0, heartbeat;
u32 peg_status;
int err = 0;
......@@ -3376,7 +3372,7 @@ qlcnic_check_health(struct qlcnic_adapter *adapter)
if (adapter->need_fw_reset)
goto detach;
if (adapter->ahw->reset_context && qlcnic_auto_fw_reset)
if (ahw->reset_context && qlcnic_auto_fw_reset)
qlcnic_reset_hw_context(adapter);
return 0;
......@@ -3419,6 +3415,9 @@ qlcnic_check_health(struct qlcnic_adapter *adapter)
qlcnic_schedule_work(adapter, qlcnic_detach_work, 0);
QLCDB(adapter, DRV, "fw recovery scheduled.\n");
} else if (!qlcnic_auto_fw_reset && fw_dump->enable &&
adapter->flags & QLCNIC_FW_RESET_OWNER) {
qlcnic_dump_fw(adapter);
}
return 1;
......
......@@ -1187,41 +1187,38 @@ int qlcnic_dump_fw(struct qlcnic_adapter *adapter)
}
if (ops_index == ops_cnt) {
dev_info(&adapter->pdev->dev,
"Invalid entry type %d, exiting dump\n",
dev_info(dev, "Skipping unknown entry opcode %d\n",
entry->hdr.type);
goto error;
entry->hdr.flags |= QLCNIC_DUMP_SKIP;
entry_offset += entry->hdr.offset;
continue;
}
/* Collect dump for this entry */
dump = fw_dump_ops[ops_index].handler(adapter, entry, buffer);
if (!qlcnic_valid_dump_entry(&adapter->pdev->dev, entry, dump))
if (!qlcnic_valid_dump_entry(dev, entry, dump)) {
entry->hdr.flags |= QLCNIC_DUMP_SKIP;
entry_offset += entry->hdr.offset;
continue;
}
buf_offset += entry->hdr.cap_size;
entry_offset += entry->hdr.offset;
buffer = fw_dump->data + buf_offset;
}
if (dump_size != buf_offset) {
dev_info(&adapter->pdev->dev,
"Captured(%d) and expected size(%d) do not match\n",
buf_offset, dump_size);
goto error;
} else {
fw_dump->clr = 1;
snprintf(mesg, sizeof(mesg), "FW_DUMP=%s",
adapter->netdev->name);
dev_info(&adapter->pdev->dev, "%s: Dump data, %d bytes captured\n",
adapter->netdev->name, fw_dump->size);
/* Send a udev event to notify availability of FW dump */
kobject_uevent_env(&adapter->pdev->dev.kobj, KOBJ_CHANGE, msg);
return 0;
}
error:
fw_dump->clr = 1;
snprintf(mesg, sizeof(mesg), "FW_DUMP=%s", adapter->netdev->name);
dev_info(dev, "%s: Dump data %d bytes captured, template header size %d bytes\n",
adapter->netdev->name, fw_dump->size, tmpl_hdr->size);
/* Send a udev event to notify availability of FW dump */
kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, msg);
if (fw_dump->use_pex_dma)
dma_free_coherent(dev, QLC_PEX_DMA_READ_SIZE,
fw_dump->dma_buffer, fw_dump->phys_addr);
vfree(fw_dump->data);
return -EINVAL;
return 0;
}
void qlcnic_83xx_get_minidump_template(struct qlcnic_adapter *adapter)
......
......@@ -500,6 +500,7 @@ static int qlcnic_sriov_vf_init_driver(struct qlcnic_adapter *adapter)
static int qlcnic_sriov_setup_vf(struct qlcnic_adapter *adapter,
int pci_using_dac)
{
struct qlcnic_dcb *dcb;
int err;
INIT_LIST_HEAD(&adapter->vf_mc_list);
......@@ -533,8 +534,10 @@ static int qlcnic_sriov_setup_vf(struct qlcnic_adapter *adapter,
if (err)
goto err_out_send_channel_term;
if (adapter->dcb && qlcnic_dcb_attach(adapter))
qlcnic_clear_dcb_ops(adapter);
dcb = adapter->dcb;
if (dcb && qlcnic_dcb_attach(dcb))
qlcnic_clear_dcb_ops(dcb);
err = qlcnic_setup_netdev(adapter, adapter->netdev, pci_using_dac);
if (err)
......@@ -1577,7 +1580,7 @@ static int qlcnic_sriov_vf_reinit_driver(struct qlcnic_adapter *adapter)
if (err)
goto err_out_term_channel;
qlcnic_dcb_get_info(adapter);
qlcnic_dcb_get_info(adapter->dcb);
return 0;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册