qed: Add support for processing iscsi tlv request.
authorSudarsana Reddy Kalluru <sudarsana.kalluru@cavium.com>
Tue, 22 May 2018 07:28:40 +0000 (00:28 -0700)
committerDavid S. Miller <davem@davemloft.net>
Wed, 23 May 2018 03:29:54 +0000 (23:29 -0400)
Signed-off-by: Sudarsana Reddy Kalluru <Sudarsana.Kalluru@cavium.com>
Signed-off-by: Ariel Elior <ariel.elior@cavium.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/qlogic/qed/qed_mcp.h
drivers/net/ethernet/qlogic/qed/qed_mng_tlv.c
include/linux/qed/qed_if.h

index b31f5d8bd27c59291d5341c39a40d2d74701133c..632a838f1fe3b8780d3a58795afac5bcf63156c7 100644 (file)
@@ -217,7 +217,8 @@ enum qed_mfw_tlv_type {
        QED_MFW_TLV_GENERIC = 0x1,      /* Core driver TLVs */
        QED_MFW_TLV_ETH = 0x2,          /* L2 driver TLVs */
        QED_MFW_TLV_FCOE = 0x4,         /* FCoE protocol TLVs */
-       QED_MFW_TLV_MAX = 0x8,
+       QED_MFW_TLV_ISCSI = 0x8,        /* SCSI protocol TLVs */
+       QED_MFW_TLV_MAX = 0x16,
 };
 
 struct qed_mfw_tlv_generic {
@@ -247,6 +248,7 @@ union qed_mfw_tlv_data {
        struct qed_mfw_tlv_generic generic;
        struct qed_mfw_tlv_eth eth;
        struct qed_mfw_tlv_fcoe fcoe;
+       struct qed_mfw_tlv_iscsi iscsi;
 };
 
 /**
index 1873cfc087156b94546d4754598c3eaf9574b176..6c16158d80900f7074599dbdd05ae188f2575bd6 100644 (file)
@@ -215,6 +215,23 @@ static int qed_mfw_get_tlv_group(u8 tlv_type, u8 *tlv_group)
        case DRV_TLV_SCSI_CHECK_5_TIMESTAMP:
                *tlv_group = QED_MFW_TLV_FCOE;
                break;
+       case DRV_TLV_TARGET_LLMNR_ENABLED:
+       case DRV_TLV_HEADER_DIGEST_FLAG_ENABLED:
+       case DRV_TLV_DATA_DIGEST_FLAG_ENABLED:
+       case DRV_TLV_AUTHENTICATION_METHOD:
+       case DRV_TLV_ISCSI_BOOT_TARGET_PORTAL:
+       case DRV_TLV_MAX_FRAME_SIZE:
+       case DRV_TLV_PDU_TX_DESCRIPTORS_QUEUE_SIZE:
+       case DRV_TLV_PDU_RX_DESCRIPTORS_QUEUE_SIZE:
+       case DRV_TLV_ISCSI_BOOT_PROGRESS:
+       case DRV_TLV_PDU_TX_DESCRIPTOR_QUEUE_AVG_DEPTH:
+       case DRV_TLV_PDU_RX_DESCRIPTORS_QUEUE_AVG_DEPTH:
+       case DRV_TLV_ISCSI_PDU_RX_FRAMES_RECEIVED:
+       case DRV_TLV_ISCSI_PDU_RX_BYTES_RECEIVED:
+       case DRV_TLV_ISCSI_PDU_TX_FRAMES_SENT:
+       case DRV_TLV_ISCSI_PDU_TX_BYTES_SENT:
+               *tlv_group |= QED_MFW_TLV_ISCSI;
+               break;
        default:
                return -EINVAL;
        }
@@ -1054,6 +1071,109 @@ qed_mfw_get_fcoe_tlv_value(struct qed_drv_tlv_hdr *p_tlv,
        return -1;
 }
 
+static int
+qed_mfw_get_iscsi_tlv_value(struct qed_drv_tlv_hdr *p_tlv,
+                           struct qed_mfw_tlv_iscsi *p_drv_buf,
+                           struct qed_tlv_parsed_buf *p_buf)
+{
+       switch (p_tlv->tlv_type) {
+       case DRV_TLV_TARGET_LLMNR_ENABLED:
+               if (p_drv_buf->target_llmnr_set) {
+                       p_buf->p_val = &p_drv_buf->target_llmnr;
+                       return sizeof(p_drv_buf->target_llmnr);
+               }
+               break;
+       case DRV_TLV_HEADER_DIGEST_FLAG_ENABLED:
+               if (p_drv_buf->header_digest_set) {
+                       p_buf->p_val = &p_drv_buf->header_digest;
+                       return sizeof(p_drv_buf->header_digest);
+               }
+               break;
+       case DRV_TLV_DATA_DIGEST_FLAG_ENABLED:
+               if (p_drv_buf->data_digest_set) {
+                       p_buf->p_val = &p_drv_buf->data_digest;
+                       return sizeof(p_drv_buf->data_digest);
+               }
+               break;
+       case DRV_TLV_AUTHENTICATION_METHOD:
+               if (p_drv_buf->auth_method_set) {
+                       p_buf->p_val = &p_drv_buf->auth_method;
+                       return sizeof(p_drv_buf->auth_method);
+               }
+               break;
+       case DRV_TLV_ISCSI_BOOT_TARGET_PORTAL:
+               if (p_drv_buf->boot_taget_portal_set) {
+                       p_buf->p_val = &p_drv_buf->boot_taget_portal;
+                       return sizeof(p_drv_buf->boot_taget_portal);
+               }
+               break;
+       case DRV_TLV_MAX_FRAME_SIZE:
+               if (p_drv_buf->frame_size_set) {
+                       p_buf->p_val = &p_drv_buf->frame_size;
+                       return sizeof(p_drv_buf->frame_size);
+               }
+               break;
+       case DRV_TLV_PDU_TX_DESCRIPTORS_QUEUE_SIZE:
+               if (p_drv_buf->tx_desc_size_set) {
+                       p_buf->p_val = &p_drv_buf->tx_desc_size;
+                       return sizeof(p_drv_buf->tx_desc_size);
+               }
+               break;
+       case DRV_TLV_PDU_RX_DESCRIPTORS_QUEUE_SIZE:
+               if (p_drv_buf->rx_desc_size_set) {
+                       p_buf->p_val = &p_drv_buf->rx_desc_size;
+                       return sizeof(p_drv_buf->rx_desc_size);
+               }
+               break;
+       case DRV_TLV_ISCSI_BOOT_PROGRESS:
+               if (p_drv_buf->boot_progress_set) {
+                       p_buf->p_val = &p_drv_buf->boot_progress;
+                       return sizeof(p_drv_buf->boot_progress);
+               }
+               break;
+       case DRV_TLV_PDU_TX_DESCRIPTOR_QUEUE_AVG_DEPTH:
+               if (p_drv_buf->tx_desc_qdepth_set) {
+                       p_buf->p_val = &p_drv_buf->tx_desc_qdepth;
+                       return sizeof(p_drv_buf->tx_desc_qdepth);
+               }
+               break;
+       case DRV_TLV_PDU_RX_DESCRIPTORS_QUEUE_AVG_DEPTH:
+               if (p_drv_buf->rx_desc_qdepth_set) {
+                       p_buf->p_val = &p_drv_buf->rx_desc_qdepth;
+                       return sizeof(p_drv_buf->rx_desc_qdepth);
+               }
+               break;
+       case DRV_TLV_ISCSI_PDU_RX_FRAMES_RECEIVED:
+               if (p_drv_buf->rx_frames_set) {
+                       p_buf->p_val = &p_drv_buf->rx_frames;
+                       return sizeof(p_drv_buf->rx_frames);
+               }
+               break;
+       case DRV_TLV_ISCSI_PDU_RX_BYTES_RECEIVED:
+               if (p_drv_buf->rx_bytes_set) {
+                       p_buf->p_val = &p_drv_buf->rx_bytes;
+                       return sizeof(p_drv_buf->rx_bytes);
+               }
+               break;
+       case DRV_TLV_ISCSI_PDU_TX_FRAMES_SENT:
+               if (p_drv_buf->tx_frames_set) {
+                       p_buf->p_val = &p_drv_buf->tx_frames;
+                       return sizeof(p_drv_buf->tx_frames);
+               }
+               break;
+       case DRV_TLV_ISCSI_PDU_TX_BYTES_SENT:
+               if (p_drv_buf->tx_bytes_set) {
+                       p_buf->p_val = &p_drv_buf->tx_bytes;
+                       return sizeof(p_drv_buf->tx_bytes);
+               }
+               break;
+       default:
+               break;
+       }
+
+       return -1;
+}
+
 static int qed_mfw_update_tlvs(struct qed_hwfn *p_hwfn,
                               u8 tlv_group, u8 *p_mfw_buf, u32 size)
 {
@@ -1097,6 +1217,10 @@ static int qed_mfw_update_tlvs(struct qed_hwfn *p_hwfn,
                        len = qed_mfw_get_fcoe_tlv_value(&tlv,
                                                         &p_tlv_data->fcoe,
                                                         &buffer);
+               else
+                       len = qed_mfw_get_iscsi_tlv_value(&tlv,
+                                                         &p_tlv_data->iscsi,
+                                                         &buffer);
 
                if (len > 0) {
                        WARN(len > 4 * tlv.tlv_length,
@@ -1179,6 +1303,13 @@ int qed_mfw_process_tlv_req(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
                tlv_group &= ~QED_MFW_TLV_FCOE;
        }
 
+       if ((tlv_group & QED_MFW_TLV_ISCSI) &&
+           p_hwfn->hw_info.personality != QED_PCI_ISCSI) {
+               DP_VERBOSE(p_hwfn, QED_MSG_SP,
+                          "Skipping iSCSI TLVs for non-iSCSI function\n");
+               tlv_group &= ~QED_MFW_TLV_ISCSI;
+       }
+
        /* Update the TLV values in the local buffer */
        for (id = QED_MFW_TLV_GENERIC; id < QED_MFW_TLV_MAX; id <<= 1) {
                if (tlv_group & id)
index 74c2b9ad8afa29a9d90d02b93fcaf66cb508a99a..92b5352287dfaa446d4fa9958a24db3528908224 100644 (file)
@@ -412,6 +412,42 @@ struct qed_mfw_tlv_fcoe {
        struct qed_mfw_tlv_time scsi_chk_tstamp[5];
 };
 
+struct qed_mfw_tlv_iscsi {
+       u8 target_llmnr;
+       bool target_llmnr_set;
+       u8 header_digest;
+       bool header_digest_set;
+       u8 data_digest;
+       bool data_digest_set;
+       u8 auth_method;
+#define QED_MFW_TLV_AUTH_METHOD_NONE            (1)
+#define QED_MFW_TLV_AUTH_METHOD_CHAP            (2)
+#define QED_MFW_TLV_AUTH_METHOD_MUTUAL_CHAP     (3)
+       bool auth_method_set;
+       u16 boot_taget_portal;
+       bool boot_taget_portal_set;
+       u16 frame_size;
+       bool frame_size_set;
+       u16 tx_desc_size;
+       bool tx_desc_size_set;
+       u16 rx_desc_size;
+       bool rx_desc_size_set;
+       u8 boot_progress;
+       bool boot_progress_set;
+       u16 tx_desc_qdepth;
+       bool tx_desc_qdepth_set;
+       u16 rx_desc_qdepth;
+       bool rx_desc_qdepth_set;
+       u64 rx_frames;
+       bool rx_frames_set;
+       u64 rx_bytes;
+       bool rx_bytes_set;
+       u64 tx_frames;
+       bool tx_frames_set;
+       u64 tx_bytes;
+       bool tx_bytes_set;
+};
+
 #define DIRECT_REG_WR(reg_addr, val) writel((u32)val, \
                                            (void __iomem *)(reg_addr))