Commit 629263ac authored by Sony Chacko's avatar Sony Chacko Committed by David S. Miller

qlcnic: 83xx CNA inter driver communication mechanism

Inter Driver Communication (IDC) module.
CNA function drivers(ISCSI, FCOE and NIC) which shares the adapter
relies on IDC mechanism for gracefull shut down, restart and
firmware error recovery.
Signed-off-by: default avatarRajesh Borundia <rajesh.borundia@qlogic.com>
Signed-off-by: default avatarSucheta Chakraborty <sucheta.chakraborty@qlogic.com>
Signed-off-by: default avatarSony Chacko <sony.chacko@qlogic.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d865ebb4
...@@ -6,4 +6,5 @@ obj-$(CONFIG_QLCNIC) := qlcnic.o ...@@ -6,4 +6,5 @@ obj-$(CONFIG_QLCNIC) := qlcnic.o
qlcnic-y := qlcnic_hw.o qlcnic_main.o qlcnic_init.o \ qlcnic-y := qlcnic_hw.o qlcnic_main.o qlcnic_init.o \
qlcnic_ethtool.o qlcnic_ctx.o qlcnic_io.o \ qlcnic_ethtool.o qlcnic_ctx.o qlcnic_io.o \
qlcnic_sysfs.o qlcnic_minidump.o qlcnic_83xx_hw.o qlcnic_sysfs.o qlcnic_minidump.o qlcnic_83xx_hw.o \
qlcnic_83xx_init.o
...@@ -299,6 +299,12 @@ struct qlcnic_fdt { ...@@ -299,6 +299,12 @@ struct qlcnic_fdt {
extern char qlcnic_driver_name[]; extern char qlcnic_driver_name[];
extern int qlcnic_use_msi;
extern int qlcnic_use_msi_x;
extern int qlcnic_auto_fw_reset;
extern int qlcnic_load_fw_file;
extern int qlcnic_config_npars;
/* Number of status descriptors to handle per interrupt */ /* Number of status descriptors to handle per interrupt */
#define MAX_STATUS_HANDLE (64) #define MAX_STATUS_HANDLE (64)
...@@ -436,6 +442,8 @@ struct qlcnic_hardware_context { ...@@ -436,6 +442,8 @@ struct qlcnic_hardware_context {
struct qlcnic_nic_intr_coalesce coal; struct qlcnic_nic_intr_coalesce coal;
struct qlcnic_fw_dump fw_dump; struct qlcnic_fw_dump fw_dump;
struct qlcnic_fdt fdt; struct qlcnic_fdt fdt;
struct qlc_83xx_idc idc;
struct qlc_83xx_fw_info fw_info;
struct qlcnic_intrpt_config *intr_tbl; struct qlcnic_intrpt_config *intr_tbl;
u32 *reg_tbl; u32 *reg_tbl;
u32 *ext_reg_tbl; u32 *ext_reg_tbl;
...@@ -947,6 +955,7 @@ struct qlcnic_ipaddr { ...@@ -947,6 +955,7 @@ struct qlcnic_ipaddr {
#define QLCNIC_TEST_IN_PROGRESS 52 #define QLCNIC_TEST_IN_PROGRESS 52
#define QLCNIC_UNDEFINED_ERROR 53 #define QLCNIC_UNDEFINED_ERROR 53
#define QLCNIC_LB_CABLE_NOT_CONN 54 #define QLCNIC_LB_CABLE_NOT_CONN 54
#define QLCNIC_ILB_MAX_RCV_LOOP 10
struct qlcnic_filter { struct qlcnic_filter {
struct hlist_node fnode; struct hlist_node fnode;
...@@ -1470,6 +1479,7 @@ int qlcnic_enable_msix(struct qlcnic_adapter *, u32); ...@@ -1470,6 +1479,7 @@ int qlcnic_enable_msix(struct qlcnic_adapter *, u32);
/* eSwitch management functions */ /* eSwitch management functions */
int qlcnic_config_switch_port(struct qlcnic_adapter *, int qlcnic_config_switch_port(struct qlcnic_adapter *,
struct qlcnic_esw_func_cfg *); struct qlcnic_esw_func_cfg *);
int qlcnic_get_eswitch_port_config(struct qlcnic_adapter *, int qlcnic_get_eswitch_port_config(struct qlcnic_adapter *,
struct qlcnic_esw_func_cfg *); struct qlcnic_esw_func_cfg *);
int qlcnic_config_port_mirroring(struct qlcnic_adapter *, u8, u8, u8); int qlcnic_config_port_mirroring(struct qlcnic_adapter *, u8, u8, u8);
...@@ -1501,6 +1511,9 @@ void qlcnic_set_vlan_config(struct qlcnic_adapter *, ...@@ -1501,6 +1511,9 @@ void qlcnic_set_vlan_config(struct qlcnic_adapter *,
struct qlcnic_esw_func_cfg *); struct qlcnic_esw_func_cfg *);
void qlcnic_set_eswitch_port_features(struct qlcnic_adapter *, void qlcnic_set_eswitch_port_features(struct qlcnic_adapter *,
struct qlcnic_esw_func_cfg *); struct qlcnic_esw_func_cfg *);
void qlcnic_down(struct qlcnic_adapter *, struct net_device *);
int qlcnic_up(struct qlcnic_adapter *, struct net_device *);
void __qlcnic_down(struct qlcnic_adapter *, struct net_device *); void __qlcnic_down(struct qlcnic_adapter *, struct net_device *);
void qlcnic_detach(struct qlcnic_adapter *); void qlcnic_detach(struct qlcnic_adapter *);
void qlcnic_teardown_intr(struct qlcnic_adapter *); void qlcnic_teardown_intr(struct qlcnic_adapter *);
...@@ -1508,6 +1521,7 @@ int qlcnic_attach(struct qlcnic_adapter *); ...@@ -1508,6 +1521,7 @@ int qlcnic_attach(struct qlcnic_adapter *);
int __qlcnic_up(struct qlcnic_adapter *, struct net_device *); int __qlcnic_up(struct qlcnic_adapter *, struct net_device *);
void qlcnic_restore_indev_addr(struct net_device *, unsigned long); void qlcnic_restore_indev_addr(struct net_device *, unsigned long);
int qlcnic_check_temp(struct qlcnic_adapter *);
/* /*
* QLOGIC Board information * QLOGIC Board information
......
...@@ -267,6 +267,8 @@ static struct qlcnic_hardware_ops qlcnic_83xx_hw_ops = { ...@@ -267,6 +267,8 @@ static struct qlcnic_hardware_ops qlcnic_83xx_hw_ops = {
static struct qlcnic_nic_template qlcnic_83xx_ops = { static struct qlcnic_nic_template qlcnic_83xx_ops = {
.config_bridged_mode = qlcnic_config_bridged_mode, .config_bridged_mode = qlcnic_config_bridged_mode,
.config_led = qlcnic_config_led, .config_led = qlcnic_config_led,
.request_reset = qlcnic_83xx_idc_request_reset,
.cancel_idc_work = qlcnic_83xx_idc_exit,
.napi_add = qlcnic_83xx_napi_add, .napi_add = qlcnic_83xx_napi_add,
.napi_del = qlcnic_83xx_napi_del, .napi_del = qlcnic_83xx_napi_del,
.config_ipaddr = qlcnic_83xx_config_ipaddr, .config_ipaddr = qlcnic_83xx_config_ipaddr,
...@@ -589,6 +591,7 @@ int qlcnic_83xx_get_port_info(struct qlcnic_adapter *adapter) ...@@ -589,6 +591,7 @@ int qlcnic_83xx_get_port_info(struct qlcnic_adapter *adapter)
adapter->ahw->port_type = QLCNIC_XGBE; adapter->ahw->port_type = QLCNIC_XGBE;
else else
adapter->ahw->port_type = QLCNIC_GBE; adapter->ahw->port_type = QLCNIC_GBE;
if (QLC_83XX_AUTONEG(adapter->ahw->port_config)) if (QLC_83XX_AUTONEG(adapter->ahw->port_config))
adapter->ahw->link_autoneg = AUTONEG_ENABLE; adapter->ahw->link_autoneg = AUTONEG_ENABLE;
} }
...@@ -603,6 +606,7 @@ void qlcnic_83xx_enable_mbx_intrpt(struct qlcnic_adapter *adapter) ...@@ -603,6 +606,7 @@ void qlcnic_83xx_enable_mbx_intrpt(struct qlcnic_adapter *adapter)
val = BIT_2 | ((adapter->ahw->num_msix - 1) << 8); val = BIT_2 | ((adapter->ahw->num_msix - 1) << 8);
else else
val = BIT_2; val = BIT_2;
QLCWRX(adapter->ahw, QLCNIC_MBX_INTR_ENBL, val); QLCWRX(adapter->ahw, QLCNIC_MBX_INTR_ENBL, val);
} }
...@@ -612,9 +616,7 @@ void qlcnic_83xx_check_vf(struct qlcnic_adapter *adapter, ...@@ -612,9 +616,7 @@ void qlcnic_83xx_check_vf(struct qlcnic_adapter *adapter,
u32 op_mode, priv_level; u32 op_mode, priv_level;
struct qlcnic_hardware_context *ahw = adapter->ahw; struct qlcnic_hardware_context *ahw = adapter->ahw;
/* Determine FW API version */
ahw->fw_hal_version = 2; ahw->fw_hal_version = 2;
/* Find PCI function number */
qlcnic_get_func_no(adapter); qlcnic_get_func_no(adapter);
/* Determine function privilege level */ /* Determine function privilege level */
...@@ -691,6 +693,13 @@ int qlcnic_83xx_mbx_op(struct qlcnic_adapter *adapter, ...@@ -691,6 +693,13 @@ int qlcnic_83xx_mbx_op(struct qlcnic_adapter *adapter,
struct qlcnic_hardware_context *ahw = adapter->ahw; struct qlcnic_hardware_context *ahw = adapter->ahw;
opcode = LSW(cmd->req.arg[0]); opcode = LSW(cmd->req.arg[0]);
if (!test_bit(QLC_83XX_MBX_READY, &adapter->ahw->idc.status)) {
dev_info(&adapter->pdev->dev,
"Mailbox cmd attempted, 0x%x\n", opcode);
dev_info(&adapter->pdev->dev, "Mailbox detached\n");
return 0;
}
spin_lock(&ahw->mbx_lock); spin_lock(&ahw->mbx_lock);
mbx_val = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL); mbx_val = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL);
...@@ -853,6 +862,7 @@ static void qlcnic_83xx_handle_idc_comp_aen(struct qlcnic_adapter *adapter, ...@@ -853,6 +862,7 @@ static void qlcnic_83xx_handle_idc_comp_aen(struct qlcnic_adapter *adapter,
{ {
dev_dbg(&adapter->pdev->dev, "Completion AEN:0x%x.\n", dev_dbg(&adapter->pdev->dev, "Completion AEN:0x%x.\n",
QLCNIC_MBX_RSP(data[0])); QLCNIC_MBX_RSP(data[0]));
clear_bit(QLC_83XX_IDC_COMP_AEN, &adapter->ahw->idc.status);
return; return;
} }
...@@ -1306,7 +1316,7 @@ int qlcnic_83xx_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode) ...@@ -1306,7 +1316,7 @@ int qlcnic_83xx_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode)
int qlcnic_83xx_set_lb_mode(struct qlcnic_adapter *adapter, u8 mode) int qlcnic_83xx_set_lb_mode(struct qlcnic_adapter *adapter, u8 mode)
{ {
struct qlcnic_hardware_context *ahw = adapter->ahw; struct qlcnic_hardware_context *ahw = adapter->ahw;
int status = 0; int status = 0, loop = 0;
u32 config; u32 config;
status = qlcnic_83xx_get_port_config(adapter); status = qlcnic_83xx_get_port_config(adapter);
...@@ -1314,6 +1324,7 @@ int qlcnic_83xx_set_lb_mode(struct qlcnic_adapter *adapter, u8 mode) ...@@ -1314,6 +1324,7 @@ int qlcnic_83xx_set_lb_mode(struct qlcnic_adapter *adapter, u8 mode)
return status; return status;
config = ahw->port_config; config = ahw->port_config;
set_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
if (mode == QLCNIC_ILB_MODE) if (mode == QLCNIC_ILB_MODE)
ahw->port_config |= QLC_83XX_CFG_LOOPBACK_HSS; ahw->port_config |= QLC_83XX_CFG_LOOPBACK_HSS;
...@@ -1326,9 +1337,21 @@ int qlcnic_83xx_set_lb_mode(struct qlcnic_adapter *adapter, u8 mode) ...@@ -1326,9 +1337,21 @@ int qlcnic_83xx_set_lb_mode(struct qlcnic_adapter *adapter, u8 mode)
"Failed to Set Loopback Mode = 0x%x.\n", "Failed to Set Loopback Mode = 0x%x.\n",
ahw->port_config); ahw->port_config);
ahw->port_config = config; ahw->port_config = config;
clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
return status; return status;
} }
/* Wait until firmware send IDC Completion AEN */
do {
msleep(300);
if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP) {
dev_err(&adapter->pdev->dev,
"FW did not generate IDC completion AEN\n");
clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
return -EIO;
}
} while (test_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status));
qlcnic_sre_macaddr_change(adapter, adapter->mac_addr, 0, qlcnic_sre_macaddr_change(adapter, adapter->mac_addr, 0,
QLCNIC_MAC_ADD); QLCNIC_MAC_ADD);
return status; return status;
...@@ -1337,9 +1360,10 @@ int qlcnic_83xx_set_lb_mode(struct qlcnic_adapter *adapter, u8 mode) ...@@ -1337,9 +1360,10 @@ int qlcnic_83xx_set_lb_mode(struct qlcnic_adapter *adapter, u8 mode)
int qlcnic_83xx_clear_lb_mode(struct qlcnic_adapter *adapter, u8 mode) int qlcnic_83xx_clear_lb_mode(struct qlcnic_adapter *adapter, u8 mode)
{ {
struct qlcnic_hardware_context *ahw = adapter->ahw; struct qlcnic_hardware_context *ahw = adapter->ahw;
int status = 0; int status = 0, loop = 0;
u32 config = ahw->port_config; u32 config = ahw->port_config;
set_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
if (mode == QLCNIC_ILB_MODE) if (mode == QLCNIC_ILB_MODE)
ahw->port_config &= ~QLC_83XX_CFG_LOOPBACK_HSS; ahw->port_config &= ~QLC_83XX_CFG_LOOPBACK_HSS;
if (mode == QLCNIC_ELB_MODE) if (mode == QLCNIC_ELB_MODE)
...@@ -1351,9 +1375,21 @@ int qlcnic_83xx_clear_lb_mode(struct qlcnic_adapter *adapter, u8 mode) ...@@ -1351,9 +1375,21 @@ int qlcnic_83xx_clear_lb_mode(struct qlcnic_adapter *adapter, u8 mode)
"Failed to Clear Loopback Mode = 0x%x.\n", "Failed to Clear Loopback Mode = 0x%x.\n",
ahw->port_config); ahw->port_config);
ahw->port_config = config; ahw->port_config = config;
clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
return status; return status;
} }
/* Wait until firmware send IDC Completion AEN */
do {
msleep(300);
if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP) {
dev_err(&adapter->pdev->dev,
"Firmware didn't sent IDC completion AEN\n");
clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
return -EIO;
}
} while (test_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status));
qlcnic_sre_macaddr_change(adapter, adapter->mac_addr, 0, qlcnic_sre_macaddr_change(adapter, adapter->mac_addr, 0,
QLCNIC_MAC_DEL); QLCNIC_MAC_DEL);
return status; return status;
...@@ -1813,9 +1849,9 @@ void qlcnic_83xx_unlock_flash(struct qlcnic_adapter *adapter) ...@@ -1813,9 +1849,9 @@ void qlcnic_83xx_unlock_flash(struct qlcnic_adapter *adapter)
QLC_SHARED_REG_WR32(adapter, QLCNIC_FLASH_LOCK_OWNER, 0xFF); QLC_SHARED_REG_WR32(adapter, QLCNIC_FLASH_LOCK_OWNER, 0xFF);
} }
static int qlcnic_83xx_lockless_flash_read32(struct qlcnic_adapter *adapter, int qlcnic_83xx_lockless_flash_read32(struct qlcnic_adapter *adapter,
u32 flash_addr, u8 *p_data, u32 flash_addr, u8 *p_data,
int count) int count)
{ {
int i, ret; int i, ret;
u32 word, range, flash_offset, addr = flash_addr; u32 word, range, flash_offset, addr = flash_addr;
...@@ -2142,3 +2178,168 @@ int qlcnic_83xx_flash_bulk_write(struct qlcnic_adapter *adapter, u32 addr, ...@@ -2142,3 +2178,168 @@ int qlcnic_83xx_flash_bulk_write(struct qlcnic_adapter *adapter, u32 addr,
return 0; return 0;
} }
static void qlcnic_83xx_recover_driver_lock(struct qlcnic_adapter *adapter)
{
u32 val, id;
val = QLCRDX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK);
/* Check if recovery need to be performed by the calling function */
if ((val & QLC_83XX_DRV_LOCK_RECOVERY_STATUS_MASK) == 0) {
val = val & ~0x3F;
val = val | ((adapter->portnum << 2) |
QLC_83XX_NEED_DRV_LOCK_RECOVERY);
QLCWRX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK, val);
dev_info(&adapter->pdev->dev,
"%s: lock recovery initiated\n", __func__);
msleep(QLC_83XX_DRV_LOCK_RECOVERY_DELAY);
val = QLCRDX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK);
id = ((val >> 2) & 0xF);
if (id == adapter->portnum) {
val = val & ~QLC_83XX_DRV_LOCK_RECOVERY_STATUS_MASK;
val = val | QLC_83XX_DRV_LOCK_RECOVERY_IN_PROGRESS;
QLCWRX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK, val);
/* Force release the lock */
QLCRDX(adapter->ahw, QLC_83XX_DRV_UNLOCK);
/* Clear recovery bits */
val = val & ~0x3F;
QLCWRX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK, val);
dev_info(&adapter->pdev->dev,
"%s: lock recovery completed\n", __func__);
} else {
dev_info(&adapter->pdev->dev,
"%s: func %d to resume lock recovery process\n",
__func__, id);
}
} else {
dev_info(&adapter->pdev->dev,
"%s: lock recovery initiated by other functions\n",
__func__);
}
}
int qlcnic_83xx_lock_driver(struct qlcnic_adapter *adapter)
{
u32 lock_alive_counter, val, id, i = 0, status = 0, temp = 0;
int max_attempt = 0;
while (status == 0) {
status = QLCRDX(adapter->ahw, QLC_83XX_DRV_LOCK);
if (status)
break;
msleep(QLC_83XX_DRV_LOCK_WAIT_DELAY);
i++;
if (i == 1)
temp = QLCRDX(adapter->ahw, QLC_83XX_DRV_LOCK_ID);
if (i == QLC_83XX_DRV_LOCK_WAIT_COUNTER) {
val = QLCRDX(adapter->ahw, QLC_83XX_DRV_LOCK_ID);
if (val == temp) {
id = val & 0xFF;
dev_info(&adapter->pdev->dev,
"%s: lock to be recovered from %d\n",
__func__, id);
qlcnic_83xx_recover_driver_lock(adapter);
i = 0;
max_attempt++;
} else {
dev_err(&adapter->pdev->dev,
"%s: failed to get lock\n", __func__);
return -EIO;
}
}
/* Force exit from while loop after few attempts */
if (max_attempt == QLC_83XX_MAX_DRV_LOCK_RECOVERY_ATTEMPT) {
dev_err(&adapter->pdev->dev,
"%s: failed to get lock\n", __func__);
return -EIO;
}
}
val = QLCRDX(adapter->ahw, QLC_83XX_DRV_LOCK_ID);
lock_alive_counter = val >> 8;
lock_alive_counter++;
val = lock_alive_counter << 8 | adapter->portnum;
QLCWRX(adapter->ahw, QLC_83XX_DRV_LOCK_ID, val);
return 0;
}
void qlcnic_83xx_unlock_driver(struct qlcnic_adapter *adapter)
{
u32 val, lock_alive_counter, id;
val = QLCRDX(adapter->ahw, QLC_83XX_DRV_LOCK_ID);
id = val & 0xFF;
lock_alive_counter = val >> 8;
if (id != adapter->portnum)
dev_err(&adapter->pdev->dev,
"%s:Warning func %d is unlocking lock owned by %d\n",
__func__, adapter->portnum, id);
val = (lock_alive_counter << 8) | 0xFF;
QLCWRX(adapter->ahw, QLC_83XX_DRV_LOCK_ID, val);
QLCRDX(adapter->ahw, QLC_83XX_DRV_UNLOCK);
}
int qlcnic_83xx_ms_mem_write128(struct qlcnic_adapter *adapter, u64 addr,
u32 *data, u32 count)
{
int i, j, ret = 0;
u32 temp;
/* Check alignment */
if (addr & 0xF)
return -EIO;
mutex_lock(&adapter->ahw->mem_lock);
qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_ADDR_HI, 0);
for (i = 0; i < count; i++, addr += 16) {
if (!((ADDR_IN_RANGE(addr, QLCNIC_ADDR_QDR_NET,
QLCNIC_ADDR_QDR_NET_MAX)) ||
(ADDR_IN_RANGE(addr, QLCNIC_ADDR_DDR_NET,
QLCNIC_ADDR_DDR_NET_MAX)))) {
mutex_unlock(&adapter->ahw->mem_lock);
return -EIO;
}
qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_ADDR_LO, addr);
qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_WRTDATA_LO,
*data++);
qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_WRTDATA_HI,
*data++);
qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_WRTDATA_ULO,
*data++);
qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_WRTDATA_UHI,
*data++);
qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_CTRL,
QLCNIC_TA_WRITE_ENABLE);
qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_CTRL,
QLCNIC_TA_WRITE_START);
for (j = 0; j < MAX_CTL_CHECK; j++) {
temp = qlcnic_83xx_rd_reg_indirect(adapter,
QLCNIC_MS_CTRL);
if ((temp & TA_CTL_BUSY) == 0)
break;
}
/* Status check failure */
if (j >= MAX_CTL_CHECK) {
printk_ratelimited(KERN_WARNING
"MS memory write failed\n");
mutex_unlock(&adapter->ahw->mem_lock);
return -EIO;
}
}
mutex_unlock(&adapter->ahw->mem_lock);
return ret;
}
...@@ -53,6 +53,30 @@ ...@@ -53,6 +53,30 @@
#define QLCNIC_HOST_RDS_MBX_IDX 88 #define QLCNIC_HOST_RDS_MBX_IDX 88
#define QLCNIC_MAX_RING_SETS 8 #define QLCNIC_MAX_RING_SETS 8
/* Pause control registers */
#define QLC_83XX_SRE_SHIM_REG 0x0D200284
#define QLC_83XX_PORT0_THRESHOLD 0x0B2003A4
#define QLC_83XX_PORT1_THRESHOLD 0x0B2013A4
#define QLC_83XX_PORT0_TC_MC_REG 0x0B200388
#define QLC_83XX_PORT1_TC_MC_REG 0x0B201388
#define QLC_83XX_PORT0_TC_STATS 0x0B20039C
#define QLC_83XX_PORT1_TC_STATS 0x0B20139C
#define QLC_83XX_PORT2_IFB_THRESHOLD 0x0B200704
#define QLC_83XX_PORT3_IFB_THRESHOLD 0x0B201704
/* Peg PC status registers */
#define QLC_83XX_CRB_PEG_NET_0 0x3400003c
#define QLC_83XX_CRB_PEG_NET_1 0x3410003c
#define QLC_83XX_CRB_PEG_NET_2 0x3420003c
#define QLC_83XX_CRB_PEG_NET_3 0x3430003c
#define QLC_83XX_CRB_PEG_NET_4 0x34b0003c
/* Firmware image definitions */
#define QLC_83XX_BOOTLOADER_FLASH_ADDR 0x10000
#define QLC_83XX_FW_FILE_NAME "83xx_fw.bin"
#define QLC_83XX_BOOT_FROM_FLASH 0
#define QLC_83XX_BOOT_FROM_FILE 0x12345678
struct qlcnic_intrpt_config { struct qlcnic_intrpt_config {
u8 type; u8 type;
u8 enabled; u8 enabled;
...@@ -65,6 +89,49 @@ struct qlcnic_macvlan_mbx { ...@@ -65,6 +89,49 @@ struct qlcnic_macvlan_mbx {
u16 vlan; u16 vlan;
}; };
struct qlc_83xx_fw_info {
const struct firmware *fw;
u16 major_fw_version;
u8 minor_fw_version;
u8 sub_fw_version;
u8 fw_build_num;
u8 load_from_file;
};
#define QLC_83XX_IDC_DISABLE_FW_RESET_RECOVERY 0x1
#define QLC_83XX_IDC_GRACEFULL_RESET 0x2
#define QLC_83XX_IDC_TIMESTAMP 0
#define QLC_83XX_IDC_DURATION 1
#define QLC_83XX_IDC_INIT_TIMEOUT_SECS 30
#define QLC_83XX_IDC_RESET_ACK_TIMEOUT_SECS 10
#define QLC_83XX_IDC_RESET_TIMEOUT_SECS 10
#define QLC_83XX_IDC_QUIESCE_ACK_TIMEOUT_SECS 20
#define QLC_83XX_IDC_FW_POLL_DELAY (1 * HZ)
#define QLC_83XX_IDC_FW_FAIL_THRESH 2
#define QLC_83XX_IDC_MAX_FUNC_PER_PARTITION_INFO 8
#define QLC_83XX_IDC_MAX_CNA_FUNCTIONS 16
#define QLC_83XX_IDC_MAJOR_VERSION 1
#define QLC_83XX_IDC_MINOR_VERSION 0
#define QLC_83XX_IDC_FLASH_PARAM_ADDR 0x3e8020
/* Mailbox process AEN count */
#define QLC_83XX_MBX_AEN_CNT 5
struct qlcnic_adapter;
struct qlc_83xx_idc {
int (*state_entry) (struct qlcnic_adapter *);
u64 sec_counter;
u64 delay;
unsigned long status;
int err_code;
int collect_dump;
u8 curr_state;
u8 prev_state;
u8 vnic_state;
u8 vnic_wait_limit;
u8 quiesce_req;
char **name;
};
/* Mailbox process AEN count */ /* Mailbox process AEN count */
#define QLC_83XX_IDC_COMP_AEN 3 #define QLC_83XX_IDC_COMP_AEN 3
...@@ -303,4 +370,17 @@ int qlcnic_83xx_save_flash_status(struct qlcnic_adapter *); ...@@ -303,4 +370,17 @@ int qlcnic_83xx_save_flash_status(struct qlcnic_adapter *);
int qlcnic_83xx_restore_flash_status(struct qlcnic_adapter *, int); int qlcnic_83xx_restore_flash_status(struct qlcnic_adapter *, int);
int qlcnic_83xx_read_flash_mfg_id(struct qlcnic_adapter *); int qlcnic_83xx_read_flash_mfg_id(struct qlcnic_adapter *);
int qlcnic_83xx_read_flash_descriptor_table(struct qlcnic_adapter *); int qlcnic_83xx_read_flash_descriptor_table(struct qlcnic_adapter *);
int qlcnic_83xx_flash_read32(struct qlcnic_adapter *, u32, u8 *, int);
int qlcnic_83xx_lockless_flash_read32(struct qlcnic_adapter *,
u32, u8 *, int);
int qlcnic_83xx_init(struct qlcnic_adapter *);
int qlcnic_83xx_idc_ready_state_entry(struct qlcnic_adapter *);
int qlcnic_83xx_check_hw_status(struct qlcnic_adapter *p_dev);
void qlcnic_83xx_idc_poll_dev_state(struct work_struct *);
void qlcnic_83xx_idc_exit(struct qlcnic_adapter *);
void qlcnic_83xx_idc_request_reset(struct qlcnic_adapter *, u32);
int qlcnic_83xx_lock_driver(struct qlcnic_adapter *);
void qlcnic_83xx_unlock_driver(struct qlcnic_adapter *);
int qlcnic_83xx_set_default_offload_settings(struct qlcnic_adapter *);
int qlcnic_83xx_ms_mem_write128(struct qlcnic_adapter *, u64, u32 *, u32);
#endif #endif
This diff is collapsed.
...@@ -39,23 +39,23 @@ static int qlcnic_mac_learn; ...@@ -39,23 +39,23 @@ static int qlcnic_mac_learn;
module_param(qlcnic_mac_learn, int, 0444); module_param(qlcnic_mac_learn, int, 0444);
MODULE_PARM_DESC(qlcnic_mac_learn, "Mac Filter (0=disabled, 1=enabled)"); MODULE_PARM_DESC(qlcnic_mac_learn, "Mac Filter (0=disabled, 1=enabled)");
static 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);
static 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);
static 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);
static 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);
static 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");
...@@ -1294,9 +1294,7 @@ int __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev) ...@@ -1294,9 +1294,7 @@ int __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev)
return 0; return 0;
} }
/* Usage: During resume and firmware recovery module.*/ int qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev)
static int qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev)
{ {
int err = 0; int err = 0;
...@@ -1340,8 +1338,7 @@ void __qlcnic_down(struct qlcnic_adapter *adapter, struct net_device *netdev) ...@@ -1340,8 +1338,7 @@ void __qlcnic_down(struct qlcnic_adapter *adapter, struct net_device *netdev)
/* Usage: During suspend and firmware recovery module */ /* Usage: During suspend and firmware recovery module */
static void void qlcnic_down(struct qlcnic_adapter *adapter, struct net_device *netdev)
qlcnic_down(struct qlcnic_adapter *adapter, struct net_device *netdev)
{ {
rtnl_lock(); rtnl_lock();
if (netif_running(netdev)) if (netif_running(netdev))
...@@ -1812,6 +1809,11 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1812,6 +1809,11 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
} else if (qlcnic_83xx_check(adapter)) { } else if (qlcnic_83xx_check(adapter)) {
qlcnic_83xx_check_vf(adapter, ent); qlcnic_83xx_check_vf(adapter, ent);
adapter->portnum = adapter->ahw->pci_func; adapter->portnum = adapter->ahw->pci_func;
err = qlcnic_83xx_init(adapter);
if (err) {
dev_err(&pdev->dev, "%s: failed\n", __func__);
goto err_out_free_hw;
}
} else { } else {
dev_err(&pdev->dev, dev_err(&pdev->dev,
"%s: failed. Please Reboot\n", __func__); "%s: failed. Please Reboot\n", __func__);
...@@ -2135,7 +2137,7 @@ static void qlcnic_free_lb_filters_mem(struct qlcnic_adapter *adapter) ...@@ -2135,7 +2137,7 @@ static void qlcnic_free_lb_filters_mem(struct qlcnic_adapter *adapter)
adapter->fhash.fmax = 0; adapter->fhash.fmax = 0;
} }
static int qlcnic_check_temp(struct qlcnic_adapter *adapter) int qlcnic_check_temp(struct qlcnic_adapter *adapter)
{ {
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
u32 temp_state, temp_val, temp = 0; u32 temp_state, temp_val, temp = 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