All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] enic: This patchset adds support for Cisco Low Latency NIC
@ 2013-08-09 18:12 Neel Patel
  2013-08-09 18:12 ` [PATCH 1/4] drivers/net: enic: Adding " Neel Patel
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: Neel Patel @ 2013-08-09 18:12 UTC (permalink / raw)
  To: netdev; +Cc: Neel Patel, Nishank Trivedi, Christian Benvenuti

Signed-off-by: Neel Patel <neepatel@cisco.com>
Signed-off-by: Nishank Trivedi <nistrive@cisco.com>
Signed-off-by: Christian Benvenuti <benve@cisco.com>

Neel Patel (4):
  drivers/net: enic: Adding support for Cisco Low Latency NIC
  drivers/net: enic: Add an interface for USNIC to interact with
    firmware
  drivers/net: enic: Make ASIC information available to USNIC
  drivers/net: enic: Generate notification of hardware crash

 drivers/net/ethernet/cisco/enic/Makefile       |   2 +-
 drivers/net/ethernet/cisco/enic/driver_utils.h |  49 +++++++
 drivers/net/ethernet/cisco/enic/enic.h         |   5 +-
 drivers/net/ethernet/cisco/enic/enic_api.c     |  48 +++++++
 drivers/net/ethernet/cisco/enic/enic_api.h     |  30 +++++
 drivers/net/ethernet/cisco/enic/enic_ethtool.c |   4 +
 drivers/net/ethernet/cisco/enic/enic_main.c    |   4 +
 drivers/net/ethernet/cisco/enic/enic_res.h     |   9 +-
 drivers/net/ethernet/cisco/enic/vnic_dev.c     |   5 +
 drivers/net/ethernet/cisco/enic/vnic_dev.h     |   1 +
 drivers/net/ethernet/cisco/enic/vnic_devcmd.h  | 176 ++++++++++++++++++++++++-
 drivers/net/ethernet/cisco/enic/vnic_rq.c      |   9 +-
 drivers/net/ethernet/cisco/enic/vnic_rq.h      |   5 +-
 drivers/net/ethernet/cisco/enic/vnic_wq.c      |   7 +-
 drivers/net/ethernet/cisco/enic/vnic_wq.h      |  86 +++++++++++-
 15 files changed, 419 insertions(+), 21 deletions(-)
 create mode 100644 drivers/net/ethernet/cisco/enic/driver_utils.h
 create mode 100644 drivers/net/ethernet/cisco/enic/enic_api.c
 create mode 100644 drivers/net/ethernet/cisco/enic/enic_api.h

-- 
1.8.4-rc0

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/4] drivers/net: enic: Adding support for Cisco Low Latency NIC
  2013-08-09 18:12 [PATCH 0/4] enic: This patchset adds support for Cisco Low Latency NIC Neel Patel
@ 2013-08-09 18:12 ` Neel Patel
  2013-08-09 18:12 ` [PATCH 2/4] drivers/net: enic: Add an interface for USNIC to interact with firmware Neel Patel
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 10+ messages in thread
From: Neel Patel @ 2013-08-09 18:12 UTC (permalink / raw)
  To: netdev; +Cc: Neel Patel, Nishank Trivedi, Christian Benvenuti

This patch,
	- Adds new firmware commands for the new Cisco Low Latency NIC
      (aka. USNIC).
    - Enables descriptor prefetch on the hardware. This feature
      reduces latency for small packet transmit.

Signed-off-by: Neel Patel <neepatel@cisco.com>
Signed-off-by: Nishank Trivedi <nistrive@cisco.com>
Signed-off-by: Christian Benvenuti <benve@cisco.com>
---
 drivers/net/ethernet/cisco/enic/enic.h        |   2 +-
 drivers/net/ethernet/cisco/enic/enic_res.h    |   9 +-
 drivers/net/ethernet/cisco/enic/vnic_dev.c    |   5 +
 drivers/net/ethernet/cisco/enic/vnic_dev.h    |   1 +
 drivers/net/ethernet/cisco/enic/vnic_devcmd.h | 176 +++++++++++++++++++++++++-
 drivers/net/ethernet/cisco/enic/vnic_rq.c     |   9 +-
 drivers/net/ethernet/cisco/enic/vnic_rq.h     |   5 +-
 drivers/net/ethernet/cisco/enic/vnic_wq.c     |   7 +-
 drivers/net/ethernet/cisco/enic/vnic_wq.h     |  86 ++++++++++++-
 9 files changed, 281 insertions(+), 19 deletions(-)

diff --git a/drivers/net/ethernet/cisco/enic/enic.h b/drivers/net/ethernet/cisco/enic/enic.h
index 2e37c63..75e842d 100644
--- a/drivers/net/ethernet/cisco/enic/enic.h
+++ b/drivers/net/ethernet/cisco/enic/enic.h
@@ -33,7 +33,7 @@
 #define DRV_NAME		"enic"
 #define DRV_DESCRIPTION		"Cisco VIC Ethernet NIC Driver"
 #define DRV_VERSION		"2.1.1.39"
-#define DRV_COPYRIGHT		"Copyright 2008-2011 Cisco Systems, Inc"
+#define DRV_COPYRIGHT		"Copyright 2008-2013 Cisco Systems, Inc"
 
 #define ENIC_BARS_MAX		6
 
diff --git a/drivers/net/ethernet/cisco/enic/enic_res.h b/drivers/net/ethernet/cisco/enic/enic_res.h
index 25be273..69f60af 100644
--- a/drivers/net/ethernet/cisco/enic/enic_res.h
+++ b/drivers/net/ethernet/cisco/enic/enic_res.h
@@ -47,6 +47,9 @@ static inline void enic_queue_wq_desc_ex(struct vnic_wq *wq,
 	int offload_mode, int cq_entry, int sop, int eop, int loopback)
 {
 	struct wq_enet_desc *desc = vnic_wq_next_desc(wq);
+	u8 desc_skip_cnt = 1;
+	u8 compressed_send = 0;
+	u64 wrid = 0;
 
 	wq_enet_desc_enc(desc,
 		(u64)dma_addr | VNIC_PADDR_TARGET,
@@ -59,7 +62,8 @@ static inline void enic_queue_wq_desc_ex(struct vnic_wq *wq,
 		(u16)vlan_tag,
 		(u8)loopback);
 
-	vnic_wq_post(wq, os_buf, dma_addr, len, sop, eop);
+	vnic_wq_post(wq, os_buf, dma_addr, len, sop, eop, desc_skip_cnt,
+			(u8)cq_entry, compressed_send, wrid);
 }
 
 static inline void enic_queue_wq_desc_cont(struct vnic_wq *wq,
@@ -120,6 +124,7 @@ static inline void enic_queue_rq_desc(struct vnic_rq *rq,
 	dma_addr_t dma_addr, unsigned int len)
 {
 	struct rq_enet_desc *desc = vnic_rq_next_desc(rq);
+	u64 wrid = 0;
 	u8 type = os_buf_index ?
 		RQ_ENET_TYPE_NOT_SOP : RQ_ENET_TYPE_ONLY_SOP;
 
@@ -127,7 +132,7 @@ static inline void enic_queue_rq_desc(struct vnic_rq *rq,
 		(u64)dma_addr | VNIC_PADDR_TARGET,
 		type, (u16)len);
 
-	vnic_rq_post(rq, os_buf, os_buf_index, dma_addr, len);
+	vnic_rq_post(rq, os_buf, os_buf_index, dma_addr, len, wrid);
 }
 
 struct enic;
diff --git a/drivers/net/ethernet/cisco/enic/vnic_dev.c b/drivers/net/ethernet/cisco/enic/vnic_dev.c
index 97455c5..1b436b3 100644
--- a/drivers/net/ethernet/cisco/enic/vnic_dev.c
+++ b/drivers/net/ethernet/cisco/enic/vnic_dev.c
@@ -970,6 +970,11 @@ err_out:
 	return NULL;
 }
 
+struct pci_dev *vnic_dev_get_pdev(struct vnic_dev *vdev)
+{
+	return vdev->pdev;
+}
+
 int vnic_dev_init_prov2(struct vnic_dev *vdev, u8 *buf, u32 len)
 {
 	u64 a0, a1 = len;
diff --git a/drivers/net/ethernet/cisco/enic/vnic_dev.h b/drivers/net/ethernet/cisco/enic/vnic_dev.h
index f3d9b79..e670029 100644
--- a/drivers/net/ethernet/cisco/enic/vnic_dev.h
+++ b/drivers/net/ethernet/cisco/enic/vnic_dev.h
@@ -127,6 +127,7 @@ int vnic_dev_set_ig_vlan_rewrite_mode(struct vnic_dev *vdev,
 struct vnic_dev *vnic_dev_register(struct vnic_dev *vdev,
 	void *priv, struct pci_dev *pdev, struct vnic_dev_bar *bar,
 	unsigned int num_bars);
+struct pci_dev *vnic_dev_get_pdev(struct vnic_dev *vdev);
 int vnic_dev_init_prov2(struct vnic_dev *vdev, u8 *buf, u32 len);
 int vnic_dev_enable2(struct vnic_dev *vdev, int active);
 int vnic_dev_enable2_done(struct vnic_dev *vdev, int *status);
diff --git a/drivers/net/ethernet/cisco/enic/vnic_devcmd.h b/drivers/net/ethernet/cisco/enic/vnic_devcmd.h
index 23d5552..b9a0d78 100644
--- a/drivers/net/ethernet/cisco/enic/vnic_devcmd.h
+++ b/drivers/net/ethernet/cisco/enic/vnic_devcmd.h
@@ -281,11 +281,25 @@ enum vnic_devcmd_cmd {
 	 *              0 if no VIF-CONFIG-INFO TLV was ever received. */
 	CMD_CONFIG_INFO_GET     = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 44),
 
+	/* INT13 API: (u64)a0=paddr to vnic_int13_params struct
+	 *            (u32)a1=INT13_CMD_xxx
+	 */
+	CMD_INT13_ALL = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 45),
+
+	/* Set default vlan:
+	 * in: (u16)a0=new default vlan
+	 *     (u16)a1=zero for overriding vlan with param a0,
+	 *		       non-zero for resetting vlan to the default
+	 * out: (u16)a0=old default vlan
+	 */
+	CMD_SET_DEFAULT_VLAN = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 46),
+
 	/* init_prov_info2:
 	 * Variant of CMD_INIT_PROV_INFO, where it will not try to enable
 	 * the vnic until CMD_ENABLE2 is issued.
 	 *     (u64)a0=paddr of vnic_devcmd_provinfo
-	 *     (u32)a1=sizeof provision info */
+	 *     (u32)a1=sizeof provision info
+	 */
 	CMD_INIT_PROV_INFO2  = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 47),
 
 	/* enable2:
@@ -339,16 +353,57 @@ enum vnic_devcmd_cmd {
 	CMD_INTR_COAL_CONVERT = _CMDC(_CMD_DIR_READ, _CMD_VTYPE_ALL, 50),
 
 	/*
-	 * cmd_set_mac_addr
-	 *	set mac address
+	 * Set the predefined mac address as default
 	 * in:
 	 *   (u48)a0 = mac addr
-	 *
 	 */
 	CMD_SET_MAC_ADDR = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 55),
+
+	/* Update the provisioning info of the given VIF
+	 *     (u64)a0=paddr of vnic_devcmd_provinfo
+	 *     (u32)a1=sizeof provision info
+	 */
+	CMD_PROV_INFO_UPDATE = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 56),
+
+	/* Add a filter.
+	 * in: (u64) a0= filter address
+	 *     (u32) a1= size of filter
+	 * out: (u32) a0=filter identifier
+	 */
+	CMD_ADD_FILTER = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ENET, 58),
+
+	/* Delete a filter.
+	 * in: (u32) a0=filter identifier
+	 */
+	CMD_DEL_FILTER = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 59),
+
+	/* Enable a Queue Pair in User space NIC
+	 * in: (u32) a0=Queue Pair number
+	 *     (u32) a1= command
+	 */
+	CMD_QP_ENABLE = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 60),
+
+	/* Disable a Queue Pair in User space NIC
+	 * in: (u32) a0=Queue Pair number
+	 *     (u32) a1= command
+	 */
+	CMD_QP_DISABLE = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 61),
+
+	/* Stats dump Queue Pair in User space NIC
+	 * in: (u32) a0=Queue Pair number
+	 *     (u64) a1=host buffer addr for status dump
+	 *     (u32) a2=length of the buffer
+	 */
+	CMD_QP_STATS_DUMP = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 62),
+
+	/* Clear stats for Queue Pair in User space NIC
+	 * in: (u32) a0=Queue Pair number
+	 */
+	CMD_QP_STATS_CLEAR = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 63),
 };
 
 /* CMD_ENABLE2 flags */
+#define CMD_ENABLE2_STANDBY 0x0
 #define CMD_ENABLE2_ACTIVE  0x1
 
 /* flags for CMD_OPEN */
@@ -364,6 +419,9 @@ enum vnic_devcmd_cmd {
 #define CMD_PFILTER_PROMISCUOUS		0x08
 #define CMD_PFILTER_ALL_MULTICAST	0x10
 
+/* Commands for CMD_QP_ENABLE/CM_QP_DISABLE */
+#define CMD_QP_RQWQ                     0x0
+
 /* rewrite modes for CMD_IG_VLAN_REWRITE_MODE */
 #define IG_VLAN_REWRITE_MODE_DEFAULT_TRUNK              0
 #define IG_VLAN_REWRITE_MODE_UNTAG_DEFAULT_VLAN         1
@@ -390,6 +448,7 @@ enum vnic_devcmd_error {
 	ERR_EMAXRES = 10,
 	ERR_ENOTSUPPORTED = 11,
 	ERR_EINPROGRESS = 12,
+	ERR_MAX
 };
 
 /*
@@ -435,6 +494,115 @@ struct vnic_devcmd_provinfo {
 	u8 data[0];
 };
 
+/* These are used in flags field of different filters to denote
+ * valid fields used.
+ */
+#define FILTER_FIELD_VALID(fld) (1 << (fld - 1))
+
+#define FILTER_FIELDS_USNIC ( \
+			FILTER_FIELD_VALID(1) | \
+			FILTER_FIELD_VALID(2) | \
+			FILTER_FIELD_VALID(3) | \
+			FILTER_FIELD_VALID(4))
+
+#define FILTER_FIELDS_IPV4_5TUPLE ( \
+			FILTER_FIELD_VALID(1) | \
+			FILTER_FIELD_VALID(2) | \
+			FILTER_FIELD_VALID(3) | \
+			FILTER_FIELD_VALID(4) | \
+			FILTER_FIELD_VALID(5))
+
+#define FILTER_FIELDS_MAC_VLAN ( \
+			FILTER_FIELD_VALID(1) | \
+			FILTER_FIELD_VALID(2))
+
+#define FILTER_FIELD_USNIC_VLAN    FILTER_FIELD_VALID(1)
+#define FILTER_FIELD_USNIC_ETHTYPE FILTER_FIELD_VALID(2)
+#define FILTER_FIELD_USNIC_PROTO   FILTER_FIELD_VALID(3)
+#define FILTER_FIELD_USNIC_ID      FILTER_FIELD_VALID(4)
+
+struct filter_usnic_id {
+	u32 flags;
+	u16 vlan;
+	u16 ethtype;
+	u8 proto_version;
+	u32 usnic_id;
+} __packed;
+
+#define FILTER_FIELD_5TUP_PROTO  FILTER_FIELD_VALID(1)
+#define FILTER_FIELD_5TUP_SRC_AD FILTER_FIELD_VALID(2)
+#define FILTER_FIELD_5TUP_DST_AD FILTER_FIELD_VALID(3)
+#define FILTER_FIELD_5TUP_SRC_PT FILTER_FIELD_VALID(4)
+#define FILTER_FIELD_5TUP_DST_PT FILTER_FIELD_VALID(5)
+
+/* Enums for the protocol field. */
+enum protocol_e {
+	PROTO_UDP = 0,
+	PROTO_TCP = 1,
+};
+
+struct filter_ipv4_5tuple {
+	u32 flags;
+	u32 protocol;
+	u32 src_addr;
+	u32 dst_addr;
+	u16 src_port;
+	u16 dst_port;
+} __packed;
+
+#define FILTER_FIELD_VMQ_VLAN   FILTER_FIELD_VALID(1)
+#define FILTER_FIELD_VMQ_MAC    FILTER_FIELD_VALID(2)
+
+struct filter_mac_vlan {
+	u32 flags;
+	u16 vlan;
+	u8 mac_addr[6];
+} __packed;
+
+/* Specifies the filter_action type. */
+enum {
+	FILTER_ACTION_RQ_STEERING = 0,
+	FILTER_ACTION_MAX
+};
+
+struct filter_action {
+	u32 type;
+	union {
+		u32 rq_idx;
+	} u;
+} __packed;
+
+/* Specifies the filter type. */
+enum filter_type {
+	FILTER_USNIC_ID = 0,
+	FILTER_IPV4_5TUPLE = 1,
+	FILTER_MAC_VLAN = 2,
+	FILTER_MAX
+};
+
+struct filter {
+	u32 type;
+	union {
+		struct filter_usnic_id usnic;
+		struct filter_ipv4_5tuple ipv4;
+		struct filter_mac_vlan mac_vlan;
+	} u;
+} __packed;
+
+enum {
+	CLSF_TLV_FILTER = 0,
+	CLSF_TLV_ACTION = 1,
+};
+
+/* Maximum size of buffer to CMD_ADD_FILTER */
+#define FILTER_MAX_BUF_SIZE 100
+
+struct filter_tlv {
+	u_int32_t type;
+	u_int32_t length;
+	u_int32_t val[0];
+};
+
 /*
  * Writing cmd register causes STAT_BUSY to get set in status register.
  * When cmd completes, STAT_BUSY will be cleared.
diff --git a/drivers/net/ethernet/cisco/enic/vnic_rq.c b/drivers/net/ethernet/cisco/enic/vnic_rq.c
index 7e1488f..e003b48 100644
--- a/drivers/net/ethernet/cisco/enic/vnic_rq.c
+++ b/drivers/net/ethernet/cisco/enic/vnic_rq.c
@@ -30,16 +30,15 @@
 static int vnic_rq_alloc_bufs(struct vnic_rq *rq)
 {
 	struct vnic_rq_buf *buf;
-	struct vnic_dev *vdev;
 	unsigned int i, j, count = rq->ring.desc_count;
 	unsigned int blks = VNIC_RQ_BUF_BLKS_NEEDED(count);
 
-	vdev = rq->vdev;
-
 	for (i = 0; i < blks; i++) {
 		rq->bufs[i] = kzalloc(VNIC_RQ_BUF_BLK_SZ(count), GFP_ATOMIC);
-		if (!rq->bufs[i])
+		if (!rq->bufs[i]) {
+			pr_err("Failed to alloc rq_bufs\n");
 			return -ENOMEM;
+		}
 	}
 
 	for (i = 0; i < blks; i++) {
@@ -141,7 +140,7 @@ void vnic_rq_init(struct vnic_rq *rq, unsigned int cq_index,
 	unsigned int error_interrupt_enable,
 	unsigned int error_interrupt_offset)
 {
-	u32 fetch_index;
+	u32 fetch_index = 0;
 
 	/* Use current fetch_index as the ring starting point */
 	fetch_index = ioread32(&rq->ctrl->fetch_index);
diff --git a/drivers/net/ethernet/cisco/enic/vnic_rq.h b/drivers/net/ethernet/cisco/enic/vnic_rq.h
index 2056586..ee7bc95 100644
--- a/drivers/net/ethernet/cisco/enic/vnic_rq.h
+++ b/drivers/net/ethernet/cisco/enic/vnic_rq.h
@@ -72,6 +72,7 @@ struct vnic_rq_buf {
 	unsigned int len;
 	unsigned int index;
 	void *desc;
+	uint64_t wr_id;
 };
 
 struct vnic_rq {
@@ -110,7 +111,8 @@ static inline unsigned int vnic_rq_next_index(struct vnic_rq *rq)
 
 static inline void vnic_rq_post(struct vnic_rq *rq,
 	void *os_buf, unsigned int os_buf_index,
-	dma_addr_t dma_addr, unsigned int len)
+	dma_addr_t dma_addr, unsigned int len,
+	uint64_t wrid)
 {
 	struct vnic_rq_buf *buf = rq->to_use;
 
@@ -118,6 +120,7 @@ static inline void vnic_rq_post(struct vnic_rq *rq,
 	buf->os_buf_index = os_buf_index;
 	buf->dma_addr = dma_addr;
 	buf->len = len;
+	buf->wr_id = wrid;
 
 	buf = buf->next;
 	rq->to_use = buf;
diff --git a/drivers/net/ethernet/cisco/enic/vnic_wq.c b/drivers/net/ethernet/cisco/enic/vnic_wq.c
index 5e0d7a2..fff35d4 100644
--- a/drivers/net/ethernet/cisco/enic/vnic_wq.c
+++ b/drivers/net/ethernet/cisco/enic/vnic_wq.c
@@ -30,16 +30,15 @@
 static int vnic_wq_alloc_bufs(struct vnic_wq *wq)
 {
 	struct vnic_wq_buf *buf;
-	struct vnic_dev *vdev;
 	unsigned int i, j, count = wq->ring.desc_count;
 	unsigned int blks = VNIC_WQ_BUF_BLKS_NEEDED(count);
 
-	vdev = wq->vdev;
-
 	for (i = 0; i < blks; i++) {
 		wq->bufs[i] = kzalloc(VNIC_WQ_BUF_BLK_SZ(count), GFP_ATOMIC);
-		if (!wq->bufs[i])
+		if (!wq->bufs[i]) {
+			pr_err("Failed to alloc wq_bufs\n");
 			return -ENOMEM;
+		}
 	}
 
 	for (i = 0; i < blks; i++) {
diff --git a/drivers/net/ethernet/cisco/enic/vnic_wq.h b/drivers/net/ethernet/cisco/enic/vnic_wq.h
index 7dd937a..b655667 100644
--- a/drivers/net/ethernet/cisco/enic/vnic_wq.h
+++ b/drivers/net/ethernet/cisco/enic/vnic_wq.h
@@ -58,6 +58,10 @@ struct vnic_wq_buf {
 	unsigned int index;
 	int sop;
 	void *desc;
+	uint64_t wr_id; /* Cookie */
+	uint8_t cq_entry; /* Gets completion event from hw */
+	uint8_t desc_skip_cnt; /* Num descs to occupy */
+	uint8_t compressed_send; /* Both hdr and payload in one desc */
 };
 
 /* Break the vnic_wq_buf allocations into blocks of 32/64 entries */
@@ -100,16 +104,94 @@ static inline void *vnic_wq_next_desc(struct vnic_wq *wq)
 	return wq->to_use->desc;
 }
 
+#define PI_LOG2_CACHE_LINE_SIZE        5
+#define PI_INDEX_BITS            12
+#define PI_INDEX_MASK ((1U << PI_INDEX_BITS) - 1)
+#define PI_PREFETCH_LEN_MASK ((1U << PI_LOG2_CACHE_LINE_SIZE) - 1)
+#define PI_PREFETCH_LEN_OFF 16
+#define PI_PREFETCH_ADDR_BITS 43
+#define PI_PREFETCH_ADDR_MASK ((1ULL << PI_PREFETCH_ADDR_BITS) - 1)
+#define PI_PREFETCH_ADDR_OFF 21
+
+/* How many cache lines are touched by buffer (addr, len). */
+static inline unsigned int num_cache_lines_touched(dma_addr_t addr,
+	unsigned int len)
+{
+	const unsigned long mask = PI_PREFETCH_LEN_MASK;
+	const unsigned long laddr = (unsigned long)addr;
+	unsigned long lines, equiv_len;
+	/* A. If addr is aligned, our solution is just to round up len to the
+	 * next boundary.
+	 *
+	 *  e.g. addr = 0, len = 48
+	 * +--------------------+
+	 * |XXXXXXXXXXXXXXXXXXXX|    32-byte cacheline a
+	 * +--------------------+
+	 * |XXXXXXXXXX          |    cacheline b
+	 * +--------------------+
+	 *
+	 * B. If addr is not aligned, however, we may use an extra
+	 * cacheline.  e.g. addr = 12, len = 22
+	 *
+	 * +--------------------+
+	 * |       XXXXXXXXXXXXX|
+	 * +--------------------+
+	 * |XX                  |
+	 * +--------------------+
+	 *
+	 * Our solution is to make the problem equivalent to case A
+	 * above by adding the empty space in the first cacheline to the length:
+	 * unsigned long len;
+	 *
+	 * +--------------------+
+	 * |eeeeeeeXXXXXXXXXXXXX|    "e" is empty space, which we add to len
+	 * +--------------------+
+	 * |XX                  |
+	 * +--------------------+
+	 */
+	equiv_len = len + (laddr & mask);
+
+	/* Now we can just round up this len to the next 32-byte boundary. */
+	lines = (equiv_len + mask) & (~mask);
+
+	/* Scale bytes -> cachelines. */
+	return lines >> PI_LOG2_CACHE_LINE_SIZE;
+}
+
+static inline u64 vnic_cached_posted_index(dma_addr_t addr,
+	unsigned int len, unsigned int index)
+{
+	unsigned int num_cache_lines = num_cache_lines_touched(addr, len);
+	/* Wish we could avoid a branch here.  We could have separate
+	 * vnic_wq_post() and vinc_wq_post_inline(), the latter
+	 * only supporting < 1k (2^5 * 2^5) sends, I suppose.  This would
+	 * eliminate the if (eop) branch as well.
+	 */
+	if (num_cache_lines > PI_PREFETCH_LEN_MASK)
+		num_cache_lines = 0;
+	return (index & PI_INDEX_MASK) |
+		((num_cache_lines & PI_PREFETCH_LEN_MASK)
+		 << PI_PREFETCH_LEN_OFF) |
+			(((addr >> PI_LOG2_CACHE_LINE_SIZE) &
+			  PI_PREFETCH_ADDR_MASK) << PI_PREFETCH_ADDR_OFF);
+}
+
 static inline void vnic_wq_post(struct vnic_wq *wq,
 	void *os_buf, dma_addr_t dma_addr,
-	unsigned int len, int sop, int eop)
+	unsigned int len, int sop, int eop,
+	uint8_t desc_skip_cnt, uint8_t cq_entry,
+	uint8_t compressed_send, uint64_t wrid)
 {
 	struct vnic_wq_buf *buf = wq->to_use;
 
 	buf->sop = sop;
+	buf->cq_entry = cq_entry;
+	buf->compressed_send = compressed_send;
+	buf->desc_skip_cnt = desc_skip_cnt;
 	buf->os_buf = eop ? os_buf : NULL;
 	buf->dma_addr = dma_addr;
 	buf->len = len;
+	buf->wr_id = wrid;
 
 	buf = buf->next;
 	if (eop) {
@@ -123,7 +205,7 @@ static inline void vnic_wq_post(struct vnic_wq *wq,
 	}
 	wq->to_use = buf;
 
-	wq->ring.desc_avail--;
+	wq->ring.desc_avail -= desc_skip_cnt;
 }
 
 static inline void vnic_wq_service(struct vnic_wq *wq,
-- 
1.8.4-rc0

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/4] drivers/net: enic: Add an interface for USNIC to interact with firmware
  2013-08-09 18:12 [PATCH 0/4] enic: This patchset adds support for Cisco Low Latency NIC Neel Patel
  2013-08-09 18:12 ` [PATCH 1/4] drivers/net: enic: Adding " Neel Patel
