Commit 1e9e9901 authored by David S. Miller's avatar David S. Miller

Merge branch 'qlcnic'

Shahed Shaikh says:

====================
This patch series has following bug fixes:
* Fix a bug in unicast MAC address setting in adapter.
  Driver was not deleting older unicast MAC while adding new one.
* Fix an ethtool stats string array by adding missing string entry
  and fix a typo.
* Fix module paramter description. Bracket ')' was missing.
* Fix port status provided though 'ethtool <device>' for 83xx adapter.
* Fix reset recovery path in case of transmit timeout.
* Fix reset recovery during diagnostic tests by preserving
  current device status information.
* Fix mailbox response handling. Driver was not maintaining poll time properly.
* Fix validation of link event command.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 61f15982 cbccb18f
...@@ -429,6 +429,7 @@ struct qlcnic_hardware_context { ...@@ -429,6 +429,7 @@ struct qlcnic_hardware_context {
u16 port_type; u16 port_type;
u16 board_type; u16 board_type;
u16 supported_type;
u16 link_speed; u16 link_speed;
u16 link_duplex; u16 link_duplex;
...@@ -1514,6 +1515,7 @@ void qlcnic_create_diag_entries(struct qlcnic_adapter *adapter); ...@@ -1514,6 +1515,7 @@ void qlcnic_create_diag_entries(struct qlcnic_adapter *adapter);
void qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter); void qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter);
void qlcnic_82xx_add_sysfs(struct qlcnic_adapter *adapter); void qlcnic_82xx_add_sysfs(struct qlcnic_adapter *adapter);
void qlcnic_82xx_remove_sysfs(struct qlcnic_adapter *adapter); void qlcnic_82xx_remove_sysfs(struct qlcnic_adapter *adapter);
int qlcnic_82xx_get_settings(struct qlcnic_adapter *, struct ethtool_cmd *);
int qlcnicvf_config_bridged_mode(struct qlcnic_adapter *, u32); int qlcnicvf_config_bridged_mode(struct qlcnic_adapter *, u32);
int qlcnicvf_config_led(struct qlcnic_adapter *, u32, u32); int qlcnicvf_config_led(struct qlcnic_adapter *, u32, u32);
......
...@@ -696,15 +696,14 @@ u32 qlcnic_83xx_mac_rcode(struct qlcnic_adapter *adapter) ...@@ -696,15 +696,14 @@ u32 qlcnic_83xx_mac_rcode(struct qlcnic_adapter *adapter)
return 1; return 1;
} }
u32 qlcnic_83xx_mbx_poll(struct qlcnic_adapter *adapter) u32 qlcnic_83xx_mbx_poll(struct qlcnic_adapter *adapter, u32 *wait_time)
{ {
u32 data; u32 data;
unsigned long wait_time = 0;
struct qlcnic_hardware_context *ahw = adapter->ahw; struct qlcnic_hardware_context *ahw = adapter->ahw;
/* wait for mailbox completion */ /* wait for mailbox completion */
do { do {
data = QLCRDX(ahw, QLCNIC_FW_MBX_CTRL); data = QLCRDX(ahw, QLCNIC_FW_MBX_CTRL);
if (++wait_time > QLCNIC_MBX_TIMEOUT) { if (++(*wait_time) > QLCNIC_MBX_TIMEOUT) {
data = QLCNIC_RCODE_TIMEOUT; data = QLCNIC_RCODE_TIMEOUT;
break; break;
} }
...@@ -720,8 +719,8 @@ int qlcnic_83xx_mbx_op(struct qlcnic_adapter *adapter, ...@@ -720,8 +719,8 @@ int qlcnic_83xx_mbx_op(struct qlcnic_adapter *adapter,
u16 opcode; u16 opcode;
u8 mbx_err_code; u8 mbx_err_code;
unsigned long flags; unsigned long flags;
u32 rsp, mbx_val, fw_data, rsp_num, mbx_cmd;
struct qlcnic_hardware_context *ahw = adapter->ahw; struct qlcnic_hardware_context *ahw = adapter->ahw;
u32 rsp, mbx_val, fw_data, rsp_num, mbx_cmd, wait_time = 0;
opcode = LSW(cmd->req.arg[0]); opcode = LSW(cmd->req.arg[0]);
if (!test_bit(QLC_83XX_MBX_READY, &adapter->ahw->idc.status)) { if (!test_bit(QLC_83XX_MBX_READY, &adapter->ahw->idc.status)) {
...@@ -754,15 +753,13 @@ int qlcnic_83xx_mbx_op(struct qlcnic_adapter *adapter, ...@@ -754,15 +753,13 @@ int qlcnic_83xx_mbx_op(struct qlcnic_adapter *adapter,
/* Signal FW about the impending command */ /* Signal FW about the impending command */
QLCWRX(ahw, QLCNIC_HOST_MBX_CTRL, QLCNIC_SET_OWNER); QLCWRX(ahw, QLCNIC_HOST_MBX_CTRL, QLCNIC_SET_OWNER);
poll: poll:
rsp = qlcnic_83xx_mbx_poll(adapter); rsp = qlcnic_83xx_mbx_poll(adapter, &wait_time);
if (rsp != QLCNIC_RCODE_TIMEOUT) { if (rsp != QLCNIC_RCODE_TIMEOUT) {
/* Get the FW response data */ /* Get the FW response data */
fw_data = readl(QLCNIC_MBX_FW(ahw, 0)); fw_data = readl(QLCNIC_MBX_FW(ahw, 0));
if (fw_data & QLCNIC_MBX_ASYNC_EVENT) { if (fw_data & QLCNIC_MBX_ASYNC_EVENT) {
__qlcnic_83xx_process_aen(adapter); __qlcnic_83xx_process_aen(adapter);
mbx_val = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL); goto poll;
if (mbx_val)
goto poll;
} }
mbx_err_code = QLCNIC_MBX_STATUS(fw_data); mbx_err_code = QLCNIC_MBX_STATUS(fw_data);
rsp_num = QLCNIC_MBX_NUM_REGS(fw_data); rsp_num = QLCNIC_MBX_NUM_REGS(fw_data);
...@@ -1276,11 +1273,13 @@ int qlcnic_83xx_create_tx_ctx(struct qlcnic_adapter *adapter, ...@@ -1276,11 +1273,13 @@ int qlcnic_83xx_create_tx_ctx(struct qlcnic_adapter *adapter,
return err; return err;
} }
static int qlcnic_83xx_diag_alloc_res(struct net_device *netdev, int test) static int qlcnic_83xx_diag_alloc_res(struct net_device *netdev, int test,
int num_sds_ring)
{ {
struct qlcnic_adapter *adapter = netdev_priv(netdev); struct qlcnic_adapter *adapter = netdev_priv(netdev);
struct qlcnic_host_sds_ring *sds_ring; struct qlcnic_host_sds_ring *sds_ring;
struct qlcnic_host_rds_ring *rds_ring; struct qlcnic_host_rds_ring *rds_ring;
u16 adapter_state = adapter->is_up;
u8 ring; u8 ring;
int ret; int ret;
...@@ -1304,6 +1303,10 @@ static int qlcnic_83xx_diag_alloc_res(struct net_device *netdev, int test) ...@@ -1304,6 +1303,10 @@ static int qlcnic_83xx_diag_alloc_res(struct net_device *netdev, int test)
ret = qlcnic_fw_create_ctx(adapter); ret = qlcnic_fw_create_ctx(adapter);
if (ret) { if (ret) {
qlcnic_detach(adapter); qlcnic_detach(adapter);
if (adapter_state == QLCNIC_ADAPTER_UP_MAGIC) {
adapter->max_sds_rings = num_sds_ring;
qlcnic_attach(adapter);
}
netif_device_attach(netdev); netif_device_attach(netdev);
return ret; return ret;
} }
...@@ -1596,7 +1599,8 @@ int qlcnic_83xx_loopback_test(struct net_device *netdev, u8 mode) ...@@ -1596,7 +1599,8 @@ int qlcnic_83xx_loopback_test(struct net_device *netdev, u8 mode)
if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state)) if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
return -EBUSY; return -EBUSY;
ret = qlcnic_83xx_diag_alloc_res(netdev, QLCNIC_LOOPBACK_TEST); ret = qlcnic_83xx_diag_alloc_res(netdev, QLCNIC_LOOPBACK_TEST,
max_sds_rings);
if (ret) if (ret)
goto fail_diag_alloc; goto fail_diag_alloc;
...@@ -2830,6 +2834,23 @@ int qlcnic_83xx_test_link(struct qlcnic_adapter *adapter) ...@@ -2830,6 +2834,23 @@ int qlcnic_83xx_test_link(struct qlcnic_adapter *adapter)
break; break;
} }
config = cmd.rsp.arg[3]; config = cmd.rsp.arg[3];
if (QLC_83XX_SFP_PRESENT(config)) {
switch (ahw->module_type) {
case LINKEVENT_MODULE_OPTICAL_UNKNOWN:
case LINKEVENT_MODULE_OPTICAL_SRLR:
case LINKEVENT_MODULE_OPTICAL_LRM:
case LINKEVENT_MODULE_OPTICAL_SFP_1G:
ahw->supported_type = PORT_FIBRE;
break;
case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE:
case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN:
case LINKEVENT_MODULE_TWINAX:
ahw->supported_type = PORT_TP;
break;
default:
ahw->supported_type = PORT_OTHER;
}
}
if (config & 1) if (config & 1)
err = 1; err = 1;
} }
...@@ -2838,7 +2859,8 @@ int qlcnic_83xx_test_link(struct qlcnic_adapter *adapter) ...@@ -2838,7 +2859,8 @@ int qlcnic_83xx_test_link(struct qlcnic_adapter *adapter)
return config; return config;
} }
int qlcnic_83xx_get_settings(struct qlcnic_adapter *adapter) int qlcnic_83xx_get_settings(struct qlcnic_adapter *adapter,
struct ethtool_cmd *ecmd)
{ {
u32 config = 0; u32 config = 0;
int status = 0; int status = 0;
...@@ -2851,6 +2873,54 @@ int qlcnic_83xx_get_settings(struct qlcnic_adapter *adapter) ...@@ -2851,6 +2873,54 @@ int qlcnic_83xx_get_settings(struct qlcnic_adapter *adapter)
ahw->module_type = QLC_83XX_SFP_MODULE_TYPE(config); ahw->module_type = QLC_83XX_SFP_MODULE_TYPE(config);
/* hard code until there is a way to get it from flash */ /* hard code until there is a way to get it from flash */
ahw->board_type = QLCNIC_BRDTYPE_83XX_10G; ahw->board_type = QLCNIC_BRDTYPE_83XX_10G;
if (netif_running(adapter->netdev) && ahw->has_link_events) {
ethtool_cmd_speed_set(ecmd, ahw->link_speed);
ecmd->duplex = ahw->link_duplex;
ecmd->autoneg = ahw->link_autoneg;
} else {
ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN);
ecmd->duplex = DUPLEX_UNKNOWN;
ecmd->autoneg = AUTONEG_DISABLE;
}
if (ahw->port_type == QLCNIC_XGBE) {
ecmd->supported = SUPPORTED_1000baseT_Full;
ecmd->advertising = ADVERTISED_1000baseT_Full;
} else {
ecmd->supported = (SUPPORTED_10baseT_Half |
SUPPORTED_10baseT_Full |
SUPPORTED_100baseT_Half |
SUPPORTED_100baseT_Full |
SUPPORTED_1000baseT_Half |
SUPPORTED_1000baseT_Full);
ecmd->advertising = (ADVERTISED_100baseT_Half |
ADVERTISED_100baseT_Full |
ADVERTISED_1000baseT_Half |
ADVERTISED_1000baseT_Full);
}
switch (ahw->supported_type) {
case PORT_FIBRE:
ecmd->supported |= SUPPORTED_FIBRE;
ecmd->advertising |= ADVERTISED_FIBRE;
ecmd->port = PORT_FIBRE;
ecmd->transceiver = XCVR_EXTERNAL;
break;
case PORT_TP:
ecmd->supported |= SUPPORTED_TP;
ecmd->advertising |= ADVERTISED_TP;
ecmd->port = PORT_TP;
ecmd->transceiver = XCVR_INTERNAL;
break;
default:
ecmd->supported |= SUPPORTED_FIBRE;
ecmd->advertising |= ADVERTISED_FIBRE;
ecmd->port = PORT_OTHER;
ecmd->transceiver = XCVR_EXTERNAL;
break;
}
ecmd->phy_address = ahw->physical_port;
return status; return status;
} }
...@@ -3046,7 +3116,8 @@ int qlcnic_83xx_interrupt_test(struct net_device *netdev) ...@@ -3046,7 +3116,8 @@ int qlcnic_83xx_interrupt_test(struct net_device *netdev)
if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state)) if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
return -EIO; return -EIO;
ret = qlcnic_83xx_diag_alloc_res(netdev, QLCNIC_INTERRUPT_TEST); ret = qlcnic_83xx_diag_alloc_res(netdev, QLCNIC_INTERRUPT_TEST,
max_sds_rings);
if (ret) if (ret)
goto fail_diag_irq; goto fail_diag_irq;
......
...@@ -603,7 +603,7 @@ int qlcnic_83xx_get_vnic_pf_info(struct qlcnic_adapter *, struct qlcnic_info *); ...@@ -603,7 +603,7 @@ int qlcnic_83xx_get_vnic_pf_info(struct qlcnic_adapter *, struct qlcnic_info *);
void qlcnic_83xx_get_minidump_template(struct qlcnic_adapter *); void qlcnic_83xx_get_minidump_template(struct qlcnic_adapter *);
void qlcnic_83xx_get_stats(struct qlcnic_adapter *adapter, u64 *data); void qlcnic_83xx_get_stats(struct qlcnic_adapter *adapter, u64 *data);
int qlcnic_83xx_get_settings(struct qlcnic_adapter *); int qlcnic_83xx_get_settings(struct qlcnic_adapter *, struct ethtool_cmd *);
int qlcnic_83xx_set_settings(struct qlcnic_adapter *, struct ethtool_cmd *); int qlcnic_83xx_set_settings(struct qlcnic_adapter *, struct ethtool_cmd *);
void qlcnic_83xx_get_pauseparam(struct qlcnic_adapter *, void qlcnic_83xx_get_pauseparam(struct qlcnic_adapter *,
struct ethtool_pauseparam *); struct ethtool_pauseparam *);
...@@ -620,7 +620,7 @@ int qlcnic_83xx_flash_test(struct qlcnic_adapter *); ...@@ -620,7 +620,7 @@ int qlcnic_83xx_flash_test(struct qlcnic_adapter *);
int qlcnic_83xx_enable_flash_write(struct qlcnic_adapter *); int qlcnic_83xx_enable_flash_write(struct qlcnic_adapter *);
int qlcnic_83xx_disable_flash_write(struct qlcnic_adapter *); int qlcnic_83xx_disable_flash_write(struct qlcnic_adapter *);
u32 qlcnic_83xx_mac_rcode(struct qlcnic_adapter *); u32 qlcnic_83xx_mac_rcode(struct qlcnic_adapter *);
u32 qlcnic_83xx_mbx_poll(struct qlcnic_adapter *); u32 qlcnic_83xx_mbx_poll(struct qlcnic_adapter *, u32 *);
void qlcnic_83xx_enable_mbx_poll(struct qlcnic_adapter *); void qlcnic_83xx_enable_mbx_poll(struct qlcnic_adapter *);
void qlcnic_83xx_disable_mbx_poll(struct qlcnic_adapter *); void qlcnic_83xx_disable_mbx_poll(struct qlcnic_adapter *);
#endif #endif
...@@ -435,10 +435,6 @@ static void qlcnic_83xx_idc_attach_driver(struct qlcnic_adapter *adapter) ...@@ -435,10 +435,6 @@ static void qlcnic_83xx_idc_attach_driver(struct qlcnic_adapter *adapter)
} }
done: done:
netif_device_attach(netdev); netif_device_attach(netdev);
if (netif_running(netdev)) {
netif_carrier_on(netdev);
netif_wake_queue(netdev);
}
} }
static int qlcnic_83xx_idc_enter_failed_state(struct qlcnic_adapter *adapter, static int qlcnic_83xx_idc_enter_failed_state(struct qlcnic_adapter *adapter,
...@@ -642,15 +638,21 @@ static int qlcnic_83xx_idc_reattach_driver(struct qlcnic_adapter *adapter) ...@@ -642,15 +638,21 @@ static int qlcnic_83xx_idc_reattach_driver(struct qlcnic_adapter *adapter)
static void qlcnic_83xx_idc_update_idc_params(struct qlcnic_adapter *adapter) static void qlcnic_83xx_idc_update_idc_params(struct qlcnic_adapter *adapter)
{ {
struct qlcnic_hardware_context *ahw = adapter->ahw;
qlcnic_83xx_idc_update_drv_presence_reg(adapter, 1, 1); qlcnic_83xx_idc_update_drv_presence_reg(adapter, 1, 1);
clear_bit(__QLCNIC_RESETTING, &adapter->state);
set_bit(QLC_83XX_MBX_READY, &adapter->ahw->idc.status); set_bit(QLC_83XX_MBX_READY, &adapter->ahw->idc.status);
qlcnic_83xx_idc_update_audit_reg(adapter, 0, 1); qlcnic_83xx_idc_update_audit_reg(adapter, 0, 1);
set_bit(QLC_83XX_MODULE_LOADED, &adapter->ahw->idc.status); set_bit(QLC_83XX_MODULE_LOADED, &adapter->ahw->idc.status);
adapter->ahw->idc.quiesce_req = 0;
adapter->ahw->idc.delay = QLC_83XX_IDC_FW_POLL_DELAY; ahw->idc.quiesce_req = 0;
adapter->ahw->idc.err_code = 0; ahw->idc.delay = QLC_83XX_IDC_FW_POLL_DELAY;
adapter->ahw->idc.collect_dump = 0; ahw->idc.err_code = 0;
ahw->idc.collect_dump = 0;
ahw->reset_context = 0;
adapter->tx_timeo_cnt = 0;
clear_bit(__QLCNIC_RESETTING, &adapter->state);
} }
/** /**
...@@ -851,6 +853,7 @@ static int qlcnic_83xx_idc_ready_state(struct qlcnic_adapter *adapter) ...@@ -851,6 +853,7 @@ static int qlcnic_83xx_idc_ready_state(struct qlcnic_adapter *adapter)
/* Check for soft reset request */ /* Check for soft reset request */
if (ahw->reset_context && if (ahw->reset_context &&
!(val & QLC_83XX_IDC_DISABLE_FW_RESET_RECOVERY)) { !(val & QLC_83XX_IDC_DISABLE_FW_RESET_RECOVERY)) {
adapter->ahw->reset_context = 0;
qlcnic_83xx_idc_tx_soft_reset(adapter); qlcnic_83xx_idc_tx_soft_reset(adapter);
return ret; return ret;
} }
...@@ -914,6 +917,7 @@ static int qlcnic_83xx_idc_need_quiesce_state(struct qlcnic_adapter *adapter) ...@@ -914,6 +917,7 @@ static int qlcnic_83xx_idc_need_quiesce_state(struct qlcnic_adapter *adapter)
static int qlcnic_83xx_idc_failed_state(struct qlcnic_adapter *adapter) static int qlcnic_83xx_idc_failed_state(struct qlcnic_adapter *adapter)
{ {
dev_err(&adapter->pdev->dev, "%s: please restart!!\n", __func__); dev_err(&adapter->pdev->dev, "%s: please restart!!\n", __func__);
clear_bit(__QLCNIC_RESETTING, &adapter->state);
adapter->ahw->idc.err_code = -EIO; adapter->ahw->idc.err_code = -EIO;
return 0; return 0;
......
...@@ -131,12 +131,13 @@ static const char qlcnic_83xx_rx_stats_strings[][ETH_GSTRING_LEN] = { ...@@ -131,12 +131,13 @@ static const char qlcnic_83xx_rx_stats_strings[][ETH_GSTRING_LEN] = {
"ctx_lro_pkt_cnt", "ctx_lro_pkt_cnt",
"ctx_ip_csum_error", "ctx_ip_csum_error",
"ctx_rx_pkts_wo_ctx", "ctx_rx_pkts_wo_ctx",
"ctx_rx_pkts_dropped_wo_sts", "ctx_rx_pkts_drop_wo_sds_on_card",
"ctx_rx_pkts_drop_wo_sds_on_host",
"ctx_rx_osized_pkts", "ctx_rx_osized_pkts",
"ctx_rx_pkts_dropped_wo_rds", "ctx_rx_pkts_dropped_wo_rds",
"ctx_rx_unexpected_mcast_pkts", "ctx_rx_unexpected_mcast_pkts",
"ctx_invalid_mac_address", "ctx_invalid_mac_address",
"ctx_rx_rds_ring_prim_attemoted", "ctx_rx_rds_ring_prim_attempted",
"ctx_rx_rds_ring_prim_success", "ctx_rx_rds_ring_prim_success",
"ctx_num_lro_flows_added", "ctx_num_lro_flows_added",
"ctx_num_lro_flows_removed", "ctx_num_lro_flows_removed",
...@@ -251,6 +252,18 @@ static int ...@@ -251,6 +252,18 @@ static int
qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
{ {
struct qlcnic_adapter *adapter = netdev_priv(dev); struct qlcnic_adapter *adapter = netdev_priv(dev);
if (qlcnic_82xx_check(adapter))
return qlcnic_82xx_get_settings(adapter, ecmd);
else if (qlcnic_83xx_check(adapter))
return qlcnic_83xx_get_settings(adapter, ecmd);
return -EIO;
}
int qlcnic_82xx_get_settings(struct qlcnic_adapter *adapter,
struct ethtool_cmd *ecmd)
{
struct qlcnic_hardware_context *ahw = adapter->ahw; struct qlcnic_hardware_context *ahw = adapter->ahw;
u32 speed, reg; u32 speed, reg;
int check_sfp_module = 0; int check_sfp_module = 0;
...@@ -276,10 +289,7 @@ qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) ...@@ -276,10 +289,7 @@ qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
} else if (adapter->ahw->port_type == QLCNIC_XGBE) { } else if (adapter->ahw->port_type == QLCNIC_XGBE) {
u32 val = 0; u32 val = 0;
if (qlcnic_83xx_check(adapter)) val = QLCRD32(adapter, QLCNIC_PORT_MODE_ADDR);
qlcnic_83xx_get_settings(adapter);
else
val = QLCRD32(adapter, QLCNIC_PORT_MODE_ADDR);
if (val == QLCNIC_PORT_MODE_802_3_AP) { if (val == QLCNIC_PORT_MODE_802_3_AP) {
ecmd->supported = SUPPORTED_1000baseT_Full; ecmd->supported = SUPPORTED_1000baseT_Full;
...@@ -289,16 +299,13 @@ qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) ...@@ -289,16 +299,13 @@ qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
ecmd->advertising = ADVERTISED_10000baseT_Full; ecmd->advertising = ADVERTISED_10000baseT_Full;
} }
if (netif_running(dev) && adapter->ahw->has_link_events) { if (netif_running(adapter->netdev) && ahw->has_link_events) {
if (qlcnic_82xx_check(adapter)) { reg = QLCRD32(adapter, P3P_LINK_SPEED_REG(pcifn));
reg = QLCRD32(adapter, speed = P3P_LINK_SPEED_VAL(pcifn, reg);
P3P_LINK_SPEED_REG(pcifn)); ahw->link_speed = speed * P3P_LINK_SPEED_MHZ;
speed = P3P_LINK_SPEED_VAL(pcifn, reg); ethtool_cmd_speed_set(ecmd, ahw->link_speed);
ahw->link_speed = speed * P3P_LINK_SPEED_MHZ; ecmd->autoneg = ahw->link_autoneg;
} ecmd->duplex = ahw->link_duplex;
ethtool_cmd_speed_set(ecmd, adapter->ahw->link_speed);
ecmd->autoneg = adapter->ahw->link_autoneg;
ecmd->duplex = adapter->ahw->link_duplex;
goto skip; goto skip;
} }
...@@ -340,8 +347,8 @@ qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) ...@@ -340,8 +347,8 @@ qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
case QLCNIC_BRDTYPE_P3P_10G_SFP_QT: case QLCNIC_BRDTYPE_P3P_10G_SFP_QT:
ecmd->advertising |= ADVERTISED_TP; ecmd->advertising |= ADVERTISED_TP;
ecmd->supported |= SUPPORTED_TP; ecmd->supported |= SUPPORTED_TP;
check_sfp_module = netif_running(dev) && check_sfp_module = netif_running(adapter->netdev) &&
adapter->ahw->has_link_events; ahw->has_link_events;
case QLCNIC_BRDTYPE_P3P_10G_XFP: case QLCNIC_BRDTYPE_P3P_10G_XFP:
ecmd->supported |= SUPPORTED_FIBRE; ecmd->supported |= SUPPORTED_FIBRE;
ecmd->advertising |= ADVERTISED_FIBRE; ecmd->advertising |= ADVERTISED_FIBRE;
...@@ -355,8 +362,8 @@ qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) ...@@ -355,8 +362,8 @@ qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
ecmd->advertising |= ecmd->advertising |=
(ADVERTISED_FIBRE | ADVERTISED_TP); (ADVERTISED_FIBRE | ADVERTISED_TP);
ecmd->port = PORT_FIBRE; ecmd->port = PORT_FIBRE;
check_sfp_module = netif_running(dev) && check_sfp_module = netif_running(adapter->netdev) &&
adapter->ahw->has_link_events; ahw->has_link_events;
} else { } else {
ecmd->autoneg = AUTONEG_ENABLE; ecmd->autoneg = AUTONEG_ENABLE;
ecmd->supported |= (SUPPORTED_TP | SUPPORTED_Autoneg); ecmd->supported |= (SUPPORTED_TP | SUPPORTED_Autoneg);
...@@ -365,13 +372,6 @@ qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) ...@@ -365,13 +372,6 @@ qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
ecmd->port = PORT_TP; ecmd->port = PORT_TP;
} }
break; break;
case QLCNIC_BRDTYPE_83XX_10G:
ecmd->autoneg = AUTONEG_DISABLE;
ecmd->supported |= (SUPPORTED_FIBRE | SUPPORTED_TP);
ecmd->advertising |= (ADVERTISED_FIBRE | ADVERTISED_TP);
ecmd->port = PORT_FIBRE;
check_sfp_module = netif_running(dev) && ahw->has_link_events;
break;
default: default:
dev_err(&adapter->pdev->dev, "Unsupported board model %d\n", dev_err(&adapter->pdev->dev, "Unsupported board model %d\n",
adapter->ahw->board_type); adapter->ahw->board_type);
......
...@@ -134,7 +134,7 @@ struct qlcnic_mailbox_metadata { ...@@ -134,7 +134,7 @@ struct qlcnic_mailbox_metadata {
#define QLCNIC_SET_OWNER 1 #define QLCNIC_SET_OWNER 1
#define QLCNIC_CLR_OWNER 0 #define QLCNIC_CLR_OWNER 0
#define QLCNIC_MBX_TIMEOUT 10000 #define QLCNIC_MBX_TIMEOUT 5000
#define QLCNIC_MBX_RSP_OK 1 #define QLCNIC_MBX_RSP_OK 1
#define QLCNIC_MBX_PORT_RSP_OK 0x1a #define QLCNIC_MBX_PORT_RSP_OK 0x1a
......
...@@ -37,24 +37,24 @@ MODULE_PARM_DESC(qlcnic_mac_learn, ...@@ -37,24 +37,24 @@ MODULE_PARM_DESC(qlcnic_mac_learn,
"Mac Filter (0=learning is disabled, 1=Driver learning is enabled, 2=FDB learning is enabled)"); "Mac Filter (0=learning is disabled, 1=Driver learning is enabled, 2=FDB learning is enabled)");
int qlcnic_use_msi = 1; int qlcnic_use_msi = 1;
MODULE_PARM_DESC(use_msi, "MSI interrupt (0=disabled, 1=enabled"); MODULE_PARM_DESC(use_msi, "MSI interrupt (0=disabled, 1=enabled)");
module_param_named(use_msi, qlcnic_use_msi, int, 0444); module_param_named(use_msi, qlcnic_use_msi, int, 0444);
int qlcnic_use_msi_x = 1; int qlcnic_use_msi_x = 1;
MODULE_PARM_DESC(use_msi_x, "MSI-X interrupt (0=disabled, 1=enabled"); MODULE_PARM_DESC(use_msi_x, "MSI-X interrupt (0=disabled, 1=enabled)");
module_param_named(use_msi_x, qlcnic_use_msi_x, int, 0444); module_param_named(use_msi_x, qlcnic_use_msi_x, int, 0444);
int qlcnic_auto_fw_reset = 1; int qlcnic_auto_fw_reset = 1;
MODULE_PARM_DESC(auto_fw_reset, "Auto firmware reset (0=disabled, 1=enabled"); MODULE_PARM_DESC(auto_fw_reset, "Auto firmware reset (0=disabled, 1=enabled)");
module_param_named(auto_fw_reset, qlcnic_auto_fw_reset, int, 0644); module_param_named(auto_fw_reset, qlcnic_auto_fw_reset, int, 0644);
int qlcnic_load_fw_file; int qlcnic_load_fw_file;
MODULE_PARM_DESC(load_fw_file, "Load firmware from (0=flash, 1=file"); MODULE_PARM_DESC(load_fw_file, "Load firmware from (0=flash, 1=file)");
module_param_named(load_fw_file, qlcnic_load_fw_file, int, 0444); module_param_named(load_fw_file, qlcnic_load_fw_file, int, 0444);
int qlcnic_config_npars; int qlcnic_config_npars;
module_param(qlcnic_config_npars, int, 0444); module_param(qlcnic_config_npars, int, 0444);
MODULE_PARM_DESC(qlcnic_config_npars, "Configure NPARs (0=disabled, 1=enabled"); MODULE_PARM_DESC(qlcnic_config_npars, "Configure NPARs (0=disabled, 1=enabled)");
static int qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent); static int qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
static void qlcnic_remove(struct pci_dev *pdev); static void qlcnic_remove(struct pci_dev *pdev);
...@@ -308,6 +308,23 @@ int qlcnic_read_mac_addr(struct qlcnic_adapter *adapter) ...@@ -308,6 +308,23 @@ int qlcnic_read_mac_addr(struct qlcnic_adapter *adapter)
return 0; return 0;
} }
static void qlcnic_delete_adapter_mac(struct qlcnic_adapter *adapter)
{
struct qlcnic_mac_list_s *cur;
struct list_head *head;
list_for_each(head, &adapter->mac_list) {
cur = list_entry(head, struct qlcnic_mac_list_s, list);
if (!memcmp(adapter->mac_addr, cur->mac_addr, ETH_ALEN)) {
qlcnic_sre_macaddr_change(adapter, cur->mac_addr,
0, QLCNIC_MAC_DEL);
list_del(&cur->list);
kfree(cur);
return;
}
}
}
static int qlcnic_set_mac(struct net_device *netdev, void *p) static int qlcnic_set_mac(struct net_device *netdev, void *p)
{ {
struct qlcnic_adapter *adapter = netdev_priv(netdev); struct qlcnic_adapter *adapter = netdev_priv(netdev);
...@@ -322,11 +339,15 @@ static int qlcnic_set_mac(struct net_device *netdev, void *p) ...@@ -322,11 +339,15 @@ static int qlcnic_set_mac(struct net_device *netdev, void *p)
if (!is_valid_ether_addr(addr->sa_data)) if (!is_valid_ether_addr(addr->sa_data))
return -EINVAL; return -EINVAL;
if (!memcmp(adapter->mac_addr, addr->sa_data, ETH_ALEN))
return 0;
if (test_bit(__QLCNIC_DEV_UP, &adapter->state)) { if (test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
netif_device_detach(netdev); netif_device_detach(netdev);
qlcnic_napi_disable(adapter); qlcnic_napi_disable(adapter);
} }
qlcnic_delete_adapter_mac(adapter);
memcpy(adapter->mac_addr, addr->sa_data, netdev->addr_len); memcpy(adapter->mac_addr, addr->sa_data, netdev->addr_len);
memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
qlcnic_set_multi(adapter->netdev); qlcnic_set_multi(adapter->netdev);
...@@ -2481,12 +2502,17 @@ static void qlcnic_tx_timeout(struct net_device *netdev) ...@@ -2481,12 +2502,17 @@ static void qlcnic_tx_timeout(struct net_device *netdev)
if (test_bit(__QLCNIC_RESETTING, &adapter->state)) if (test_bit(__QLCNIC_RESETTING, &adapter->state))
return; return;
dev_err(&netdev->dev, "transmit timeout, resetting.\n"); if (++adapter->tx_timeo_cnt >= QLCNIC_MAX_TX_TIMEOUTS) {
netdev_info(netdev, "Tx timeout, reset the adapter.\n");
if (++adapter->tx_timeo_cnt >= QLCNIC_MAX_TX_TIMEOUTS) if (qlcnic_82xx_check(adapter))
adapter->need_fw_reset = 1; adapter->need_fw_reset = 1;
else else if (qlcnic_83xx_check(adapter))
qlcnic_83xx_idc_request_reset(adapter,
QLCNIC_FORCE_FW_DUMP_KEY);
} else {
netdev_info(netdev, "Tx timeout, reset adapter context.\n");
adapter->ahw->reset_context = 1; adapter->ahw->reset_context = 1;
}
} }
static struct net_device_stats *qlcnic_get_stats(struct net_device *netdev) static struct net_device_stats *qlcnic_get_stats(struct net_device *netdev)
......
...@@ -280,9 +280,9 @@ void qlcnic_sriov_cleanup(struct qlcnic_adapter *adapter) ...@@ -280,9 +280,9 @@ void qlcnic_sriov_cleanup(struct qlcnic_adapter *adapter)
static int qlcnic_sriov_post_bc_msg(struct qlcnic_adapter *adapter, u32 *hdr, static int qlcnic_sriov_post_bc_msg(struct qlcnic_adapter *adapter, u32 *hdr,
u32 *pay, u8 pci_func, u8 size) u32 *pay, u8 pci_func, u8 size)
{ {
u32 rsp, mbx_val, fw_data, rsp_num, mbx_cmd, val, wait_time = 0;
struct qlcnic_hardware_context *ahw = adapter->ahw; struct qlcnic_hardware_context *ahw = adapter->ahw;
unsigned long flags; unsigned long flags;
u32 rsp, mbx_val, fw_data, rsp_num, mbx_cmd, val;
u16 opcode; u16 opcode;
u8 mbx_err_code; u8 mbx_err_code;
int i, j; int i, j;
...@@ -330,15 +330,13 @@ static int qlcnic_sriov_post_bc_msg(struct qlcnic_adapter *adapter, u32 *hdr, ...@@ -330,15 +330,13 @@ static int qlcnic_sriov_post_bc_msg(struct qlcnic_adapter *adapter, u32 *hdr,
* assume something is wrong. * assume something is wrong.
*/ */
poll: poll:
rsp = qlcnic_83xx_mbx_poll(adapter); rsp = qlcnic_83xx_mbx_poll(adapter, &wait_time);
if (rsp != QLCNIC_RCODE_TIMEOUT) { if (rsp != QLCNIC_RCODE_TIMEOUT) {
/* Get the FW response data */ /* Get the FW response data */
fw_data = readl(QLCNIC_MBX_FW(ahw, 0)); fw_data = readl(QLCNIC_MBX_FW(ahw, 0));
if (fw_data & QLCNIC_MBX_ASYNC_EVENT) { if (fw_data & QLCNIC_MBX_ASYNC_EVENT) {
__qlcnic_83xx_process_aen(adapter); __qlcnic_83xx_process_aen(adapter);
mbx_val = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL); goto poll;
if (mbx_val)
goto poll;
} }
mbx_err_code = QLCNIC_MBX_STATUS(fw_data); mbx_err_code = QLCNIC_MBX_STATUS(fw_data);
rsp_num = QLCNIC_MBX_NUM_REGS(fw_data); rsp_num = QLCNIC_MBX_NUM_REGS(fw_data);
......
...@@ -1133,9 +1133,6 @@ static int qlcnic_sriov_validate_linkevent(struct qlcnic_vf_info *vf, ...@@ -1133,9 +1133,6 @@ static int qlcnic_sriov_validate_linkevent(struct qlcnic_vf_info *vf,
if ((cmd->req.arg[1] >> 16) != vf->rx_ctx_id) if ((cmd->req.arg[1] >> 16) != vf->rx_ctx_id)
return -EINVAL; return -EINVAL;
if (!(cmd->req.arg[1] & BIT_8))
return -EINVAL;
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment