File Index
Files and directories
Sign in
FILE

fnic_res.c

File preview with syntax highlighting.

linux-6.19.14/drivers/scsi/fnic/fnic_res.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * Copyright 2008 Cisco Systems, Inc.  All rights reserved.
  4 * Copyright 2007 Nuova Systems, Inc.  All rights reserved.
  5 */
  6#include <linux/errno.h>
  7#include <linux/types.h>
  8#include <linux/pci.h>
  9#include "wq_enet_desc.h"
 10#include "rq_enet_desc.h"
 11#include "cq_enet_desc.h"
 12#include "vnic_resource.h"
 13#include "vnic_dev.h"
 14#include "vnic_wq.h"
 15#include "vnic_rq.h"
 16#include "vnic_cq.h"
 17#include "vnic_intr.h"
 18#include "vnic_stats.h"
 19#include "vnic_nic.h"
 20#include "fnic.h"
 21
 22int fnic_get_vnic_config(struct fnic *fnic)
 23{
 24	struct vnic_fc_config *c = &fnic->config;
 25	int err;
 26
 27#define GET_CONFIG(m) \
 28	do { \
 29		err = vnic_dev_spec(fnic->vdev, \
 30				    offsetof(struct vnic_fc_config, m), \
 31				    sizeof(c->m), &c->m); \
 32		if (err) { \
 33			dev_err(&fnic->pdev->dev, "Error getting %s, %d\n", #m, err); \
 34			return err; \
 35		} \
 36	} while (0);
 37
 38	GET_CONFIG(node_wwn);
 39	GET_CONFIG(port_wwn);
 40	GET_CONFIG(wq_enet_desc_count);
 41	GET_CONFIG(wq_copy_desc_count);
 42	GET_CONFIG(rq_desc_count);
 43	GET_CONFIG(maxdatafieldsize);
 44	GET_CONFIG(ed_tov);
 45	GET_CONFIG(ra_tov);
 46	GET_CONFIG(intr_timer);
 47	GET_CONFIG(intr_timer_type);
 48	GET_CONFIG(flags);
 49	GET_CONFIG(flogi_retries);
 50	GET_CONFIG(flogi_timeout);
 51	GET_CONFIG(plogi_retries);
 52	GET_CONFIG(plogi_timeout);
 53	GET_CONFIG(io_throttle_count);
 54	GET_CONFIG(link_down_timeout);
 55	GET_CONFIG(port_down_timeout);
 56	GET_CONFIG(port_down_io_retries);
 57	GET_CONFIG(luns_per_tgt);
 58	GET_CONFIG(intr_mode);
 59	GET_CONFIG(wq_copy_count);
 60
 61	if ((c->flags & (VFCF_FC_INITIATOR)) == 0) {
 62		dev_info(&fnic->pdev->dev, "vNIC role not defined (def role: FC Init)\n");
 63		c->flags |= VFCF_FC_INITIATOR;
 64	}
 65
 66	c->wq_enet_desc_count =
 67		min_t(u32, VNIC_FNIC_WQ_DESCS_MAX,
 68		      max_t(u32, VNIC_FNIC_WQ_DESCS_MIN,
 69			    c->wq_enet_desc_count));
 70	c->wq_enet_desc_count = ALIGN(c->wq_enet_desc_count, 16);
 71
 72	c->wq_copy_desc_count =
 73		min_t(u32, VNIC_FNIC_WQ_COPY_DESCS_MAX,
 74		      max_t(u32, VNIC_FNIC_WQ_COPY_DESCS_MIN,
 75			    c->wq_copy_desc_count));
 76	c->wq_copy_desc_count = ALIGN(c->wq_copy_desc_count, 16);
 77
 78	c->rq_desc_count =
 79		min_t(u32, VNIC_FNIC_RQ_DESCS_MAX,
 80		      max_t(u32, VNIC_FNIC_RQ_DESCS_MIN,
 81			    c->rq_desc_count));
 82	c->rq_desc_count = ALIGN(c->rq_desc_count, 16);
 83
 84	c->maxdatafieldsize =
 85		min_t(u16, VNIC_FNIC_MAXDATAFIELDSIZE_MAX,
 86		      max_t(u16, VNIC_FNIC_MAXDATAFIELDSIZE_MIN,
 87			    c->maxdatafieldsize));
 88	c->ed_tov =
 89		min_t(u32, VNIC_FNIC_EDTOV_MAX,
 90		      max_t(u32, VNIC_FNIC_EDTOV_MIN,
 91			    c->ed_tov));
 92
 93	c->ra_tov =
 94		min_t(u32, VNIC_FNIC_RATOV_MAX,
 95		      max_t(u32, VNIC_FNIC_RATOV_MIN,
 96			    c->ra_tov));
 97
 98	c->flogi_retries =
 99		min_t(u32, VNIC_FNIC_FLOGI_RETRIES_MAX, c->flogi_retries);
100
101	c->flogi_timeout =
102		min_t(u32, VNIC_FNIC_FLOGI_TIMEOUT_MAX,
103		      max_t(u32, VNIC_FNIC_FLOGI_TIMEOUT_MIN,
104			    c->flogi_timeout));
105
106	c->plogi_retries =
107		min_t(u32, VNIC_FNIC_PLOGI_RETRIES_MAX, c->plogi_retries);
108
109	c->plogi_timeout =
110		min_t(u32, VNIC_FNIC_PLOGI_TIMEOUT_MAX,
111		      max_t(u32, VNIC_FNIC_PLOGI_TIMEOUT_MIN,
112			    c->plogi_timeout));
113
114	c->io_throttle_count =
115		min_t(u32, VNIC_FNIC_IO_THROTTLE_COUNT_MAX,
116		      max_t(u32, VNIC_FNIC_IO_THROTTLE_COUNT_MIN,
117			    c->io_throttle_count));
118
119	c->link_down_timeout =
120		min_t(u32, VNIC_FNIC_LINK_DOWN_TIMEOUT_MAX,
121		      c->link_down_timeout);
122
123	c->port_down_timeout =
124		min_t(u32, VNIC_FNIC_PORT_DOWN_TIMEOUT_MAX,
125		      c->port_down_timeout);
126
127	c->port_down_io_retries =
128		min_t(u32, VNIC_FNIC_PORT_DOWN_IO_RETRIES_MAX,
129		      c->port_down_io_retries);
130
131	c->luns_per_tgt =
132		min_t(u32, VNIC_FNIC_LUNS_PER_TARGET_MAX,
133		      max_t(u32, VNIC_FNIC_LUNS_PER_TARGET_MIN,
134			    c->luns_per_tgt));
135
136	c->intr_timer = min_t(u16, VNIC_INTR_TIMER_MAX, c->intr_timer);
137
138	/* for older firmware, GET_CONFIG will not return anything */
139	if (c->wq_copy_count == 0)
140		c->wq_copy_count = 1;
141
142	c->wq_copy_count = min_t(u16, FNIC_WQ_COPY_MAX, c->wq_copy_count);
143
144	dev_info(&fnic->pdev->dev, "fNIC MAC addr %p wq/wq_copy/rq %d/%d/%d\n",
145			fnic->data_src_addr,
146		     c->wq_enet_desc_count, c->wq_copy_desc_count,
147		     c->rq_desc_count);
148	dev_info(&fnic->pdev->dev, "fNIC node wwn 0x%llx port wwn 0x%llx\n",
149		     c->node_wwn, c->port_wwn);
150	dev_info(&fnic->pdev->dev, "fNIC ed_tov %d ra_tov %d\n",
151		     c->ed_tov, c->ra_tov);
152	dev_info(&fnic->pdev->dev, "fNIC mtu %d intr timer %d\n",
153		     c->maxdatafieldsize, c->intr_timer);
154	dev_info(&fnic->pdev->dev, "fNIC flags 0x%x luns per tgt %d\n",
155		     c->flags, c->luns_per_tgt);
156	dev_info(&fnic->pdev->dev, "fNIC flogi_retries %d flogi timeout %d\n",
157		     c->flogi_retries, c->flogi_timeout);
158	dev_info(&fnic->pdev->dev, "fNIC plogi retries %d plogi timeout %d\n",
159		     c->plogi_retries, c->plogi_timeout);
160	dev_info(&fnic->pdev->dev, "fNIC io throttle count %d link dn timeout %d\n",
161		     c->io_throttle_count, c->link_down_timeout);
162	dev_info(&fnic->pdev->dev, "fNIC port dn io retries %d port dn timeout %d\n",
163		     c->port_down_io_retries, c->port_down_timeout);
164	dev_info(&fnic->pdev->dev, "fNIC wq_copy_count: %d\n", c->wq_copy_count);
165	dev_info(&fnic->pdev->dev, "fNIC intr mode: %d\n", c->intr_mode);
166
167	return 0;
168}
169
170int fnic_set_nic_config(struct fnic *fnic, u8 rss_default_cpu,
171			u8 rss_hash_type,
172			u8 rss_hash_bits, u8 rss_base_cpu, u8 rss_enable,
173			u8 tso_ipid_split_en, u8 ig_vlan_strip_en)
174{
175	u64 a0, a1;
176	u32 nic_cfg;
177	int wait = 1000;
178
179	vnic_set_nic_cfg(&nic_cfg, rss_default_cpu,
180		rss_hash_type, rss_hash_bits, rss_base_cpu,
181		rss_enable, tso_ipid_split_en, ig_vlan_strip_en);
182
183	a0 = nic_cfg;
184	a1 = 0;
185
186	return vnic_dev_cmd(fnic->vdev, CMD_NIC_CFG, &a0, &a1, wait);
187}
188
189void fnic_get_res_counts(struct fnic *fnic)
190{
191	fnic->wq_count = vnic_dev_get_res_count(fnic->vdev, RES_TYPE_WQ);
192	fnic->raw_wq_count = 1;
193	fnic->wq_copy_count = fnic->config.wq_copy_count;
194	fnic->rq_count = vnic_dev_get_res_count(fnic->vdev, RES_TYPE_RQ);
195	fnic->cq_count = vnic_dev_get_res_count(fnic->vdev, RES_TYPE_CQ);
196	fnic->intr_count = vnic_dev_get_res_count(fnic->vdev,
197		RES_TYPE_INTR_CTRL);
198
199	dev_info(&fnic->pdev->dev, "vNIC fw resources wq_count: %d\n", fnic->wq_count);
200	dev_info(&fnic->pdev->dev, "vNIC fw resources raw_wq_count: %d\n", fnic->raw_wq_count);
201	dev_info(&fnic->pdev->dev, "vNIC fw resources wq_copy_count: %d\n", fnic->wq_copy_count);
202	dev_info(&fnic->pdev->dev, "vNIC fw resources rq_count: %d\n", fnic->rq_count);
203	dev_info(&fnic->pdev->dev, "vNIC fw resources cq_count: %d\n", fnic->cq_count);
204	dev_info(&fnic->pdev->dev, "vNIC fw resources intr_count: %d\n", fnic->intr_count);
205}
206
207void fnic_free_vnic_resources(struct fnic *fnic)
208{
209	unsigned int i;
210
211	for (i = 0; i < fnic->raw_wq_count; i++)
212		vnic_wq_free(&fnic->wq[i]);
213
214	for (i = 0; i < fnic->wq_copy_count; i++)
215		vnic_wq_copy_free(&fnic->hw_copy_wq[i]);
216
217	for (i = 0; i < fnic->rq_count; i++)
218		vnic_rq_free(&fnic->rq[i]);
219
220	for (i = 0; i < fnic->cq_count; i++)
221		vnic_cq_free(&fnic->cq[i]);
222
223	for (i = 0; i < fnic->intr_count; i++)
224		vnic_intr_free(&fnic->intr[i]);
225}
226
227int fnic_alloc_vnic_resources(struct fnic *fnic)
228{
229	enum vnic_dev_intr_mode intr_mode;
230	unsigned int mask_on_assertion;
231	unsigned int interrupt_offset;
232	unsigned int error_interrupt_enable;
233	unsigned int error_interrupt_offset;
234	unsigned int i, cq_index;
235	unsigned int wq_copy_cq_desc_count;
236	int err;
237
238	intr_mode = vnic_dev_get_intr_mode(fnic->vdev);
239
240	dev_info(&fnic->pdev->dev, "vNIC interrupt mode: %s\n",
241		     intr_mode == VNIC_DEV_INTR_MODE_INTX ? "legacy PCI INTx" :
242		     intr_mode == VNIC_DEV_INTR_MODE_MSI ? "MSI" :
243		     intr_mode == VNIC_DEV_INTR_MODE_MSIX ?
244		     "MSI-X" : "unknown");
245
246	dev_info(&fnic->pdev->dev, "res avail: wq %d cp_wq %d raw_wq %d rq %d",
247			fnic->wq_count, fnic->wq_copy_count,
248			fnic->raw_wq_count, fnic->rq_count);
249
250	dev_info(&fnic->pdev->dev, "res avail: cq %d intr %d cpy-wq desc count %d\n",
251			fnic->cq_count, fnic->intr_count,
252			fnic->config.wq_copy_desc_count);
253
254	/* Allocate Raw WQ used for FCS frames */
255	for (i = 0; i < fnic->raw_wq_count; i++) {
256		err = vnic_wq_alloc(fnic->vdev, &fnic->wq[i], i,
257			fnic->config.wq_enet_desc_count,
258			sizeof(struct wq_enet_desc));
259		if (err)
260			goto err_out_cleanup;
261	}
262
263	/* Allocate Copy WQs used for SCSI IOs */
264	for (i = 0; i < fnic->wq_copy_count; i++) {
265		err = vnic_wq_copy_alloc(fnic->vdev, &fnic->hw_copy_wq[i],
266			(fnic->raw_wq_count + i),
267			fnic->config.wq_copy_desc_count,
268			sizeof(struct fcpio_host_req));
269		if (err)
270			goto err_out_cleanup;
271	}
272
273	/* RQ for receiving FCS frames */
274	for (i = 0; i < fnic->rq_count; i++) {
275		err = vnic_rq_alloc(fnic->vdev, &fnic->rq[i], i,
276			fnic->config.rq_desc_count,
277			sizeof(struct rq_enet_desc));
278		if (err)
279			goto err_out_cleanup;
280	}
281
282	/* CQ for each RQ */
283	for (i = 0; i < fnic->rq_count; i++) {
284		cq_index = i;
285		err = vnic_cq_alloc(fnic->vdev,
286			&fnic->cq[cq_index], cq_index,
287			fnic->config.rq_desc_count,
288			sizeof(struct cq_enet_rq_desc));
289		if (err)
290			goto err_out_cleanup;
291	}
292
293	/* CQ for each WQ */
294	for (i = 0; i < fnic->raw_wq_count; i++) {
295		cq_index = fnic->rq_count + i;
296		err = vnic_cq_alloc(fnic->vdev, &fnic->cq[cq_index], cq_index,
297			fnic->config.wq_enet_desc_count,
298			sizeof(struct cq_enet_wq_desc));
299		if (err)
300			goto err_out_cleanup;
301	}
302
303	/* CQ for each COPY WQ */
304	wq_copy_cq_desc_count = (fnic->config.wq_copy_desc_count * 3);
305	for (i = 0; i < fnic->wq_copy_count; i++) {
306		cq_index = fnic->raw_wq_count + fnic->rq_count + i;
307		err = vnic_cq_alloc(fnic->vdev, &fnic->cq[cq_index],
308			cq_index,
309			wq_copy_cq_desc_count,
310			sizeof(struct fcpio_fw_req));
311		if (err)
312			goto err_out_cleanup;
313	}
314
315	for (i = 0; i < fnic->intr_count; i++) {
316		err = vnic_intr_alloc(fnic->vdev, &fnic->intr[i], i);
317		if (err)
318			goto err_out_cleanup;
319	}
320
321	fnic->legacy_pba = vnic_dev_get_res(fnic->vdev,
322				RES_TYPE_INTR_PBA_LEGACY, 0);
323
324	if (!fnic->legacy_pba && intr_mode == VNIC_DEV_INTR_MODE_INTX) {
325		dev_err(&fnic->pdev->dev, "Failed to hook legacy pba resource\n");
326		err = -ENODEV;
327		goto err_out_cleanup;
328	}
329
330	/*
331	 * Init RQ/WQ resources.
332	 *
333	 * RQ[0 to n-1] point to CQ[0 to n-1]
334	 * WQ[0 to m-1] point to CQ[n to n+m-1]
335	 * WQ_COPY[0 to k-1] points to CQ[n+m to n+m+k-1]
336	 *
337	 * Note for copy wq we always initialize with cq_index = 0
338	 *
339	 * Error interrupt is not enabled for MSI.
340	 */
341
342	switch (intr_mode) {
343	case VNIC_DEV_INTR_MODE_INTX:
344	case VNIC_DEV_INTR_MODE_MSIX:
345		error_interrupt_enable = 1;
346		error_interrupt_offset = fnic->err_intr_offset;
347		break;
348	default:
349		error_interrupt_enable = 0;
350		error_interrupt_offset = 0;
351		break;
352	}
353
354	for (i = 0; i < fnic->rq_count; i++) {
355		cq_index = i;
356		vnic_rq_init(&fnic->rq[i],
357			     cq_index,
358			     error_interrupt_enable,
359			     error_interrupt_offset);
360	}
361
362	for (i = 0; i < fnic->raw_wq_count; i++) {
363		cq_index = i + fnic->rq_count;
364		vnic_wq_init(&fnic->wq[i],
365			     cq_index,
366			     error_interrupt_enable,
367			     error_interrupt_offset);
368	}
369
370	for (i = 0; i < fnic->wq_copy_count; i++) {
371		vnic_wq_copy_init(&fnic->hw_copy_wq[i],
372				  0 /* cq_index 0 - always */,
373				  error_interrupt_enable,
374				  error_interrupt_offset);
375	}
376
377	for (i = 0; i < fnic->cq_count; i++) {
378
379		switch (intr_mode) {
380		case VNIC_DEV_INTR_MODE_MSIX:
381			interrupt_offset = i;
382			break;
383		default:
384			interrupt_offset = 0;
385			break;
386		}
387
388		vnic_cq_init(&fnic->cq[i],
389			0 /* flow_control_enable */,
390			1 /* color_enable */,
391			0 /* cq_head */,
392			0 /* cq_tail */,
393			1 /* cq_tail_color */,
394			1 /* interrupt_enable */,
395			1 /* cq_entry_enable */,
396			0 /* cq_message_enable */,
397			interrupt_offset,
398			0 /* cq_message_addr */);
399	}
400
401	/*
402	 * Init INTR resources
403	 *
404	 * mask_on_assertion is not used for INTx due to the level-
405	 * triggered nature of INTx
406	 */
407
408	switch (intr_mode) {
409	case VNIC_DEV_INTR_MODE_MSI:
410	case VNIC_DEV_INTR_MODE_MSIX:
411		mask_on_assertion = 1;
412		break;
413	default:
414		mask_on_assertion = 0;
415		break;
416	}
417
418	for (i = 0; i < fnic->intr_count; i++) {
419		vnic_intr_init(&fnic->intr[i],
420			fnic->config.intr_timer,
421			fnic->config.intr_timer_type,
422			mask_on_assertion);
423	}
424
425	/* init the stats memory by making the first call here */
426	err = vnic_dev_stats_dump(fnic->vdev, &fnic->stats);
427	if (err) {
428		dev_err(&fnic->pdev->dev, "vnic_dev_stats_dump failed - x%x\n", err);
429		goto err_out_cleanup;
430	}
431
432	/* Clear LIF stats */
433	vnic_dev_stats_clear(fnic->vdev);
434
435	return 0;
436
437err_out_cleanup:
438	fnic_free_vnic_resources(fnic);
439
440	return err;
441}
~/ Read-only file preview.