@ 2013-08-09 18:12 ` Neel Patel
  2013-08-09 18:12 ` [PATCH 3/4] drivers/net: enic: Make ASIC information available to USNIC Neel Patel
  2013-08-09 18:12 ` [PATCH 4/4] drivers/net: enic: Generate notification of hardware crash Neel Patel
  3 siblings, 0 replies; 10+ messages in thread
From: Neel Patel @ 2013-08-09 18:12 UTC (permalink / raw)
  To: netdev; +Cc: Neel Patel, Nishank Trivedi, Christian Benvenuti

This patch adds an interface for USNIC to proxy firmware commands through
ENIC.

Signed-off-by: Neel Patel <neepatel@cisco.com>
Signed-off-by: Nishank Trivedi <nistrive@cisco.com>
Signed-off-by: Christian Benvenuti <benve@cisco.com>
---
 drivers/net/ethernet/cisco/enic/Makefile    |  2 +-
 drivers/net/ethernet/cisco/enic/enic.h      |  1 +
 drivers/net/ethernet/cisco/enic/enic_api.c  | 48 +++++++++++++++++++++++++++++
 drivers/net/ethernet/cisco/enic/enic_api.h  | 30 ++++++++++++++++++
 drivers/net/ethernet/cisco/enic/enic_main.c |  3 ++
 5 files changed, 83 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/ethernet/cisco/enic/enic_api.c
 create mode 100644 drivers/net/ethernet/cisco/enic/enic_api.h

diff --git a/drivers/net/ethernet/cisco/enic/Makefile b/drivers/net/ethernet/cisco/enic/Makefile
index e52296d..239e1e4 100644
--- a/drivers/net/ethernet/cisco/enic/Makefile
+++ b/drivers/net/ethernet/cisco/enic/Makefile
@@ -2,5 +2,5 @@ obj-$(CONFIG_ENIC) := enic.o
 
 enic-y := enic_main.o vnic_cq.o vnic_intr.o vnic_wq.o \
 	enic_res.o enic_dev.o enic_pp.o vnic_dev.o vnic_rq.o vnic_vic.o \
-	enic_ethtool.o
+	enic_ethtool.o enic_api.o
 
diff --git a/drivers/net/ethernet/cisco/enic/enic.h b/drivers/net/ethernet/cisco/enic/enic.h
index 75e842d..cacca29 100644
--- a/drivers/net/ethernet/cisco/enic/enic.h
+++ b/drivers/net/ethernet/cisco/enic/enic.h
@@ -96,6 +96,7 @@ struct enic {
 #ifdef CONFIG_PCI_IOV
 	u16 num_vfs;
 #endif
+	spinlock_t enic_api_lock;
 	struct enic_port_profile *pp;
 
 	/* work queue cache line section */
diff --git a/drivers/net/ethernet/cisco/enic/enic_api.c b/drivers/net/ethernet/cisco/enic/enic_api.c
new file mode 100644
index 0000000..e13efbd
--- /dev/null
+++ b/drivers/net/ethernet/cisco/enic/enic_api.c
@@ -0,0 +1,48 @@
+/**
+ * Copyright 2013 Cisco Systems, Inc.  All rights reserved.
+ *
+ * This program is free software; you may redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#include <linux/netdevice.h>
+#include <linux/spinlock.h>
+
+#include "vnic_dev.h"
+#include "vnic_devcmd.h"
+
+#include "enic_res.h"
+#include "enic.h"
+#include "enic_api.h"
+
+int enic_api_devcmd_proxy_by_index(struct net_device *netdev, int vf,
+	enum vnic_devcmd_cmd cmd, u64 *a0, u64 *a1, int wait)
+{
+	int err;
+	struct enic *enic = netdev_priv(netdev);
+	struct vnic_dev *vdev = enic->vdev;
+
+	spin_lock(&enic->enic_api_lock);
+	spin_lock(&enic->devcmd_lock);
+
+	vnic_dev_cmd_proxy_by_index_start(vdev, vf);
+	err = vnic_dev_cmd(vdev, cmd, a0, a1, wait);
+	vnic_dev_cmd_proxy_end(vdev);
+
+	spin_unlock(&enic->devcmd_lock);
+	spin_unlock(&enic->enic_api_lock);
+
+	return err;
+}
+EXPORT_SYMBOL(enic_api_devcmd_proxy_by_index);
diff --git a/drivers/net/ethernet/cisco/enic/enic_api.h b/drivers/net/ethernet/cisco/enic/enic_api.h
new file mode 100644
index 0000000..6b9f925
--- /dev/null
+++ b/drivers/net/ethernet/cisco/enic/enic_api.h
@@ -0,0 +1,30 @@
+/**
+ * Copyright 2013 Cisco Systems, Inc.  All rights reserved.
+ *
+ * This program is free software; you may redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#ifndef __ENIC_API_H__
+#define __ENIC_API_H__
+
+#include <linux/netdevice.h>
+
+#include "vnic_dev.h"
+#include "vnic_devcmd.h"
+
+int enic_api_devcmd_proxy_by_index(struct net_device *netdev, int vf,
+	enum vnic_devcmd_cmd cmd, u64 *a0, u64 *a1, int wait);
+
+#endif
diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c
index b12b32b..7f8891b 100644
--- a/drivers/net/ethernet/cisco/enic/enic_main.c
+++ b/drivers/net/ethernet/cisco/enic/enic_main.c
@@ -1733,6 +1733,7 @@ static void enic_reset(struct work_struct *work)
 
 	rtnl_lock();
 
+	spin_lock(&enic->enic_api_lock);
 	enic_dev_hang_notify(enic);
 	enic_stop(enic->netdev);
 	enic_dev_hang_reset(enic);
@@ -1741,6 +1742,7 @@ static void enic_reset(struct work_struct *work)
 	enic_set_rss_nic_cfg(enic);
 	enic_dev_set_ig_vlan_rewrite_mode(enic);
 	enic_open(enic->netdev);
+	spin_unlock(&enic->enic_api_lock);
 
 	rtnl_unlock();
 }
@@ -2153,6 +2155,7 @@ static int enic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	 */
 
 	spin_lock_init(&enic->devcmd_lock);
+	spin_lock_init(&enic->enic_api_lock);
 
 	/*
 	 * Set ingress vlan rewrite mode before vnic initialization
-- 
1.8.4-rc0

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/4] drivers/net: enic: Make ASIC information available to USNIC
  2013-08-09 18:12 [PATCH 0/4] enic: This patchset adds support for Cisco Low Latency NIC Neel Patel
  2013-08-09 18:12 ` [PATCH 1/4] drivers/net: enic: Adding " Neel Patel
  2013-08-09 18:12 ` [PATCH 2/4] drivers/net: enic: Add an interface for USNIC to interact with firmware Neel Patel
@ 2013-08-09 18:12 ` Neel Patel
  2013-08-09 22:21   ` Stephen Hemminger
  2013-08-09 18:12 ` [PATCH 4/4] drivers/net: enic: Generate notification of hardware crash Neel Patel
  3 siblings, 1 reply; 10+ messages in thread
