Re: [RFC 4/6] qedi: Add LL2 iSCSI interface for offload iSCSI.

2016-10-19 Thread Hannes Reinecke
On 10/19/2016 07:01 AM, manish.rangan...@cavium.com wrote:
> From: Manish Rangankar 
> 
> This patch adds support for iscsiuio interface using Light L2 (LL2) qed
> interface.
> 
> Signed-off-by: Nilesh Javali 
> Signed-off-by: Adheer Chandravanshi 
> Signed-off-by: Chad Dupuis 
> Signed-off-by: Saurav Kashyap 
> Signed-off-by: Arun Easi 
> Signed-off-by: Manish Rangankar 
> ---
>  drivers/scsi/qedi/qedi.h  |  73 +
>  drivers/scsi/qedi/qedi_main.c | 357 
> ++
>  2 files changed, 430 insertions(+)
> 
Reviewed-by: Hannes Reinecke 

Cheers,

Hannes
-- 
Dr. Hannes ReineckeTeamlead Storage & Networking
h...@suse.de   +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)


[RFC 4/6] qedi: Add LL2 iSCSI interface for offload iSCSI.

2016-10-18 Thread manish.rangankar
From: Manish Rangankar 

This patch adds support for iscsiuio interface using Light L2 (LL2) qed
interface.

Signed-off-by: Nilesh Javali 
Signed-off-by: Adheer Chandravanshi 
Signed-off-by: Chad Dupuis 
Signed-off-by: Saurav Kashyap 
Signed-off-by: Arun Easi 
Signed-off-by: Manish Rangankar 
---
 drivers/scsi/qedi/qedi.h  |  73 +
 drivers/scsi/qedi/qedi_main.c | 357 ++
 2 files changed, 430 insertions(+)

diff --git a/drivers/scsi/qedi/qedi.h b/drivers/scsi/qedi/qedi.h
index 0a5035e..02fefbd 100644
--- a/drivers/scsi/qedi/qedi.h
+++ b/drivers/scsi/qedi/qedi.h
@@ -21,6 +21,7 @@
 #include 
 #include "qedi_dbg.h"
 #include 
+#include 
 #include "qedi_version.h"
 
 #define QEDI_MODULE_NAME   "qedi"
@@ -54,6 +55,78 @@
 #define QEDI_LOCAL_PORT_MAX 61024
 #define QEDI_LOCAL_PORT_RANGE   (QEDI_LOCAL_PORT_MAX - QEDI_LOCAL_PORT_MIN)
 #define QEDI_LOCAL_PORT_INVALID0x
+#define TX_RX_RING 16
+#define RX_RING(TX_RX_RING - 1)
+#define LL2_SINGLE_BUF_SIZE0x400
+#define QEDI_PAGE_SIZE 4096
+#define QEDI_PAGE_ALIGN(addr)  ALIGN(addr, QEDI_PAGE_SIZE)
+#define QEDI_PAGE_MASK (~((QEDI_PAGE_SIZE) - 1))
+
+#define QEDI_PAGE_SIZE 4096
+#define QEDI_PATH_HANDLE   0xFE000UL
+
+struct qedi_uio_ctrl {
+   /* meta data */
+   u32 uio_hsi_version;
+
+   /* user writes */
+   u32 host_tx_prod;
+   u32 host_rx_cons;
+   u32 host_rx_bd_cons;
+   u32 host_tx_pkt_len;
+   u32 host_rx_cons_cnt;
+
+   /* driver writes */
+   u32 hw_tx_cons;
+   u32 hw_rx_prod;
+   u32 hw_rx_bd_prod;
+   u32 hw_rx_prod_cnt;
+
+   /* other */
+   u8 mac_addr[6];
+   u8 reserve[2];
+};
+
+struct qedi_rx_bd {
+   u32 rx_pkt_index;
+   u32 rx_pkt_len;
+   u16 vlan_id;
+};
+
+#define QEDI_RX_DESC_CNT   (QEDI_PAGE_SIZE / sizeof(struct qedi_rx_bd))
+#define QEDI_MAX_RX_DESC_CNT   (QEDI_RX_DESC_CNT - 1)
+#define QEDI_NUM_RX_BD (QEDI_RX_DESC_CNT * 1)
+#define QEDI_MAX_RX_BD (QEDI_NUM_RX_BD - 1)
+
+#define QEDI_NEXT_RX_IDX(x)x) & (QEDI_MAX_RX_DESC_CNT)) == \
+ (QEDI_MAX_RX_DESC_CNT - 1)) ? \
+(x) + 2 : (x) + 1)
+
+struct qedi_uio_dev {
+   struct uio_info qedi_uinfo;
+   u32 uio_dev;
+   struct list_headlist;
+
+   u32 ll2_ring_size;
+   void*ll2_ring;
+
+   u32 ll2_buf_size;
+   void*ll2_buf;
+
+   void*rx_pkt;
+   void*tx_pkt;
+
+   struct qedi_ctx *qedi;
+   struct pci_dev  *pdev;
+   void*uctrl;
+};
+
+/* List to maintain the skb pointers */
+struct skb_work_list {
+   struct list_head list;
+   struct sk_buff *skb;
+   u16 vlan_id;
+};
 
 /* Queue sizes in number of elements */
 #define QEDI_SQ_SIZE   MAX_OUSTANDING_TASKS_PER_CON
diff --git a/drivers/scsi/qedi/qedi_main.c b/drivers/scsi/qedi/qedi_main.c
index 35ab2f9..58ac9a2 100644
--- a/drivers/scsi/qedi/qedi_main.c
+++ b/drivers/scsi/qedi/qedi_main.c
@@ -45,9 +45,12 @@
 static struct scsi_transport_template *qedi_scsi_transport;
 static struct pci_driver qedi_pci_driver;
 static DEFINE_PER_CPU(struct qedi_percpu_s, qedi_percpu);
+static LIST_HEAD(qedi_udev_list);
 /* Static function declaration */
 static int qedi_alloc_global_queues(struct qedi_ctx *qedi);
 static void qedi_free_global_queues(struct qedi_ctx *qedi);
+static void qedi_reset_uio_rings(struct qedi_uio_dev *udev);
+static void qedi_ll2_free_skbs(struct qedi_ctx *qedi);
 
 static int qedi_iscsi_event_cb(void *context, u8 fw_event_code, void 
*fw_handle)
 {
@@ -112,6 +115,224 @@ static int qedi_iscsi_event_cb(void *context, u8 
fw_event_code, void *fw_handle)
return rval;
 }
 
+static int qedi_uio_open(struct uio_info *uinfo, struct inode *inode)
+{
+   struct qedi_uio_dev *udev = uinfo->priv;
+   struct qedi_ctx *qedi = udev->qedi;
+
+   if (!capable(CAP_NET_ADMIN))
+   return -EPERM;
+
+   if (udev->uio_dev != -1)
+   return -EBUSY;
+
+   rtnl_lock();
+   udev->uio_dev = iminor(inode);
+   qedi_reset_uio_rings(udev);
+   set_bit(UIO_DEV_OPENED, >flags);
+   rtnl_unlock();
+
+   return 0;
+}
+
+static int qedi_uio_close(struct uio_info *uinfo, struct inode *inode)
+{
+   struct qedi_uio_dev *udev = uinfo->priv;
+   struct qedi_ctx *qedi = udev->qedi;
+
+   udev->uio_dev = -1;
+   clear_bit(UIO_DEV_OPENED, >flags);
+   qedi_ll2_free_skbs(qedi);
+   return 0;
+}
+
+static void