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