From: Neel Patel @ 2013-08-09 18:12 UTC (permalink / raw)
  To: netdev; +Cc: Neel Patel, Nishank Trivedi, Christian Benvenuti

This patch provides asic information via ethtool.

Signed-off-by: Neel Patel <neepatel@cisco.com>
Signed-off-by: Nishank Trivedi <nistrive@cisco.com>
Signed-off-by: Christian Benvenuti <benve@cisco.com>
---
 drivers/net/ethernet/cisco/enic/driver_utils.h | 49 ++++++++++++++++++++++++++
 drivers/net/ethernet/cisco/enic/enic_ethtool.c |  4 +++
 2 files changed, 53 insertions(+)
 create mode 100644 drivers/net/ethernet/cisco/enic/driver_utils.h

diff --git a/drivers/net/ethernet/cisco/enic/driver_utils.h b/drivers/net/ethernet/cisco/enic/driver_utils.h
new file mode 100644
index 0000000..e654b4d
--- /dev/null
+++ b/drivers/net/ethernet/cisco/enic/driver_utils.h
@@ -0,0 +1,49 @@
+/**
+ * Copyright 2013 Cisco Systems, Inc.  All rights reserved.
+ *
+ * This program is free software; you may redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#ifndef __DRIVER_UTILS_H__
+#define __DRIVER_UTILS_H__
+
+#include <linux/string.h>
+
+static inline int driver_encode_asic_info(char *str, int strlen, u16 asic_type,
+				u16 asic_rev)
+{
+	if (strlen < sizeof(asic_type) + sizeof(asic_rev))
+		return -EINVAL;
+
+	memcpy(str, &asic_type, sizeof(asic_type));
+	memcpy(str + sizeof(asic_type), &asic_rev, sizeof(asic_rev));
+
+	return 0;
+}
+
+static inline int driver_decode_asic_info(char *str, int strlen, u16 *asic_type,
+						u16 *asic_rev)
+{
+	if (strlen < sizeof(*asic_type) + sizeof(*asic_rev))
+		return -EINVAL;
+
+	if (asic_type)
+		memcpy(asic_type, str, sizeof(*asic_type));
+	if (asic_rev)
+		memcpy(asic_rev, str + sizeof(*asic_type), sizeof(*asic_rev));
+	return 0;
+}
+
+#endif /*!__DRIVER_UTILS_H__*/
diff --git a/drivers/net/ethernet/cisco/enic/enic_ethtool.c b/drivers/net/ethernet/cisco/enic/enic_ethtool.c
index 47e3562..c5d938a 100644
--- a/drivers/net/ethernet/cisco/enic/enic_ethtool.c
+++ b/drivers/net/ethernet/cisco/enic/enic_ethtool.c
@@ -19,6 +19,7 @@
 #include <linux/netdevice.h>
 #include <linux/ethtool.h>
 
