Skip to content

Commit

Permalink
[SCSI] qla4xxx: Add flash node mgmt support
Browse files Browse the repository at this point in the history
This patch allows iscsiadm to manage iSCSI target information stored on
qla4xxx adapter flash on per host basis.

Signed-off-by: Adheer Chandravanshi <adheer.chandravanshi@qlogic.com>
Signed-off-by: Manish Rangankar <manish.rangankar@qlogic.com>
Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
  • Loading branch information
Adheer Chandravanshi authored and James Bottomley committed Apr 11, 2013
1 parent adaf699 commit 1e9e2be
Show file tree
Hide file tree
Showing 6 changed files with 1,931 additions and 111 deletions.
22 changes: 22 additions & 0 deletions drivers/scsi/qla4xxx/ql4_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,25 @@
#define LSDW(x) ((u32)((u64)(x)))
#define MSDW(x) ((u32)((((u64)(x)) >> 16) >> 16))

#define DEV_TYPE_IPV4 "ipv4"
#define DEV_TYPE_IPV6 "ipv6"

#define DEV_DB_NON_PERSISTENT 0
#define DEV_DB_PERSISTENT 1

#define COPY_ISID(dst_isid, src_isid) { \
int i, j; \
for (i = 0, j = ISID_SIZE - 1; i < ISID_SIZE;) \
dst_isid[i++] = src_isid[j--]; \
}

#define SET_BITVAL(o, n, v) { \
if (o) \
n |= v; \
else \
n &= ~v; \
}

/*
* Retry & Timeout Values
*/
Expand Down Expand Up @@ -363,6 +382,8 @@ struct ql82xx_hw_data {
uint32_t flt_iscsi_param;
uint32_t flt_region_chap;
uint32_t flt_chap_size;
uint32_t flt_region_ddb;
uint32_t flt_ddb_size;
};

