File Index
Files and directories
Sign in
FILE

octep_vf_cnxk.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_cnxk.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/* Marvell Octeon EP (EndPoint) VF Ethernet Driver
  3 *
  4 * Copyright (C) 2020 Marvell.
  5 *
  6 */
  7
  8#include <linux/pci.h>
  9#include <linux/netdevice.h>
 10#include <linux/etherdevice.h>
 11
 12#include "octep_vf_config.h"
 13#include "octep_vf_main.h"
 14#include "octep_vf_regs_cnxk.h"
 15
 16/* Dump useful hardware IQ/OQ CSRs for debug purpose */
 17static void cnxk_vf_dump_q_regs(struct octep_vf_device *oct, int qno)
 18{
 19	struct device *dev = &oct->pdev->dev;
 20
 21	dev_info(dev, "IQ-%d register dump\n", qno);
 22	dev_info(dev, "R[%d]_IN_INSTR_DBELL[0x%llx]: 0x%016llx\n",
 23		 qno, CNXK_VF_SDP_R_IN_INSTR_DBELL(qno),
 24		 octep_vf_read_csr64(oct, CNXK_VF_SDP_R_IN_INSTR_DBELL(qno)));
 25	dev_info(dev, "R[%d]_IN_CONTROL[0x%llx]: 0x%016llx\n",
 26		 qno, CNXK_VF_SDP_R_IN_CONTROL(qno),
 27		 octep_vf_read_csr64(oct, CNXK_VF_SDP_R_IN_CONTROL(qno)));
 28	dev_info(dev, "R[%d]_IN_ENABLE[0x%llx]: 0x%016llx\n",
 29		 qno, CNXK_VF_SDP_R_IN_ENABLE(qno),
 30		 octep_vf_read_csr64(oct, CNXK_VF_SDP_R_IN_ENABLE(qno)));
 31	dev_info(dev, "R[%d]_IN_INSTR_BADDR[0x%llx]: 0x%016llx\n",
 32		 qno, CNXK_VF_SDP_R_IN_INSTR_BADDR(qno),
 33		 octep_vf_read_csr64(oct, CNXK_VF_SDP_R_IN_INSTR_BADDR(qno)));
 34	dev_info(dev, "R[%d]_IN_INSTR_RSIZE[0x%llx]: 0x%016llx\n",
 35		 qno, CNXK_VF_SDP_R_IN_INSTR_RSIZE(qno),
 36		 octep_vf_read_csr64(oct, CNXK_VF_SDP_R_IN_INSTR_RSIZE(qno)));
 37	dev_info(dev, "R[%d]_IN_CNTS[0x%llx]: 0x%016llx\n",
 38		 qno, CNXK_VF_SDP_R_IN_CNTS(qno),
 39		 octep_vf_read_csr64(oct, CNXK_VF_SDP_R_IN_CNTS(qno)));
 40	dev_info(dev, "R[%d]_IN_INT_LEVELS[0x%llx]: 0x%016llx\n",
 41		 qno, CNXK_VF_SDP_R_IN_INT_LEVELS(qno),
 42		 octep_vf_read_csr64(oct, CNXK_VF_SDP_R_IN_INT_LEVELS(qno)));
 43	dev_info(dev, "R[%d]_IN_PKT_CNT[0x%llx]: 0x%016llx\n",
 44		 qno, CNXK_VF_SDP_R_IN_PKT_CNT(qno),
 45		 octep_vf_read_csr64(oct, CNXK_VF_SDP_R_IN_PKT_CNT(qno)));
 46	dev_info(dev, "R[%d]_IN_BYTE_CNT[0x%llx]: 0x%016llx\n",
 47		 qno, CNXK_VF_SDP_R_IN_BYTE_CNT(qno),
 48		 octep_vf_read_csr64(oct, CNXK_VF_SDP_R_IN_BYTE_CNT(qno)));
 49
 50	dev_info(dev, "OQ-%d register dump\n", qno);
 51	dev_info(dev, "R[%d]_OUT_SLIST_DBELL[0x%llx]: 0x%016llx\n",
 52		 qno, CNXK_VF_SDP_R_OUT_SLIST_DBELL(qno),
 53		 octep_vf_read_csr64(oct, CNXK_VF_SDP_R_OUT_SLIST_DBELL(qno)));
 54	dev_info(dev, "R[%d]_OUT_CONTROL[0x%llx]: 0x%016llx\n",
 55		 qno, CNXK_VF_SDP_R_OUT_CONTROL(qno),
 56		 octep_vf_read_csr64(oct, CNXK_VF_SDP_R_OUT_CONTROL(qno)));
 57	dev_info(dev, "R[%d]_OUT_ENABLE[0x%llx]: 0x%016llx\n",
 58		 qno, CNXK_VF_SDP_R_OUT_ENABLE(qno),
 59		 octep_vf_read_csr64(oct, CNXK_VF_SDP_R_OUT_ENABLE(qno)));
 60	dev_info(dev, "R[%d]_OUT_SLIST_BADDR[0x%llx]: 0x%016llx\n",
 61		 qno, CNXK_VF_SDP_R_OUT_SLIST_BADDR(qno),
 62		 octep_vf_read_csr64(oct, CNXK_VF_SDP_R_OUT_SLIST_BADDR(qno)));
 63	dev_info(dev, "R[%d]_OUT_SLIST_RSIZE[0x%llx]: 0x%016llx\n",
 64		 qno, CNXK_VF_SDP_R_OUT_SLIST_RSIZE(qno),
 65		 octep_vf_read_csr64(oct, CNXK_VF_SDP_R_OUT_SLIST_RSIZE(qno)));
 66	dev_info(dev, "R[%d]_OUT_CNTS[0x%llx]: 0x%016llx\n",
 67		 qno, CNXK_VF_SDP_R_OUT_CNTS(qno),
 68		 octep_vf_read_csr64(oct, CNXK_VF_SDP_R_OUT_CNTS(qno)));
 69	dev_info(dev, "R[%d]_OUT_INT_LEVELS[0x%llx]: 0x%016llx\n",
 70		 qno, CNXK_VF_SDP_R_OUT_INT_LEVELS(qno),
 71		 octep_vf_read_csr64(oct, CNXK_VF_SDP_R_OUT_INT_LEVELS(qno)));
 72	dev_info(dev, "R[%d]_OUT_PKT_CNT[0x%llx]: 0x%016llx\n",
 73		 qno, CNXK_VF_SDP_R_OUT_PKT_CNT(qno),
 74		 octep_vf_read_csr64(oct, CNXK_VF_SDP_R_OUT_PKT_CNT(qno)));
 75	dev_info(dev, "R[%d]_OUT_BYTE_CNT[0x%llx]: 0x%016llx\n",
 76		 qno, CNXK_VF_SDP_R_OUT_BYTE_CNT(qno),
 77		 octep_vf_read_csr64(oct, CNXK_VF_SDP_R_OUT_BYTE_CNT(qno)));
 78	dev_info(dev, "R[%d]_ERR_TYPE[0x%llx]: 0x%016llx\n",
 79		 qno, CNXK_VF_SDP_R_ERR_TYPE(qno),
 80		 octep_vf_read_csr64(oct, CNXK_VF_SDP_R_ERR_TYPE(qno)));
 81}
 82
 83/* Reset Hardware Tx queue */
 84static void cnxk_vf_reset_iq(struct octep_vf_device *oct, int q_no)
 85{
 86	u64 val = ULL(0);
 87
 88	dev_dbg(&oct->pdev->dev, "Reset VF IQ-%d\n", q_no);
 89
 90	/* Disable the Tx/Instruction Ring */
 91	octep_vf_write_csr64(oct, CNXK_VF_SDP_R_IN_ENABLE(q_no), val);
 92
 93	/* clear the Instruction Ring packet/byte counts and doorbell CSRs */
 94	octep_vf_write_csr64(oct, CNXK_VF_SDP_R_IN_INT_LEVELS(q_no), val);
 95	octep_vf_write_csr64(oct, CNXK_VF_SDP_R_IN_PKT_CNT(q_no), val);
 96	octep_vf_write_csr64(oct, CNXK_VF_SDP_R_IN_BYTE_CNT(q_no), val);
 97	octep_vf_write_csr64(oct, CNXK_VF_SDP_R_IN_INSTR_BADDR(q_no), val);
 98	octep_vf_write_csr64(oct, CNXK_VF_SDP_R_IN_INSTR_RSIZE(q_no), val);
 99
100	val = GENMASK_ULL(31, 0);
101	octep_vf_write_csr64(oct, CNXK_VF_SDP_R_IN_INSTR_DBELL(q_no), val);
102
103	val = octep_vf_read_csr64(oct, CNXK_VF_SDP_R_IN_CNTS(q_no));
104	octep_vf_write_csr64(oct, CNXK_VF_SDP_R_IN_CNTS(q_no), val & GENMASK_ULL(31, 0));
105}
106
107/* Reset Hardware Rx queue */
108static void cnxk_vf_reset_oq(struct octep_vf_device *oct, int q_no)
109{
110	u64 val = ULL(0);
111
112	/* Disable Output (Rx) Ring */
113	octep_vf_write_csr64(oct, CNXK_VF_SDP_R_OUT_ENABLE(q_no), val);
114
115	/* Clear count CSRs */
116	val = octep_vf_read_csr(oct, CNXK_VF_SDP_R_OUT_CNTS(q_no));
117	octep_vf_write_csr(oct, CNXK_VF_SDP_R_OUT_CNTS(q_no), val);
118
119	octep_vf_write_csr64(oct, CNXK_VF_SDP_R_OUT_PKT_CNT(q_no), GENMASK_ULL(35, 0));
120	octep_vf_write_csr64(oct, CNXK_VF_SDP_R_OUT_SLIST_DBELL(q_no), GENMASK_ULL(31, 0));
121}
122
123/* Reset all hardware Tx/Rx queues */
124static void octep_vf_reset_io_queues_cnxk(struct octep_vf_device *oct)
125{
126	struct pci_dev *pdev = oct->pdev;
127	int q;
128
129	dev_dbg(&pdev->dev, "Reset OCTEP_CNXK VF IO Queues\n");
130
131	for (q = 0; q < CFG_GET_PORTS_ACTIVE_IO_RINGS(oct->conf); q++) {
132		cnxk_vf_reset_iq(oct, q);
133		cnxk_vf_reset_oq(oct, q);
134	}
135}
136
137/* Initialize configuration limits and initial active config */
138static void octep_vf_init_config_cnxk_vf(struct octep_vf_device *oct)
139{
140	struct octep_vf_config *conf = oct->conf;
141	u64 reg_val;
142
143	reg_val = octep_vf_read_csr64(oct, CNXK_VF_SDP_R_IN_CONTROL(0));
144	conf->ring_cfg.max_io_rings = (reg_val >> CNXK_VF_R_IN_CTL_RPVF_POS) &
145				      CNXK_VF_R_IN_CTL_RPVF_MASK;
146	conf->ring_cfg.active_io_rings = conf->ring_cfg.max_io_rings;
147
148	conf->iq.num_descs = OCTEP_VF_IQ_MAX_DESCRIPTORS;
149	conf->iq.instr_type = OCTEP_VF_64BYTE_INSTR;
150	conf->iq.db_min = OCTEP_VF_DB_MIN;
151	conf->iq.intr_threshold = OCTEP_VF_IQ_INTR_THRESHOLD;
152
153	conf->oq.num_descs = OCTEP_VF_OQ_MAX_DESCRIPTORS;
154	conf->oq.buf_size = OCTEP_VF_OQ_BUF_SIZE;
155	conf->oq.refill_threshold = OCTEP_VF_OQ_REFILL_THRESHOLD;
156	conf->oq.oq_intr_pkt = OCTEP_VF_OQ_INTR_PKT_THRESHOLD;
157	conf->oq.oq_intr_time = OCTEP_VF_OQ_INTR_TIME_THRESHOLD;
158	conf->oq.wmark = OCTEP_VF_OQ_WMARK_MIN;
159
160	conf->msix_cfg.ioq_msix = conf->ring_cfg.active_io_rings;
161}
162
163/* Setup registers for a hardware Tx Queue  */
164static void octep_vf_setup_iq_regs_cnxk(struct octep_vf_device *oct, int iq_no)
165{
166	struct octep_vf_iq *iq = oct->iq[iq_no];
167	u32 reset_instr_cnt;
168	u64 reg_val;
169
170	reg_val = octep_vf_read_csr64(oct, CNXK_VF_SDP_R_IN_CONTROL(iq_no));
171
172	/* wait for IDLE to set to 1 */
173	if (!(reg_val & CNXK_VF_R_IN_CTL_IDLE)) {
174		do {
175			reg_val = octep_vf_read_csr64(oct, CNXK_VF_SDP_R_IN_CONTROL(iq_no));
176		} while (!(reg_val & CNXK_VF_R_IN_CTL_IDLE));
177	}
178	reg_val |= CNXK_VF_R_IN_CTL_RDSIZE;
179	reg_val |= CNXK_VF_R_IN_CTL_IS_64B;
180	reg_val |= CNXK_VF_R_IN_CTL_ESR;
181	octep_vf_write_csr64(oct, CNXK_VF_SDP_R_IN_CONTROL(iq_no), reg_val);
182
183	/* Write the start of the input queue's ring and its size  */
184	octep_vf_write_csr64(oct, CNXK_VF_SDP_R_IN_INSTR_BADDR(iq_no), iq->desc_ring_dma);
185	octep_vf_write_csr64(oct, CNXK_VF_SDP_R_IN_INSTR_RSIZE(iq_no), iq->max_count);
186
187	/* Remember the doorbell & instruction count register addr for this queue */
188	iq->doorbell_reg = oct->mmio.hw_addr + CNXK_VF_SDP_R_IN_INSTR_DBELL(iq_no);
189	iq->inst_cnt_reg = oct->mmio.hw_addr + CNXK_VF_SDP_R_IN_CNTS(iq_no);
190	iq->intr_lvl_reg = oct->mmio.hw_addr + CNXK_VF_SDP_R_IN_INT_LEVELS(iq_no);
191
192	/* Store the current instruction counter (used in flush_iq calculation) */
193	reset_instr_cnt = readl(iq->inst_cnt_reg);
194	writel(reset_instr_cnt, iq->inst_cnt_reg);
195
196	/* INTR_THRESHOLD is set to max(FFFFFFFF) to disable the INTR */
197	reg_val = CFG_GET_IQ_INTR_THRESHOLD(oct->conf) & GENMASK_ULL(31, 0);
198	octep_vf_write_csr64(oct, CNXK_VF_SDP_R_IN_INT_LEVELS(iq_no), reg_val);
199}
200
201/* Setup registers for a hardware Rx Queue  */
202static int octep_vf_setup_oq_regs_cnxk(struct octep_vf_device *oct, int oq_no)
203{
204	struct octep_vf_oq *oq = oct->oq[oq_no];
205	unsigned long t_out_jiffies;
206	u32 time_threshold = 0;
207	u64 oq_ctl = ULL(0);
208	u64 reg_ba_val;
209	u64 reg_val;
210
211	reg_val = octep_vf_read_csr64(oct, CNXK_VF_SDP_R_OUT_CONTROL(oq_no));
212
213	/* wait for IDLE to set to 1 */
214	if (!(reg_val & CNXK_VF_R_OUT_CTL_IDLE)) {
215		do {
216			reg_val = octep_vf_read_csr64(oct, CNXK_VF_SDP_R_OUT_CONTROL(oq_no));
217		} while (!(reg_val & CNXK_VF_R_OUT_CTL_IDLE));
218	}
219	octep_vf_write_csr64(oct, CNXK_VF_SDP_R_OUT_WMARK(oq_no),
220			     oq->max_count);
221	/* Wait for WMARK to get applied */
222	usleep_range(10, 15);
223
224	octep_vf_write_csr64(oct, CNXK_VF_SDP_R_OUT_SLIST_BADDR(oq_no),
225			     oq->desc_ring_dma);
226	octep_vf_write_csr64(oct, CNXK_VF_SDP_R_OUT_SLIST_RSIZE(oq_no),
227			     oq->max_count);
228	reg_ba_val = octep_vf_read_csr64(oct,
229					 CNXK_VF_SDP_R_OUT_SLIST_BADDR(oq_no));
230	if (reg_ba_val != oq->desc_ring_dma) {
231		t_out_jiffies = jiffies + 10 * HZ;
232		do {
233			if (reg_ba_val == ULLONG_MAX)
234				return -EFAULT;
235			octep_vf_write_csr64(oct,
236					     CNXK_VF_SDP_R_OUT_SLIST_BADDR
237					     (oq_no), oq->desc_ring_dma);
238			octep_vf_write_csr64(oct,
239					     CNXK_VF_SDP_R_OUT_SLIST_RSIZE
240					     (oq_no), oq->max_count);
241			reg_ba_val =
242			octep_vf_read_csr64(oct,
243					    CNXK_VF_SDP_R_OUT_SLIST_BADDR
244					    (oq_no));
245		} while ((reg_ba_val != oq->desc_ring_dma) &&
246			  time_before(jiffies, t_out_jiffies));
247
248		if (reg_ba_val != oq->desc_ring_dma)
249			return -EAGAIN;
250	}
251
252	reg_val &= ~(CNXK_VF_R_OUT_CTL_IMODE);
253	reg_val &= ~(CNXK_VF_R_OUT_CTL_ROR_P);
254	reg_val &= ~(CNXK_VF_R_OUT_CTL_NSR_P);
255	reg_val &= ~(CNXK_VF_R_OUT_CTL_ROR_I);
256	reg_val &= ~(CNXK_VF_R_OUT_CTL_NSR_I);
257	reg_val &= ~(CNXK_VF_R_OUT_CTL_ES_I);
258	reg_val &= ~(CNXK_VF_R_OUT_CTL_ROR_D);
259	reg_val &= ~(CNXK_VF_R_OUT_CTL_NSR_D);
260	reg_val &= ~(CNXK_VF_R_OUT_CTL_ES_D);
261	reg_val |= (CNXK_VF_R_OUT_CTL_ES_P);
262
263	octep_vf_write_csr64(oct, CNXK_VF_SDP_R_OUT_CONTROL(oq_no), reg_val);
264
265	oq_ctl = octep_vf_read_csr64(oct, CNXK_VF_SDP_R_OUT_CONTROL(oq_no));
266	/* Clear the ISIZE and BSIZE (22-0) */
267	oq_ctl &= ~GENMASK_ULL(22, 0);
268	/* Populate the BSIZE (15-0) */
269	oq_ctl |= (oq->buffer_size & GENMASK_ULL(15, 0));
270	octep_vf_write_csr64(oct, CNXK_VF_SDP_R_OUT_CONTROL(oq_no), oq_ctl);
271
272	/* Get the mapped address of the pkt_sent and pkts_credit regs */
273	oq->pkts_sent_reg = oct->mmio.hw_addr + CNXK_VF_SDP_R_OUT_CNTS(oq_no);
274	oq->pkts_credit_reg = oct->mmio.hw_addr + CNXK_VF_SDP_R_OUT_SLIST_DBELL(oq_no);
275
276	time_threshold = CFG_GET_OQ_INTR_TIME(oct->conf);
277	reg_val = ((u64)time_threshold << 32) | CFG_GET_OQ_INTR_PKT(oct->conf);
278	octep_vf_write_csr64(oct, CNXK_VF_SDP_R_OUT_INT_LEVELS(oq_no), reg_val);
279
280	/* set watermark for backpressure */
281	reg_val = octep_vf_read_csr64(oct, CNXK_VF_SDP_R_OUT_WMARK(oq_no));
282	reg_val &= ~GENMASK_ULL(31, 0);
283	reg_val |= CFG_GET_OQ_WMARK(oct->conf);
284	octep_vf_write_csr64(oct, CNXK_VF_SDP_R_OUT_WMARK(oq_no), reg_val);
285	return 0;
286}
287
288/* Setup registers for a VF mailbox */
289static void octep_vf_setup_mbox_regs_cnxk(struct octep_vf_device *oct, int q_no)
290{
291	struct octep_vf_mbox *mbox = oct->mbox;
292
293	/* PF to VF DATA reg. VF reads from this reg */
294	mbox->mbox_read_reg = oct->mmio.hw_addr + CNXK_VF_SDP_R_MBOX_PF_VF_DATA(q_no);
295
296	/* VF mbox interrupt reg */
297	mbox->mbox_int_reg = oct->mmio.hw_addr + CNXK_VF_SDP_R_MBOX_PF_VF_INT(q_no);
298
299	/* VF to PF DATA reg. VF writes into this reg */
300	mbox->mbox_write_reg = oct->mmio.hw_addr + CNXK_VF_SDP_R_MBOX_VF_PF_DATA(q_no);
301}
302
303/* Mailbox Interrupt handler */
304static void cnxk_handle_vf_mbox_intr(struct octep_vf_device *oct)
305{
306	if (oct->mbox)
307		schedule_work(&oct->mbox->wk.work);
308	else
309		dev_err(&oct->pdev->dev, "cannot schedule work on invalid mbox\n");
310}
311
312/* Tx/Rx queue interrupt handler */
313static irqreturn_t octep_vf_ioq_intr_handler_cnxk(void *data)
314{
315	struct octep_vf_ioq_vector *vector = data;
316	struct octep_vf_device *oct;
317	struct octep_vf_oq *oq;
318	u64 reg_val;
319
320	oct = vector->octep_vf_dev;
321	oq = vector->oq;
322	/* Mailbox interrupt arrives along with interrupt of tx/rx ring pair 0 */
323	if (oq->q_no == 0) {
324		reg_val = octep_vf_read_csr64(oct, CNXK_VF_SDP_R_MBOX_PF_VF_INT(0));
325		if (reg_val & CNXK_VF_SDP_R_MBOX_PF_VF_INT_STATUS) {
326			cnxk_handle_vf_mbox_intr(oct);
327			octep_vf_write_csr64(oct, CNXK_VF_SDP_R_MBOX_PF_VF_INT(0), reg_val);
328		}
329	}
330	napi_schedule_irqoff(oq->napi);
331	return IRQ_HANDLED;
332}
333
334/* Re-initialize Octeon hardware registers */
335static void octep_vf_reinit_regs_cnxk(struct octep_vf_device *oct)
336{
337	u32 i;
338
339	for (i = 0; i < CFG_GET_PORTS_ACTIVE_IO_RINGS(oct->conf); i++)
340		oct->hw_ops.setup_iq_regs(oct, i);
341
342	for (i = 0; i < CFG_GET_PORTS_ACTIVE_IO_RINGS(oct->conf); i++)
343		oct->hw_ops.setup_oq_regs(oct, i);
344
345	oct->hw_ops.enable_interrupts(oct);
346	oct->hw_ops.enable_io_queues(oct);
347
348	for (i = 0; i < CFG_GET_PORTS_ACTIVE_IO_RINGS(oct->conf); i++)
349		writel(oct->oq[i]->max_count, oct->oq[i]->pkts_credit_reg);
350}
351
352/* Enable all interrupts */
353static void octep_vf_enable_interrupts_cnxk(struct octep_vf_device *oct)
354{
355	int num_rings, q;
356	u64 reg_val;
357
358	num_rings = CFG_GET_PORTS_ACTIVE_IO_RINGS(oct->conf);
359	for (q = 0; q < num_rings; q++) {
360		reg_val = octep_vf_read_csr64(oct, CNXK_VF_SDP_R_IN_INT_LEVELS(q));
361		reg_val |= BIT_ULL_MASK(62);
362		octep_vf_write_csr64(oct, CNXK_VF_SDP_R_IN_INT_LEVELS(q), reg_val);
363
364		reg_val = octep_vf_read_csr64(oct, CNXK_VF_SDP_R_OUT_INT_LEVELS(q));
365		reg_val |= BIT_ULL_MASK(62);
366		octep_vf_write_csr64(oct, CNXK_VF_SDP_R_OUT_INT_LEVELS(q), reg_val);
367	}
368	/* Enable PF to VF mbox interrupt by setting 2nd bit*/
369	octep_vf_write_csr64(oct, CNXK_VF_SDP_R_MBOX_PF_VF_INT(0),
370			     CNXK_VF_SDP_R_MBOX_PF_VF_INT_ENAB);
371}
372
373/* Disable all interrupts */
374static void octep_vf_disable_interrupts_cnxk(struct octep_vf_device *oct)
375{
376	int num_rings, q;
377	u64 reg_val;
378
379	/* Disable PF to VF mbox interrupt by setting 2nd bit*/
380	if (oct->mbox)
381		octep_vf_write_csr64(oct, CNXK_VF_SDP_R_MBOX_PF_VF_INT(0), 0x0);
382
383	num_rings = CFG_GET_PORTS_ACTIVE_IO_RINGS(oct->conf);
384	for (q = 0; q < num_rings; q++) {
385		reg_val = octep_vf_read_csr64(oct, CNXK_VF_SDP_R_IN_INT_LEVELS(q));
386		reg_val &= ~BIT_ULL_MASK(62);
387		octep_vf_write_csr64(oct, CNXK_VF_SDP_R_IN_INT_LEVELS(q), reg_val);
388
389		reg_val = octep_vf_read_csr64(oct, CNXK_VF_SDP_R_OUT_INT_LEVELS(q));
390		reg_val &= ~BIT_ULL_MASK(62);
391		octep_vf_write_csr64(oct, CNXK_VF_SDP_R_OUT_INT_LEVELS(q), reg_val);
392	}
393}
394
395/* Get new Octeon Read Index: index of descriptor that Octeon reads next. */
396static u32 octep_vf_update_iq_read_index_cnxk(struct octep_vf_iq *iq)
397{
398	u32 pkt_in_done = readl(iq->inst_cnt_reg);
399	u32 last_done, new_idx;
400
401	last_done = pkt_in_done - iq->pkt_in_done;
402	iq->pkt_in_done = pkt_in_done;
403
404	new_idx = (iq->octep_vf_read_index + last_done) % iq->max_count;
405
406	return new_idx;
407}
408
409/* Enable a hardware Tx Queue */
410static void octep_vf_enable_iq_cnxk(struct octep_vf_device *oct, int iq_no)
411{
412	u64 loop = HZ;
413	u64 reg_val;
414
415	octep_vf_write_csr64(oct, CNXK_VF_SDP_R_IN_INSTR_DBELL(iq_no), GENMASK_ULL(31, 0));
416
417	while (octep_vf_read_csr64(oct, CNXK_VF_SDP_R_IN_INSTR_DBELL(iq_no)) &&
418	       loop--) {
419		schedule_timeout_interruptible(1);
420	}
421
422	reg_val = octep_vf_read_csr64(oct,  CNXK_VF_SDP_R_IN_INT_LEVELS(iq_no));
423	reg_val |= BIT_ULL_MASK(62);
424	octep_vf_write_csr64(oct, CNXK_VF_SDP_R_IN_INT_LEVELS(iq_no), reg_val);
425
426	reg_val = octep_vf_read_csr64(oct, CNXK_VF_SDP_R_IN_ENABLE(iq_no));
427	reg_val |= ULL(1);
428	octep_vf_write_csr64(oct, CNXK_VF_SDP_R_IN_ENABLE(iq_no), reg_val);
429}
430
431/* Enable a hardware Rx Queue */
432static void octep_vf_enable_oq_cnxk(struct octep_vf_device *oct, int oq_no)
433{
434	u64 reg_val;
435
436	reg_val = octep_vf_read_csr64(oct,  CNXK_VF_SDP_R_OUT_INT_LEVELS(oq_no));
437	reg_val |= BIT_ULL_MASK(62);
438	octep_vf_write_csr64(oct, CNXK_VF_SDP_R_OUT_INT_LEVELS(oq_no), reg_val);
439
440	octep_vf_write_csr64(oct, CNXK_VF_SDP_R_OUT_SLIST_DBELL(oq_no), GENMASK_ULL(31, 0));
441
442	reg_val = octep_vf_read_csr64(oct, CNXK_VF_SDP_R_OUT_ENABLE(oq_no));
443	reg_val |= ULL(1);
444	octep_vf_write_csr64(oct, CNXK_VF_SDP_R_OUT_ENABLE(oq_no), reg_val);
445}
446
447/* Enable all hardware Tx/Rx Queues assigned to VF */
448static void octep_vf_enable_io_queues_cnxk(struct octep_vf_device *oct)
449{
450	u8 q;
451
452	for (q = 0; q < CFG_GET_PORTS_ACTIVE_IO_RINGS(oct->conf); q++) {
453		octep_vf_enable_iq_cnxk(oct, q);
454		octep_vf_enable_oq_cnxk(oct, q);
455	}
456}
457
458/* Disable a hardware Tx Queue assigned to VF */
459static void octep_vf_disable_iq_cnxk(struct octep_vf_device *oct, int iq_no)
460{
461	u64 reg_val;
462
463	reg_val = octep_vf_read_csr64(oct, CNXK_VF_SDP_R_IN_ENABLE(iq_no));
464	reg_val &= ~ULL(1);
465	octep_vf_write_csr64(oct, CNXK_VF_SDP_R_IN_ENABLE(iq_no), reg_val);
466}
467
468/* Disable a hardware Rx Queue assigned to VF */
469static void octep_vf_disable_oq_cnxk(struct octep_vf_device *oct, int oq_no)
470{
471	u64 reg_val;
472
473	reg_val = octep_vf_read_csr64(oct, CNXK_VF_SDP_R_OUT_ENABLE(oq_no));
474	reg_val &= ~ULL(1);
475	octep_vf_write_csr64(oct, CNXK_VF_SDP_R_OUT_ENABLE(oq_no), reg_val);
476}
477
478/* Disable all hardware Tx/Rx Queues assigned to VF */
479static void octep_vf_disable_io_queues_cnxk(struct octep_vf_device *oct)
480{
481	int q;
482
483	for (q = 0; q < CFG_GET_PORTS_ACTIVE_IO_RINGS(oct->conf); q++) {
484		octep_vf_disable_iq_cnxk(oct, q);
485		octep_vf_disable_oq_cnxk(oct, q);
486	}
487}
488
489/* Dump hardware registers (including Tx/Rx queues) for debugging. */
490static void octep_vf_dump_registers_cnxk(struct octep_vf_device *oct)
491{
492	u8 num_rings, q;
493
494	num_rings = CFG_GET_PORTS_ACTIVE_IO_RINGS(oct->conf);
495	for (q = 0; q < num_rings; q++)
496		cnxk_vf_dump_q_regs(oct, q);
497}
498
499/**
500 * octep_vf_device_setup_cnxk() - Setup Octeon device.
501 *
502 * @oct: Octeon device private data structure.
503 *
504 * - initialize hardware operations.
505 * - get target side pcie port number for the device.
506 * - set initial configuration and max limits.
507 */
508void octep_vf_device_setup_cnxk(struct octep_vf_device *oct)
509{
510	oct->hw_ops.setup_iq_regs = octep_vf_setup_iq_regs_cnxk;
511	oct->hw_ops.setup_oq_regs = octep_vf_setup_oq_regs_cnxk;
512	oct->hw_ops.setup_mbox_regs = octep_vf_setup_mbox_regs_cnxk;
513
514	oct->hw_ops.ioq_intr_handler = octep_vf_ioq_intr_handler_cnxk;
515	oct->hw_ops.reinit_regs = octep_vf_reinit_regs_cnxk;
516
517	oct->hw_ops.enable_interrupts = octep_vf_enable_interrupts_cnxk;
518	oct->hw_ops.disable_interrupts = octep_vf_disable_interrupts_cnxk;
519
520	oct->hw_ops.update_iq_read_idx = octep_vf_update_iq_read_index_cnxk;
521
522	oct->hw_ops.enable_iq = octep_vf_enable_iq_cnxk;
523	oct->hw_ops.enable_oq = octep_vf_enable_oq_cnxk;
524	oct->hw_ops.enable_io_queues = octep_vf_enable_io_queues_cnxk;
525
526	oct->hw_ops.disable_iq = octep_vf_disable_iq_cnxk;
527	oct->hw_ops.disable_oq = octep_vf_disable_oq_cnxk;
528	oct->hw_ops.disable_io_queues = octep_vf_disable_io_queues_cnxk;
529	oct->hw_ops.reset_io_queues = octep_vf_reset_io_queues_cnxk;
530
531	oct->hw_ops.dump_registers = octep_vf_dump_registers_cnxk;
532	octep_vf_init_config_cnxk_vf(oct);
533}
~/ Read-only file preview.