+#include "driver_utils.h"
 #include "enic_res.h"
 #include "enic.h"
 #include "enic_dev.h"
@@ -116,6 +117,9 @@ static void enic_get_drvinfo(struct net_device *netdev,
 		sizeof(drvinfo->fw_version));
 	strlcpy(drvinfo->bus_info, pci_name(enic->pdev),
 		sizeof(drvinfo->bus_info));
+	memset(drvinfo->reserved1, 0, sizeof(drvinfo->reserved1));
+	driver_encode_asic_info(drvinfo->reserved1, sizeof(drvinfo->reserved1),
+		fw_info->asic_type, fw_info->asic_rev);
 }
 
 static void enic_get_strings(struct net_device *netdev, u32 stringset,
-- 
1.8.4-rc0

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 4/4] drivers/net: enic: Generate notification of hardware crash
  2013-08-09 18:12 [PATCH 0/4] enic: This patchset adds support for Cisco Low Latency NIC Neel Patel
                   ` (2 preceding siblings ...)
  2013-08-09 18:12 ` [PATCH 3/4] drivers/net: enic: Make ASIC information available to USNIC Neel Patel
@ 2013-08-09 18:12 ` Neel Patel
  3 siblings, 0 replies; 10+ messages in thread
From: Neel Patel @ 2013-08-09 18:12 UTC (permalink / raw)
  To: netdev; +Cc: Neel Patel, Nishank Trivedi, Christian Benvenuti

This patch generates a hardware crash notification (NETDEV_REBOOT)
during reset. After a hardware crash, ENIC resets all its resources
including queue pair filters programmed by USNIC. USNIC registers for
this notification, and on receiving it, reprograms the queue pair filters.

Signed-off-by: Neel Patel <neepatel@cisco.com>
Signed-off-by: Nishank Trivedi <nistrive@cisco.com>
Signed-off-by: Christian Benvenuti <benve@cisco.com>
---
 drivers/net/ethernet/cisco/enic/enic.h      | 2 +-
 drivers/net/ethernet/cisco/enic/enic_main.c | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/cisco/enic/enic.h b/drivers/net/ethernet/cisco/enic/enic.h
index cacca29..be16731 100644
--- a/drivers/net/ethernet/cisco/enic/enic.h
+++ b/drivers/net/ethernet/cisco/enic/enic.h
@@ -32,7 +32,7 @@
 
 #define DRV_NAME		"enic"
 #define DRV_DESCRIPTION		"Cisco VIC Ethernet NIC Driver"
-#define DRV_VERSION		"2.1.1.39"
+#define DRV_VERSION		"2.1.1.43"
 #define DRV_COPYRIGHT		"Copyright 2008-2013 Cisco Systems, Inc"
 
 #define ENIC_BARS_MAX		6
diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c
index 7f8891b..bcf15b1 100644
--- a/drivers/net/ethernet/cisco/enic/enic_main.c
+++ b/drivers/net/ethernet/cisco/enic/enic_main.c
@@ -1743,6 +1743,7 @@ static void enic_reset(struct work_struct *work)
 	enic_dev_set_ig_vlan_rewrite_mode(enic);
 	enic_open(enic->netdev);
 	spin_unlock(&enic->enic_api_lock);
+	call_netdevice_notifiers(NETDEV_REBOOT, enic->netdev);
 
 	rtnl_unlock();
 }
-- 
1.8.4-rc0

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 3/4] drivers/net: enic: Make ASIC information available to USNIC
  2013-08-09 18:12 ` [PATCH 3/4] drivers/net: enic: Make ASIC information available to USNIC Neel Patel
