xref: /linux/drivers/net/ethernet/wangxun/libwx/wx_vf_lib.c (revision 91ec2035134982b98fab0609a9fd8480e8217dc1)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2015 - 2025 Beijing WangXun Technology Co., Ltd. */
3 
4 #include <linux/etherdevice.h>
5 #include <linux/pci.h>
6 
7 #include "wx_type.h"
8 #include "wx_hw.h"
9 #include "wx_lib.h"
10 #include "wx_vf.h"
11 #include "wx_vf_lib.h"
12 
wx_write_eitr_vf(struct wx_q_vector * q_vector)13 void wx_write_eitr_vf(struct wx_q_vector *q_vector)
14 {
15 	struct wx *wx = q_vector->wx;
16 	int v_idx = q_vector->v_idx;
17 	u32 itr_reg;
18 
19 	switch (wx->mac.type) {
20 	case wx_mac_sp:
21 		itr_reg = q_vector->itr & WX_SP_MAX_EITR;
22 		break;
23 	case wx_mac_aml:
24 	case wx_mac_aml40:
25 		itr_reg = (q_vector->itr >> 3) & WX_AML_MAX_EITR;
26 		break;
27 	default:
28 		itr_reg = q_vector->itr & WX_EM_MAX_EITR;
29 		break;
30 	}
31 
32 	/* set the WDIS bit to not clear the timer bits and cause an
33 	 * immediate assertion of the interrupt
34 	 */
35 	itr_reg |= WX_VXITR_CNT_WDIS;
36 
37 	wr32(wx, WX_VXITR(v_idx), itr_reg);
38 }
39 
wx_set_ivar_vf(struct wx * wx,s8 direction,u8 queue,u8 msix_vector)40 static void wx_set_ivar_vf(struct wx *wx, s8 direction, u8 queue,
41 			   u8 msix_vector)
42 {
43 	u32 ivar, index;
44 
45 	if (direction == -1) {
46 		/* other causes */
47 		msix_vector |= WX_PX_IVAR_ALLOC_VAL;
48 		ivar = rd32(wx, WX_VXIVAR_MISC);
49 		ivar &= ~0xFF;
50 		ivar |= msix_vector;
51 		wr32(wx, WX_VXIVAR_MISC, ivar);
52 	} else {
53 		/* tx or rx causes */
54 		msix_vector |= WX_PX_IVAR_ALLOC_VAL;
55 		index = ((16 * (queue & 1)) + (8 * direction));
56 		ivar = rd32(wx, WX_VXIVAR(queue >> 1));
57 		ivar &= ~(0xFF << index);
58 		ivar |= (msix_vector << index);
59 		wr32(wx, WX_VXIVAR(queue >> 1), ivar);
60 	}
61 }
62 
wx_configure_msix_vf(struct wx * wx)63 void wx_configure_msix_vf(struct wx *wx)
64 {
65 	int v_idx;
66 
67 	wx->eims_enable_mask = 0;
68 	for (v_idx = 0; v_idx < wx->num_q_vectors; v_idx++) {
69 		struct wx_q_vector *q_vector = wx->q_vector[v_idx];
70 		struct wx_ring *ring;
71 
72 		wx_for_each_ring(ring, q_vector->rx)
73 			wx_set_ivar_vf(wx, 0, ring->reg_idx, v_idx);
74 
75 		wx_for_each_ring(ring, q_vector->tx)
76 			wx_set_ivar_vf(wx, 1, ring->reg_idx, v_idx);
77 
78 		/* add q_vector eims value to global eims_enable_mask */
79 		wx->eims_enable_mask |= BIT(v_idx);
80 		wx_write_eitr_vf(q_vector);
81 	}
82 
83 	wx_set_ivar_vf(wx, -1, 1, v_idx);
84 
85 	/* setup eims_other and add value to global eims_enable_mask */
86 	wx->eims_other = BIT(v_idx);
87 	wx->eims_enable_mask |= wx->eims_other;
88 }
89 
wx_write_uc_addr_list_vf(struct net_device * netdev)90 int wx_write_uc_addr_list_vf(struct net_device *netdev)
91 {
92 	struct wx *wx = netdev_priv(netdev);
93 	int count = 0;
94 
95 	if (!netdev_uc_empty(netdev)) {
96 		struct netdev_hw_addr *ha;
97 
98 		netdev_for_each_uc_addr(ha, netdev)
99 			wx_set_uc_addr_vf(wx, ++count, ha->addr);
100 	} else {
101 		/*
102 		 * If the list is empty then send message to PF driver to
103 		 * clear all macvlans on this VF.
104 		 */
105 		wx_set_uc_addr_vf(wx, 0, NULL);
106 	}
107 
108 	return count;
109 }
110 
111 /**
112  * wx_configure_tx_ring_vf - Configure Tx ring after Reset
113  * @wx: board private structure
114  * @ring: structure containing ring specific data
115  *
116  * Configure the Tx descriptor ring after a reset.
117  **/
wx_configure_tx_ring_vf(struct wx * wx,struct wx_ring * ring)118 static void wx_configure_tx_ring_vf(struct wx *wx, struct wx_ring *ring)
119 {
120 	u8 reg_idx = ring->reg_idx;
121 	u64 tdba = ring->dma;
122 	u32 txdctl = 0;
123 	int ret;
124 
125 	/* disable queue to avoid issues while updating state */
126 	wr32(wx, WX_VXTXDCTL(reg_idx), WX_VXTXDCTL_FLUSH);
127 	wr32(wx, WX_VXTDBAL(reg_idx), tdba & DMA_BIT_MASK(32));
128 	wr32(wx, WX_VXTDBAH(reg_idx), tdba >> 32);
129 
130 	/* enable relaxed ordering */
131 	pcie_capability_clear_and_set_word(wx->pdev, PCI_EXP_DEVCTL,
132 					   0, PCI_EXP_DEVCTL_RELAX_EN);
133 
134 	/* reset head and tail pointers */
135 	wr32(wx, WX_VXTDH(reg_idx), 0);
136 	wr32(wx, WX_VXTDT(reg_idx), 0);
137 	ring->tail = wx->hw_addr + WX_VXTDT(reg_idx);
138 
139 	/* reset ntu and ntc to place SW in sync with hardwdare */
140 	ring->next_to_clean = 0;
141 	ring->next_to_use = 0;
142 
143 	txdctl |= WX_VXTXDCTL_BUFLEN(wx_buf_len(ring->count));
144 	txdctl |= WX_VXTXDCTL_ENABLE;
145 
146 	if (ring->headwb_mem) {
147 		wr32(wx, WX_VXTXD_HEAD_ADDRL(reg_idx),
148 		     ring->headwb_dma & DMA_BIT_MASK(32));
149 		wr32(wx, WX_VXTXD_HEAD_ADDRH(reg_idx),
150 		     upper_32_bits(ring->headwb_dma));
151 
152 		txdctl |= WX_VXTXDCTL_HEAD_WB;
153 	}
154 
155 	/* reinitialize tx_buffer_info */
156 	memset(ring->tx_buffer_info, 0,
157 	       sizeof(struct wx_tx_buffer) * ring->count);
158 
159 	wr32(wx, WX_VXTXDCTL(reg_idx), txdctl);
160 	/* poll to verify queue is enabled */
161 	ret = read_poll_timeout(rd32, txdctl, txdctl & WX_VXTXDCTL_ENABLE,
162 				1000, 10000, true, wx, WX_VXTXDCTL(reg_idx));
163 	if (ret == -ETIMEDOUT)
164 		wx_err(wx, "Could not enable Tx Queue %d\n", reg_idx);
165 }
166 
167 /**
168  * wx_configure_tx_vf - Configure Transmit Unit after Reset
169  * @wx: board private structure
170  *
171  * Configure the Tx unit of the MAC after a reset.
172  **/
wx_configure_tx_vf(struct wx * wx)173 void wx_configure_tx_vf(struct wx *wx)
174 {
175 	u32 i;
176 
177 	/* Setup the HW Tx Head and Tail descriptor pointers */
178 	for (i = 0; i < wx->num_tx_queues; i++)
179 		wx_configure_tx_ring_vf(wx, wx->tx_ring[i]);
180 }
181 
wx_configure_srrctl_vf(struct wx * wx,struct wx_ring * ring,int index)182 static void wx_configure_srrctl_vf(struct wx *wx, struct wx_ring *ring,
183 				   int index)
184 {
185 	u32 srrctl;
186 
187 	srrctl = rd32m(wx, WX_VXRXDCTL(index),
188 		       (u32)~(WX_VXRXDCTL_HDRSZ_MASK | WX_VXRXDCTL_BUFSZ_MASK));
189 	srrctl |= WX_VXRXDCTL_DROP;
190 	srrctl |= WX_VXRXDCTL_HDRSZ(wx_hdr_sz(WX_RX_HDR_SIZE));
191 	srrctl |= WX_VXRXDCTL_BUFSZ(wx_buf_sz(WX_RX_BUF_SIZE));
192 
193 	wr32(wx, WX_VXRXDCTL(index), srrctl);
194 }
195 
wx_setup_psrtype_vf(struct wx * wx)196 void wx_setup_psrtype_vf(struct wx *wx)
197 {
198 	/* PSRTYPE must be initialized */
199 	u32 psrtype = WX_VXMRQC_PSR_L2HDR |
200 		      WX_VXMRQC_PSR_L3HDR |
201 		      WX_VXMRQC_PSR_L4HDR |
202 		      WX_VXMRQC_PSR_TUNHDR |
203 		      WX_VXMRQC_PSR_TUNMAC;
204 
205 	wr32m(wx, WX_VXMRQC, WX_VXMRQC_PSR_MASK, WX_VXMRQC_PSR(psrtype));
206 }
207 
wx_setup_vfmrqc_vf(struct wx * wx)208 void wx_setup_vfmrqc_vf(struct wx *wx)
209 {
210 	u16 rss_i = wx->num_rx_queues;
211 	u32 vfmrqc = 0, vfreta = 0;
212 	u8 i, j;
213 
214 	/* Fill out hash function seeds */
215 	netdev_rss_key_fill(wx->rss_key, WX_RSS_KEY_SIZE);
216 	for (i = 0; i < WX_RSS_KEY_SIZE / 4; i++)
217 		wr32(wx, WX_VXRSSRK(i), wx->rss_key[i]);
218 
219 	for (i = 0, j = 0; i < WX_MAX_RETA_ENTRIES; i++, j++) {
220 		if (j == rss_i)
221 			j = 0;
222 
223 		wx->rss_indir_tbl[i] = j;
224 
225 		vfreta |= j << (i & 0x3) * 8;
226 		if ((i & 3) == 3) {
227 			wr32(wx, WX_VXRETA(i >> 2), vfreta);
228 			vfreta = 0;
229 		}
230 	}
231 
232 	/* Perform hash on these packet types */
233 	vfmrqc |= WX_VXMRQC_RSS_ALG_IPV4 |
234 		  WX_VXMRQC_RSS_ALG_IPV4_TCP |
235 		  WX_VXMRQC_RSS_ALG_IPV6 |
236 		  WX_VXMRQC_RSS_ALG_IPV6_TCP;
237 
238 	vfmrqc |= WX_VXMRQC_RSS_EN;
239 
240 	if (wx->num_rx_queues > 3)
241 		vfmrqc |= WX_VXMRQC_RSS_HASH(2);
242 	else if (wx->num_rx_queues > 1)
243 		vfmrqc |= WX_VXMRQC_RSS_HASH(1);
244 	wr32m(wx, WX_VXMRQC, WX_VXMRQC_RSS_MASK, WX_VXMRQC_RSS(vfmrqc));
245 }
246 
wx_configure_rx_ring_vf(struct wx * wx,struct wx_ring * ring)247 void wx_configure_rx_ring_vf(struct wx *wx, struct wx_ring *ring)
248 {
249 	u8 reg_idx = ring->reg_idx;
250 	union wx_rx_desc *rx_desc;
251 	u64 rdba = ring->dma;
252 	u32 rxdctl;
253 
254 	/* disable queue to avoid issues while updating state */
255 	rxdctl = rd32(wx, WX_VXRXDCTL(reg_idx));
256 	wx_disable_rx_queue(wx, ring);
257 
258 	wr32(wx, WX_VXRDBAL(reg_idx), rdba & DMA_BIT_MASK(32));
259 	wr32(wx, WX_VXRDBAH(reg_idx), rdba >> 32);
260 
261 	/* enable relaxed ordering */
262 	pcie_capability_clear_and_set_word(wx->pdev, PCI_EXP_DEVCTL,
263 					   0, PCI_EXP_DEVCTL_RELAX_EN);
264 
265 	/* reset head and tail pointers */
266 	wr32(wx, WX_VXRDH(reg_idx), 0);
267 	wr32(wx, WX_VXRDT(reg_idx), 0);
268 	ring->tail = wx->hw_addr + WX_VXRDT(reg_idx);
269 
270 	/* initialize rx_buffer_info */
271 	memset(ring->rx_buffer_info, 0,
272 	       sizeof(struct wx_rx_buffer) * ring->count);
273 
274 	/* initialize Rx descriptor 0 */
275 	rx_desc = WX_RX_DESC(ring, 0);
276 	rx_desc->wb.upper.length = 0;
277 
278 	/* reset ntu and ntc to place SW in sync with hardwdare */
279 	ring->next_to_clean = 0;
280 	ring->next_to_use = 0;
281 	ring->next_to_alloc = 0;
282 
283 	wx_configure_srrctl_vf(wx, ring, reg_idx);
284 
285 	/* allow any size packet since we can handle overflow */
286 	rxdctl &= ~WX_VXRXDCTL_BUFLEN_MASK;
287 	rxdctl |= WX_VXRXDCTL_BUFLEN(wx_buf_len(ring->count));
288 	rxdctl |= WX_VXRXDCTL_ENABLE | WX_VXRXDCTL_VLAN;
289 
290 	/* enable RSC */
291 	rxdctl &= ~WX_VXRXDCTL_RSCMAX_MASK;
292 	rxdctl |= WX_VXRXDCTL_RSCMAX(0);
293 	rxdctl |= WX_VXRXDCTL_RSCEN;
294 
295 	if (test_bit(WX_FLAG_RX_MERGE_ENABLED, wx->flags))
296 		rxdctl |= WX_VXRXDCTL_DESC_MERGE;
297 
298 	wr32(wx, WX_VXRXDCTL(reg_idx), rxdctl);
299 
300 	/* pf/vf reuse */
301 	wx_enable_rx_queue(wx, ring);
302 	wx_alloc_rx_buffers(ring, wx_desc_unused(ring));
303 }
304