Skip to content

Commit 534bbdf

Browse files
Manish Rangankardavem330
authored andcommitted
qedi: Add support for populating ethernet TLVs.
This patch adds callbacks for providing the ethernet protocol driver TLVs. Signed-off-by: Manish Rangankar <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 8673daf commit 534bbdf

File tree

3 files changed

+191
-0
lines changed

3 files changed

+191
-0
lines changed

drivers/scsi/qedi/qedi.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,9 @@ struct qedi_ctx {
353353
#define IPV6_LEN 41
354354
#define IPV4_LEN 17
355355
struct iscsi_boot_kset *boot_kset;
356+
357+
/* Used for iscsi statistics */
358+
struct mutex stats_lock;
356359
};
357360

358361
struct qedi_work {

drivers/scsi/qedi/qedi_iscsi.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,12 @@ struct qedi_work_map {
223223
struct work_struct *ptr_tmf_work;
224224
};
225225

226+
struct qedi_boot_target {
227+
char ip_addr[64];
228+
char iscsi_name[255];
229+
u32 ipv6_en;
230+
};
231+
226232
#define qedi_set_itt(task_id, itt) ((u32)(((task_id) & 0xffff) | ((itt) << 16)))
227233
#define qedi_get_itt(cqe) (cqe.iscsi_hdr.cmd.itt >> 16)
228234

drivers/scsi/qedi/qedi_main.c

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ static void qedi_free_global_queues(struct qedi_ctx *qedi);
5555
static struct qedi_cmd *qedi_get_cmd_from_tid(struct qedi_ctx *qedi, u32 tid);
5656
static void qedi_reset_uio_rings(struct qedi_uio_dev *udev);
5757
static void qedi_ll2_free_skbs(struct qedi_ctx *qedi);
58+
static struct nvm_iscsi_block *qedi_get_nvram_block(struct qedi_ctx *qedi);
5859

5960
static int qedi_iscsi_event_cb(void *context, u8 fw_event_code, void *fw_handle)
6061
{
@@ -879,6 +880,186 @@ static void qedi_free_iscsi_pf_param(struct qedi_ctx *qedi)
879880
kfree(qedi->global_queues);
880881
}
881882

883+
static void qedi_get_boot_tgt_info(struct nvm_iscsi_block *block,
884+
struct qedi_boot_target *tgt, u8 index)
885+
{
886+
u32 ipv6_en;
887+
888+
ipv6_en = !!(block->generic.ctrl_flags &
889+
NVM_ISCSI_CFG_GEN_IPV6_ENABLED);
890+
891+
snprintf(tgt->iscsi_name, NVM_ISCSI_CFG_ISCSI_NAME_MAX_LEN, "%s\n",
892+
block->target[index].target_name.byte);
893+
894+
tgt->ipv6_en = ipv6_en;
895+
896+
if (ipv6_en)
897+
snprintf(tgt->ip_addr, IPV6_LEN, "%pI6\n",
898+
block->target[index].ipv6_addr.byte);
899+
else
900+
snprintf(tgt->ip_addr, IPV4_LEN, "%pI4\n",
901+
block->target[index].ipv4_addr.byte);
902+
}
903+
904+
static int qedi_find_boot_info(struct qedi_ctx *qedi,
905+
struct qed_mfw_tlv_iscsi *iscsi,
906+
struct nvm_iscsi_block *block)
907+
{
908+
struct qedi_boot_target *pri_tgt = NULL, *sec_tgt = NULL;
909+
u32 pri_ctrl_flags = 0, sec_ctrl_flags = 0, found = 0;
910+
struct iscsi_cls_session *cls_sess;
911+
struct iscsi_cls_conn *cls_conn;
912+
struct qedi_conn *qedi_conn;
913+
struct iscsi_session *sess;
914+
struct iscsi_conn *conn;
915+
char ep_ip_addr[64];
916+
int i, ret = 0;
917+
918+
pri_ctrl_flags = !!(block->target[0].ctrl_flags &
919+
NVM_ISCSI_CFG_TARGET_ENABLED);
920+
if (pri_ctrl_flags) {
921+
pri_tgt = kzalloc(sizeof(*pri_tgt), GFP_KERNEL);
922+
if (!pri_tgt)
923+
return -1;
924+
qedi_get_boot_tgt_info(block, pri_tgt, 0);
925+
}
926+
927+
sec_ctrl_flags = !!(block->target[1].ctrl_flags &
928+
NVM_ISCSI_CFG_TARGET_ENABLED);
929+
if (sec_ctrl_flags) {
930+
sec_tgt = kzalloc(sizeof(*sec_tgt), GFP_KERNEL);
931+
if (!sec_tgt) {
932+
ret = -1;
933+
goto free_tgt;
934+
}
935+
qedi_get_boot_tgt_info(block, sec_tgt, 1);
936+
}
937+
938+
for (i = 0; i < qedi->max_active_conns; i++) {
939+
qedi_conn = qedi_get_conn_from_id(qedi, i);
940+
if (!qedi_conn)
941+
continue;
942+
943+
if (qedi_conn->ep->ip_type == TCP_IPV4)
944+
snprintf(ep_ip_addr, IPV4_LEN, "%pI4\n",
945+
qedi_conn->ep->dst_addr);
946+
else
947+
snprintf(ep_ip_addr, IPV6_LEN, "%pI6\n",
948+
qedi_conn->ep->dst_addr);
949+
950+
cls_conn = qedi_conn->cls_conn;
951+
conn = cls_conn->dd_data;
952+
cls_sess = iscsi_conn_to_session(cls_conn);
953+
sess = cls_sess->dd_data;
954+
955+
if (pri_ctrl_flags) {
956+
if (!strcmp(pri_tgt->iscsi_name, sess->targetname) &&
957+
!strcmp(pri_tgt->ip_addr, ep_ip_addr)) {
958+
found = 1;
959+
break;
960+
}
961+
}
962+
963+
if (sec_ctrl_flags) {
964+
if (!strcmp(sec_tgt->iscsi_name, sess->targetname) &&
965+
!strcmp(sec_tgt->ip_addr, ep_ip_addr)) {
966+
found = 1;
967+
break;
968+
}
969+
}
970+
}
971+
972+
if (found) {
973+
if (conn->hdrdgst_en) {
974+
iscsi->header_digest_set = true;
975+
iscsi->header_digest = 1;
976+
}
977+
978+
if (conn->datadgst_en) {
979+
iscsi->data_digest_set = true;
980+
iscsi->data_digest = 1;
981+
}
982+
iscsi->boot_taget_portal_set = true;
983+
iscsi->boot_taget_portal = sess->tpgt;
984+
985+
} else {
986+
ret = -1;
987+
}
988+
989+
if (sec_ctrl_flags)
990+
kfree(sec_tgt);
991+
free_tgt:
992+
if (pri_ctrl_flags)
993+
kfree(pri_tgt);
994+
995+
return ret;
996+
}
997+
998+
/*
999+
* Protocol TLV handler
1000+
*/
1001+
static void qedi_get_protocol_tlv_data(void *dev, void *data)
1002+
{
1003+
struct qed_mfw_tlv_iscsi *iscsi = data;
1004+
struct qed_iscsi_stats *fw_iscsi_stats;
1005+
struct nvm_iscsi_block *block = NULL;
1006+
u32 chap_en = 0, mchap_en = 0;
1007+
struct qedi_ctx *qedi = dev;
1008+
int rval = 0;
1009+
1010+
fw_iscsi_stats = kmalloc(sizeof(*fw_iscsi_stats), GFP_KERNEL);
1011+
if (!fw_iscsi_stats) {
1012+
QEDI_ERR(&qedi->dbg_ctx,
1013+
"Could not allocate memory for fw_iscsi_stats.\n");
1014+
goto exit_get_data;
1015+
}
1016+
1017+
mutex_lock(&qedi->stats_lock);
1018+
/* Query firmware for offload stats */
1019+
qedi_ops->get_stats(qedi->cdev, fw_iscsi_stats);
1020+
mutex_unlock(&qedi->stats_lock);
1021+
1022+
iscsi->rx_frames_set = true;
1023+
iscsi->rx_frames = fw_iscsi_stats->iscsi_rx_packet_cnt;
1024+
iscsi->rx_bytes_set = true;
1025+
iscsi->rx_bytes = fw_iscsi_stats->iscsi_rx_bytes_cnt;
1026+
iscsi->tx_frames_set = true;
1027+
iscsi->tx_frames = fw_iscsi_stats->iscsi_tx_packet_cnt;
1028+
iscsi->tx_bytes_set = true;
1029+
iscsi->tx_bytes = fw_iscsi_stats->iscsi_tx_bytes_cnt;
1030+
iscsi->frame_size_set = true;
1031+
iscsi->frame_size = qedi->ll2_mtu;
1032+
block = qedi_get_nvram_block(qedi);
1033+
if (block) {
1034+
chap_en = !!(block->generic.ctrl_flags &
1035+
NVM_ISCSI_CFG_GEN_CHAP_ENABLED);
1036+
mchap_en = !!(block->generic.ctrl_flags &
1037+
NVM_ISCSI_CFG_GEN_CHAP_MUTUAL_ENABLED);
1038+
1039+
iscsi->auth_method_set = (chap_en || mchap_en) ? true : false;
1040+
iscsi->auth_method = 1;
1041+
if (chap_en)
1042+
iscsi->auth_method = 2;
1043+
if (mchap_en)
1044+
iscsi->auth_method = 3;
1045+
1046+
iscsi->tx_desc_size_set = true;
1047+
iscsi->tx_desc_size = QEDI_SQ_SIZE;
1048+
iscsi->rx_desc_size_set = true;
1049+
iscsi->rx_desc_size = QEDI_CQ_SIZE;
1050+
1051+
/* tpgt, hdr digest, data digest */
1052+
rval = qedi_find_boot_info(qedi, iscsi, block);
1053+
if (rval)
1054+
QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_INFO,
1055+
"Boot target not set");
1056+
}
1057+
1058+
kfree(fw_iscsi_stats);
1059+
exit_get_data:
1060+
return;
1061+
}
1062+
8821063
static void qedi_link_update(void *dev, struct qed_link_output *link)
8831064
{
8841065
struct qedi_ctx *qedi = (struct qedi_ctx *)dev;
@@ -896,6 +1077,7 @@ static void qedi_link_update(void *dev, struct qed_link_output *link)
8961077
static struct qed_iscsi_cb_ops qedi_cb_ops = {
8971078
{
8981079
.link_update = qedi_link_update,
1080+
.get_protocol_tlv_data = qedi_get_protocol_tlv_data,
8991081
}
9001082
};
9011083

0 commit comments

Comments
 (0)