@ 2013-08-09 22:21   ` Stephen Hemminger
  2013-08-10 16:13     ` Ben Hutchings
  0 siblings, 1 reply; 10+ messages in thread
From: Stephen Hemminger @ 2013-08-09 22:21 UTC (permalink / raw)
  To: Neel Patel; +Cc: netdev, Nishank Trivedi, Christian Benvenuti

On Fri,  9 Aug 2013 11:12:20 -0700
Neel Patel <neepatel@cisco.com> wrote:

> This patch provides asic information via ethtool.
> 
> Signed-off-by: Neel Patel <neepatel@cisco.com>
> Signed-off-by: Nishank Trivedi <nistrive@cisco.com>
> Signed-off-by: Christian Benvenuti <benve@cisco.com>
> ---
>  drivers/net/ethernet/cisco/enic/driver_utils.h | 49 ++++++++++++++++++++++++++
>  drivers/net/ethernet/cisco/enic/enic_ethtool.c |  4 +++
>  2 files changed, 53 insertions(+)
>  create mode 100644 drivers/net/ethernet/cisco/enic/driver_utils.h
> 
> diff --git a/drivers/net/ethernet/cisco/enic/driver_utils.h b/drivers/net/ethernet/cisco/enic/driver_utils.h
> new file mode 100644
> index 0000000..e654b4d
> --- /dev/null
> +++ b/drivers/net/ethernet/cisco/enic/driver_utils.h
> @@ -0,0 +1,49 @@
> +/**
> + * Copyright 2013 Cisco Systems, Inc.  All rights reserved.
> + *
> + * This program is free software; you may redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; version 2 of the License.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
> + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
> + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
> + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
> + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
> + * SOFTWARE.
> + *
> + */
> +
> +#ifndef __DRIVER_UTILS_H__
> +#define __DRIVER_UTILS_H__
> +
> +#include <linux/string.h>
> +
> +static inline int driver_encode_asic_info(char *str, int strlen, u16 asic_type,
> +				u16 asic_rev)
> +{
> +	if (strlen < sizeof(asic_type) + sizeof(asic_rev))
> +		return -EINVAL;
> +
> +	memcpy(str, &asic_type, sizeof(asic_type));
> +	memcpy(str + sizeof(asic_type), &asic_rev, sizeof(asic_rev));
> +
> +	return 0;
> +}
> +
> +static inline int driver_decode_asic_info(char *str, int strlen, u16 *asic_type,
> +						u16 *asic_rev)
> +{
> +	if (strlen < sizeof(*asic_type) + sizeof(*asic_rev))
> +		return -EINVAL;
> +
> +	if (asic_type)
> +		memcpy(asic_type, str, sizeof(*asic_type));
> +	if (asic_rev)
> +		memcpy(asic_rev, str + sizeof(*asic_type), sizeof(*asic_rev));
> +	return 0;
> +}
> +
> +#endif /*!__DRIVER_UTILS_H__*/
> diff --git a/drivers/net/ethernet/cisco/enic/enic_ethtool.c b/drivers/net/ethernet/cisco/enic/enic_ethtool.c
> index 47e3562..c5d938a 100644
> --- a/drivers/net/ethernet/cisco/enic/enic_ethtool.c
> +++ b/drivers/net/ethernet/cisco/enic/enic_ethtool.c
> @@ -19,6 +19,7 @@
>  #include <linux/netdevice.h>
>  #include <linux/ethtool.h>
>  
> +#include "driver_utils.h"
>  #include "enic_res.h"
>  #include "enic.h"
>  #include "enic_dev.h"
> @@ -116,6 +117,9 @@ static void enic_get_drvinfo(struct net_device *netdev,
>  		sizeof(drvinfo->fw_version));
>  	strlcpy(drvinfo->bus_info, pci_name(enic->pdev),
>  		sizeof(drvinfo->bus_info));
> +	memset(drvinfo->reserved1, 0, sizeof(drvinfo->reserved1));
> +	driver_encode_asic_info(drvinfo->reserved1, sizeof(drvinfo->reserved1),
> +		fw_info->asic_type, fw_info->asic_rev);
>  }

