drivers/net: enic: Adding support for Cisco Low Latency NIC
This patch, - Adds new firmware commands for the new Cisco Low Latency NIC (aka. USNIC). Signed-off-by: Neel Patel <neepatel@cisco.com> Signed-off-by: Nishank Trivedi <nistrive@cisco.com> Signed-off-by: Christian Benvenuti <benve@cisco.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
89d5e23210
commit
92e2b46962
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -30,12 +30,9 @@
|
|||
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])
|
||||
|
@ -141,7 +138,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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -30,12 +30,9 @@
|
|||
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])
|
||||
|
|
|
@ -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 */
|
||||
|
@ -102,14 +106,20 @@ static inline void *vnic_wq_next_desc(struct vnic_wq *wq)
|
|||
|
||||
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 +133,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,
|
||||
|
|
Loading…
Reference in New Issue