diff options
Diffstat (limited to 'drivers/net/ethernet/cisco/enic/enic.h')
-rw-r--r-- | drivers/net/ethernet/cisco/enic/enic.h | 96 |
1 files changed, 73 insertions, 23 deletions
diff --git a/drivers/net/ethernet/cisco/enic/enic.h b/drivers/net/ethernet/cisco/enic/enic.h index 300ad05ee05b..10b7e02ba4d0 100644 --- a/drivers/net/ethernet/cisco/enic/enic.h +++ b/drivers/net/ethernet/cisco/enic/enic.h @@ -23,10 +23,8 @@ #define ENIC_BARS_MAX 6 -#define ENIC_WQ_MAX 8 -#define ENIC_RQ_MAX 8 -#define ENIC_CQ_MAX (ENIC_WQ_MAX + ENIC_RQ_MAX) -#define ENIC_INTR_MAX (ENIC_CQ_MAX + 2) +#define ENIC_WQ_MAX 256 +#define ENIC_RQ_MAX 256 #define ENIC_WQ_NAPI_BUDGET 256 @@ -128,6 +126,51 @@ struct vxlan_offload { u8 flags; }; +struct enic_wq_stats { + u64 packets; /* pkts queued for Tx */ + u64 stopped; /* Tx ring almost full, queue stopped */ + u64 wake; /* Tx ring no longer full, queue woken up*/ + u64 tso; /* non-encap tso pkt */ + u64 encap_tso; /* encap tso pkt */ + u64 encap_csum; /* encap HW csum */ + u64 csum_partial; /* skb->ip_summed = CHECKSUM_PARTIAL */ + u64 csum_none; /* HW csum not required */ + u64 bytes; /* bytes queued for Tx */ + u64 add_vlan; /* HW adds vlan tag */ + u64 cq_work; /* Tx completions processed */ + u64 cq_bytes; /* Tx bytes processed */ + u64 null_pkt; /* skb length <= 0 */ + u64 skb_linear_fail; /* linearize failures */ + u64 desc_full_awake; /* TX ring full while queue awake */ +}; + +struct enic_rq_stats { + u64 packets; /* pkts received */ + u64 bytes; /* bytes received */ + u64 l4_rss_hash; /* hashed on l4 */ + u64 l3_rss_hash; /* hashed on l3 */ + u64 csum_unnecessary; /* HW verified csum */ + u64 csum_unnecessary_encap; /* HW verified csum on encap packet */ + u64 vlan_stripped; /* HW stripped vlan */ + u64 napi_complete; /* napi complete intr reenabled */ + u64 napi_repoll; /* napi poll again */ + u64 bad_fcs; /* bad pkts */ + u64 pkt_truncated; /* truncated pkts */ + u64 no_skb; /* out of skbs */ + u64 desc_skip; /* Rx pkt went into later buffer */ +}; + +struct enic_wq { + spinlock_t lock; /* spinlock for wq */ + struct vnic_wq vwq; + struct enic_wq_stats stats; +} ____cacheline_aligned; + +struct enic_rq { + struct vnic_rq vrq; + struct enic_rq_stats stats; +} ____cacheline_aligned; + /* Per-instance private data structure */ struct enic { struct net_device *netdev; @@ -139,8 +182,8 @@ struct enic { struct work_struct reset; struct work_struct tx_hang_reset; struct work_struct change_mtu_work; - struct msix_entry msix_entry[ENIC_INTR_MAX]; - struct enic_msix_entry msix[ENIC_INTR_MAX]; + struct msix_entry *msix_entry; + struct enic_msix_entry *msix; u32 msg_enable; spinlock_t devcmd_lock; u8 mac_addr[ETH_ALEN]; @@ -159,28 +202,25 @@ struct enic { bool enic_api_busy; struct enic_port_profile *pp; - /* work queue cache line section */ - ____cacheline_aligned struct vnic_wq wq[ENIC_WQ_MAX]; - spinlock_t wq_lock[ENIC_WQ_MAX]; + struct enic_wq *wq; + unsigned int wq_avail; unsigned int wq_count; u16 loop_enable; u16 loop_tag; - /* receive queue cache line section */ - ____cacheline_aligned struct vnic_rq rq[ENIC_RQ_MAX]; + struct enic_rq *rq; + unsigned int rq_avail; unsigned int rq_count; struct vxlan_offload vxlan; - u64 rq_truncated_pkts; - u64 rq_bad_fcs; - struct napi_struct napi[ENIC_RQ_MAX + ENIC_WQ_MAX]; + struct napi_struct *napi; - /* interrupt resource cache line section */ - ____cacheline_aligned struct vnic_intr intr[ENIC_INTR_MAX]; + struct vnic_intr *intr; + unsigned int intr_avail; unsigned int intr_count; u32 __iomem *legacy_pba; /* memory-mapped */ - /* completion queue cache line section */ - ____cacheline_aligned struct vnic_cq cq[ENIC_CQ_MAX]; + struct vnic_cq *cq; + unsigned int cq_avail; unsigned int cq_count; struct enic_rfs_flw_tbl rfs_h; u32 rx_copybreak; @@ -238,18 +278,28 @@ static inline unsigned int enic_msix_wq_intr(struct enic *enic, return enic->cq[enic_cq_wq(enic, wq)].interrupt_offset; } -static inline unsigned int enic_msix_err_intr(struct enic *enic) -{ - return enic->rq_count + enic->wq_count; -} +/* MSIX interrupts are organized as the error interrupt, then the notify + * interrupt followed by all the I/O interrupts. The error interrupt needs + * to fit in 7 bits due to hardware constraints + */ +#define ENIC_MSIX_RESERVED_INTR 2 +#define ENIC_MSIX_ERR_INTR 0 +#define ENIC_MSIX_NOTIFY_INTR 1 +#define ENIC_MSIX_IO_INTR_BASE ENIC_MSIX_RESERVED_INTR +#define ENIC_MSIX_MIN_INTR (ENIC_MSIX_RESERVED_INTR + 2) #define ENIC_LEGACY_IO_INTR 0 #define ENIC_LEGACY_ERR_INTR 1 #define ENIC_LEGACY_NOTIFY_INTR 2 +static inline unsigned int enic_msix_err_intr(struct enic *enic) +{ + return ENIC_MSIX_ERR_INTR; +} + static inline unsigned int enic_msix_notify_intr(struct enic *enic) { - return enic->rq_count + enic->wq_count + 1; + return ENIC_MSIX_NOTIFY_INTR; } static inline bool enic_is_err_intr(struct enic *enic, int intr) |