If you want to use a reserved field, then make it a first class citizen.
Rename it to asic_info, make sure the result is okay for other drivers
and add send patch so Ben can make it part of normal ethtool support.

Otherwise, this code is likely to break when someone else actually unreserves
that field.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 3/4] drivers/net: enic: Make ASIC information available to USNIC
  2013-08-09 22:21   ` Stephen Hemminger
@ 2013-08-10 16:13     ` Ben Hutchings
  2013-08-13  5:10       ` Nishank Trivedi
  0 siblings, 1 reply; 10+ messages in thread
From: Ben Hutchings @ 2013-08-10 16:13 UTC (permalink / raw)
  To: Stephen Hemminger
  Cc: Neel Patel, netdev, Nishank Trivedi, Christian Benvenuti

On Fri, 2013-08-09 at 15:21 -0700, Stephen Hemminger wrote:
> On Fri,  9 Aug 2013 11:12:20 -0700
> Neel Patel <neepatel@cisco.com> wrote:
> 
> > This patch provides asic information via ethtool.
[...]
> > --- a/drivers/net/ethernet/cisco/enic/enic_ethtool.c
> > +++ b/drivers/net/ethernet/cisco/enic/enic_ethtool.c
> > @@ -19,6 +19,7 @@
> >  #include <linux/netdevice.h>
> >  #include <linux/ethtool.h>
> >  
> > +#include "driver_utils.h"
> >  #include "enic_res.h"
> >  #include "enic.h"
> >  #include "enic_dev.h"
> > @@ -116,6 +117,9 @@ static void enic_get_drvinfo(struct net_device *netdev,
> >  		sizeof(drvinfo->fw_version));
> >  	strlcpy(drvinfo->bus_info, pci_name(enic->pdev),
> >  		sizeof(drvinfo->bus_info));
> > +	memset(drvinfo->reserved1, 0, sizeof(drvinfo->reserved1));
> > +	driver_encode_asic_info(drvinfo->reserved1, sizeof(drvinfo->reserved1),
> > +		fw_info->asic_type, fw_info->asic_rev);
> >  }
> 
> If you want to use a reserved field, then make it a first class citizen.
> Rename it to asic_info, make sure the result is okay for other drivers
> and add send patch so Ben can make it part of normal ethtool support.
> 
> Otherwise, this code is likely to break when someone else actually unreserves
> that field.

Right.  I bet this is redundant with the IDs that lspci can show,
anyway.

Ben.

-- 
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 3/4] drivers/net: enic: Make ASIC information available to USNIC
  2013-08-10 16:13     ` Ben Hutchings