struct qla4_8xxx_legacy_intr_set {
Expand Down Expand Up @@ -501,6 +522,7 @@ struct scsi_qla_host {
#define AF_INIT_DONE 1 /* 0x00000002 */
#define AF_MBOX_COMMAND 2 /* 0x00000004 */
#define AF_MBOX_COMMAND_DONE 3 /* 0x00000008 */
#define AF_ST_DISCOVERY_IN_PROGRESS 4 /* 0x00000010 */
#define AF_INTERRUPTS_ON 6 /* 0x00000040 */
#define AF_GET_CRASH_RECORD 7 /* 0x00000080 */
#define AF_LINK_UP 8 /* 0x00000100 */
Expand Down
34 changes: 34 additions & 0 deletions drivers/scsi/qla4xxx/ql4_fw.h
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,8 @@ union external_hw_config_reg {
#define FA_GOLD_RISC_CODE_ADDR_82 0x80000
#define FA_FLASH_ISCSI_CHAP 0x540000
#define FA_FLASH_CHAP_SIZE 0xC0000
#define FA_FLASH_ISCSI_DDB 0x420000
#define FA_FLASH_DDB_SIZE 0x080000

/* Flash Description Table */
struct qla_fdt_layout {
Expand Down Expand Up @@ -348,6 +350,7 @@ struct qla_flt_header {
#define FLT_REG_BOOT_CODE_82 0x78
#define FLT_REG_ISCSI_PARAM 0x65
#define FLT_REG_ISCSI_CHAP 0x63
#define FLT_REG_ISCSI_DDB 0x6A

struct qla_flt_region {
uint32_t code;
Expand Down Expand Up @@ -779,12 +782,41 @@ struct dev_db_entry {
#define DDB_OPT_IPV6_NULL_LINK_LOCAL 0x800 /* post connection */
#define DDB_OPT_IPV6_FW_DEFINED_LINK_LOCAL 0x800 /* pre connection */

#define OPT_IS_FW_ASSIGNED_IPV6 11
#define OPT_IPV6_DEVICE 8
#define OPT_AUTO_SENDTGTS_DISABLE 6
#define OPT_DISC_SESSION 4
#define OPT_ENTRY_STATE 3
uint16_t exec_throttle; /* 02-03 */
uint16_t exec_count; /* 04-05 */
uint16_t res0; /* 06-07 */
uint16_t iscsi_options; /* 08-09 */
#define ISCSIOPT_HEADER_DIGEST_EN 13
#define ISCSIOPT_DATA_DIGEST_EN 12
#define ISCSIOPT_IMMEDIATE_DATA_EN 11
#define ISCSIOPT_INITIAL_R2T_EN 10
#define ISCSIOPT_DATA_SEQ_IN_ORDER 9
#define ISCSIOPT_DATA_PDU_IN_ORDER 8
#define ISCSIOPT_CHAP_AUTH_EN 7
#define ISCSIOPT_SNACK_REQ_EN 6
#define ISCSIOPT_DISCOVERY_LOGOUT_EN 5
#define ISCSIOPT_BIDI_CHAP_EN 4
#define ISCSIOPT_DISCOVERY_AUTH_OPTIONAL 3
#define ISCSIOPT_ERL1 1
#define ISCSIOPT_ERL0 0

uint16_t tcp_options; /* 0A-0B */
#define TCPOPT_TIMESTAMP_STAT 6
#define TCPOPT_NAGLE_DISABLE 5
#define TCPOPT_WSF_DISABLE 4
#define TCPOPT_TIMER_SCALE3 3
#define TCPOPT_TIMER_SCALE2 2
#define TCPOPT_TIMER_SCALE1 1
#define TCPOPT_TIMESTAMP_EN 0

uint16_t ip_options; /* 0C-0D */
#define IPOPT_FRAGMENT_DISABLE 4

uint16_t iscsi_max_rcv_data_seg_len; /* 0E-0F */
#define BYTE_UNITS 512
uint32_t res1; /* 10-13 */
Expand Down Expand Up @@ -816,6 +848,8 @@ struct dev_db_entry {
* much RAM */
uint8_t link_local_ipv6_addr[0x10]; /* 1A0-1AF */
uint8_t res5[0x10]; /* 1B0-1BF */
#define DDB_NO_LINK 0xFFFF
#define DDB_ISNS 0xFFFD
uint16_t ddb_link; /* 1C0-1C1 */
uint16_t chap_tbl_idx; /* 1C2-1C3 */
uint16_t tgt_portal_grp; /* 1C4-1C5 */
Expand Down
7 changes: 7 additions & 0 deletions drivers/scsi/qla4xxx/ql4_glbl.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,9 @@ int qla4xxx_ping_iocb(struct scsi_qla_host *ha, uint32_t options,
int qla4xxx_post_ping_evt_work(struct scsi_qla_host *ha,
uint32_t status, uint32_t pid,
uint32_t data_size, uint8_t *data);
int qla4xxx_flashdb_by_index(struct scsi_qla_host *ha,
struct dev_db_entry *fw_ddb_entry,
dma_addr_t fw_ddb_entry_dma, uint16_t ddb_index);

/* BSG Functions */
int qla4xxx_bsg_request(struct bsg_job *bsg_job);
Expand Down Expand Up @@ -259,6 +262,10 @@ int qla4_83xx_post_idc_ack(struct scsi_qla_host *ha);
void qla4_83xx_disable_pause(struct scsi_qla_host *ha);
void qla4_83xx_enable_mbox_intrs(struct scsi_qla_host *ha);
int qla4_83xx_can_perform_reset(struct scsi_qla_host *ha);
int qla4xxx_get_default_ddb(struct scsi_qla_host *ha, uint32_t options,
dma_addr_t dma_addr);
int qla4xxx_get_uni_chap_at_index(struct scsi_qla_host *ha, char *username,
char *password, uint16_t chap_index);

extern int ql4xextended_error_logging;
extern int ql4xdontresethba;
Expand Down
106 changes: 104 additions & 2 deletions drivers/scsi/qla4xxx/ql4_mbx.c
Original file line number Diff line number Diff line change
Expand Up @@ -1288,8 +1288,8 @@ int qla4xxx_about_firmware(struct scsi_qla_host *ha)
return status;
}

static int qla4xxx_get_default_ddb(struct scsi_qla_host *ha, uint32_t options,
dma_addr_t dma_addr)
int qla4xxx_get_default_ddb(struct scsi_qla_host *ha, uint32_t options,
dma_addr_t dma_addr)
{
uint32_t mbox_cmd[MBOX_REG_COUNT];
uint32_t mbox_sts[MBOX_REG_COUNT];
Expand Down Expand Up @@ -1417,6 +1417,52 @@ int qla4xxx_bootdb_by_index(struct scsi_qla_host *ha,
return status;
}

int qla4xxx_flashdb_by_index(struct scsi_qla_host *ha,
struct dev_db_entry *fw_ddb_entry,
dma_addr_t fw_ddb_entry_dma, uint16_t ddb_index)
{
uint32_t dev_db_start_offset = FLASH_OFFSET_DB_INFO;
uint32_t dev_db_end_offset;
int status = QLA_ERROR;

memset(fw_ddb_entry, 0, sizeof(*fw_ddb_entry));

if (is_qla40XX(ha)) {
dev_db_start_offset = FLASH_OFFSET_DB_INFO;
} else {
dev_db_start_offset = FLASH_RAW_ACCESS_ADDR +
(ha->hw.flt_region_ddb << 2);
/* flt_ddb_size is DDB table size for both ports
* so divide it by 2 to calculate the offset for second port
*/
if (ha->port_num == 1)
dev_db_start_offset += (ha->hw.flt_ddb_size / 2);
}

dev_db_end_offset = dev_db_start_offset + (ha->hw.flt_ddb_size / 2);
dev_db_start_offset += (ddb_index * sizeof(*fw_ddb_entry));

if (dev_db_start_offset > dev_db_end_offset) {
DEBUG2(ql4_printk(KERN_ERR, ha,
"%s:Invalid DDB index %d", __func__,
ddb_index));
goto exit_fdb_failed;
}

if (qla4xxx_get_flash(ha, fw_ddb_entry_dma, dev_db_start_offset,
sizeof(*fw_ddb_entry)) != QLA_SUCCESS) {
ql4_printk(KERN_ERR, ha, "scsi%ld: %s: Get Flash failed\n",
ha->host_no, __func__);
goto exit_fdb_failed;
}

if (fw_ddb_entry->cookie == DDB_VALID_COOKIE)
status = QLA_SUCCESS;

exit_fdb_failed:
return status;
}

int qla4xxx_get_chap(struct scsi_qla_host *ha, char *username, char *password,
uint16_t idx)
{
Expand Down Expand Up @@ -1510,6 +1556,62 @@ static int qla4xxx_set_chap(struct scsi_qla_host *ha, char *username,
return ret;
}


int qla4xxx_get_uni_chap_at_index(struct scsi_qla_host *ha, char *username,
char *password, uint16_t chap_index)
{
int rval = QLA_ERROR;
struct ql4_chap_table *chap_table = NULL;
int max_chap_entries;

if (!ha->chap_list) {
ql4_printk(KERN_ERR, ha, "Do not have CHAP table cache\n");
rval = QLA_ERROR;
goto exit_uni_chap;
}

if (!username || !password) {
ql4_printk(KERN_ERR, ha, "No memory for username & secret\n");
rval = QLA_ERROR;
goto exit_uni_chap;
}

if (is_qla80XX(ha))
max_chap_entries = (ha->hw.flt_chap_size / 2) /
sizeof(struct ql4_chap_table);
else
max_chap_entries = MAX_CHAP_ENTRIES_40XX;

if (chap_index > max_chap_entries) {
ql4_printk(KERN_ERR, ha, "Invalid Chap index\n");
rval = QLA_ERROR;
goto exit_uni_chap;
}

mutex_lock(&ha->chap_sem);
chap_table = (struct ql4_chap_table *)ha->chap_list + chap_index;
if (chap_table->cookie != __constant_cpu_to_le16(CHAP_VALID_COOKIE)) {
rval = QLA_ERROR;
goto exit_unlock_uni_chap;
}

if (!(chap_table->flags & BIT_6)) {
ql4_printk(KERN_ERR, ha, "Unidirectional entry not set\n");
rval = QLA_ERROR;
goto exit_unlock_uni_chap;
}

strncpy(password, chap_table->secret, MAX_CHAP_SECRET_LEN);
strncpy(username, chap_table->name, MAX_CHAP_NAME_LEN);

rval = QLA_SUCCESS;

exit_unlock_uni_chap:
mutex_unlock(&ha->chap_sem);
exit_uni_chap:
return rval;
}

/**
* qla4xxx_get_chap_index - Get chap index given username and secret
* @ha: pointer to adapter structure
Expand Down
12 changes: 10 additions & 2 deletions drivers/scsi/qla4xxx/ql4_nx.c
Original file line number Diff line number Diff line change
Expand Up @@ -3154,6 +3154,10 @@ qla4_8xxx_get_flt_info(struct scsi_qla_host *ha, uint32_t flt_addr)
hw->flt_region_chap = start;
hw->flt_chap_size = le32_to_cpu(region->size);
break;
case FLT_REG_ISCSI_DDB:
hw->flt_region_ddb = start;
hw->flt_ddb_size = le32_to_cpu(region->size);
break;
}
}
goto done;
Expand All @@ -3168,13 +3172,17 @@ qla4_8xxx_get_flt_info(struct scsi_qla_host *ha, uint32_t flt_addr)
hw->flt_region_fw = FA_RISC_CODE_ADDR_82;
hw->flt_region_chap = FA_FLASH_ISCSI_CHAP >> 2;
hw->flt_chap_size = FA_FLASH_CHAP_SIZE;
hw->flt_region_ddb = FA_FLASH_ISCSI_DDB >> 2;
hw->flt_ddb_size = FA_FLASH_DDB_SIZE;

done:
DEBUG2(ql4_printk(KERN_INFO, ha,
"FLT[%s]: flt=0x%x fdt=0x%x boot=0x%x bootload=0x%x fw=0x%x chap=0x%x\n",
"FLT[%s]: flt=0x%x fdt=0x%x boot=0x%x bootload=0x%x fw=0x%x chap=0x%x chap_size=0x%x ddb=0x%x ddb_size=0x%x\n",
loc, hw->flt_region_flt, hw->flt_region_fdt,
hw->flt_region_boot, hw->flt_region_bootload,
hw->flt_region_fw, hw->flt_region_chap));
hw->flt_region_fw, hw->flt_region_chap,
hw->flt_chap_size, hw->flt_region_ddb,
hw->flt_ddb_size));
}

static void
Expand Down
Loading

0 comments on commit 1e9e2be

Please sign in to comment.