Commit 879ece6e authored by David S. Miller's avatar David S. Miller

Merge branch 'qlcnic-next'

Shahed Shaikh says:

====================
qlcnic: Feature addition and enhancements

This series contains following feature addition and enhancements,
- Update Link speed and Port type information for 83xx series adapters
- Support 0x8830 device ID
- Support for Power on Self Test (POST) feature for 83xx
- Use usleep_range() instead of msleep() for values less than 20ms
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 10c51b56 07fbc6b7
...@@ -7361,7 +7361,7 @@ F: drivers/net/ethernet/qlogic/qla3xxx.* ...@@ -7361,7 +7361,7 @@ F: drivers/net/ethernet/qlogic/qla3xxx.*
QLOGIC QLCNIC (1/10)Gb ETHERNET DRIVER QLOGIC QLCNIC (1/10)Gb ETHERNET DRIVER
M: Shahed Shaikh <shahed.shaikh@qlogic.com> M: Shahed Shaikh <shahed.shaikh@qlogic.com>
M: Dept-HSGLinuxNICDev@qlogic.com M: Dept-GELinuxNICDev@qlogic.com
L: netdev@vger.kernel.org L: netdev@vger.kernel.org
S: Supported S: Supported
F: drivers/net/ethernet/qlogic/qlcnic/ F: drivers/net/ethernet/qlogic/qlcnic/
......
...@@ -39,8 +39,8 @@ ...@@ -39,8 +39,8 @@
#define _QLCNIC_LINUX_MAJOR 5 #define _QLCNIC_LINUX_MAJOR 5
#define _QLCNIC_LINUX_MINOR 3 #define _QLCNIC_LINUX_MINOR 3
#define _QLCNIC_LINUX_SUBVERSION 61 #define _QLCNIC_LINUX_SUBVERSION 62
#define QLCNIC_LINUX_VERSIONID "5.3.61" #define QLCNIC_LINUX_VERSIONID "5.3.62"
#define QLCNIC_DRV_IDC_VER 0x01 #define QLCNIC_DRV_IDC_VER 0x01
#define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ #define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\
(_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION))
...@@ -540,6 +540,8 @@ struct qlcnic_hardware_context { ...@@ -540,6 +540,8 @@ struct qlcnic_hardware_context {
u8 lb_mode; u8 lb_mode;
u16 vxlan_port; u16 vxlan_port;
struct device *hwmon_dev; struct device *hwmon_dev;
u32 post_mode;
bool run_post;
}; };
struct qlcnic_adapter_stats { struct qlcnic_adapter_stats {
...@@ -2283,6 +2285,7 @@ extern const struct ethtool_ops qlcnic_ethtool_failed_ops; ...@@ -2283,6 +2285,7 @@ extern const struct ethtool_ops qlcnic_ethtool_failed_ops;
#define PCI_DEVICE_ID_QLOGIC_QLE824X 0x8020 #define PCI_DEVICE_ID_QLOGIC_QLE824X 0x8020
#define PCI_DEVICE_ID_QLOGIC_QLE834X 0x8030 #define PCI_DEVICE_ID_QLOGIC_QLE834X 0x8030
#define PCI_DEVICE_ID_QLOGIC_QLE8830 0x8830
#define PCI_DEVICE_ID_QLOGIC_VF_QLE834X 0x8430 #define PCI_DEVICE_ID_QLOGIC_VF_QLE834X 0x8430
#define PCI_DEVICE_ID_QLOGIC_QLE844X 0x8040 #define PCI_DEVICE_ID_QLOGIC_QLE844X 0x8040
#define PCI_DEVICE_ID_QLOGIC_VF_QLE844X 0x8440 #define PCI_DEVICE_ID_QLOGIC_VF_QLE844X 0x8440
...@@ -2307,6 +2310,7 @@ static inline bool qlcnic_83xx_check(struct qlcnic_adapter *adapter) ...@@ -2307,6 +2310,7 @@ static inline bool qlcnic_83xx_check(struct qlcnic_adapter *adapter)
bool status; bool status;
status = ((device == PCI_DEVICE_ID_QLOGIC_QLE834X) || status = ((device == PCI_DEVICE_ID_QLOGIC_QLE834X) ||
(device == PCI_DEVICE_ID_QLOGIC_QLE8830) ||
(device == PCI_DEVICE_ID_QLOGIC_QLE844X) || (device == PCI_DEVICE_ID_QLOGIC_QLE844X) ||
(device == PCI_DEVICE_ID_QLOGIC_VF_QLE844X) || (device == PCI_DEVICE_ID_QLOGIC_VF_QLE844X) ||
(device == PCI_DEVICE_ID_QLOGIC_VF_QLE834X)) ? true : false; (device == PCI_DEVICE_ID_QLOGIC_VF_QLE834X)) ? true : false;
......
...@@ -35,6 +35,35 @@ static void qlcnic_83xx_get_beacon_state(struct qlcnic_adapter *); ...@@ -35,6 +35,35 @@ static void qlcnic_83xx_get_beacon_state(struct qlcnic_adapter *);
#define QLC_SKIP_INACTIVE_PCI_REGS 7 #define QLC_SKIP_INACTIVE_PCI_REGS 7
#define QLC_MAX_LEGACY_FUNC_SUPP 8 #define QLC_MAX_LEGACY_FUNC_SUPP 8
/* 83xx Module type */
#define QLC_83XX_MODULE_FIBRE_10GBASE_LRM 0x1 /* 10GBase-LRM */
#define QLC_83XX_MODULE_FIBRE_10GBASE_LR 0x2 /* 10GBase-LR */
#define QLC_83XX_MODULE_FIBRE_10GBASE_SR 0x3 /* 10GBase-SR */
#define QLC_83XX_MODULE_DA_10GE_PASSIVE_CP 0x4 /* 10GE passive
* copper(compliant)
*/
#define QLC_83XX_MODULE_DA_10GE_ACTIVE_CP 0x5 /* 10GE active limiting
* copper(compliant)
*/
#define QLC_83XX_MODULE_DA_10GE_LEGACY_CP 0x6 /* 10GE passive copper
* (legacy, best effort)
*/
#define QLC_83XX_MODULE_FIBRE_1000BASE_SX 0x7 /* 1000Base-SX */
#define QLC_83XX_MODULE_FIBRE_1000BASE_LX 0x8 /* 1000Base-LX */
#define QLC_83XX_MODULE_FIBRE_1000BASE_CX 0x9 /* 1000Base-CX */
#define QLC_83XX_MODULE_TP_1000BASE_T 0xa /* 1000Base-T*/
#define QLC_83XX_MODULE_DA_1GE_PASSIVE_CP 0xb /* 1GE passive copper
* (legacy, best effort)
*/
#define QLC_83XX_MODULE_UNKNOWN 0xf /* Unknown module type */
/* Port types */
#define QLC_83XX_10_CAPABLE BIT_8
#define QLC_83XX_100_CAPABLE BIT_9
#define QLC_83XX_1G_CAPABLE BIT_10
#define QLC_83XX_10G_CAPABLE BIT_11
#define QLC_83XX_AUTONEG_ENABLE BIT_15
static const struct qlcnic_mailbox_metadata qlcnic_83xx_mbx_tbl[] = { static const struct qlcnic_mailbox_metadata qlcnic_83xx_mbx_tbl[] = {
{QLCNIC_CMD_CONFIGURE_IP_ADDR, 6, 1}, {QLCNIC_CMD_CONFIGURE_IP_ADDR, 6, 1},
{QLCNIC_CMD_CONFIG_INTRPT, 18, 34}, {QLCNIC_CMD_CONFIG_INTRPT, 18, 34},
...@@ -667,6 +696,7 @@ void qlcnic_83xx_write_crb(struct qlcnic_adapter *adapter, char *buf, ...@@ -667,6 +696,7 @@ void qlcnic_83xx_write_crb(struct qlcnic_adapter *adapter, char *buf,
int qlcnic_83xx_get_port_info(struct qlcnic_adapter *adapter) int qlcnic_83xx_get_port_info(struct qlcnic_adapter *adapter)
{ {
struct qlcnic_hardware_context *ahw = adapter->ahw;
int status; int status;
status = qlcnic_83xx_get_port_config(adapter); status = qlcnic_83xx_get_port_config(adapter);
...@@ -674,13 +704,20 @@ int qlcnic_83xx_get_port_info(struct qlcnic_adapter *adapter) ...@@ -674,13 +704,20 @@ int qlcnic_83xx_get_port_info(struct qlcnic_adapter *adapter)
dev_err(&adapter->pdev->dev, dev_err(&adapter->pdev->dev,
"Get Port Info failed\n"); "Get Port Info failed\n");
} else { } else {
if (QLC_83XX_SFP_10G_CAPABLE(adapter->ahw->port_config))
adapter->ahw->port_type = QLCNIC_XGBE;
else
adapter->ahw->port_type = QLCNIC_GBE;
if (QLC_83XX_AUTONEG(adapter->ahw->port_config)) if (ahw->port_config & QLC_83XX_10G_CAPABLE) {
adapter->ahw->link_autoneg = AUTONEG_ENABLE; ahw->port_type = QLCNIC_XGBE;
} else if (ahw->port_config & QLC_83XX_10_CAPABLE ||
ahw->port_config & QLC_83XX_100_CAPABLE ||
ahw->port_config & QLC_83XX_1G_CAPABLE) {
ahw->port_type = QLCNIC_GBE;
} else {
ahw->port_type = QLCNIC_XGBE;
}
if (QLC_83XX_AUTONEG(ahw->port_config))
ahw->link_autoneg = AUTONEG_ENABLE;
} }
return status; return status;
} }
...@@ -2664,7 +2701,7 @@ static int qlcnic_83xx_poll_flash_status_reg(struct qlcnic_adapter *adapter) ...@@ -2664,7 +2701,7 @@ static int qlcnic_83xx_poll_flash_status_reg(struct qlcnic_adapter *adapter)
QLC_83XX_FLASH_STATUS_READY) QLC_83XX_FLASH_STATUS_READY)
break; break;
msleep(QLC_83XX_FLASH_STATUS_REG_POLL_DELAY); usleep_range(1000, 1100);
} while (--retries); } while (--retries);
if (!retries) if (!retries)
...@@ -3176,22 +3213,33 @@ int qlcnic_83xx_test_link(struct qlcnic_adapter *adapter) ...@@ -3176,22 +3213,33 @@ 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 (QLC_83XX_SFP_MODULE_TYPE(config)) {
switch (ahw->module_type) { case QLC_83XX_MODULE_FIBRE_10GBASE_LRM:
case LINKEVENT_MODULE_OPTICAL_UNKNOWN: case QLC_83XX_MODULE_FIBRE_10GBASE_LR:
case LINKEVENT_MODULE_OPTICAL_SRLR: case QLC_83XX_MODULE_FIBRE_10GBASE_SR:
case LINKEVENT_MODULE_OPTICAL_LRM: ahw->supported_type = PORT_FIBRE;
case LINKEVENT_MODULE_OPTICAL_SFP_1G: ahw->port_type = QLCNIC_XGBE;
ahw->supported_type = PORT_FIBRE; break;
break; case QLC_83XX_MODULE_FIBRE_1000BASE_SX:
case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE: case QLC_83XX_MODULE_FIBRE_1000BASE_LX:
case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN: case QLC_83XX_MODULE_FIBRE_1000BASE_CX:
case LINKEVENT_MODULE_TWINAX: ahw->supported_type = PORT_FIBRE;
ahw->supported_type = PORT_TP; ahw->port_type = QLCNIC_GBE;
break; break;
default: case QLC_83XX_MODULE_TP_1000BASE_T:
ahw->supported_type = PORT_OTHER; ahw->supported_type = PORT_TP;
} ahw->port_type = QLCNIC_GBE;
break;
case QLC_83XX_MODULE_DA_10GE_PASSIVE_CP:
case QLC_83XX_MODULE_DA_10GE_ACTIVE_CP:
case QLC_83XX_MODULE_DA_10GE_LEGACY_CP:
case QLC_83XX_MODULE_DA_1GE_PASSIVE_CP:
ahw->supported_type = PORT_DA;
ahw->port_type = QLCNIC_XGBE;
break;
default:
ahw->supported_type = PORT_OTHER;
ahw->port_type = QLCNIC_XGBE;
} }
if (config & 1) if (config & 1)
err = 1; err = 1;
...@@ -3204,9 +3252,9 @@ int qlcnic_83xx_test_link(struct qlcnic_adapter *adapter) ...@@ -3204,9 +3252,9 @@ int qlcnic_83xx_test_link(struct qlcnic_adapter *adapter)
int qlcnic_83xx_get_settings(struct qlcnic_adapter *adapter, int qlcnic_83xx_get_settings(struct qlcnic_adapter *adapter,
struct ethtool_cmd *ecmd) struct ethtool_cmd *ecmd)
{ {
struct qlcnic_hardware_context *ahw = adapter->ahw;
u32 config = 0; u32 config = 0;
int status = 0; int status = 0;
struct qlcnic_hardware_context *ahw = adapter->ahw;
if (!test_bit(__QLCNIC_MAINTENANCE_MODE, &adapter->state)) { if (!test_bit(__QLCNIC_MAINTENANCE_MODE, &adapter->state)) {
/* Get port configuration info */ /* Get port configuration info */
...@@ -3229,20 +3277,41 @@ int qlcnic_83xx_get_settings(struct qlcnic_adapter *adapter, ...@@ -3229,20 +3277,41 @@ int qlcnic_83xx_get_settings(struct qlcnic_adapter *adapter,
ecmd->autoneg = AUTONEG_DISABLE; ecmd->autoneg = AUTONEG_DISABLE;
} }
if (ahw->port_type == QLCNIC_XGBE) { ecmd->supported = (SUPPORTED_10baseT_Full |
ecmd->supported = SUPPORTED_10000baseT_Full; SUPPORTED_100baseT_Full |
ecmd->advertising = ADVERTISED_10000baseT_Full; SUPPORTED_1000baseT_Full |
SUPPORTED_10000baseT_Full |
SUPPORTED_Autoneg);
if (ecmd->autoneg == AUTONEG_ENABLE) {
if (ahw->port_config & QLC_83XX_10_CAPABLE)
ecmd->advertising |= SUPPORTED_10baseT_Full;
if (ahw->port_config & QLC_83XX_100_CAPABLE)
ecmd->advertising |= SUPPORTED_100baseT_Full;
if (ahw->port_config & QLC_83XX_1G_CAPABLE)
ecmd->advertising |= SUPPORTED_1000baseT_Full;
if (ahw->port_config & QLC_83XX_10G_CAPABLE)
ecmd->advertising |= SUPPORTED_10000baseT_Full;
if (ahw->port_config & QLC_83XX_AUTONEG_ENABLE)
ecmd->advertising |= ADVERTISED_Autoneg;
} else { } else {
ecmd->supported = (SUPPORTED_10baseT_Half | switch (ahw->link_speed) {
SUPPORTED_10baseT_Full | case SPEED_10:
SUPPORTED_100baseT_Half | ecmd->advertising = SUPPORTED_10baseT_Full;
SUPPORTED_100baseT_Full | break;
SUPPORTED_1000baseT_Half | case SPEED_100:
SUPPORTED_1000baseT_Full); ecmd->advertising = SUPPORTED_100baseT_Full;
ecmd->advertising = (ADVERTISED_100baseT_Half | break;
ADVERTISED_100baseT_Full | case SPEED_1000:
ADVERTISED_1000baseT_Half | ecmd->advertising = SUPPORTED_1000baseT_Full;
ADVERTISED_1000baseT_Full); break;
case SPEED_10000:
ecmd->advertising = SUPPORTED_10000baseT_Full;
break;
default:
break;
}
} }
switch (ahw->supported_type) { switch (ahw->supported_type) {
...@@ -3258,6 +3327,12 @@ int qlcnic_83xx_get_settings(struct qlcnic_adapter *adapter, ...@@ -3258,6 +3327,12 @@ int qlcnic_83xx_get_settings(struct qlcnic_adapter *adapter,
ecmd->port = PORT_TP; ecmd->port = PORT_TP;
ecmd->transceiver = XCVR_INTERNAL; ecmd->transceiver = XCVR_INTERNAL;
break; break;
case PORT_DA:
ecmd->supported |= SUPPORTED_FIBRE;
ecmd->advertising |= ADVERTISED_FIBRE;
ecmd->port = PORT_DA;
ecmd->transceiver = XCVR_EXTERNAL;
break;
default: default:
ecmd->supported |= SUPPORTED_FIBRE; ecmd->supported |= SUPPORTED_FIBRE;
ecmd->advertising |= ADVERTISED_FIBRE; ecmd->advertising |= ADVERTISED_FIBRE;
...@@ -3272,35 +3347,60 @@ int qlcnic_83xx_get_settings(struct qlcnic_adapter *adapter, ...@@ -3272,35 +3347,60 @@ int qlcnic_83xx_get_settings(struct qlcnic_adapter *adapter,
int qlcnic_83xx_set_settings(struct qlcnic_adapter *adapter, int qlcnic_83xx_set_settings(struct qlcnic_adapter *adapter,
struct ethtool_cmd *ecmd) struct ethtool_cmd *ecmd)
{ {
int status = 0; struct qlcnic_hardware_context *ahw = adapter->ahw;
u32 config = adapter->ahw->port_config; u32 config = adapter->ahw->port_config;
int status = 0;
if (ecmd->autoneg) /* 83xx devices do not support Half duplex */
adapter->ahw->port_config |= BIT_15; if (ecmd->duplex == DUPLEX_HALF) {
netdev_info(adapter->netdev,
switch (ethtool_cmd_speed(ecmd)) { "Half duplex mode not supported\n");
case SPEED_10: return -EINVAL;
adapter->ahw->port_config |= BIT_8;
break;
case SPEED_100:
adapter->ahw->port_config |= BIT_9;
break;
case SPEED_1000:
adapter->ahw->port_config |= BIT_10;
break;
case SPEED_10000:
adapter->ahw->port_config |= BIT_11;
break;
default:
return -EINVAL;
} }
if (ecmd->autoneg) {
ahw->port_config |= QLC_83XX_AUTONEG_ENABLE;
ahw->port_config |= (QLC_83XX_100_CAPABLE |
QLC_83XX_1G_CAPABLE |
QLC_83XX_10G_CAPABLE);
} else { /* force speed */
ahw->port_config &= ~QLC_83XX_AUTONEG_ENABLE;
switch (ethtool_cmd_speed(ecmd)) {
case SPEED_10:
ahw->port_config &= ~(QLC_83XX_100_CAPABLE |
QLC_83XX_1G_CAPABLE |
QLC_83XX_10G_CAPABLE);
ahw->port_config |= QLC_83XX_10_CAPABLE;
break;
case SPEED_100:
ahw->port_config &= ~(QLC_83XX_10_CAPABLE |
QLC_83XX_1G_CAPABLE |
QLC_83XX_10G_CAPABLE);
ahw->port_config |= QLC_83XX_100_CAPABLE;
break;
case SPEED_1000:
ahw->port_config &= ~(QLC_83XX_10_CAPABLE |
QLC_83XX_100_CAPABLE |
QLC_83XX_10G_CAPABLE);
ahw->port_config |= QLC_83XX_1G_CAPABLE;
break;
case SPEED_10000:
ahw->port_config &= ~(QLC_83XX_10_CAPABLE |
QLC_83XX_100_CAPABLE |
QLC_83XX_1G_CAPABLE);
ahw->port_config |= QLC_83XX_10G_CAPABLE;
break;
default:
return -EINVAL;
}
}
status = qlcnic_83xx_set_port_config(adapter); status = qlcnic_83xx_set_port_config(adapter);
if (status) { if (status) {
dev_info(&adapter->pdev->dev, netdev_info(adapter->netdev,
"Failed to Set Link Speed and autoneg.\n"); "Failed to Set Link Speed and autoneg.\n");
adapter->ahw->port_config = config; ahw->port_config = config;
} }
return status; return status;
} }
......
...@@ -83,6 +83,7 @@ ...@@ -83,6 +83,7 @@
/* Firmware image definitions */ /* Firmware image definitions */
#define QLC_83XX_BOOTLOADER_FLASH_ADDR 0x10000 #define QLC_83XX_BOOTLOADER_FLASH_ADDR 0x10000
#define QLC_83XX_FW_FILE_NAME "83xx_fw.bin" #define QLC_83XX_FW_FILE_NAME "83xx_fw.bin"
#define QLC_83XX_POST_FW_FILE_NAME "83xx_post_fw.bin"
#define QLC_84XX_FW_FILE_NAME "84xx_fw.bin" #define QLC_84XX_FW_FILE_NAME "84xx_fw.bin"
#define QLC_83XX_BOOT_FROM_FLASH 0 #define QLC_83XX_BOOT_FROM_FLASH 0
#define QLC_83XX_BOOT_FROM_FILE 0x12345678 #define QLC_83XX_BOOT_FROM_FILE 0x12345678
...@@ -360,7 +361,6 @@ enum qlcnic_83xx_states { ...@@ -360,7 +361,6 @@ enum qlcnic_83xx_states {
#define QLC_83XX_SFP_MODULE_TYPE(data) (((data) >> 4) & 0x1F) #define QLC_83XX_SFP_MODULE_TYPE(data) (((data) >> 4) & 0x1F)
#define QLC_83XX_SFP_CU_LENGTH(data) (LSB((data) >> 16)) #define QLC_83XX_SFP_CU_LENGTH(data) (LSB((data) >> 16))
#define QLC_83XX_SFP_TX_FAULT(data) ((data) & BIT_10) #define QLC_83XX_SFP_TX_FAULT(data) ((data) & BIT_10)
#define QLC_83XX_SFP_10G_CAPABLE(data) ((data) & BIT_11)
#define QLC_83XX_LINK_STATS(data) ((data) & BIT_0) #define QLC_83XX_LINK_STATS(data) ((data) & BIT_0)
#define QLC_83XX_CURRENT_LINK_SPEED(data) (((data) >> 3) & 7) #define QLC_83XX_CURRENT_LINK_SPEED(data) (((data) >> 3) & 7)
#define QLC_83XX_LINK_PAUSE(data) (((data) >> 6) & 3) #define QLC_83XX_LINK_PAUSE(data) (((data) >> 6) & 3)
......
...@@ -2075,6 +2075,121 @@ static void qlcnic_83xx_init_hw(struct qlcnic_adapter *p_dev) ...@@ -2075,6 +2075,121 @@ static void qlcnic_83xx_init_hw(struct qlcnic_adapter *p_dev)
dev_err(&p_dev->pdev->dev, "%s: failed\n", __func__); dev_err(&p_dev->pdev->dev, "%s: failed\n", __func__);
} }
/* POST FW related definations*/
#define QLC_83XX_POST_SIGNATURE_REG 0x41602014
#define QLC_83XX_POST_MODE_REG 0x41602018
#define QLC_83XX_POST_FAST_MODE 0
#define QLC_83XX_POST_MEDIUM_MODE 1
#define QLC_83XX_POST_SLOW_MODE 2
/* POST Timeout values in milliseconds */
#define QLC_83XX_POST_FAST_MODE_TIMEOUT 690
#define QLC_83XX_POST_MED_MODE_TIMEOUT 2930
#define QLC_83XX_POST_SLOW_MODE_TIMEOUT 7500
/* POST result values */
#define QLC_83XX_POST_PASS 0xfffffff0
#define QLC_83XX_POST_ASIC_STRESS_TEST_FAIL 0xffffffff
#define QLC_83XX_POST_DDR_TEST_FAIL 0xfffffffe
#define QLC_83XX_POST_ASIC_MEMORY_TEST_FAIL 0xfffffffc
#define QLC_83XX_POST_FLASH_TEST_FAIL 0xfffffff8
static int qlcnic_83xx_run_post(struct qlcnic_adapter *adapter)
{
struct qlc_83xx_fw_info *fw_info = adapter->ahw->fw_info;
struct device *dev = &adapter->pdev->dev;
int timeout, count, ret = 0;
u32 signature;
/* Set timeout values with extra 2 seconds of buffer */
switch (adapter->ahw->post_mode) {
case QLC_83XX_POST_FAST_MODE:
timeout = QLC_83XX_POST_FAST_MODE_TIMEOUT + 2000;
break;
case QLC_83XX_POST_MEDIUM_MODE:
timeout = QLC_83XX_POST_MED_MODE_TIMEOUT + 2000;
break;
case QLC_83XX_POST_SLOW_MODE:
timeout = QLC_83XX_POST_SLOW_MODE_TIMEOUT + 2000;
break;
default:
return -EINVAL;
}
strncpy(fw_info->fw_file_name, QLC_83XX_POST_FW_FILE_NAME,
QLC_FW_FILE_NAME_LEN);
ret = request_firmware(&fw_info->fw, fw_info->fw_file_name, dev);
if (ret) {
dev_err(dev, "POST firmware can not be loaded, skipping POST\n");
return 0;
}
ret = qlcnic_83xx_copy_fw_file(adapter);
if (ret)
return ret;
/* clear QLC_83XX_POST_SIGNATURE_REG register */
qlcnic_ind_wr(adapter, QLC_83XX_POST_SIGNATURE_REG, 0);
/* Set POST mode */
qlcnic_ind_wr(adapter, QLC_83XX_POST_MODE_REG,
adapter->ahw->post_mode);
QLC_SHARED_REG_WR32(adapter, QLCNIC_FW_IMG_VALID,
QLC_83XX_BOOT_FROM_FILE);
qlcnic_83xx_start_hw(adapter);
count = 0;
do {
msleep(100);
count += 100;
signature = qlcnic_ind_rd(adapter, QLC_83XX_POST_SIGNATURE_REG);
if (signature == QLC_83XX_POST_PASS)
break;
} while (timeout > count);
if (timeout <= count) {
dev_err(dev, "POST timed out, signature = 0x%08x\n", signature);
return -EIO;
}
switch (signature) {
case QLC_83XX_POST_PASS:
dev_info(dev, "POST passed, Signature = 0x%08x\n", signature);
break;
case QLC_83XX_POST_ASIC_STRESS_TEST_FAIL:
dev_err(dev, "POST failed, Test case : ASIC STRESS TEST, Signature = 0x%08x\n",
signature);
ret = -EIO;
break;
case QLC_83XX_POST_DDR_TEST_FAIL:
dev_err(dev, "POST failed, Test case : DDT TEST, Signature = 0x%08x\n",
signature);
ret = -EIO;
break;
case QLC_83XX_POST_ASIC_MEMORY_TEST_FAIL:
dev_err(dev, "POST failed, Test case : ASIC MEMORY TEST, Signature = 0x%08x\n",
signature);
ret = -EIO;
break;
case QLC_83XX_POST_FLASH_TEST_FAIL:
dev_err(dev, "POST failed, Test case : FLASH TEST, Signature = 0x%08x\n",
signature);
ret = -EIO;
break;
default:
dev_err(dev, "POST failed, Test case : INVALID, Signature = 0x%08x\n",
signature);
ret = -EIO;
break;
}
return ret;
}
static int qlcnic_83xx_load_fw_image_from_host(struct qlcnic_adapter *adapter) static int qlcnic_83xx_load_fw_image_from_host(struct qlcnic_adapter *adapter)
{ {
struct qlc_83xx_fw_info *fw_info = adapter->ahw->fw_info; struct qlc_83xx_fw_info *fw_info = adapter->ahw->fw_info;
...@@ -2119,8 +2234,27 @@ static int qlcnic_83xx_restart_hw(struct qlcnic_adapter *adapter) ...@@ -2119,8 +2234,27 @@ static int qlcnic_83xx_restart_hw(struct qlcnic_adapter *adapter)
if (qlcnic_83xx_copy_bootloader(adapter)) if (qlcnic_83xx_copy_bootloader(adapter))
return err; return err;
/* Check if POST needs to be run */
if (adapter->ahw->run_post) {
err = qlcnic_83xx_run_post(adapter);
if (err)
return err;
/* No need to run POST in next reset sequence */
adapter->ahw->run_post = false;
/* Again reset the adapter to load regular firmware */
qlcnic_83xx_stop_hw(adapter);
qlcnic_83xx_init_hw(adapter);
err = qlcnic_83xx_copy_bootloader(adapter);
if (err)
return err;
}
/* Boot either flash image or firmware image from host file system */ /* Boot either flash image or firmware image from host file system */
if (qlcnic_load_fw_file) { if (qlcnic_load_fw_file == 1) {
if (qlcnic_83xx_load_fw_image_from_host(adapter)) if (qlcnic_83xx_load_fw_image_from_host(adapter))
return err; return err;
} else { } else {
...@@ -2284,6 +2418,7 @@ static int qlcnic_83xx_get_fw_info(struct qlcnic_adapter *adapter) ...@@ -2284,6 +2418,7 @@ static int qlcnic_83xx_get_fw_info(struct qlcnic_adapter *adapter)
fw_info = ahw->fw_info; fw_info = ahw->fw_info;
switch (pdev->device) { switch (pdev->device) {
case PCI_DEVICE_ID_QLOGIC_QLE834X: case PCI_DEVICE_ID_QLOGIC_QLE834X:
case PCI_DEVICE_ID_QLOGIC_QLE8830:
strncpy(fw_info->fw_file_name, QLC_83XX_FW_FILE_NAME, strncpy(fw_info->fw_file_name, QLC_83XX_FW_FILE_NAME,
QLC_FW_FILE_NAME_LEN); QLC_FW_FILE_NAME_LEN);
break; break;
...@@ -2328,6 +2463,25 @@ int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac) ...@@ -2328,6 +2463,25 @@ int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac)
adapter->rx_mac_learn = false; adapter->rx_mac_learn = false;
ahw->msix_supported = !!qlcnic_use_msi_x; ahw->msix_supported = !!qlcnic_use_msi_x;
/* Check if POST needs to be run */
switch (qlcnic_load_fw_file) {
case 2:
ahw->post_mode = QLC_83XX_POST_FAST_MODE;
ahw->run_post = true;
break;
case 3:
ahw->post_mode = QLC_83XX_POST_MEDIUM_MODE;
ahw->run_post = true;
break;
case 4:
ahw->post_mode = QLC_83XX_POST_SLOW_MODE;
ahw->run_post = true;
break;
default:
ahw->run_post = false;
break;
}
qlcnic_83xx_init_rings(adapter); qlcnic_83xx_init_rings(adapter);
err = qlcnic_83xx_init_mailbox_work(adapter); err = qlcnic_83xx_init_mailbox_work(adapter);
......
...@@ -341,7 +341,7 @@ qlcnic_pcie_sem_lock(struct qlcnic_adapter *adapter, int sem, u32 id_reg) ...@@ -341,7 +341,7 @@ qlcnic_pcie_sem_lock(struct qlcnic_adapter *adapter, int sem, u32 id_reg)
} }
return -EIO; return -EIO;
} }
msleep(1); usleep_range(1000, 1500);
} }
if (id_reg) if (id_reg)
......
...@@ -537,7 +537,7 @@ int qlcnic_pinit_from_rom(struct qlcnic_adapter *adapter) ...@@ -537,7 +537,7 @@ int qlcnic_pinit_from_rom(struct qlcnic_adapter *adapter)
QLCWR32(adapter, QLCNIC_CRB_PEG_NET_3 + 0xc, 0); QLCWR32(adapter, QLCNIC_CRB_PEG_NET_3 + 0xc, 0);
QLCWR32(adapter, QLCNIC_CRB_PEG_NET_4 + 0x8, 0); QLCWR32(adapter, QLCNIC_CRB_PEG_NET_4 + 0x8, 0);
QLCWR32(adapter, QLCNIC_CRB_PEG_NET_4 + 0xc, 0); QLCWR32(adapter, QLCNIC_CRB_PEG_NET_4 + 0xc, 0);
msleep(1); usleep_range(1000, 1500);
QLC_SHARED_REG_WR32(adapter, QLCNIC_PEG_HALT_STATUS1, 0); QLC_SHARED_REG_WR32(adapter, QLCNIC_PEG_HALT_STATUS1, 0);
QLC_SHARED_REG_WR32(adapter, QLCNIC_PEG_HALT_STATUS2, 0); QLC_SHARED_REG_WR32(adapter, QLCNIC_PEG_HALT_STATUS2, 0);
...@@ -1198,7 +1198,7 @@ qlcnic_load_firmware(struct qlcnic_adapter *adapter) ...@@ -1198,7 +1198,7 @@ qlcnic_load_firmware(struct qlcnic_adapter *adapter)
flashaddr += 8; flashaddr += 8;
} }
} }
msleep(1); usleep_range(1000, 1500);
QLCWR32(adapter, QLCNIC_CRB_PEG_NET_0 + 0x18, 0x1020); QLCWR32(adapter, QLCNIC_CRB_PEG_NET_0 + 0x18, 0x1020);
QLCWR32(adapter, QLCNIC_ROMUSB_GLB_SW_RESET, 0x80001e); QLCWR32(adapter, QLCNIC_ROMUSB_GLB_SW_RESET, 0x80001e);
...@@ -1295,7 +1295,7 @@ void qlcnic_request_firmware(struct qlcnic_adapter *adapter) ...@@ -1295,7 +1295,7 @@ void qlcnic_request_firmware(struct qlcnic_adapter *adapter)
rc = qlcnic_validate_firmware(adapter); rc = qlcnic_validate_firmware(adapter);
if (rc != 0) { if (rc != 0) {
release_firmware(adapter->fw); release_firmware(adapter->fw);
msleep(1); usleep_range(1000, 1500);
goto next; goto next;
} }
} }
......
...@@ -52,7 +52,7 @@ MODULE_PARM_DESC(auto_fw_reset, "Auto firmware reset (0=disabled, 1=enabled)"); ...@@ -52,7 +52,7 @@ 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, 2=POST in fast mode, 3= POST in medium mode, 4=POST in slow mode)");
module_param_named(load_fw_file, qlcnic_load_fw_file, int, 0444); module_param_named(load_fw_file, qlcnic_load_fw_file, int, 0444);
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);
...@@ -111,6 +111,7 @@ static u32 qlcnic_vlan_tx_check(struct qlcnic_adapter *adapter) ...@@ -111,6 +111,7 @@ static u32 qlcnic_vlan_tx_check(struct qlcnic_adapter *adapter)
static const struct pci_device_id qlcnic_pci_tbl[] = { static const struct pci_device_id qlcnic_pci_tbl[] = {
ENTRY(PCI_DEVICE_ID_QLOGIC_QLE824X), ENTRY(PCI_DEVICE_ID_QLOGIC_QLE824X),
ENTRY(PCI_DEVICE_ID_QLOGIC_QLE834X), ENTRY(PCI_DEVICE_ID_QLOGIC_QLE834X),
ENTRY(PCI_DEVICE_ID_QLOGIC_QLE8830),
ENTRY(PCI_DEVICE_ID_QLOGIC_VF_QLE834X), ENTRY(PCI_DEVICE_ID_QLOGIC_VF_QLE834X),
ENTRY(PCI_DEVICE_ID_QLOGIC_QLE844X), ENTRY(PCI_DEVICE_ID_QLOGIC_QLE844X),
ENTRY(PCI_DEVICE_ID_QLOGIC_VF_QLE844X), ENTRY(PCI_DEVICE_ID_QLOGIC_VF_QLE844X),
...@@ -227,6 +228,11 @@ static const struct qlcnic_board_info qlcnic_boards[] = { ...@@ -227,6 +228,11 @@ static const struct qlcnic_board_info qlcnic_boards[] = {
{ PCI_VENDOR_ID_QLOGIC, { PCI_VENDOR_ID_QLOGIC,
PCI_DEVICE_ID_QLOGIC_QLE834X, PCI_DEVICE_ID_QLOGIC_QLE834X,
0x0, 0x0, "8300 Series 1/10GbE Controller" }, 0x0, 0x0, "8300 Series 1/10GbE Controller" },
{ PCI_VENDOR_ID_QLOGIC,
PCI_DEVICE_ID_QLOGIC_QLE8830,
0x0,
0x0,
"8830 Series 1/10GbE Controller" },
{ PCI_VENDOR_ID_QLOGIC, { PCI_VENDOR_ID_QLOGIC,
PCI_DEVICE_ID_QLOGIC_QLE824X, PCI_DEVICE_ID_QLOGIC_QLE824X,
PCI_VENDOR_ID_QLOGIC, PCI_VENDOR_ID_QLOGIC,
...@@ -1131,6 +1137,7 @@ static void qlcnic_get_bar_length(u32 dev_id, ulong *bar) ...@@ -1131,6 +1137,7 @@ static void qlcnic_get_bar_length(u32 dev_id, ulong *bar)
*bar = QLCNIC_82XX_BAR0_LENGTH; *bar = QLCNIC_82XX_BAR0_LENGTH;
break; break;
case PCI_DEVICE_ID_QLOGIC_QLE834X: case PCI_DEVICE_ID_QLOGIC_QLE834X:
case PCI_DEVICE_ID_QLOGIC_QLE8830:
case PCI_DEVICE_ID_QLOGIC_QLE844X: case PCI_DEVICE_ID_QLOGIC_QLE844X:
case PCI_DEVICE_ID_QLOGIC_VF_QLE834X: case PCI_DEVICE_ID_QLOGIC_VF_QLE834X:
case PCI_DEVICE_ID_QLOGIC_VF_QLE844X: case PCI_DEVICE_ID_QLOGIC_VF_QLE844X:
...@@ -2474,6 +2481,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -2474,6 +2481,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
ahw->reg_tbl = (u32 *) qlcnic_reg_tbl; ahw->reg_tbl = (u32 *) qlcnic_reg_tbl;
break; break;
case PCI_DEVICE_ID_QLOGIC_QLE834X: case PCI_DEVICE_ID_QLOGIC_QLE834X:
case PCI_DEVICE_ID_QLOGIC_QLE8830:
case PCI_DEVICE_ID_QLOGIC_QLE844X: case PCI_DEVICE_ID_QLOGIC_QLE844X:
qlcnic_83xx_register_map(ahw); qlcnic_83xx_register_map(ahw);
break; break;
......
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