@ 2013-08-13  5:10       ` Nishank Trivedi
  2013-08-13  8:31         ` Ben Hutchings
  0 siblings, 1 reply; 10+ messages in thread
From: Nishank Trivedi @ 2013-08-13  5:10 UTC (permalink / raw)
  To: Ben Hutchings
  Cc: Stephen Hemminger, Neel Patel, netdev, Christian Benvenuti,
	Upinder Malhi (umalhi)

On 8/10/13 9:13 AM, Ben Hutchings wrote:
> On Fri, 2013-08-09 at 15:21 -0700, Stephen Hemminger wrote:
>> On Fri,  9 Aug 2013 11:12:20 -0700
>> Neel Patel <neepatel@cisco.com> wrote:
>>
>>> This patch provides asic information via ethtool.
> [...]
>>> --- a/drivers/net/ethernet/cisco/enic/enic_ethtool.c
>>> +++ b/drivers/net/ethernet/cisco/enic/enic_ethtool.c
>>> @@ -19,6 +19,7 @@
>>>   #include <linux/netdevice.h>
>>>   #include <linux/ethtool.h>
>>>
>>> +#include "driver_utils.h"
>>>   #include "enic_res.h"
>>>   #include "enic.h"
>>>   #include "enic_dev.h"
>>> @@ -116,6 +117,9 @@ static void enic_get_drvinfo(struct net_device *netdev,
>>>   		sizeof(drvinfo->fw_version));
>>>   	strlcpy(drvinfo->bus_info, pci_name(enic->pdev),
>>>   		sizeof(drvinfo->bus_info));
>>> +	memset(drvinfo->reserved1, 0, sizeof(drvinfo->reserved1));
>>> +	driver_encode_asic_info(drvinfo->reserved1, sizeof(drvinfo->reserved1),
>>> +		fw_info->asic_type, fw_info->asic_rev);
>>>   }
>>
>> If you want to use a reserved field, then make it a first class citizen.
>> Rename it to asic_info, make sure the result is okay for other drivers
>> and add send patch so Ben can make it part of normal ethtool support.
>>
>> Otherwise, this code is likely to break when someone else actually unreserves
>> that field.
>
> Right.  I bet this is redundant with the IDs that lspci can show,
> anyway.

Thanks Stephen, Ben for your input, they are valid points. Neel would 
send a new patch series minus 3/4 for now.

While you are right that lspci or sysfs can be used to get same info, we 
were trying to use asic info (encoded with type and version) within 
drvinfo so as to use one string to achieve same effect as reading PCI 
subsystem id and revision explicitly. Instead of going to different tool 
(lspci), ethtool would be enough to unqiuely identify the device. Asic 
version along with already existing firmware version, driver version, 
etc seems natural.

Thanks,
nishank

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 3/4] drivers/net: enic: Make ASIC information available to USNIC
  2013-08-13  5:10       ` Nishank Trivedi
@ 2013-08-13  8:31         ` Ben Hutchings
  0 siblings, 0 replies; 10+ messages in thread
From: Ben Hutchings @ 2013-08-13  8:31 UTC (permalink / raw)
  To: Nishank Trivedi
  Cc: Stephen Hemminger, Neel Patel, netdev, Christian Benvenuti,
	Upinder Malhi (umalhi)

