xref: /OK3568_Linux_fs/kernel/drivers/net/ethernet/aquantia/atlantic/aq_ring.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */
2*4882a593Smuzhiyun /* Atlantic Network Driver
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Copyright (C) 2014-2019 aQuantia Corporation
5*4882a593Smuzhiyun  * Copyright (C) 2019-2020 Marvell International Ltd.
6*4882a593Smuzhiyun  */
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun /* File aq_ring.h: Declaration of functions for Rx/Tx rings. */
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #ifndef AQ_RING_H
11*4882a593Smuzhiyun #define AQ_RING_H
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun #include "aq_common.h"
14*4882a593Smuzhiyun 
15*4882a593Smuzhiyun struct page;
16*4882a593Smuzhiyun struct aq_nic_cfg_s;
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun struct aq_rxpage {
19*4882a593Smuzhiyun 	struct page *page;
20*4882a593Smuzhiyun 	dma_addr_t daddr;
21*4882a593Smuzhiyun 	unsigned int order;
22*4882a593Smuzhiyun 	unsigned int pg_off;
23*4882a593Smuzhiyun };
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun /*           TxC       SOP        DX         EOP
26*4882a593Smuzhiyun  *         +----------+----------+----------+-----------
27*4882a593Smuzhiyun  *   8bytes|len l3,l4 | pa       | pa       | pa
28*4882a593Smuzhiyun  *         +----------+----------+----------+-----------
29*4882a593Smuzhiyun  * 4/8bytes|len pkt   |len pkt   |          | skb
30*4882a593Smuzhiyun  *         +----------+----------+----------+-----------
31*4882a593Smuzhiyun  * 4/8bytes|is_gso    |len,flags |len       |len,is_eop
32*4882a593Smuzhiyun  *         +----------+----------+----------+-----------
33*4882a593Smuzhiyun  *
34*4882a593Smuzhiyun  *  This aq_ring_buff_s doesn't have endianness dependency.
35*4882a593Smuzhiyun  *  It is __packed for cache line optimizations.
36*4882a593Smuzhiyun  */
37*4882a593Smuzhiyun struct __packed aq_ring_buff_s {
38*4882a593Smuzhiyun 	union {
39*4882a593Smuzhiyun 		/* RX/TX */
40*4882a593Smuzhiyun 		dma_addr_t pa;
41*4882a593Smuzhiyun 		/* RX */
42*4882a593Smuzhiyun 		struct {
43*4882a593Smuzhiyun 			u32 rss_hash;
44*4882a593Smuzhiyun 			u16 next;
45*4882a593Smuzhiyun 			u8 is_hash_l4;
46*4882a593Smuzhiyun 			u8 rsvd1;
47*4882a593Smuzhiyun 			struct aq_rxpage rxdata;
48*4882a593Smuzhiyun 			u16 vlan_rx_tag;
49*4882a593Smuzhiyun 		};
50*4882a593Smuzhiyun 		/* EOP */
51*4882a593Smuzhiyun 		struct {
52*4882a593Smuzhiyun 			dma_addr_t pa_eop;
53*4882a593Smuzhiyun 			struct sk_buff *skb;
54*4882a593Smuzhiyun 		};
55*4882a593Smuzhiyun 		/* TxC */
56*4882a593Smuzhiyun 		struct {
57*4882a593Smuzhiyun 			u32 mss;
58*4882a593Smuzhiyun 			u8 len_l2;
59*4882a593Smuzhiyun 			u8 len_l3;
60*4882a593Smuzhiyun 			u8 len_l4;
61*4882a593Smuzhiyun 			u8 is_ipv6:1;
62*4882a593Smuzhiyun 			u8 rsvd2:7;
63*4882a593Smuzhiyun 			u32 len_pkt;
64*4882a593Smuzhiyun 			u16 vlan_tx_tag;
65*4882a593Smuzhiyun 		};
66*4882a593Smuzhiyun 	};
67*4882a593Smuzhiyun 	union {
68*4882a593Smuzhiyun 		struct {
69*4882a593Smuzhiyun 			u32 len:16;
70*4882a593Smuzhiyun 			u32 is_ip_cso:1;
71*4882a593Smuzhiyun 			u32 is_udp_cso:1;
72*4882a593Smuzhiyun 			u32 is_tcp_cso:1;
73*4882a593Smuzhiyun 			u32 is_cso_err:1;
74*4882a593Smuzhiyun 			u32 is_sop:1;
75*4882a593Smuzhiyun 			u32 is_eop:1;
76*4882a593Smuzhiyun 			u32 is_gso_tcp:1;
77*4882a593Smuzhiyun 			u32 is_gso_udp:1;
78*4882a593Smuzhiyun 			u32 is_mapped:1;
79*4882a593Smuzhiyun 			u32 is_cleaned:1;
80*4882a593Smuzhiyun 			u32 is_error:1;
81*4882a593Smuzhiyun 			u32 is_vlan:1;
82*4882a593Smuzhiyun 			u32 is_lro:1;
83*4882a593Smuzhiyun 			u32 rsvd3:3;
84*4882a593Smuzhiyun 			u16 eop_index;
85*4882a593Smuzhiyun 			u16 rsvd4;
86*4882a593Smuzhiyun 		};
87*4882a593Smuzhiyun 		u64 flags;
88*4882a593Smuzhiyun 	};
89*4882a593Smuzhiyun };
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun struct aq_ring_stats_rx_s {
92*4882a593Smuzhiyun 	struct u64_stats_sync syncp;	/* must be first */
93*4882a593Smuzhiyun 	u64 errors;
94*4882a593Smuzhiyun 	u64 packets;
95*4882a593Smuzhiyun 	u64 bytes;
96*4882a593Smuzhiyun 	u64 lro_packets;
97*4882a593Smuzhiyun 	u64 jumbo_packets;
98*4882a593Smuzhiyun 	u64 alloc_fails;
99*4882a593Smuzhiyun 	u64 skb_alloc_fails;
100*4882a593Smuzhiyun 	u64 polls;
101*4882a593Smuzhiyun 	u64 pg_losts;
102*4882a593Smuzhiyun 	u64 pg_flips;
103*4882a593Smuzhiyun 	u64 pg_reuses;
104*4882a593Smuzhiyun };
105*4882a593Smuzhiyun 
106*4882a593Smuzhiyun struct aq_ring_stats_tx_s {
107*4882a593Smuzhiyun 	struct u64_stats_sync syncp;	/* must be first */
108*4882a593Smuzhiyun 	u64 errors;
109*4882a593Smuzhiyun 	u64 packets;
110*4882a593Smuzhiyun 	u64 bytes;
111*4882a593Smuzhiyun 	u64 queue_restarts;
112*4882a593Smuzhiyun };
113*4882a593Smuzhiyun 
114*4882a593Smuzhiyun union aq_ring_stats_s {
115*4882a593Smuzhiyun 	struct aq_ring_stats_rx_s rx;
116*4882a593Smuzhiyun 	struct aq_ring_stats_tx_s tx;
117*4882a593Smuzhiyun };
118*4882a593Smuzhiyun 
119*4882a593Smuzhiyun enum atl_ring_type {
120*4882a593Smuzhiyun 	ATL_RING_TX,
121*4882a593Smuzhiyun 	ATL_RING_RX,
122*4882a593Smuzhiyun };
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun struct aq_ring_s {
125*4882a593Smuzhiyun 	struct aq_ring_buff_s *buff_ring;
126*4882a593Smuzhiyun 	u8 *dx_ring;		/* descriptors ring, dma shared mem */
127*4882a593Smuzhiyun 	struct aq_nic_s *aq_nic;
128*4882a593Smuzhiyun 	unsigned int idx;	/* for HW layer registers operations */
129*4882a593Smuzhiyun 	unsigned int hw_head;
130*4882a593Smuzhiyun 	unsigned int sw_head;
131*4882a593Smuzhiyun 	unsigned int sw_tail;
132*4882a593Smuzhiyun 	unsigned int size;	/* descriptors number */
133*4882a593Smuzhiyun 	unsigned int dx_size;	/* TX or RX descriptor size,  */
134*4882a593Smuzhiyun 				/* stored here for fater math */
135*4882a593Smuzhiyun 	unsigned int page_order;
136*4882a593Smuzhiyun 	union aq_ring_stats_s stats;
137*4882a593Smuzhiyun 	dma_addr_t dx_ring_pa;
138*4882a593Smuzhiyun 	enum atl_ring_type ring_type;
139*4882a593Smuzhiyun };
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun struct aq_ring_param_s {
142*4882a593Smuzhiyun 	unsigned int vec_idx;
143*4882a593Smuzhiyun 	unsigned int cpu;
144*4882a593Smuzhiyun 	cpumask_t affinity_mask;
145*4882a593Smuzhiyun };
146*4882a593Smuzhiyun 
aq_buf_vaddr(struct aq_rxpage * rxpage)147*4882a593Smuzhiyun static inline void *aq_buf_vaddr(struct aq_rxpage *rxpage)
148*4882a593Smuzhiyun {
149*4882a593Smuzhiyun 	return page_to_virt(rxpage->page) + rxpage->pg_off;
150*4882a593Smuzhiyun }
151*4882a593Smuzhiyun 
aq_buf_daddr(struct aq_rxpage * rxpage)152*4882a593Smuzhiyun static inline dma_addr_t aq_buf_daddr(struct aq_rxpage *rxpage)
153*4882a593Smuzhiyun {
154*4882a593Smuzhiyun 	return rxpage->daddr + rxpage->pg_off;
155*4882a593Smuzhiyun }
156*4882a593Smuzhiyun 
aq_ring_next_dx(struct aq_ring_s * self,unsigned int dx)157*4882a593Smuzhiyun static inline unsigned int aq_ring_next_dx(struct aq_ring_s *self,
158*4882a593Smuzhiyun 					   unsigned int dx)
159*4882a593Smuzhiyun {
160*4882a593Smuzhiyun 	return (++dx >= self->size) ? 0U : dx;
161*4882a593Smuzhiyun }
162*4882a593Smuzhiyun 
aq_ring_avail_dx(struct aq_ring_s * self)163*4882a593Smuzhiyun static inline unsigned int aq_ring_avail_dx(struct aq_ring_s *self)
164*4882a593Smuzhiyun {
165*4882a593Smuzhiyun 	return (((self->sw_tail >= self->sw_head)) ?
166*4882a593Smuzhiyun 		(self->size - 1) - self->sw_tail + self->sw_head :
167*4882a593Smuzhiyun 		self->sw_head - self->sw_tail - 1);
168*4882a593Smuzhiyun }
169*4882a593Smuzhiyun 
170*4882a593Smuzhiyun struct aq_ring_s *aq_ring_tx_alloc(struct aq_ring_s *self,
171*4882a593Smuzhiyun 				   struct aq_nic_s *aq_nic,
172*4882a593Smuzhiyun 				   unsigned int idx,
173*4882a593Smuzhiyun 				   struct aq_nic_cfg_s *aq_nic_cfg);
174*4882a593Smuzhiyun struct aq_ring_s *aq_ring_rx_alloc(struct aq_ring_s *self,
175*4882a593Smuzhiyun 				   struct aq_nic_s *aq_nic,
176*4882a593Smuzhiyun 				   unsigned int idx,
177*4882a593Smuzhiyun 				   struct aq_nic_cfg_s *aq_nic_cfg);
178*4882a593Smuzhiyun int aq_ring_init(struct aq_ring_s *self, const enum atl_ring_type ring_type);
179*4882a593Smuzhiyun void aq_ring_rx_deinit(struct aq_ring_s *self);
180*4882a593Smuzhiyun void aq_ring_free(struct aq_ring_s *self);
181*4882a593Smuzhiyun void aq_ring_update_queue_state(struct aq_ring_s *ring);
182*4882a593Smuzhiyun void aq_ring_queue_wake(struct aq_ring_s *ring);
183*4882a593Smuzhiyun void aq_ring_queue_stop(struct aq_ring_s *ring);
184*4882a593Smuzhiyun bool aq_ring_tx_clean(struct aq_ring_s *self);
185*4882a593Smuzhiyun int aq_ring_rx_clean(struct aq_ring_s *self,
186*4882a593Smuzhiyun 		     struct napi_struct *napi,
187*4882a593Smuzhiyun 		     int *work_done,
188*4882a593Smuzhiyun 		     int budget);
189*4882a593Smuzhiyun int aq_ring_rx_fill(struct aq_ring_s *self);
190*4882a593Smuzhiyun 
191*4882a593Smuzhiyun struct aq_ring_s *aq_ring_hwts_rx_alloc(struct aq_ring_s *self,
192*4882a593Smuzhiyun 		struct aq_nic_s *aq_nic, unsigned int idx,
193*4882a593Smuzhiyun 		unsigned int size, unsigned int dx_size);
194*4882a593Smuzhiyun void aq_ring_hwts_rx_clean(struct aq_ring_s *self, struct aq_nic_s *aq_nic);
195*4882a593Smuzhiyun 
196*4882a593Smuzhiyun unsigned int aq_ring_fill_stats_data(struct aq_ring_s *self, u64 *data);
197*4882a593Smuzhiyun 
198*4882a593Smuzhiyun #endif /* AQ_RING_H */
199