@@ -286,7 +286,7 @@ struct name_list_extended {
#define RESPONSE_ENTRY_CNT_MQ 128 /* Number of response entries.*/
#define ATIO_ENTRY_CNT_24XX 4096 /* Number of ATIO entries. */
#define RESPONSE_ENTRY_CNT_FX00 256 /* Number of response entries.*/
-#define EXTENDED_EXCH_ENTRY_CNT 32768 /* Entries for offload case */
+#define FW_DEF_EXCHANGES_CNT 2048
struct req_que;
struct qla_tgt_sess;
@@ -3593,6 +3593,10 @@ struct qla_hw_data {
#define IS_SHADOW_REG_CAPABLE(ha) (IS_QLA27XX(ha))
#define IS_DPORT_CAPABLE(ha) (IS_QLA83XX(ha) || IS_QLA27XX(ha))
#define IS_FAWWN_CAPABLE(ha) (IS_QLA83XX(ha) || IS_QLA27XX(ha))
+#define IS_EXCHG_OFFLD_CAPABLE(ha) \
+ (IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha))
+#define IS_EXLOGIN_OFFLD_CAPABLE(ha) \
+ (IS_QLA25XX(ha) || IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha))
/* HBA serial number */
uint8_t serial0;
@@ -137,6 +137,7 @@ extern int ql2xmdcapmask;
extern int ql2xmdenable;
extern int ql2xexlogins;
extern int ql2xexchoffld;
+extern int ql2xiniexchg;
extern int ql2xfwholdabts;
extern int ql2xmvasynctoatio;
@@ -839,7 +840,7 @@ extern int qla_get_exlogin_status(scsi_qla_host_t *, uint16_t *,
uint16_t *);
extern int qla_set_exlogin_mem_cfg(scsi_qla_host_t *vha, dma_addr_t phys_addr);
extern int qla_get_exchoffld_status(scsi_qla_host_t *, uint16_t *, uint16_t *);
-extern int qla_set_exchoffld_mem_cfg(scsi_qla_host_t *, dma_addr_t);
+extern int qla_set_exchoffld_mem_cfg(scsi_qla_host_t *);
extern void qlt_handle_abts_recv(struct scsi_qla_host *, response_t *);
int qla24xx_async_notify_ack(scsi_qla_host_t *, fc_port_t *,
@@ -2723,7 +2723,7 @@ qla2x00_setup_chip(scsi_qla_host_t *vha)
if (ql2xexlogins)
ha->flags.exlogins_enabled = 1;
- if (ql2xexchoffld)
+ if (qla_is_exch_offld_enabled(vha))
ha->flags.exchoffld_enabled = 1;
rval = qla2x00_execute_fw(vha, srisc_address);
@@ -307,3 +307,19 @@ qla2x00_set_retry_delay_timestamp(fc_port_t *fcport, uint16_t retry_delay)
fcport->retry_delay_timestamp = jiffies +
(retry_delay * HZ / 10);
}
+
+static inline bool
+qla_is_exch_offld_enabled(struct scsi_qla_host *vha)
+{
+ if (qla_ini_mode_enabled(vha) &&
+ (ql2xiniexchg > FW_DEF_EXCHANGES_CNT))
+ return true;
+ else if (qla_tgt_mode_enabled(vha) &&
+ (ql2xexchoffld > FW_DEF_EXCHANGES_CNT))
+ return true;
+ else if (qla_dual_mode_enabled(vha) &&
+ ((ql2xiniexchg + ql2xexchoffld) > FW_DEF_EXCHANGES_CNT))
+ return true;
+ else
+ return false;
+}
@@ -821,7 +821,7 @@ qla_get_exchoffld_status(scsi_qla_host_t *vha, uint16_t *buf_sz,
*/
#define CONFIG_XCHOFFLD_MEM 0x3
int
-qla_set_exchoffld_mem_cfg(scsi_qla_host_t *vha, dma_addr_t phys_addr)
+qla_set_exchoffld_mem_cfg(scsi_qla_host_t *vha)
{
int rval;
mbx_cmd_t mc;
@@ -834,12 +834,12 @@ qla_set_exchoffld_mem_cfg(scsi_qla_host_t *vha, dma_addr_t phys_addr)
memset(mcp->mb, 0 , sizeof(mcp->mb));
mcp->mb[0] = MBC_GET_MEM_OFFLOAD_CNTRL_STAT;
mcp->mb[1] = CONFIG_XCHOFFLD_MEM;
- mcp->mb[2] = MSW(phys_addr);
- mcp->mb[3] = LSW(phys_addr);
- mcp->mb[6] = MSW(MSD(phys_addr));
- mcp->mb[7] = LSW(MSD(phys_addr));
- mcp->mb[8] = MSW(ha->exlogin_size);
- mcp->mb[9] = LSW(ha->exlogin_size);
+ mcp->mb[2] = MSW(ha->exchoffld_buf_dma);
+ mcp->mb[3] = LSW(ha->exchoffld_buf_dma);
+ mcp->mb[6] = MSW(MSD(ha->exchoffld_buf_dma));
+ mcp->mb[7] = LSW(MSD(ha->exchoffld_buf_dma));
+ mcp->mb[8] = MSW(ha->exchoffld_size);
+ mcp->mb[9] = LSW(ha->exchoffld_size);
mcp->out_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
mcp->in_mb = MBX_11|MBX_0;
mcp->tov = MBX_TOV_SECONDS;
@@ -224,11 +224,15 @@ MODULE_PARM_DESC(ql2xexlogins,
"Number of extended Logins. "
"0 (Default)- Disabled.");
-int ql2xexchoffld = 0;
-module_param(ql2xexchoffld, uint, S_IRUGO|S_IWUSR);
+int ql2xexchoffld = 1024;
+module_param(ql2xexchoffld, uint, 0644);
MODULE_PARM_DESC(ql2xexchoffld,
- "Number of exchanges to offload. "
- "0 (Default)- Disabled.");
+ "Number of target exchanges.");
+
+int ql2xiniexchg = 1024;
+module_param(ql2xiniexchg, uint, 0644);
+MODULE_PARM_DESC(ql2xiniexchg,
+ "Number of initiator exchanges.");
int ql2xfwholdabts = 0;
module_param(ql2xfwholdabts, int, S_IRUGO);
@@ -3982,6 +3986,9 @@ qla2x00_set_exlogins_buffer(scsi_qla_host_t *vha)
if (!ql2xexlogins)
return QLA_SUCCESS;
+ if (!IS_EXLOGIN_OFFLD_CAPABLE(ha))
+ return QLA_SUCCESS;
+
ql_log(ql_log_info, vha, 0xd021, "EXLOGIN count: %d.\n", ql2xexlogins);
max_cnt = 0;
rval = qla_get_exlogin_status(vha, &size, &max_cnt);
@@ -3992,21 +3999,27 @@ qla2x00_set_exlogins_buffer(scsi_qla_host_t *vha)
}
temp = (ql2xexlogins > max_cnt) ? max_cnt : ql2xexlogins;
- ha->exlogin_size = (size * temp);
- ql_log(ql_log_info, vha, 0xd024,
- "EXLOGIN: max_logins=%d, portdb=0x%x, total=%d.\n",
- max_cnt, size, temp);
-
- ql_log(ql_log_info, vha, 0xd025, "EXLOGIN: requested size=0x%x\n",
- ha->exlogin_size);
-
- /* Get consistent memory for extended logins */
- ha->exlogin_buf = dma_alloc_coherent(&ha->pdev->dev,
- ha->exlogin_size, &ha->exlogin_buf_dma, GFP_KERNEL);
- if (!ha->exlogin_buf) {
- ql_log_pci(ql_log_fatal, ha->pdev, 0xd02a,
+ temp *= size;
+
+ if (temp != ha->exlogin_size) {
+ qla2x00_free_exlogin_buffer(ha);
+ ha->exlogin_size = temp;
+
+ ql_log(ql_log_info, vha, 0xd024,
+ "EXLOGIN: max_logins=%d, portdb=0x%x, total=%d.\n",
+ max_cnt, size, temp);
+
+ ql_log(ql_log_info, vha, 0xd025,
+ "EXLOGIN: requested size=0x%x\n", ha->exlogin_size);
+
+ /* Get consistent memory for extended logins */
+ ha->exlogin_buf = dma_alloc_coherent(&ha->pdev->dev,
+ ha->exlogin_size, &ha->exlogin_buf_dma, GFP_KERNEL);
+ if (!ha->exlogin_buf) {
+ ql_log_pci(ql_log_fatal, ha->pdev, 0xd02a,
"Failed to allocate memory for exlogin_buf_dma.\n");
- return -ENOMEM;
+ return -ENOMEM;
+ }
}
/* Now configure the dma buffer */
@@ -4037,15 +4050,49 @@ qla2x00_free_exlogin_buffer(struct qla_hw_data *ha)
}
}
+static void
+qla2x00_number_of_exch(scsi_qla_host_t *vha, u32 *ret_cnt, u16 max_cnt)
+{
+ u32 temp;
+ *ret_cnt = FW_DEF_EXCHANGES_CNT;
+
+ if (qla_ini_mode_enabled(vha)) {
+ if (ql2xiniexchg > max_cnt)
+ ql2xiniexchg = max_cnt;
+
+ if (ql2xiniexchg > FW_DEF_EXCHANGES_CNT)
+ *ret_cnt = ql2xiniexchg;
+ } else if (qla_tgt_mode_enabled(vha)) {
+ if (ql2xexchoffld > max_cnt)
+ ql2xexchoffld = max_cnt;
+
+ if (ql2xexchoffld > FW_DEF_EXCHANGES_CNT)
+ *ret_cnt = ql2xexchoffld;
+ } else if (qla_dual_mode_enabled(vha)) {
+ temp = ql2xiniexchg + ql2xexchoffld;
+ if (temp > max_cnt) {
+ ql2xiniexchg -= (temp - max_cnt)/2;
+ ql2xexchoffld -= (((temp - max_cnt)/2) + 1);
+ temp = max_cnt;
+ }
+
+ if (temp > FW_DEF_EXCHANGES_CNT)
+ *ret_cnt = temp;
+ }
+}
+
int
qla2x00_set_exchoffld_buffer(scsi_qla_host_t *vha)
{
int rval;
- uint16_t size, max_cnt, temp;
+ u16 size, max_cnt;
+ u32 temp;
struct qla_hw_data *ha = vha->hw;
- /* Return if we don't need to alloacate any extended logins */
- if (!ql2xexchoffld)
+ if (!ha->flags.exchoffld_enabled)
+ return QLA_SUCCESS;
+
+ if (!IS_EXCHG_OFFLD_CAPABLE(ha))
return QLA_SUCCESS;
ql_log(ql_log_info, vha, 0xd014,
@@ -4059,30 +4106,45 @@ qla2x00_set_exchoffld_buffer(scsi_qla_host_t *vha)
return rval;
}
- temp = (ql2xexchoffld > max_cnt) ? max_cnt : ql2xexchoffld;
- ha->exchoffld_size = (size * temp);
- ql_log(ql_log_info, vha, 0xd016,
- "Exchange offload: max_count=%d, buffers=0x%x, total=%d.\n",
- max_cnt, size, temp);
+ qla2x00_number_of_exch(vha, &temp, max_cnt);
+ temp *= size;
- ql_log(ql_log_info, vha, 0xd017,
- "Exchange Buffers requested size = 0x%x\n", ha->exchoffld_size);
-
- /* Get consistent memory for extended logins */
- ha->exchoffld_buf = dma_alloc_coherent(&ha->pdev->dev,
- ha->exchoffld_size, &ha->exchoffld_buf_dma, GFP_KERNEL);
- if (!ha->exchoffld_buf) {
- ql_log_pci(ql_log_fatal, ha->pdev, 0xd013,
- "Failed to allocate memory for exchoffld_buf_dma.\n");
- return -ENOMEM;
+ if (temp != ha->exchoffld_size) {
+ qla2x00_free_exchoffld_buffer(ha);
+ ha->exchoffld_size = temp;
+
+ ql_log(ql_log_info, vha, 0xd016,
+ "Exchange offload: max_count=%d, buffers=0x%x, total=%d.\n",
+ max_cnt, size, temp);
+
+ ql_log(ql_log_info, vha, 0xd017,
+ "Exchange Buffers requested size = 0x%x\n",
+ ha->exchoffld_size);
+
+ /* Get consistent memory for extended logins */
+ ha->exchoffld_buf = dma_alloc_coherent(&ha->pdev->dev,
+ ha->exchoffld_size, &ha->exchoffld_buf_dma, GFP_KERNEL);
+ if (!ha->exchoffld_buf) {
+ ql_log_pci(ql_log_fatal, ha->pdev, 0xd013,
+ "Failed to allocate memory for exchoffld_buf_dma.\n");
+ return -ENOMEM;
+ }
}
/* Now configure the dma buffer */
- rval = qla_set_exchoffld_mem_cfg(vha, ha->exchoffld_buf_dma);
+ rval = qla_set_exchoffld_mem_cfg(vha);
if (rval) {
ql_log(ql_log_fatal, vha, 0xd02e,
"Setup exchange offload buffer ****FAILED****.\n");
qla2x00_free_exchoffld_buffer(ha);
+ } else {
+ /* re-adjust number of target exchange */
+ struct init_cb_81xx *icb = (struct init_cb_81xx *)ha->init_cb;
+
+ if (qla_ini_mode_enabled(vha))
+ icb->exchange_count = 0;
+ else
+ icb->exchange_count = cpu_to_le16(ql2xexchoffld);
}
return rval;
@@ -59,7 +59,7 @@ MODULE_PARM_DESC(qlini_mode,
"when ready "
"\"enabled\" (default) - initiator mode will always stay enabled.");
-static int ql_dm_tgt_ex_pct = 50;
+static int ql_dm_tgt_ex_pct = 0;
module_param(ql_dm_tgt_ex_pct, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(ql_dm_tgt_ex_pct,
"For Dual Mode (qlini_mode=dual), this parameter determines "
@@ -6438,8 +6438,9 @@ void
qlt_24xx_config_nvram_stage1(struct scsi_qla_host *vha, struct nvram_24xx *nv)
{
struct qla_hw_data *ha = vha->hw;
- u32 tmp;
- u16 t;
+
+ if (!QLA_TGT_MODE_ENABLED())
+ return;
if (qla_tgt_mode_enabled(vha) || qla_dual_mode_enabled(vha)) {
if (!ha->tgt.saved_set) {
@@ -6454,24 +6455,10 @@ qlt_24xx_config_nvram_stage1(struct scsi_qla_host *vha, struct nvram_24xx *nv)
ha->tgt.saved_set = 1;
}
- if (qla_tgt_mode_enabled(vha)) {
+ if (qla_tgt_mode_enabled(vha))
nv->exchange_count = cpu_to_le16(0xFFFF);
- } else { /* dual */
- if (ql_dm_tgt_ex_pct > 100) {
- ql_dm_tgt_ex_pct = 50;
- } else if (ql_dm_tgt_ex_pct == 100) {
- /* leave some for FW */
- ql_dm_tgt_ex_pct = 95;
- }
-
- tmp = ha->orig_fw_xcb_count * ql_dm_tgt_ex_pct;
- tmp = tmp/100;
- if (tmp > 0xffff)
- tmp = 0xffff;
-
- t = tmp & 0xffff;
- nv->exchange_count = cpu_to_le16(t);
- }
+ else /* dual */
+ nv->exchange_count = cpu_to_le16(ql2xexchoffld);
/* Enable target mode */
nv->firmware_options_1 |= cpu_to_le32(BIT_4);
@@ -6556,8 +6543,6 @@ void
qlt_81xx_config_nvram_stage1(struct scsi_qla_host *vha, struct nvram_81xx *nv)
{
struct qla_hw_data *ha = vha->hw;
- u32 tmp;
- u16 t;
if (!QLA_TGT_MODE_ENABLED())
return;
@@ -6575,23 +6560,10 @@ qlt_81xx_config_nvram_stage1(struct scsi_qla_host *vha, struct nvram_81xx *nv)
ha->tgt.saved_set = 1;
}
- if (qla_tgt_mode_enabled(vha)) {
+ if (qla_tgt_mode_enabled(vha))
nv->exchange_count = cpu_to_le16(0xFFFF);
- } else { /* dual */
- if (ql_dm_tgt_ex_pct > 100) {
- ql_dm_tgt_ex_pct = 50;
- } else if (ql_dm_tgt_ex_pct == 100) {
- /* leave some for FW */
- ql_dm_tgt_ex_pct = 95;
- }
-
- tmp = ha->orig_fw_xcb_count * ql_dm_tgt_ex_pct;
- tmp = tmp/100;
- if (tmp > 0xffff)
- tmp = 0xffff;
- t = tmp & 0xffff;
- nv->exchange_count = cpu_to_le16(t);
- }
+ else /* dual */
+ nv->exchange_count = cpu_to_le16(ql2xexchoffld);
/* Enable target mode */
nv->firmware_options_1 |= cpu_to_le32(BIT_4);