On Mon, 2013-08-12 at 22:10 -0700, Nishank Trivedi wrote:
> On 8/10/13 9:13 AM, Ben Hutchings wrote:
> > On Fri, 2013-08-09 at 15:21 -0700, Stephen Hemminger wrote:
> >> On Fri,  9 Aug 2013 11:12:20 -0700
> >> Neel Patel <neepatel@cisco.com> wrote:
> >>
> >>> This patch provides asic information via ethtool.
> > [...]
> >>> --- a/drivers/net/ethernet/cisco/enic/enic_ethtool.c
> >>> +++ b/drivers/net/ethernet/cisco/enic/enic_ethtool.c
> >>> @@ -19,6 +19,7 @@
> >>>   #include <linux/netdevice.h>
> >>>   #include <linux/ethtool.h>
> >>>
> >>> +#include "driver_utils.h"
> >>>   #include "enic_res.h"
> >>>   #include "enic.h"
> >>>   #include "enic_dev.h"
> >>> @@ -116,6 +117,9 @@ static void enic_get_drvinfo(struct net_device *netdev,
> >>>   		sizeof(drvinfo->fw_version));
> >>>   	strlcpy(drvinfo->bus_info, pci_name(enic->pdev),
> >>>   		sizeof(drvinfo->bus_info));
> >>> +	memset(drvinfo->reserved1, 0, sizeof(drvinfo->reserved1));
> >>> +	driver_encode_asic_info(drvinfo->reserved1, sizeof(drvinfo->reserved1),
> >>> +		fw_info->asic_type, fw_info->asic_rev);
> >>>   }
> >>
> >> If you want to use a reserved field, then make it a first class citizen.
> >> Rename it to asic_info, make sure the result is okay for other drivers
> >> and add send patch so Ben can make it part of normal ethtool support.
> >>
> >> Otherwise, this code is likely to break when someone else actually unreserves
> >> that field.
> >
> > Right.  I bet this is redundant with the IDs that lspci can show,
> > anyway.
> 
> Thanks Stephen, Ben for your input, they are valid points. Neel would 
> send a new patch series minus 3/4 for now.
> 
> While you are right that lspci or sysfs can be used to get same info, we 
> were trying to use asic info (encoded with type and version) within 
> drvinfo so as to use one string to achieve same effect as reading PCI 
> subsystem id and revision explicitly. Instead of going to different tool 
> (lspci), ethtool would be enough to unqiuely identify the device. Asic 
> version along with already existing firmware version, driver version, 
> etc seems natural.

Well we've managed without this for the last 15 years, so it seems like
it's not that much of a problem to run lspci too.

Sure, it's an extra command for users to run, but if you're trying to
get diagnostic information from them there's a *lot* more you'll want to
gather.

We could do something in the ethtool *command* to report what the device
is (if bus_info matches PCI address format), which would then work for
every PCI network driver.

Ben.

-- 
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 3/4] drivers/net: enic: Make ASIC information available to USNIC
  2013-08-09 18:38 [PATCH 0/4] enic: This patchset adds support for Cisco Low Latency NIC Neel Patel
@ 2013-08-09 18:38 ` Neel Patel
  0 siblings, 0 replies; 10+ messages in thread
From: Neel Patel @ 2013-08-09 18:38 UTC (permalink / raw)
  To: netdev; +Cc: Neel Patel

This patch provides asic information via ethtool.

Signed-off-by: Neel Patel <neepatel@cisco.com>
Signed-off-by: Nishank Trivedi <nistrive@cisco.com>
Signed-off-by: Christian Benvenuti <benve@cisco.com>
---
 drivers/net/ethernet/cisco/enic/driver_utils.h | 49 ++++++++++++++++++++++++++
 drivers/net/ethernet/cisco/enic/enic_ethtool.c |  4 +++
 2 files changed, 53 insertions(+)
 create mode 100644 drivers/net/ethernet/cisco/enic/driver_utils.h

diff --git a/drivers/net/ethernet/cisco/enic/driver_utils.h b/drivers/net/ethernet/cisco/enic/driver_utils.h
new file mode 100644
index 0000000..e654b4d
--- /dev/null
+++ b/drivers/net/ethernet/cisco/enic/driver_utils.h
@@ -0,0 +1,49 @@
+/**
+ * Copyright 2013 Cisco Systems, Inc.  All rights reserved.
+ *
+ * This program is free software; you may redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#ifndef __DRIVER_UTILS_H__
+#define __DRIVER_UTILS_H__
+
+#include <linux/string.h>
+
+static inline int driver_encode_asic_info(char *str, int strlen, u16 asic_type,
+				u16 asic_rev)
+{
+	if (strlen < sizeof(asic_type) + sizeof(asic_rev))
+		return -EINVAL;
+
+	memcpy(str, &asic_type, sizeof(asic_type));
+	memcpy(str + sizeof(asic_type), &asic_rev, sizeof(asic_rev));
+
+	return 0;
+}
+
+static inline int driver_decode_asic_info(char *str, int strlen, u16 *asic_type,
+						u16 *asic_rev)
+{
+	if (strlen < sizeof(*asic_type) + sizeof(*asic_rev))
+		return -EINVAL;
+
+	if (asic_type)
+		memcpy(asic_type, str, sizeof(*asic_type));
+	if (asic_rev)
+		memcpy(asic_rev, str + sizeof(*asic_type), sizeof(*asic_rev));
+	return 0;
+}
+
+#endif /*!__DRIVER_UTILS_H__*/
diff --git a/drivers/net/ethernet/cisco/enic/enic_ethtool.c b/drivers/net/ethernet/cisco/enic/enic_ethtool.c
index 47e3562..c5d938a 100644
--- a/drivers/net/ethernet/cisco/enic/enic_ethtool.c
+++ b/drivers/net/ethernet/cisco/enic/enic_ethtool.c
@@ -19,6 +19,7 @@
 #include <linux/netdevice.h>
 #include <linux/ethtool.h>
 
+#include "driver_utils.h"
 #include "enic_res.h"
 #include "enic.h"
 #include "enic_dev.h"
@@ -116,6 +117,9 @@ static void enic_get_drvinfo(struct net_device *netdev,
 		sizeof(drvinfo->fw_version));
 	strlcpy(drvinfo->bus_info, pci_name(enic->pdev),
 		sizeof(drvinfo->bus_info));
+	memset(drvinfo->reserved1, 0, sizeof(drvinfo->reserved1));
+	driver_encode_asic_info(drvinfo->reserved1, sizeof(drvinfo->reserved1),
+		fw_info->asic_type, fw_info->asic_rev);
 }
 
 static void enic_get_strings(struct net_device *netdev, u32 stringset,
-- 
1.8.4-rc0

^ permalink raw reply related	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2013-08-13  8:31 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-08-09 18:12 [PATCH 0/4] enic: This patchset adds support for Cisco Low Latency NIC Neel Patel
2013-08-09 18:12 ` [PATCH 1/4] drivers/net: enic: Adding " Neel Patel
2013-08-09 18:12 ` [PATCH 2/4] drivers/net: enic: Add an interface for USNIC to interact with firmware Neel Patel
2013-08-09 18:12 ` [PATCH 3/4] drivers/net: enic: Make ASIC information available to USNIC Neel Patel
2013-08-09 22:21   ` Stephen Hemminger
2013-08-10 16:13     ` Ben Hutchings
2013-08-13  5:10       ` Nishank Trivedi
2013-08-13  8:31         ` Ben Hutchings
2013-08-09 18:12 ` [PATCH 4/4] drivers/net: enic: Generate notification of hardware crash Neel Patel
2013-08-09 18:38 [PATCH 0/4] enic: This patchset adds support for Cisco Low Latency NIC Neel Patel
2013-08-09 18:38 ` [PATCH 3/4] drivers/net: enic: Make ASIC information available to USNIC Neel Patel

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.