1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
2 /* QLogic qed NIC Driver
3 * Copyright (c) 2015-2017 QLogic Corporation
4 * Copyright (c) 2019-2020 Marvell International Ltd.
7 #include <linux/types.h>
8 #include <asm/byteorder.h>
10 #include <linux/delay.h>
11 #include <linux/dma-mapping.h>
12 #include <linux/interrupt.h>
13 #include <linux/kernel.h>
14 #include <linux/log2.h>
15 #include <linux/module.h>
16 #include <linux/pci.h>
17 #include <linux/slab.h>
18 #include <linux/stddef.h>
19 #include <linux/string.h>
20 #include <linux/workqueue.h>
21 #include <linux/errno.h>
22 #include <linux/list.h>
23 #include <linux/spinlock.h>
24 #define __PREVENT_DUMP_MEM_ARR__
25 #define __PREVENT_PXP_GLOBAL_WIN__
28 #include "qed_dev_api.h"
33 #include "qed_iro_hsi.h"
36 #include "qed_reg_addr.h"
38 #include "qed_sriov.h"
39 #include <linux/qed/qed_fcoe_if.h>
41 struct qed_fcoe_conn
{
42 struct list_head list_entry
;
50 dma_addr_t sq_pbl_addr
;
51 dma_addr_t sq_curr_page_addr
;
52 dma_addr_t sq_next_page_addr
;
53 dma_addr_t xferq_pbl_addr
;
54 void *xferq_pbl_addr_virt_addr
;
55 dma_addr_t xferq_addr
[4];
56 void *xferq_addr_virt_addr
[4];
57 dma_addr_t confq_pbl_addr
;
58 void *confq_pbl_addr_virt_addr
;
59 dma_addr_t confq_addr
[2];
60 void *confq_addr_virt_addr
[2];
62 dma_addr_t terminate_params
;
71 u16 tx_max_fc_pay_len
;
72 u16 e_d_tov_timer_val
;
73 u16 rec_tov_timer_val
;
74 u16 rx_max_fc_pay_len
;
78 struct fc_addr_nw s_id
;
80 struct fc_addr_nw d_id
;
86 qed_sp_fcoe_func_start(struct qed_hwfn
*p_hwfn
,
87 enum spq_mode comp_mode
,
88 struct qed_spq_comp_cb
*p_comp_addr
)
90 struct qed_fcoe_pf_params
*fcoe_pf_params
= NULL
;
91 struct fcoe_init_ramrod_params
*p_ramrod
= NULL
;
92 struct fcoe_init_func_ramrod_data
*p_data
;
93 struct fcoe_conn_context
*p_cxt
= NULL
;
94 struct qed_spq_entry
*p_ent
= NULL
;
95 struct qed_sp_init_data init_data
;
96 struct qed_cxt_info cxt_info
;
103 memset(&init_data
, 0, sizeof(init_data
));
104 init_data
.cid
= qed_spq_get_cid(p_hwfn
);
105 init_data
.opaque_fid
= p_hwfn
->hw_info
.opaque_fid
;
106 init_data
.comp_mode
= comp_mode
;
107 init_data
.p_comp_data
= p_comp_addr
;
109 rc
= qed_sp_init_request(p_hwfn
, &p_ent
,
110 FCOE_RAMROD_CMD_ID_INIT_FUNC
,
111 PROTOCOLID_FCOE
, &init_data
);
115 p_ramrod
= &p_ent
->ramrod
.fcoe_init
;
116 p_data
= &p_ramrod
->init_ramrod_data
;
117 fcoe_pf_params
= &p_hwfn
->pf_params
.fcoe_pf_params
;
120 if (fcoe_pf_params
->num_cqs
> p_hwfn
->hw_info
.feat_num
[QED_FCOE_CQ
]) {
122 "Cannot satisfy CQ amount. CQs requested %d, CQs available %d. Aborting function start\n",
123 fcoe_pf_params
->num_cqs
,
124 p_hwfn
->hw_info
.feat_num
[QED_FCOE_CQ
]);
129 p_data
->mtu
= cpu_to_le16(fcoe_pf_params
->mtu
);
130 tmp
= cpu_to_le16(fcoe_pf_params
->sq_num_pbl_pages
);
131 p_data
->sq_num_pages_in_pbl
= tmp
;
133 rc
= qed_cxt_acquire_cid(p_hwfn
, PROTOCOLID_FCOE
, &dummy_cid
);
137 cxt_info
.iid
= dummy_cid
;
138 rc
= qed_cxt_get_cid_info(p_hwfn
, &cxt_info
);
140 DP_NOTICE(p_hwfn
, "Cannot find context info for dummy cid=%d\n",
144 p_cxt
= cxt_info
.p_cxt
;
145 memset(p_cxt
, 0, sizeof(*p_cxt
));
147 SET_FIELD(p_cxt
->tstorm_ag_context
.flags3
,
148 TSTORM_FCOE_CONN_AG_CTX_DUMMY_TIMER_CF_EN
, 1);
150 fcoe_pf_params
->dummy_icid
= (u16
)dummy_cid
;
152 tmp
= cpu_to_le16(fcoe_pf_params
->num_tasks
);
153 p_data
->func_params
.num_tasks
= tmp
;
154 p_data
->func_params
.log_page_size
= fcoe_pf_params
->log_page_size
;
155 p_data
->func_params
.debug_mode
= fcoe_pf_params
->debug_mode
;
157 DMA_REGPAIR_LE(p_data
->q_params
.glbl_q_params_addr
,
158 fcoe_pf_params
->glbl_q_params_addr
);
160 tmp
= cpu_to_le16(fcoe_pf_params
->cq_num_entries
);
161 p_data
->q_params
.cq_num_entries
= tmp
;
163 tmp
= cpu_to_le16(fcoe_pf_params
->cmdq_num_entries
);
164 p_data
->q_params
.cmdq_num_entries
= tmp
;
166 p_data
->q_params
.num_queues
= fcoe_pf_params
->num_cqs
;
168 tmp
= (__force __le16
)p_hwfn
->hw_info
.resc_start
[QED_CMDQS_CQS
];
169 p_data
->q_params
.queue_relative_offset
= (__force u8
)tmp
;
171 for (i
= 0; i
< fcoe_pf_params
->num_cqs
; i
++) {
172 tmp
= cpu_to_le16(qed_get_igu_sb_id(p_hwfn
, i
));
173 p_data
->q_params
.cq_cmdq_sb_num_arr
[i
] = tmp
;
176 p_data
->q_params
.cq_sb_pi
= fcoe_pf_params
->gl_rq_pi
;
177 p_data
->q_params
.cmdq_sb_pi
= fcoe_pf_params
->gl_cmd_pi
;
179 p_data
->q_params
.bdq_resource_id
= (u8
)RESC_START(p_hwfn
, QED_BDQ
);
181 DMA_REGPAIR_LE(p_data
->q_params
.bdq_pbl_base_address
[BDQ_ID_RQ
],
182 fcoe_pf_params
->bdq_pbl_base_addr
[BDQ_ID_RQ
]);
183 p_data
->q_params
.bdq_pbl_num_entries
[BDQ_ID_RQ
] =
184 fcoe_pf_params
->bdq_pbl_num_entries
[BDQ_ID_RQ
];
185 tmp
= cpu_to_le16(fcoe_pf_params
->bdq_xoff_threshold
[BDQ_ID_RQ
]);
186 p_data
->q_params
.bdq_xoff_threshold
[BDQ_ID_RQ
] = tmp
;
187 tmp
= cpu_to_le16(fcoe_pf_params
->bdq_xon_threshold
[BDQ_ID_RQ
]);
188 p_data
->q_params
.bdq_xon_threshold
[BDQ_ID_RQ
] = tmp
;
190 DMA_REGPAIR_LE(p_data
->q_params
.bdq_pbl_base_address
[BDQ_ID_IMM_DATA
],
191 fcoe_pf_params
->bdq_pbl_base_addr
[BDQ_ID_IMM_DATA
]);
192 p_data
->q_params
.bdq_pbl_num_entries
[BDQ_ID_IMM_DATA
] =
193 fcoe_pf_params
->bdq_pbl_num_entries
[BDQ_ID_IMM_DATA
];
194 tmp
= cpu_to_le16(fcoe_pf_params
->bdq_xoff_threshold
[BDQ_ID_IMM_DATA
]);
195 p_data
->q_params
.bdq_xoff_threshold
[BDQ_ID_IMM_DATA
] = tmp
;
196 tmp
= cpu_to_le16(fcoe_pf_params
->bdq_xon_threshold
[BDQ_ID_IMM_DATA
]);
197 p_data
->q_params
.bdq_xon_threshold
[BDQ_ID_IMM_DATA
] = tmp
;
198 tmp
= cpu_to_le16(fcoe_pf_params
->rq_buffer_size
);
199 p_data
->q_params
.rq_buffer_size
= tmp
;
201 if (fcoe_pf_params
->is_target
) {
202 SET_FIELD(p_data
->q_params
.q_validity
,
203 SCSI_INIT_FUNC_QUEUES_RQ_VALID
, 1);
204 if (p_data
->q_params
.bdq_pbl_num_entries
[BDQ_ID_IMM_DATA
])
205 SET_FIELD(p_data
->q_params
.q_validity
,
206 SCSI_INIT_FUNC_QUEUES_IMM_DATA_VALID
, 1);
207 SET_FIELD(p_data
->q_params
.q_validity
,
208 SCSI_INIT_FUNC_QUEUES_CMD_VALID
, 1);
210 SET_FIELD(p_data
->q_params
.q_validity
,
211 SCSI_INIT_FUNC_QUEUES_RQ_VALID
, 1);
214 rc
= qed_spq_post(p_hwfn
, p_ent
, NULL
);
219 qed_sp_destroy_request(p_hwfn
, p_ent
);
224 qed_sp_fcoe_conn_offload(struct qed_hwfn
*p_hwfn
,
225 struct qed_fcoe_conn
*p_conn
,
226 enum spq_mode comp_mode
,
227 struct qed_spq_comp_cb
*p_comp_addr
)
229 struct fcoe_conn_offload_ramrod_params
*p_ramrod
= NULL
;
230 struct fcoe_conn_offload_ramrod_data
*p_data
;
231 struct qed_spq_entry
*p_ent
= NULL
;
232 struct qed_sp_init_data init_data
;
238 memset(&init_data
, 0, sizeof(init_data
));
239 init_data
.cid
= p_conn
->icid
;
240 init_data
.opaque_fid
= p_hwfn
->hw_info
.opaque_fid
;
241 init_data
.comp_mode
= comp_mode
;
242 init_data
.p_comp_data
= p_comp_addr
;
244 rc
= qed_sp_init_request(p_hwfn
, &p_ent
,
245 FCOE_RAMROD_CMD_ID_OFFLOAD_CONN
,
246 PROTOCOLID_FCOE
, &init_data
);
250 p_ramrod
= &p_ent
->ramrod
.fcoe_conn_ofld
;
251 p_data
= &p_ramrod
->offload_ramrod_data
;
253 /* Transmission PQ is the first of the PF */
254 physical_q0
= qed_get_cm_pq_idx(p_hwfn
, PQ_FLAGS_OFLD
);
255 p_conn
->physical_q0
= physical_q0
;
256 p_data
->physical_q0
= cpu_to_le16(physical_q0
);
258 p_data
->conn_id
= cpu_to_le16(p_conn
->conn_id
);
259 DMA_REGPAIR_LE(p_data
->sq_pbl_addr
, p_conn
->sq_pbl_addr
);
260 DMA_REGPAIR_LE(p_data
->sq_curr_page_addr
, p_conn
->sq_curr_page_addr
);
261 DMA_REGPAIR_LE(p_data
->sq_next_page_addr
, p_conn
->sq_next_page_addr
);
262 DMA_REGPAIR_LE(p_data
->xferq_pbl_addr
, p_conn
->xferq_pbl_addr
);
263 DMA_REGPAIR_LE(p_data
->xferq_curr_page_addr
, p_conn
->xferq_addr
[0]);
264 DMA_REGPAIR_LE(p_data
->xferq_next_page_addr
, p_conn
->xferq_addr
[1]);
266 DMA_REGPAIR_LE(p_data
->respq_pbl_addr
, p_conn
->confq_pbl_addr
);
267 DMA_REGPAIR_LE(p_data
->respq_curr_page_addr
, p_conn
->confq_addr
[0]);
268 DMA_REGPAIR_LE(p_data
->respq_next_page_addr
, p_conn
->confq_addr
[1]);
270 p_data
->dst_mac_addr_lo
= cpu_to_le16(p_conn
->dst_mac_addr_lo
);
271 p_data
->dst_mac_addr_mid
= cpu_to_le16(p_conn
->dst_mac_addr_mid
);
272 p_data
->dst_mac_addr_hi
= cpu_to_le16(p_conn
->dst_mac_addr_hi
);
273 p_data
->src_mac_addr_lo
= cpu_to_le16(p_conn
->src_mac_addr_lo
);
274 p_data
->src_mac_addr_mid
= cpu_to_le16(p_conn
->src_mac_addr_mid
);
275 p_data
->src_mac_addr_hi
= cpu_to_le16(p_conn
->src_mac_addr_hi
);
277 tmp
= cpu_to_le16(p_conn
->tx_max_fc_pay_len
);
278 p_data
->tx_max_fc_pay_len
= tmp
;
279 tmp
= cpu_to_le16(p_conn
->e_d_tov_timer_val
);
280 p_data
->e_d_tov_timer_val
= tmp
;
281 tmp
= cpu_to_le16(p_conn
->rec_tov_timer_val
);
282 p_data
->rec_rr_tov_timer_val
= tmp
;
283 tmp
= cpu_to_le16(p_conn
->rx_max_fc_pay_len
);
284 p_data
->rx_max_fc_pay_len
= tmp
;
286 p_data
->vlan_tag
= cpu_to_le16(p_conn
->vlan_tag
);
287 p_data
->s_id
.addr_hi
= p_conn
->s_id
.addr_hi
;
288 p_data
->s_id
.addr_mid
= p_conn
->s_id
.addr_mid
;
289 p_data
->s_id
.addr_lo
= p_conn
->s_id
.addr_lo
;
290 p_data
->max_conc_seqs_c3
= p_conn
->max_conc_seqs_c3
;
291 p_data
->d_id
.addr_hi
= p_conn
->d_id
.addr_hi
;
292 p_data
->d_id
.addr_mid
= p_conn
->d_id
.addr_mid
;
293 p_data
->d_id
.addr_lo
= p_conn
->d_id
.addr_lo
;
294 p_data
->flags
= p_conn
->flags
;
295 if (test_bit(QED_MF_UFP_SPECIFIC
, &p_hwfn
->cdev
->mf_bits
))
296 SET_FIELD(p_data
->flags
,
297 FCOE_CONN_OFFLOAD_RAMROD_DATA_B_SINGLE_VLAN
, 1);
298 p_data
->def_q_idx
= p_conn
->def_q_idx
;
300 return qed_spq_post(p_hwfn
, p_ent
, NULL
);
304 qed_sp_fcoe_conn_destroy(struct qed_hwfn
*p_hwfn
,
305 struct qed_fcoe_conn
*p_conn
,
306 enum spq_mode comp_mode
,
307 struct qed_spq_comp_cb
*p_comp_addr
)
309 struct fcoe_conn_terminate_ramrod_params
*p_ramrod
= NULL
;
310 struct qed_spq_entry
*p_ent
= NULL
;
311 struct qed_sp_init_data init_data
;
315 memset(&init_data
, 0, sizeof(init_data
));
316 init_data
.cid
= p_conn
->icid
;
317 init_data
.opaque_fid
= p_hwfn
->hw_info
.opaque_fid
;
318 init_data
.comp_mode
= comp_mode
;
319 init_data
.p_comp_data
= p_comp_addr
;
321 rc
= qed_sp_init_request(p_hwfn
, &p_ent
,
322 FCOE_RAMROD_CMD_ID_TERMINATE_CONN
,
323 PROTOCOLID_FCOE
, &init_data
);
327 p_ramrod
= &p_ent
->ramrod
.fcoe_conn_terminate
;
328 DMA_REGPAIR_LE(p_ramrod
->terminate_ramrod_data
.terminate_params_addr
,
329 p_conn
->terminate_params
);
331 return qed_spq_post(p_hwfn
, p_ent
, NULL
);
335 qed_sp_fcoe_func_stop(struct qed_hwfn
*p_hwfn
,
336 struct qed_ptt
*p_ptt
,
337 enum spq_mode comp_mode
,
338 struct qed_spq_comp_cb
*p_comp_addr
)
340 struct qed_spq_entry
*p_ent
= NULL
;
341 struct qed_sp_init_data init_data
;
346 memset(&init_data
, 0, sizeof(init_data
));
347 init_data
.cid
= p_hwfn
->pf_params
.fcoe_pf_params
.dummy_icid
;
348 init_data
.opaque_fid
= p_hwfn
->hw_info
.opaque_fid
;
349 init_data
.comp_mode
= comp_mode
;
350 init_data
.p_comp_data
= p_comp_addr
;
352 rc
= qed_sp_init_request(p_hwfn
, &p_ent
,
353 FCOE_RAMROD_CMD_ID_DESTROY_FUNC
,
354 PROTOCOLID_FCOE
, &init_data
);
358 active_segs
= qed_rd(p_hwfn
, p_ptt
, TM_REG_PF_ENABLE_TASK
);
359 active_segs
&= ~BIT(QED_CXT_FCOE_TID_SEG
);
360 qed_wr(p_hwfn
, p_ptt
, TM_REG_PF_ENABLE_TASK
, active_segs
);
362 return qed_spq_post(p_hwfn
, p_ent
, NULL
);
366 qed_fcoe_allocate_connection(struct qed_hwfn
*p_hwfn
,
367 struct qed_fcoe_conn
**p_out_conn
)
369 struct qed_fcoe_conn
*p_conn
= NULL
;
373 spin_lock_bh(&p_hwfn
->p_fcoe_info
->lock
);
374 if (!list_empty(&p_hwfn
->p_fcoe_info
->free_list
))
376 list_first_entry(&p_hwfn
->p_fcoe_info
->free_list
,
377 struct qed_fcoe_conn
, list_entry
);
379 list_del(&p_conn
->list_entry
);
380 spin_unlock_bh(&p_hwfn
->p_fcoe_info
->lock
);
381 *p_out_conn
= p_conn
;
384 spin_unlock_bh(&p_hwfn
->p_fcoe_info
->lock
);
386 p_conn
= kzalloc(sizeof(*p_conn
), GFP_KERNEL
);
390 p_addr
= dma_alloc_coherent(&p_hwfn
->cdev
->pdev
->dev
,
392 &p_conn
->xferq_pbl_addr
, GFP_KERNEL
);
394 goto nomem_pbl_xferq
;
395 p_conn
->xferq_pbl_addr_virt_addr
= p_addr
;
397 for (i
= 0; i
< ARRAY_SIZE(p_conn
->xferq_addr
); i
++) {
398 p_addr
= dma_alloc_coherent(&p_hwfn
->cdev
->pdev
->dev
,
400 &p_conn
->xferq_addr
[i
], GFP_KERNEL
);
403 p_conn
->xferq_addr_virt_addr
[i
] = p_addr
;
405 p_addr
= p_conn
->xferq_pbl_addr_virt_addr
;
406 ((dma_addr_t
*)p_addr
)[i
] = p_conn
->xferq_addr
[i
];
409 p_addr
= dma_alloc_coherent(&p_hwfn
->cdev
->pdev
->dev
,
411 &p_conn
->confq_pbl_addr
, GFP_KERNEL
);
414 p_conn
->confq_pbl_addr_virt_addr
= p_addr
;
416 for (i
= 0; i
< ARRAY_SIZE(p_conn
->confq_addr
); i
++) {
417 p_addr
= dma_alloc_coherent(&p_hwfn
->cdev
->pdev
->dev
,
419 &p_conn
->confq_addr
[i
], GFP_KERNEL
);
422 p_conn
->confq_addr_virt_addr
[i
] = p_addr
;
424 p_addr
= p_conn
->confq_pbl_addr_virt_addr
;
425 ((dma_addr_t
*)p_addr
)[i
] = p_conn
->confq_addr
[i
];
428 p_conn
->free_on_delete
= true;
429 *p_out_conn
= p_conn
;
433 dma_free_coherent(&p_hwfn
->cdev
->pdev
->dev
,
435 p_conn
->confq_pbl_addr_virt_addr
,
436 p_conn
->confq_pbl_addr
);
437 for (i
= 0; i
< ARRAY_SIZE(p_conn
->confq_addr
); i
++)
438 if (p_conn
->confq_addr_virt_addr
[i
])
439 dma_free_coherent(&p_hwfn
->cdev
->pdev
->dev
,
441 p_conn
->confq_addr_virt_addr
[i
],
442 p_conn
->confq_addr
[i
]);
444 dma_free_coherent(&p_hwfn
->cdev
->pdev
->dev
,
446 p_conn
->xferq_pbl_addr_virt_addr
,
447 p_conn
->xferq_pbl_addr
);
448 for (i
= 0; i
< ARRAY_SIZE(p_conn
->xferq_addr
); i
++)
449 if (p_conn
->xferq_addr_virt_addr
[i
])
450 dma_free_coherent(&p_hwfn
->cdev
->pdev
->dev
,
452 p_conn
->xferq_addr_virt_addr
[i
],
453 p_conn
->xferq_addr
[i
]);
459 static void qed_fcoe_free_connection(struct qed_hwfn
*p_hwfn
,
460 struct qed_fcoe_conn
*p_conn
)
467 if (p_conn
->confq_pbl_addr_virt_addr
)
468 dma_free_coherent(&p_hwfn
->cdev
->pdev
->dev
,
470 p_conn
->confq_pbl_addr_virt_addr
,
471 p_conn
->confq_pbl_addr
);
473 for (i
= 0; i
< ARRAY_SIZE(p_conn
->confq_addr
); i
++) {
474 if (!p_conn
->confq_addr_virt_addr
[i
])
476 dma_free_coherent(&p_hwfn
->cdev
->pdev
->dev
,
478 p_conn
->confq_addr_virt_addr
[i
],
479 p_conn
->confq_addr
[i
]);
482 if (p_conn
->xferq_pbl_addr_virt_addr
)
483 dma_free_coherent(&p_hwfn
->cdev
->pdev
->dev
,
485 p_conn
->xferq_pbl_addr_virt_addr
,
486 p_conn
->xferq_pbl_addr
);
488 for (i
= 0; i
< ARRAY_SIZE(p_conn
->xferq_addr
); i
++) {
489 if (!p_conn
->xferq_addr_virt_addr
[i
])
491 dma_free_coherent(&p_hwfn
->cdev
->pdev
->dev
,
493 p_conn
->xferq_addr_virt_addr
[i
],
494 p_conn
->xferq_addr
[i
]);
499 static void __iomem
*qed_fcoe_get_db_addr(struct qed_hwfn
*p_hwfn
, u32 cid
)
501 return (u8 __iomem
*)p_hwfn
->doorbells
+
502 qed_db_addr(cid
, DQ_DEMS_LEGACY
);
505 static void __iomem
*qed_fcoe_get_primary_bdq_prod(struct qed_hwfn
*p_hwfn
,
508 if (RESC_NUM(p_hwfn
, QED_BDQ
)) {
509 return (u8 __iomem
*)p_hwfn
->regview
+
510 GET_GTT_BDQ_REG_ADDR(GTT_BAR0_MAP_REG_MSDM_RAM
,
511 MSTORM_SCSI_BDQ_EXT_PROD
,
512 RESC_START(p_hwfn
, QED_BDQ
), bdq_id
);
514 DP_NOTICE(p_hwfn
, "BDQ is not allocated!\n");
519 static void __iomem
*qed_fcoe_get_secondary_bdq_prod(struct qed_hwfn
*p_hwfn
,
522 if (RESC_NUM(p_hwfn
, QED_BDQ
)) {
523 return (u8 __iomem
*)p_hwfn
->regview
+
524 GET_GTT_BDQ_REG_ADDR(GTT_BAR0_MAP_REG_TSDM_RAM
,
525 TSTORM_SCSI_BDQ_EXT_PROD
,
526 RESC_START(p_hwfn
, QED_BDQ
), bdq_id
);
528 DP_NOTICE(p_hwfn
, "BDQ is not allocated!\n");
533 int qed_fcoe_alloc(struct qed_hwfn
*p_hwfn
)
535 struct qed_fcoe_info
*p_fcoe_info
;
537 /* Allocate LL2's set struct */
538 p_fcoe_info
= kzalloc(sizeof(*p_fcoe_info
), GFP_KERNEL
);
540 DP_NOTICE(p_hwfn
, "Failed to allocate qed_fcoe_info'\n");
543 INIT_LIST_HEAD(&p_fcoe_info
->free_list
);
545 p_hwfn
->p_fcoe_info
= p_fcoe_info
;
549 void qed_fcoe_setup(struct qed_hwfn
*p_hwfn
)
551 struct fcoe_task_context
*p_task_ctx
= NULL
;
555 spin_lock_init(&p_hwfn
->p_fcoe_info
->lock
);
556 for (i
= 0; i
< p_hwfn
->pf_params
.fcoe_pf_params
.num_tasks
; i
++) {
557 rc
= qed_cxt_get_task_ctx(p_hwfn
, i
,
559 (void **)&p_task_ctx
);
563 memset(p_task_ctx
, 0, sizeof(struct fcoe_task_context
));
566 SET_FIELD(lc
, TIMERS_CONTEXT_VALIDLC0
, 1);
567 p_task_ctx
->timer_context
.logical_client_0
= cpu_to_le32(lc
);
570 SET_FIELD(lc
, TIMERS_CONTEXT_VALIDLC1
, 1);
571 p_task_ctx
->timer_context
.logical_client_1
= cpu_to_le32(lc
);
573 SET_FIELD(p_task_ctx
->tstorm_ag_context
.flags0
,
574 TSTORM_FCOE_TASK_AG_CTX_CONNECTION_TYPE
, 1);
578 void qed_fcoe_free(struct qed_hwfn
*p_hwfn
)
580 struct qed_fcoe_conn
*p_conn
= NULL
;
582 if (!p_hwfn
->p_fcoe_info
)
585 while (!list_empty(&p_hwfn
->p_fcoe_info
->free_list
)) {
586 p_conn
= list_first_entry(&p_hwfn
->p_fcoe_info
->free_list
,
587 struct qed_fcoe_conn
, list_entry
);
590 list_del(&p_conn
->list_entry
);
591 qed_fcoe_free_connection(p_hwfn
, p_conn
);
594 kfree(p_hwfn
->p_fcoe_info
);
595 p_hwfn
->p_fcoe_info
= NULL
;
599 qed_fcoe_acquire_connection(struct qed_hwfn
*p_hwfn
,
600 struct qed_fcoe_conn
*p_in_conn
,
601 struct qed_fcoe_conn
**p_out_conn
)
603 struct qed_fcoe_conn
*p_conn
= NULL
;
607 spin_lock_bh(&p_hwfn
->p_fcoe_info
->lock
);
608 rc
= qed_cxt_acquire_cid(p_hwfn
, PROTOCOLID_FCOE
, &icid
);
609 spin_unlock_bh(&p_hwfn
->p_fcoe_info
->lock
);
613 /* Use input connection [if provided] or allocate a new one */
617 rc
= qed_fcoe_allocate_connection(p_hwfn
, &p_conn
);
619 spin_lock_bh(&p_hwfn
->p_fcoe_info
->lock
);
620 qed_cxt_release_cid(p_hwfn
, icid
);
621 spin_unlock_bh(&p_hwfn
->p_fcoe_info
->lock
);
627 p_conn
->fw_cid
= (p_hwfn
->hw_info
.opaque_fid
<< 16) | icid
;
628 *p_out_conn
= p_conn
;
633 static void qed_fcoe_release_connection(struct qed_hwfn
*p_hwfn
,
634 struct qed_fcoe_conn
*p_conn
)
636 spin_lock_bh(&p_hwfn
->p_fcoe_info
->lock
);
637 list_add_tail(&p_conn
->list_entry
, &p_hwfn
->p_fcoe_info
->free_list
);
638 qed_cxt_release_cid(p_hwfn
, p_conn
->icid
);
639 spin_unlock_bh(&p_hwfn
->p_fcoe_info
->lock
);
642 static void _qed_fcoe_get_tstats(struct qed_hwfn
*p_hwfn
,
643 struct qed_ptt
*p_ptt
,
644 struct qed_fcoe_stats
*p_stats
)
646 struct fcoe_rx_stat tstats
;
649 memset(&tstats
, 0, sizeof(tstats
));
650 tstats_addr
= BAR0_MAP_REG_TSDM_RAM
+
651 TSTORM_FCOE_RX_STATS_OFFSET(p_hwfn
->rel_pf_id
);
652 qed_memcpy_from(p_hwfn
, p_ptt
, &tstats
, tstats_addr
, sizeof(tstats
));
654 p_stats
->fcoe_rx_byte_cnt
= HILO_64_REGPAIR(tstats
.fcoe_rx_byte_cnt
);
655 p_stats
->fcoe_rx_data_pkt_cnt
=
656 HILO_64_REGPAIR(tstats
.fcoe_rx_data_pkt_cnt
);
657 p_stats
->fcoe_rx_xfer_pkt_cnt
=
658 HILO_64_REGPAIR(tstats
.fcoe_rx_xfer_pkt_cnt
);
659 p_stats
->fcoe_rx_other_pkt_cnt
=
660 HILO_64_REGPAIR(tstats
.fcoe_rx_other_pkt_cnt
);
662 p_stats
->fcoe_silent_drop_pkt_cmdq_full_cnt
=
663 le32_to_cpu(tstats
.fcoe_silent_drop_pkt_cmdq_full_cnt
);
664 p_stats
->fcoe_silent_drop_pkt_rq_full_cnt
=
665 le32_to_cpu(tstats
.fcoe_silent_drop_pkt_rq_full_cnt
);
666 p_stats
->fcoe_silent_drop_pkt_crc_error_cnt
=
667 le32_to_cpu(tstats
.fcoe_silent_drop_pkt_crc_error_cnt
);
668 p_stats
->fcoe_silent_drop_pkt_task_invalid_cnt
=
669 le32_to_cpu(tstats
.fcoe_silent_drop_pkt_task_invalid_cnt
);
670 p_stats
->fcoe_silent_drop_total_pkt_cnt
=
671 le32_to_cpu(tstats
.fcoe_silent_drop_total_pkt_cnt
);
674 static void _qed_fcoe_get_pstats(struct qed_hwfn
*p_hwfn
,
675 struct qed_ptt
*p_ptt
,
676 struct qed_fcoe_stats
*p_stats
)
678 struct fcoe_tx_stat pstats
;
681 memset(&pstats
, 0, sizeof(pstats
));
682 pstats_addr
= BAR0_MAP_REG_PSDM_RAM
+
683 PSTORM_FCOE_TX_STATS_OFFSET(p_hwfn
->rel_pf_id
);
684 qed_memcpy_from(p_hwfn
, p_ptt
, &pstats
, pstats_addr
, sizeof(pstats
));
686 p_stats
->fcoe_tx_byte_cnt
= HILO_64_REGPAIR(pstats
.fcoe_tx_byte_cnt
);
687 p_stats
->fcoe_tx_data_pkt_cnt
=
688 HILO_64_REGPAIR(pstats
.fcoe_tx_data_pkt_cnt
);
689 p_stats
->fcoe_tx_xfer_pkt_cnt
=
690 HILO_64_REGPAIR(pstats
.fcoe_tx_xfer_pkt_cnt
);
691 p_stats
->fcoe_tx_other_pkt_cnt
=
692 HILO_64_REGPAIR(pstats
.fcoe_tx_other_pkt_cnt
);
695 static int qed_fcoe_get_stats(struct qed_hwfn
*p_hwfn
,
696 struct qed_fcoe_stats
*p_stats
,
699 struct qed_ptt
*p_ptt
;
701 memset(p_stats
, 0, sizeof(*p_stats
));
703 p_ptt
= qed_ptt_acquire_context(p_hwfn
, is_atomic
);
706 DP_ERR(p_hwfn
, "Failed to acquire ptt\n");
710 _qed_fcoe_get_tstats(p_hwfn
, p_ptt
, p_stats
);
711 _qed_fcoe_get_pstats(p_hwfn
, p_ptt
, p_stats
);
713 qed_ptt_release(p_hwfn
, p_ptt
);
718 struct qed_hash_fcoe_con
{
719 struct hlist_node node
;
720 struct qed_fcoe_conn
*con
;
723 static int qed_fill_fcoe_dev_info(struct qed_dev
*cdev
,
724 struct qed_dev_fcoe_info
*info
)
726 struct qed_hwfn
*hwfn
= QED_AFFIN_HWFN(cdev
);
729 memset(info
, 0, sizeof(*info
));
730 rc
= qed_fill_dev_info(cdev
, &info
->common
);
732 info
->primary_dbq_rq_addr
=
733 qed_fcoe_get_primary_bdq_prod(hwfn
, BDQ_ID_RQ
);
734 info
->secondary_bdq_rq_addr
=
735 qed_fcoe_get_secondary_bdq_prod(hwfn
, BDQ_ID_RQ
);
737 info
->wwpn
= hwfn
->mcp_info
->func_info
.wwn_port
;
738 info
->wwnn
= hwfn
->mcp_info
->func_info
.wwn_node
;
740 info
->num_cqs
= FEAT_NUM(hwfn
, QED_FCOE_CQ
);
745 static void qed_register_fcoe_ops(struct qed_dev
*cdev
,
746 struct qed_fcoe_cb_ops
*ops
, void *cookie
)
748 cdev
->protocol_ops
.fcoe
= ops
;
749 cdev
->ops_cookie
= cookie
;
752 static struct qed_hash_fcoe_con
*qed_fcoe_get_hash(struct qed_dev
*cdev
,
755 struct qed_hash_fcoe_con
*hash_con
= NULL
;
757 if (!(cdev
->flags
& QED_FLAG_STORAGE_STARTED
))
760 hash_for_each_possible(cdev
->connections
, hash_con
, node
, handle
) {
761 if (hash_con
->con
->icid
== handle
)
765 if (!hash_con
|| (hash_con
->con
->icid
!= handle
))
771 static int qed_fcoe_stop(struct qed_dev
*cdev
)
773 struct qed_ptt
*p_ptt
;
776 if (!(cdev
->flags
& QED_FLAG_STORAGE_STARTED
)) {
777 DP_NOTICE(cdev
, "fcoe already stopped\n");
781 if (!hash_empty(cdev
->connections
)) {
783 "Can't stop fcoe - not all connections were returned\n");
787 p_ptt
= qed_ptt_acquire(QED_AFFIN_HWFN(cdev
));
792 rc
= qed_sp_fcoe_func_stop(QED_AFFIN_HWFN(cdev
), p_ptt
,
793 QED_SPQ_MODE_EBLOCK
, NULL
);
794 cdev
->flags
&= ~QED_FLAG_STORAGE_STARTED
;
795 qed_ptt_release(QED_AFFIN_HWFN(cdev
), p_ptt
);
800 static int qed_fcoe_start(struct qed_dev
*cdev
, struct qed_fcoe_tid
*tasks
)
804 if (cdev
->flags
& QED_FLAG_STORAGE_STARTED
) {
805 DP_NOTICE(cdev
, "fcoe already started;\n");
809 rc
= qed_sp_fcoe_func_start(QED_AFFIN_HWFN(cdev
), QED_SPQ_MODE_EBLOCK
,
812 DP_NOTICE(cdev
, "Failed to start fcoe\n");
816 cdev
->flags
|= QED_FLAG_STORAGE_STARTED
;
817 hash_init(cdev
->connections
);
820 struct qed_tid_mem
*tid_info
= kzalloc(sizeof(*tid_info
),
825 "Failed to allocate tasks information\n");
830 rc
= qed_cxt_get_tid_mem_info(QED_AFFIN_HWFN(cdev
), tid_info
);
832 DP_NOTICE(cdev
, "Failed to gather task information\n");
838 /* Fill task information */
839 tasks
->size
= tid_info
->tid_size
;
840 tasks
->num_tids_per_block
= tid_info
->num_tids_per_block
;
841 memcpy(tasks
->blocks
, tid_info
->blocks
,
842 MAX_TID_BLOCKS_FCOE
* sizeof(u8
*));
850 static int qed_fcoe_acquire_conn(struct qed_dev
*cdev
,
852 u32
*fw_cid
, void __iomem
**p_doorbell
)
854 struct qed_hash_fcoe_con
*hash_con
;
857 /* Allocate a hashed connection */
858 hash_con
= kzalloc(sizeof(*hash_con
), GFP_KERNEL
);
860 DP_NOTICE(cdev
, "Failed to allocate hashed connection\n");
864 /* Acquire the connection */
865 rc
= qed_fcoe_acquire_connection(QED_AFFIN_HWFN(cdev
), NULL
,
868 DP_NOTICE(cdev
, "Failed to acquire Connection\n");
873 /* Added the connection to hash table */
874 *handle
= hash_con
->con
->icid
;
875 *fw_cid
= hash_con
->con
->fw_cid
;
876 hash_add(cdev
->connections
, &hash_con
->node
, *handle
);
879 *p_doorbell
= qed_fcoe_get_db_addr(QED_AFFIN_HWFN(cdev
),
885 static int qed_fcoe_release_conn(struct qed_dev
*cdev
, u32 handle
)
887 struct qed_hash_fcoe_con
*hash_con
;
889 hash_con
= qed_fcoe_get_hash(cdev
, handle
);
891 DP_NOTICE(cdev
, "Failed to find connection for handle %d\n",
896 hlist_del(&hash_con
->node
);
897 qed_fcoe_release_connection(QED_AFFIN_HWFN(cdev
), hash_con
->con
);
903 static int qed_fcoe_offload_conn(struct qed_dev
*cdev
,
905 struct qed_fcoe_params_offload
*conn_info
)
907 struct qed_hash_fcoe_con
*hash_con
;
908 struct qed_fcoe_conn
*con
;
910 hash_con
= qed_fcoe_get_hash(cdev
, handle
);
912 DP_NOTICE(cdev
, "Failed to find connection for handle %d\n",
917 /* Update the connection with information from the params */
920 con
->sq_pbl_addr
= conn_info
->sq_pbl_addr
;
921 con
->sq_curr_page_addr
= conn_info
->sq_curr_page_addr
;
922 con
->sq_next_page_addr
= conn_info
->sq_next_page_addr
;
923 con
->tx_max_fc_pay_len
= conn_info
->tx_max_fc_pay_len
;
924 con
->e_d_tov_timer_val
= conn_info
->e_d_tov_timer_val
;
925 con
->rec_tov_timer_val
= conn_info
->rec_tov_timer_val
;
926 con
->rx_max_fc_pay_len
= conn_info
->rx_max_fc_pay_len
;
927 con
->vlan_tag
= conn_info
->vlan_tag
;
928 con
->max_conc_seqs_c3
= conn_info
->max_conc_seqs_c3
;
929 con
->flags
= conn_info
->flags
;
930 con
->def_q_idx
= conn_info
->def_q_idx
;
932 con
->src_mac_addr_hi
= (conn_info
->src_mac
[5] << 8) |
933 conn_info
->src_mac
[4];
934 con
->src_mac_addr_mid
= (conn_info
->src_mac
[3] << 8) |
935 conn_info
->src_mac
[2];
936 con
->src_mac_addr_lo
= (conn_info
->src_mac
[1] << 8) |
937 conn_info
->src_mac
[0];
938 con
->dst_mac_addr_hi
= (conn_info
->dst_mac
[5] << 8) |
939 conn_info
->dst_mac
[4];
940 con
->dst_mac_addr_mid
= (conn_info
->dst_mac
[3] << 8) |
941 conn_info
->dst_mac
[2];
942 con
->dst_mac_addr_lo
= (conn_info
->dst_mac
[1] << 8) |
943 conn_info
->dst_mac
[0];
945 con
->s_id
.addr_hi
= conn_info
->s_id
.addr_hi
;
946 con
->s_id
.addr_mid
= conn_info
->s_id
.addr_mid
;
947 con
->s_id
.addr_lo
= conn_info
->s_id
.addr_lo
;
948 con
->d_id
.addr_hi
= conn_info
->d_id
.addr_hi
;
949 con
->d_id
.addr_mid
= conn_info
->d_id
.addr_mid
;
950 con
->d_id
.addr_lo
= conn_info
->d_id
.addr_lo
;
952 return qed_sp_fcoe_conn_offload(QED_AFFIN_HWFN(cdev
), con
,
953 QED_SPQ_MODE_EBLOCK
, NULL
);
956 static int qed_fcoe_destroy_conn(struct qed_dev
*cdev
,
957 u32 handle
, dma_addr_t terminate_params
)
959 struct qed_hash_fcoe_con
*hash_con
;
960 struct qed_fcoe_conn
*con
;
962 hash_con
= qed_fcoe_get_hash(cdev
, handle
);
964 DP_NOTICE(cdev
, "Failed to find connection for handle %d\n",
969 /* Update the connection with information from the params */
971 con
->terminate_params
= terminate_params
;
973 return qed_sp_fcoe_conn_destroy(QED_AFFIN_HWFN(cdev
), con
,
974 QED_SPQ_MODE_EBLOCK
, NULL
);
977 static int qed_fcoe_stats_context(struct qed_dev
*cdev
,
978 struct qed_fcoe_stats
*stats
,
981 return qed_fcoe_get_stats(QED_AFFIN_HWFN(cdev
), stats
, is_atomic
);
984 static int qed_fcoe_stats(struct qed_dev
*cdev
, struct qed_fcoe_stats
*stats
)
986 return qed_fcoe_stats_context(cdev
, stats
, false);
989 void qed_get_protocol_stats_fcoe(struct qed_dev
*cdev
,
990 struct qed_mcp_fcoe_stats
*stats
,
993 struct qed_fcoe_stats proto_stats
;
995 /* Retrieve FW statistics */
996 memset(&proto_stats
, 0, sizeof(proto_stats
));
997 if (qed_fcoe_stats_context(cdev
, &proto_stats
, is_atomic
)) {
998 DP_VERBOSE(cdev
, QED_MSG_STORAGE
,
999 "Failed to collect FCoE statistics\n");
1003 /* Translate FW statistics into struct */
1004 stats
->rx_pkts
= proto_stats
.fcoe_rx_data_pkt_cnt
+
1005 proto_stats
.fcoe_rx_xfer_pkt_cnt
+
1006 proto_stats
.fcoe_rx_other_pkt_cnt
;
1007 stats
->tx_pkts
= proto_stats
.fcoe_tx_data_pkt_cnt
+
1008 proto_stats
.fcoe_tx_xfer_pkt_cnt
+
1009 proto_stats
.fcoe_tx_other_pkt_cnt
;
1010 stats
->fcs_err
= proto_stats
.fcoe_silent_drop_pkt_crc_error_cnt
;
1012 /* Request protocol driver to fill-in the rest */
1013 if (cdev
->protocol_ops
.fcoe
&& cdev
->ops_cookie
) {
1014 struct qed_fcoe_cb_ops
*ops
= cdev
->protocol_ops
.fcoe
;
1015 void *cookie
= cdev
->ops_cookie
;
1017 if (ops
->get_login_failures
)
1018 stats
->login_failure
= ops
->get_login_failures(cookie
);
1022 static const struct qed_fcoe_ops qed_fcoe_ops_pass
= {
1023 .common
= &qed_common_ops_pass
,
1024 .ll2
= &qed_ll2_ops_pass
,
1025 .fill_dev_info
= &qed_fill_fcoe_dev_info
,
1026 .start
= &qed_fcoe_start
,
1027 .stop
= &qed_fcoe_stop
,
1028 .register_ops
= &qed_register_fcoe_ops
,
1029 .acquire_conn
= &qed_fcoe_acquire_conn
,
1030 .release_conn
= &qed_fcoe_release_conn
,
1031 .offload_conn
= &qed_fcoe_offload_conn
,
1032 .destroy_conn
= &qed_fcoe_destroy_conn
,
1033 .get_stats
= &qed_fcoe_stats
,
1036 const struct qed_fcoe_ops
*qed_get_fcoe_ops(void)
1038 return &qed_fcoe_ops_pass
;
1040 EXPORT_SYMBOL(qed_get_fcoe_ops
);
1042 void qed_put_fcoe_ops(void)
1045 EXPORT_SYMBOL(qed_put_fcoe_ops
);