1 /* QLogic qed NIC Driver
2 * Copyright (c) 2015-2017 QLogic Corporation
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and /or other materials
21 * provided with the distribution.
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33 #include <linux/types.h>
34 #include <asm/byteorder.h>
35 #include <asm/param.h>
36 #include <linux/delay.h>
37 #include <linux/dma-mapping.h>
38 #include <linux/interrupt.h>
39 #include <linux/kernel.h>
40 #include <linux/log2.h>
41 #include <linux/module.h>
42 #include <linux/pci.h>
43 #include <linux/slab.h>
44 #include <linux/stddef.h>
45 #include <linux/string.h>
46 #include <linux/workqueue.h>
47 #include <linux/errno.h>
48 #include <linux/list.h>
49 #include <linux/spinlock.h>
50 #define __PREVENT_DUMP_MEM_ARR__
51 #define __PREVENT_PXP_GLOBAL_WIN__
54 #include "qed_dev_api.h"
61 #include "qed_reg_addr.h"
63 #include "qed_sriov.h"
64 #include <linux/qed/qed_fcoe_if.h>
66 struct qed_fcoe_conn
{
67 struct list_head list_entry
;
75 dma_addr_t sq_pbl_addr
;
76 dma_addr_t sq_curr_page_addr
;
77 dma_addr_t sq_next_page_addr
;
78 dma_addr_t xferq_pbl_addr
;
79 void *xferq_pbl_addr_virt_addr
;
80 dma_addr_t xferq_addr
[4];
81 void *xferq_addr_virt_addr
[4];
82 dma_addr_t confq_pbl_addr
;
83 void *confq_pbl_addr_virt_addr
;
84 dma_addr_t confq_addr
[2];
85 void *confq_addr_virt_addr
[2];
87 dma_addr_t terminate_params
;
96 u16 tx_max_fc_pay_len
;
97 u16 e_d_tov_timer_val
;
98 u16 rec_tov_timer_val
;
99 u16 rx_max_fc_pay_len
;
103 struct fc_addr_nw s_id
;
105 struct fc_addr_nw d_id
;
111 qed_sp_fcoe_func_start(struct qed_hwfn
*p_hwfn
,
112 enum spq_mode comp_mode
,
113 struct qed_spq_comp_cb
*p_comp_addr
)
115 struct qed_fcoe_pf_params
*fcoe_pf_params
= NULL
;
116 struct fcoe_init_ramrod_params
*p_ramrod
= NULL
;
117 struct fcoe_init_func_ramrod_data
*p_data
;
118 struct e4_fcoe_conn_context
*p_cxt
= NULL
;
119 struct qed_spq_entry
*p_ent
= NULL
;
120 struct qed_sp_init_data init_data
;
121 struct qed_cxt_info cxt_info
;
128 memset(&init_data
, 0, sizeof(init_data
));
129 init_data
.cid
= qed_spq_get_cid(p_hwfn
);
130 init_data
.opaque_fid
= p_hwfn
->hw_info
.opaque_fid
;
131 init_data
.comp_mode
= comp_mode
;
132 init_data
.p_comp_data
= p_comp_addr
;
134 rc
= qed_sp_init_request(p_hwfn
, &p_ent
,
135 FCOE_RAMROD_CMD_ID_INIT_FUNC
,
136 PROTOCOLID_FCOE
, &init_data
);
140 p_ramrod
= &p_ent
->ramrod
.fcoe_init
;
141 p_data
= &p_ramrod
->init_ramrod_data
;
142 fcoe_pf_params
= &p_hwfn
->pf_params
.fcoe_pf_params
;
145 if (fcoe_pf_params
->num_cqs
> p_hwfn
->hw_info
.feat_num
[QED_FCOE_CQ
]) {
147 "Cannot satisfy CQ amount. CQs requested %d, CQs available %d. Aborting function start\n",
148 fcoe_pf_params
->num_cqs
,
149 p_hwfn
->hw_info
.feat_num
[QED_FCOE_CQ
]);
153 p_data
->mtu
= cpu_to_le16(fcoe_pf_params
->mtu
);
154 tmp
= cpu_to_le16(fcoe_pf_params
->sq_num_pbl_pages
);
155 p_data
->sq_num_pages_in_pbl
= tmp
;
157 rc
= qed_cxt_acquire_cid(p_hwfn
, PROTOCOLID_FCOE
, &dummy_cid
);
161 cxt_info
.iid
= dummy_cid
;
162 rc
= qed_cxt_get_cid_info(p_hwfn
, &cxt_info
);
164 DP_NOTICE(p_hwfn
, "Cannot find context info for dummy cid=%d\n",
168 p_cxt
= cxt_info
.p_cxt
;
169 SET_FIELD(p_cxt
->tstorm_ag_context
.flags3
,
170 E4_TSTORM_FCOE_CONN_AG_CTX_DUMMY_TIMER_CF_EN
, 1);
172 fcoe_pf_params
->dummy_icid
= (u16
)dummy_cid
;
174 tmp
= cpu_to_le16(fcoe_pf_params
->num_tasks
);
175 p_data
->func_params
.num_tasks
= tmp
;
176 p_data
->func_params
.log_page_size
= fcoe_pf_params
->log_page_size
;
177 p_data
->func_params
.debug_mode
= fcoe_pf_params
->debug_mode
;
179 DMA_REGPAIR_LE(p_data
->q_params
.glbl_q_params_addr
,
180 fcoe_pf_params
->glbl_q_params_addr
);
182 tmp
= cpu_to_le16(fcoe_pf_params
->cq_num_entries
);
183 p_data
->q_params
.cq_num_entries
= tmp
;
185 tmp
= cpu_to_le16(fcoe_pf_params
->cmdq_num_entries
);
186 p_data
->q_params
.cmdq_num_entries
= tmp
;
188 tmp
= fcoe_pf_params
->num_cqs
;
189 p_data
->q_params
.num_queues
= (u8
)tmp
;
191 tmp
= (u16
)p_hwfn
->hw_info
.resc_start
[QED_CMDQS_CQS
];
192 p_data
->q_params
.queue_relative_offset
= (u8
)tmp
;
194 for (i
= 0; i
< fcoe_pf_params
->num_cqs
; i
++) {
197 igu_sb_id
= qed_get_igu_sb_id(p_hwfn
, i
);
198 tmp
= cpu_to_le16(igu_sb_id
);
199 p_data
->q_params
.cq_cmdq_sb_num_arr
[i
] = tmp
;
202 p_data
->q_params
.cq_sb_pi
= fcoe_pf_params
->gl_rq_pi
;
203 p_data
->q_params
.cmdq_sb_pi
= fcoe_pf_params
->gl_cmd_pi
;
205 p_data
->q_params
.bdq_resource_id
= (u8
)RESC_START(p_hwfn
, QED_BDQ
);
207 DMA_REGPAIR_LE(p_data
->q_params
.bdq_pbl_base_address
[BDQ_ID_RQ
],
208 fcoe_pf_params
->bdq_pbl_base_addr
[BDQ_ID_RQ
]);
209 p_data
->q_params
.bdq_pbl_num_entries
[BDQ_ID_RQ
] =
210 fcoe_pf_params
->bdq_pbl_num_entries
[BDQ_ID_RQ
];
211 tmp
= fcoe_pf_params
->bdq_xoff_threshold
[BDQ_ID_RQ
];
212 p_data
->q_params
.bdq_xoff_threshold
[BDQ_ID_RQ
] = cpu_to_le16(tmp
);
213 tmp
= fcoe_pf_params
->bdq_xon_threshold
[BDQ_ID_RQ
];
214 p_data
->q_params
.bdq_xon_threshold
[BDQ_ID_RQ
] = cpu_to_le16(tmp
);
216 DMA_REGPAIR_LE(p_data
->q_params
.bdq_pbl_base_address
[BDQ_ID_IMM_DATA
],
217 fcoe_pf_params
->bdq_pbl_base_addr
[BDQ_ID_IMM_DATA
]);
218 p_data
->q_params
.bdq_pbl_num_entries
[BDQ_ID_IMM_DATA
] =
219 fcoe_pf_params
->bdq_pbl_num_entries
[BDQ_ID_IMM_DATA
];
220 tmp
= fcoe_pf_params
->bdq_xoff_threshold
[BDQ_ID_IMM_DATA
];
221 p_data
->q_params
.bdq_xoff_threshold
[BDQ_ID_IMM_DATA
] = cpu_to_le16(tmp
);
222 tmp
= fcoe_pf_params
->bdq_xon_threshold
[BDQ_ID_IMM_DATA
];
223 p_data
->q_params
.bdq_xon_threshold
[BDQ_ID_IMM_DATA
] = cpu_to_le16(tmp
);
224 tmp
= fcoe_pf_params
->rq_buffer_size
;
225 p_data
->q_params
.rq_buffer_size
= cpu_to_le16(tmp
);
227 if (fcoe_pf_params
->is_target
) {
228 SET_FIELD(p_data
->q_params
.q_validity
,
229 SCSI_INIT_FUNC_QUEUES_RQ_VALID
, 1);
230 if (p_data
->q_params
.bdq_pbl_num_entries
[BDQ_ID_IMM_DATA
])
231 SET_FIELD(p_data
->q_params
.q_validity
,
232 SCSI_INIT_FUNC_QUEUES_IMM_DATA_VALID
, 1);
233 SET_FIELD(p_data
->q_params
.q_validity
,
234 SCSI_INIT_FUNC_QUEUES_CMD_VALID
, 1);
236 SET_FIELD(p_data
->q_params
.q_validity
,
237 SCSI_INIT_FUNC_QUEUES_RQ_VALID
, 1);
240 rc
= qed_spq_post(p_hwfn
, p_ent
, NULL
);
246 qed_sp_fcoe_conn_offload(struct qed_hwfn
*p_hwfn
,
247 struct qed_fcoe_conn
*p_conn
,
248 enum spq_mode comp_mode
,
249 struct qed_spq_comp_cb
*p_comp_addr
)
251 struct fcoe_conn_offload_ramrod_params
*p_ramrod
= NULL
;
252 struct fcoe_conn_offload_ramrod_data
*p_data
;
253 struct qed_spq_entry
*p_ent
= NULL
;
254 struct qed_sp_init_data init_data
;
255 u16 physical_q0
, tmp
;
259 memset(&init_data
, 0, sizeof(init_data
));
260 init_data
.cid
= p_conn
->icid
;
261 init_data
.opaque_fid
= p_hwfn
->hw_info
.opaque_fid
;
262 init_data
.comp_mode
= comp_mode
;
263 init_data
.p_comp_data
= p_comp_addr
;
265 rc
= qed_sp_init_request(p_hwfn
, &p_ent
,
266 FCOE_RAMROD_CMD_ID_OFFLOAD_CONN
,
267 PROTOCOLID_FCOE
, &init_data
);
271 p_ramrod
= &p_ent
->ramrod
.fcoe_conn_ofld
;
272 p_data
= &p_ramrod
->offload_ramrod_data
;
274 /* Transmission PQ is the first of the PF */
275 physical_q0
= qed_get_cm_pq_idx(p_hwfn
, PQ_FLAGS_OFLD
);
276 p_conn
->physical_q0
= cpu_to_le16(physical_q0
);
277 p_data
->physical_q0
= cpu_to_le16(physical_q0
);
279 p_data
->conn_id
= cpu_to_le16(p_conn
->conn_id
);
280 DMA_REGPAIR_LE(p_data
->sq_pbl_addr
, p_conn
->sq_pbl_addr
);
281 DMA_REGPAIR_LE(p_data
->sq_curr_page_addr
, p_conn
->sq_curr_page_addr
);
282 DMA_REGPAIR_LE(p_data
->sq_next_page_addr
, p_conn
->sq_next_page_addr
);
283 DMA_REGPAIR_LE(p_data
->xferq_pbl_addr
, p_conn
->xferq_pbl_addr
);
284 DMA_REGPAIR_LE(p_data
->xferq_curr_page_addr
, p_conn
->xferq_addr
[0]);
285 DMA_REGPAIR_LE(p_data
->xferq_next_page_addr
, p_conn
->xferq_addr
[1]);
287 DMA_REGPAIR_LE(p_data
->respq_pbl_addr
, p_conn
->confq_pbl_addr
);
288 DMA_REGPAIR_LE(p_data
->respq_curr_page_addr
, p_conn
->confq_addr
[0]);
289 DMA_REGPAIR_LE(p_data
->respq_next_page_addr
, p_conn
->confq_addr
[1]);
291 p_data
->dst_mac_addr_lo
= cpu_to_le16(p_conn
->dst_mac_addr_lo
);
292 p_data
->dst_mac_addr_mid
= cpu_to_le16(p_conn
->dst_mac_addr_mid
);
293 p_data
->dst_mac_addr_hi
= cpu_to_le16(p_conn
->dst_mac_addr_hi
);
294 p_data
->src_mac_addr_lo
= cpu_to_le16(p_conn
->src_mac_addr_lo
);
295 p_data
->src_mac_addr_mid
= cpu_to_le16(p_conn
->src_mac_addr_mid
);
296 p_data
->src_mac_addr_hi
= cpu_to_le16(p_conn
->src_mac_addr_hi
);
298 tmp
= cpu_to_le16(p_conn
->tx_max_fc_pay_len
);
299 p_data
->tx_max_fc_pay_len
= tmp
;
300 tmp
= cpu_to_le16(p_conn
->e_d_tov_timer_val
);
301 p_data
->e_d_tov_timer_val
= tmp
;
302 tmp
= cpu_to_le16(p_conn
->rec_tov_timer_val
);
303 p_data
->rec_rr_tov_timer_val
= tmp
;
304 tmp
= cpu_to_le16(p_conn
->rx_max_fc_pay_len
);
305 p_data
->rx_max_fc_pay_len
= tmp
;
307 p_data
->vlan_tag
= cpu_to_le16(p_conn
->vlan_tag
);
308 p_data
->s_id
.addr_hi
= p_conn
->s_id
.addr_hi
;
309 p_data
->s_id
.addr_mid
= p_conn
->s_id
.addr_mid
;
310 p_data
->s_id
.addr_lo
= p_conn
->s_id
.addr_lo
;
311 p_data
->max_conc_seqs_c3
= p_conn
->max_conc_seqs_c3
;
312 p_data
->d_id
.addr_hi
= p_conn
->d_id
.addr_hi
;
313 p_data
->d_id
.addr_mid
= p_conn
->d_id
.addr_mid
;
314 p_data
->d_id
.addr_lo
= p_conn
->d_id
.addr_lo
;
315 p_data
->flags
= p_conn
->flags
;
316 p_data
->def_q_idx
= p_conn
->def_q_idx
;
318 return qed_spq_post(p_hwfn
, p_ent
, NULL
);
322 qed_sp_fcoe_conn_destroy(struct qed_hwfn
*p_hwfn
,
323 struct qed_fcoe_conn
*p_conn
,
324 enum spq_mode comp_mode
,
325 struct qed_spq_comp_cb
*p_comp_addr
)
327 struct fcoe_conn_terminate_ramrod_params
*p_ramrod
= NULL
;
328 struct qed_spq_entry
*p_ent
= NULL
;
329 struct qed_sp_init_data init_data
;
333 memset(&init_data
, 0, sizeof(init_data
));
334 init_data
.cid
= p_conn
->icid
;
335 init_data
.opaque_fid
= p_hwfn
->hw_info
.opaque_fid
;
336 init_data
.comp_mode
= comp_mode
;
337 init_data
.p_comp_data
= p_comp_addr
;
339 rc
= qed_sp_init_request(p_hwfn
, &p_ent
,
340 FCOE_RAMROD_CMD_ID_TERMINATE_CONN
,
341 PROTOCOLID_FCOE
, &init_data
);
345 p_ramrod
= &p_ent
->ramrod
.fcoe_conn_terminate
;
346 DMA_REGPAIR_LE(p_ramrod
->terminate_ramrod_data
.terminate_params_addr
,
347 p_conn
->terminate_params
);
349 return qed_spq_post(p_hwfn
, p_ent
, NULL
);
353 qed_sp_fcoe_func_stop(struct qed_hwfn
*p_hwfn
,
354 struct qed_ptt
*p_ptt
,
355 enum spq_mode comp_mode
,
356 struct qed_spq_comp_cb
*p_comp_addr
)
358 struct qed_spq_entry
*p_ent
= NULL
;
359 struct qed_sp_init_data init_data
;
364 memset(&init_data
, 0, sizeof(init_data
));
365 init_data
.cid
= p_hwfn
->pf_params
.fcoe_pf_params
.dummy_icid
;
366 init_data
.opaque_fid
= p_hwfn
->hw_info
.opaque_fid
;
367 init_data
.comp_mode
= comp_mode
;
368 init_data
.p_comp_data
= p_comp_addr
;
370 rc
= qed_sp_init_request(p_hwfn
, &p_ent
,
371 FCOE_RAMROD_CMD_ID_DESTROY_FUNC
,
372 PROTOCOLID_FCOE
, &init_data
);
376 active_segs
= qed_rd(p_hwfn
, p_ptt
, TM_REG_PF_ENABLE_TASK
);
377 active_segs
&= ~BIT(QED_CXT_FCOE_TID_SEG
);
378 qed_wr(p_hwfn
, p_ptt
, TM_REG_PF_ENABLE_TASK
, active_segs
);
380 return qed_spq_post(p_hwfn
, p_ent
, NULL
);
384 qed_fcoe_allocate_connection(struct qed_hwfn
*p_hwfn
,
385 struct qed_fcoe_conn
**p_out_conn
)
387 struct qed_fcoe_conn
*p_conn
= NULL
;
391 spin_lock_bh(&p_hwfn
->p_fcoe_info
->lock
);
392 if (!list_empty(&p_hwfn
->p_fcoe_info
->free_list
))
394 list_first_entry(&p_hwfn
->p_fcoe_info
->free_list
,
395 struct qed_fcoe_conn
, list_entry
);
397 list_del(&p_conn
->list_entry
);
398 spin_unlock_bh(&p_hwfn
->p_fcoe_info
->lock
);
399 *p_out_conn
= p_conn
;
402 spin_unlock_bh(&p_hwfn
->p_fcoe_info
->lock
);
404 p_conn
= kzalloc(sizeof(*p_conn
), GFP_KERNEL
);
408 p_addr
= dma_alloc_coherent(&p_hwfn
->cdev
->pdev
->dev
,
410 &p_conn
->xferq_pbl_addr
, GFP_KERNEL
);
412 goto nomem_pbl_xferq
;
413 p_conn
->xferq_pbl_addr_virt_addr
= p_addr
;
415 for (i
= 0; i
< ARRAY_SIZE(p_conn
->xferq_addr
); i
++) {
416 p_addr
= dma_alloc_coherent(&p_hwfn
->cdev
->pdev
->dev
,
418 &p_conn
->xferq_addr
[i
], GFP_KERNEL
);
421 p_conn
->xferq_addr_virt_addr
[i
] = p_addr
;
423 p_addr
= p_conn
->xferq_pbl_addr_virt_addr
;
424 ((dma_addr_t
*)p_addr
)[i
] = p_conn
->xferq_addr
[i
];
427 p_addr
= dma_alloc_coherent(&p_hwfn
->cdev
->pdev
->dev
,
429 &p_conn
->confq_pbl_addr
, GFP_KERNEL
);
432 p_conn
->confq_pbl_addr_virt_addr
= p_addr
;
434 for (i
= 0; i
< ARRAY_SIZE(p_conn
->confq_addr
); i
++) {
435 p_addr
= dma_alloc_coherent(&p_hwfn
->cdev
->pdev
->dev
,
437 &p_conn
->confq_addr
[i
], GFP_KERNEL
);
440 p_conn
->confq_addr_virt_addr
[i
] = p_addr
;
442 p_addr
= p_conn
->confq_pbl_addr_virt_addr
;
443 ((dma_addr_t
*)p_addr
)[i
] = p_conn
->confq_addr
[i
];
446 p_conn
->free_on_delete
= true;
447 *p_out_conn
= p_conn
;
451 dma_free_coherent(&p_hwfn
->cdev
->pdev
->dev
,
453 p_conn
->confq_pbl_addr_virt_addr
,
454 p_conn
->confq_pbl_addr
);
455 for (i
= 0; i
< ARRAY_SIZE(p_conn
->confq_addr
); i
++)
456 if (p_conn
->confq_addr_virt_addr
[i
])
457 dma_free_coherent(&p_hwfn
->cdev
->pdev
->dev
,
459 p_conn
->confq_addr_virt_addr
[i
],
460 p_conn
->confq_addr
[i
]);
462 dma_free_coherent(&p_hwfn
->cdev
->pdev
->dev
,
464 p_conn
->xferq_pbl_addr_virt_addr
,
465 p_conn
->xferq_pbl_addr
);
466 for (i
= 0; i
< ARRAY_SIZE(p_conn
->xferq_addr
); i
++)
467 if (p_conn
->xferq_addr_virt_addr
[i
])
468 dma_free_coherent(&p_hwfn
->cdev
->pdev
->dev
,
470 p_conn
->xferq_addr_virt_addr
[i
],
471 p_conn
->xferq_addr
[i
]);
477 static void qed_fcoe_free_connection(struct qed_hwfn
*p_hwfn
,
478 struct qed_fcoe_conn
*p_conn
)
485 if (p_conn
->confq_pbl_addr_virt_addr
)
486 dma_free_coherent(&p_hwfn
->cdev
->pdev
->dev
,
488 p_conn
->confq_pbl_addr_virt_addr
,
489 p_conn
->confq_pbl_addr
);
491 for (i
= 0; i
< ARRAY_SIZE(p_conn
->confq_addr
); i
++) {
492 if (!p_conn
->confq_addr_virt_addr
[i
])
494 dma_free_coherent(&p_hwfn
->cdev
->pdev
->dev
,
496 p_conn
->confq_addr_virt_addr
[i
],
497 p_conn
->confq_addr
[i
]);
500 if (p_conn
->xferq_pbl_addr_virt_addr
)
501 dma_free_coherent(&p_hwfn
->cdev
->pdev
->dev
,
503 p_conn
->xferq_pbl_addr_virt_addr
,
504 p_conn
->xferq_pbl_addr
);
506 for (i
= 0; i
< ARRAY_SIZE(p_conn
->xferq_addr
); i
++) {
507 if (!p_conn
->xferq_addr_virt_addr
[i
])
509 dma_free_coherent(&p_hwfn
->cdev
->pdev
->dev
,
511 p_conn
->xferq_addr_virt_addr
[i
],
512 p_conn
->xferq_addr
[i
]);
517 static void __iomem
*qed_fcoe_get_db_addr(struct qed_hwfn
*p_hwfn
, u32 cid
)
519 return (u8 __iomem
*)p_hwfn
->doorbells
+
520 qed_db_addr(cid
, DQ_DEMS_LEGACY
);
523 static void __iomem
*qed_fcoe_get_primary_bdq_prod(struct qed_hwfn
*p_hwfn
,
526 if (RESC_NUM(p_hwfn
, QED_BDQ
)) {
527 return (u8 __iomem
*)p_hwfn
->regview
+
528 GTT_BAR0_MAP_REG_MSDM_RAM
+
529 MSTORM_SCSI_BDQ_EXT_PROD_OFFSET(RESC_START(p_hwfn
,
533 DP_NOTICE(p_hwfn
, "BDQ is not allocated!\n");
538 static void __iomem
*qed_fcoe_get_secondary_bdq_prod(struct qed_hwfn
*p_hwfn
,
541 if (RESC_NUM(p_hwfn
, QED_BDQ
)) {
542 return (u8 __iomem
*)p_hwfn
->regview
+
543 GTT_BAR0_MAP_REG_TSDM_RAM
+
544 TSTORM_SCSI_BDQ_EXT_PROD_OFFSET(RESC_START(p_hwfn
,
548 DP_NOTICE(p_hwfn
, "BDQ is not allocated!\n");
553 int qed_fcoe_alloc(struct qed_hwfn
*p_hwfn
)
555 struct qed_fcoe_info
*p_fcoe_info
;
557 /* Allocate LL2's set struct */
558 p_fcoe_info
= kzalloc(sizeof(*p_fcoe_info
), GFP_KERNEL
);
560 DP_NOTICE(p_hwfn
, "Failed to allocate qed_fcoe_info'\n");
563 INIT_LIST_HEAD(&p_fcoe_info
->free_list
);
565 p_hwfn
->p_fcoe_info
= p_fcoe_info
;
569 void qed_fcoe_setup(struct qed_hwfn
*p_hwfn
)
571 struct e4_fcoe_task_context
*p_task_ctx
= NULL
;
575 spin_lock_init(&p_hwfn
->p_fcoe_info
->lock
);
576 for (i
= 0; i
< p_hwfn
->pf_params
.fcoe_pf_params
.num_tasks
; i
++) {
577 rc
= qed_cxt_get_task_ctx(p_hwfn
, i
,
579 (void **)&p_task_ctx
);
583 memset(p_task_ctx
, 0, sizeof(struct e4_fcoe_task_context
));
584 SET_FIELD(p_task_ctx
->timer_context
.logical_client_0
,
585 TIMERS_CONTEXT_VALIDLC0
, 1);
586 SET_FIELD(p_task_ctx
->timer_context
.logical_client_1
,
587 TIMERS_CONTEXT_VALIDLC1
, 1);
588 SET_FIELD(p_task_ctx
->tstorm_ag_context
.flags0
,
589 E4_TSTORM_FCOE_TASK_AG_CTX_CONNECTION_TYPE
, 1);
593 void qed_fcoe_free(struct qed_hwfn
*p_hwfn
)
595 struct qed_fcoe_conn
*p_conn
= NULL
;
597 if (!p_hwfn
->p_fcoe_info
)
600 while (!list_empty(&p_hwfn
->p_fcoe_info
->free_list
)) {
601 p_conn
= list_first_entry(&p_hwfn
->p_fcoe_info
->free_list
,
602 struct qed_fcoe_conn
, list_entry
);
605 list_del(&p_conn
->list_entry
);
606 qed_fcoe_free_connection(p_hwfn
, p_conn
);
609 kfree(p_hwfn
->p_fcoe_info
);
610 p_hwfn
->p_fcoe_info
= NULL
;
614 qed_fcoe_acquire_connection(struct qed_hwfn
*p_hwfn
,
615 struct qed_fcoe_conn
*p_in_conn
,
616 struct qed_fcoe_conn
**p_out_conn
)
618 struct qed_fcoe_conn
*p_conn
= NULL
;
622 spin_lock_bh(&p_hwfn
->p_fcoe_info
->lock
);
623 rc
= qed_cxt_acquire_cid(p_hwfn
, PROTOCOLID_FCOE
, &icid
);
624 spin_unlock_bh(&p_hwfn
->p_fcoe_info
->lock
);
628 /* Use input connection [if provided] or allocate a new one */
632 rc
= qed_fcoe_allocate_connection(p_hwfn
, &p_conn
);
634 spin_lock_bh(&p_hwfn
->p_fcoe_info
->lock
);
635 qed_cxt_release_cid(p_hwfn
, icid
);
636 spin_unlock_bh(&p_hwfn
->p_fcoe_info
->lock
);
642 p_conn
->fw_cid
= (p_hwfn
->hw_info
.opaque_fid
<< 16) | icid
;
643 *p_out_conn
= p_conn
;
648 static void qed_fcoe_release_connection(struct qed_hwfn
*p_hwfn
,
649 struct qed_fcoe_conn
*p_conn
)
651 spin_lock_bh(&p_hwfn
->p_fcoe_info
->lock
);
652 list_add_tail(&p_conn
->list_entry
, &p_hwfn
->p_fcoe_info
->free_list
);
653 qed_cxt_release_cid(p_hwfn
, p_conn
->icid
);
654 spin_unlock_bh(&p_hwfn
->p_fcoe_info
->lock
);
657 static void _qed_fcoe_get_tstats(struct qed_hwfn
*p_hwfn
,
658 struct qed_ptt
*p_ptt
,
659 struct qed_fcoe_stats
*p_stats
)
661 struct fcoe_rx_stat tstats
;
664 memset(&tstats
, 0, sizeof(tstats
));
665 tstats_addr
= BAR0_MAP_REG_TSDM_RAM
+
666 TSTORM_FCOE_RX_STATS_OFFSET(p_hwfn
->rel_pf_id
);
667 qed_memcpy_from(p_hwfn
, p_ptt
, &tstats
, tstats_addr
, sizeof(tstats
));
669 p_stats
->fcoe_rx_byte_cnt
= HILO_64_REGPAIR(tstats
.fcoe_rx_byte_cnt
);
670 p_stats
->fcoe_rx_data_pkt_cnt
=
671 HILO_64_REGPAIR(tstats
.fcoe_rx_data_pkt_cnt
);
672 p_stats
->fcoe_rx_xfer_pkt_cnt
=
673 HILO_64_REGPAIR(tstats
.fcoe_rx_xfer_pkt_cnt
);
674 p_stats
->fcoe_rx_other_pkt_cnt
=
675 HILO_64_REGPAIR(tstats
.fcoe_rx_other_pkt_cnt
);
677 p_stats
->fcoe_silent_drop_pkt_cmdq_full_cnt
=
678 le32_to_cpu(tstats
.fcoe_silent_drop_pkt_cmdq_full_cnt
);
679 p_stats
->fcoe_silent_drop_pkt_rq_full_cnt
=
680 le32_to_cpu(tstats
.fcoe_silent_drop_pkt_rq_full_cnt
);
681 p_stats
->fcoe_silent_drop_pkt_crc_error_cnt
=
682 le32_to_cpu(tstats
.fcoe_silent_drop_pkt_crc_error_cnt
);
683 p_stats
->fcoe_silent_drop_pkt_task_invalid_cnt
=
684 le32_to_cpu(tstats
.fcoe_silent_drop_pkt_task_invalid_cnt
);
685 p_stats
->fcoe_silent_drop_total_pkt_cnt
=
686 le32_to_cpu(tstats
.fcoe_silent_drop_total_pkt_cnt
);
689 static void _qed_fcoe_get_pstats(struct qed_hwfn
*p_hwfn
,
690 struct qed_ptt
*p_ptt
,
691 struct qed_fcoe_stats
*p_stats
)
693 struct fcoe_tx_stat pstats
;
696 memset(&pstats
, 0, sizeof(pstats
));
697 pstats_addr
= BAR0_MAP_REG_PSDM_RAM
+
698 PSTORM_FCOE_TX_STATS_OFFSET(p_hwfn
->rel_pf_id
);
699 qed_memcpy_from(p_hwfn
, p_ptt
, &pstats
, pstats_addr
, sizeof(pstats
));
701 p_stats
->fcoe_tx_byte_cnt
= HILO_64_REGPAIR(pstats
.fcoe_tx_byte_cnt
);
702 p_stats
->fcoe_tx_data_pkt_cnt
=
703 HILO_64_REGPAIR(pstats
.fcoe_tx_data_pkt_cnt
);
704 p_stats
->fcoe_tx_xfer_pkt_cnt
=
705 HILO_64_REGPAIR(pstats
.fcoe_tx_xfer_pkt_cnt
);
706 p_stats
->fcoe_tx_other_pkt_cnt
=
707 HILO_64_REGPAIR(pstats
.fcoe_tx_other_pkt_cnt
);
710 static int qed_fcoe_get_stats(struct qed_hwfn
*p_hwfn
,
711 struct qed_fcoe_stats
*p_stats
)
713 struct qed_ptt
*p_ptt
;
715 memset(p_stats
, 0, sizeof(*p_stats
));
717 p_ptt
= qed_ptt_acquire(p_hwfn
);
720 DP_ERR(p_hwfn
, "Failed to acquire ptt\n");
724 _qed_fcoe_get_tstats(p_hwfn
, p_ptt
, p_stats
);
725 _qed_fcoe_get_pstats(p_hwfn
, p_ptt
, p_stats
);
727 qed_ptt_release(p_hwfn
, p_ptt
);
732 struct qed_hash_fcoe_con
{
733 struct hlist_node node
;
734 struct qed_fcoe_conn
*con
;
737 static int qed_fill_fcoe_dev_info(struct qed_dev
*cdev
,
738 struct qed_dev_fcoe_info
*info
)
740 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
743 memset(info
, 0, sizeof(*info
));
744 rc
= qed_fill_dev_info(cdev
, &info
->common
);
746 info
->primary_dbq_rq_addr
=
747 qed_fcoe_get_primary_bdq_prod(hwfn
, BDQ_ID_RQ
);
748 info
->secondary_bdq_rq_addr
=
749 qed_fcoe_get_secondary_bdq_prod(hwfn
, BDQ_ID_RQ
);
751 info
->wwpn
= hwfn
->mcp_info
->func_info
.wwn_port
;
752 info
->wwnn
= hwfn
->mcp_info
->func_info
.wwn_node
;
754 info
->num_cqs
= FEAT_NUM(hwfn
, QED_FCOE_CQ
);
759 static void qed_register_fcoe_ops(struct qed_dev
*cdev
,
760 struct qed_fcoe_cb_ops
*ops
, void *cookie
)
762 cdev
->protocol_ops
.fcoe
= ops
;
763 cdev
->ops_cookie
= cookie
;
766 static struct qed_hash_fcoe_con
*qed_fcoe_get_hash(struct qed_dev
*cdev
,
769 struct qed_hash_fcoe_con
*hash_con
= NULL
;
771 if (!(cdev
->flags
& QED_FLAG_STORAGE_STARTED
))
774 hash_for_each_possible(cdev
->connections
, hash_con
, node
, handle
) {
775 if (hash_con
->con
->icid
== handle
)
779 if (!hash_con
|| (hash_con
->con
->icid
!= handle
))
785 static int qed_fcoe_stop(struct qed_dev
*cdev
)
787 struct qed_ptt
*p_ptt
;
790 if (!(cdev
->flags
& QED_FLAG_STORAGE_STARTED
)) {
791 DP_NOTICE(cdev
, "fcoe already stopped\n");
795 if (!hash_empty(cdev
->connections
)) {
797 "Can't stop fcoe - not all connections were returned\n");
801 p_ptt
= qed_ptt_acquire(QED_LEADING_HWFN(cdev
));
806 rc
= qed_sp_fcoe_func_stop(QED_LEADING_HWFN(cdev
), p_ptt
,
807 QED_SPQ_MODE_EBLOCK
, NULL
);
808 cdev
->flags
&= ~QED_FLAG_STORAGE_STARTED
;
809 qed_ptt_release(QED_LEADING_HWFN(cdev
), p_ptt
);
814 static int qed_fcoe_start(struct qed_dev
*cdev
, struct qed_fcoe_tid
*tasks
)
818 if (cdev
->flags
& QED_FLAG_STORAGE_STARTED
) {
819 DP_NOTICE(cdev
, "fcoe already started;\n");
823 rc
= qed_sp_fcoe_func_start(QED_LEADING_HWFN(cdev
),
824 QED_SPQ_MODE_EBLOCK
, NULL
);
826 DP_NOTICE(cdev
, "Failed to start fcoe\n");
830 cdev
->flags
|= QED_FLAG_STORAGE_STARTED
;
831 hash_init(cdev
->connections
);
834 struct qed_tid_mem
*tid_info
= kzalloc(sizeof(*tid_info
),
839 "Failed to allocate tasks information\n");
844 rc
= qed_cxt_get_tid_mem_info(QED_LEADING_HWFN(cdev
), tid_info
);
846 DP_NOTICE(cdev
, "Failed to gather task information\n");
852 /* Fill task information */
853 tasks
->size
= tid_info
->tid_size
;
854 tasks
->num_tids_per_block
= tid_info
->num_tids_per_block
;
855 memcpy(tasks
->blocks
, tid_info
->blocks
,
856 MAX_TID_BLOCKS_FCOE
* sizeof(u8
*));
864 static int qed_fcoe_acquire_conn(struct qed_dev
*cdev
,
866 u32
*fw_cid
, void __iomem
**p_doorbell
)
868 struct qed_hash_fcoe_con
*hash_con
;
871 /* Allocate a hashed connection */
872 hash_con
= kzalloc(sizeof(*hash_con
), GFP_KERNEL
);
874 DP_NOTICE(cdev
, "Failed to allocate hashed connection\n");
878 /* Acquire the connection */
879 rc
= qed_fcoe_acquire_connection(QED_LEADING_HWFN(cdev
), NULL
,
882 DP_NOTICE(cdev
, "Failed to acquire Connection\n");
887 /* Added the connection to hash table */
888 *handle
= hash_con
->con
->icid
;
889 *fw_cid
= hash_con
->con
->fw_cid
;
890 hash_add(cdev
->connections
, &hash_con
->node
, *handle
);
893 *p_doorbell
= qed_fcoe_get_db_addr(QED_LEADING_HWFN(cdev
),
899 static int qed_fcoe_release_conn(struct qed_dev
*cdev
, u32 handle
)
901 struct qed_hash_fcoe_con
*hash_con
;
903 hash_con
= qed_fcoe_get_hash(cdev
, handle
);
905 DP_NOTICE(cdev
, "Failed to find connection for handle %d\n",
910 hlist_del(&hash_con
->node
);
911 qed_fcoe_release_connection(QED_LEADING_HWFN(cdev
), hash_con
->con
);
917 static int qed_fcoe_offload_conn(struct qed_dev
*cdev
,
919 struct qed_fcoe_params_offload
*conn_info
)
921 struct qed_hash_fcoe_con
*hash_con
;
922 struct qed_fcoe_conn
*con
;
924 hash_con
= qed_fcoe_get_hash(cdev
, handle
);
926 DP_NOTICE(cdev
, "Failed to find connection for handle %d\n",
931 /* Update the connection with information from the params */
934 con
->sq_pbl_addr
= conn_info
->sq_pbl_addr
;
935 con
->sq_curr_page_addr
= conn_info
->sq_curr_page_addr
;
936 con
->sq_next_page_addr
= conn_info
->sq_next_page_addr
;
937 con
->tx_max_fc_pay_len
= conn_info
->tx_max_fc_pay_len
;
938 con
->e_d_tov_timer_val
= conn_info
->e_d_tov_timer_val
;
939 con
->rec_tov_timer_val
= conn_info
->rec_tov_timer_val
;
940 con
->rx_max_fc_pay_len
= conn_info
->rx_max_fc_pay_len
;
941 con
->vlan_tag
= conn_info
->vlan_tag
;
942 con
->max_conc_seqs_c3
= conn_info
->max_conc_seqs_c3
;
943 con
->flags
= conn_info
->flags
;
944 con
->def_q_idx
= conn_info
->def_q_idx
;
946 con
->src_mac_addr_hi
= (conn_info
->src_mac
[5] << 8) |
947 conn_info
->src_mac
[4];
948 con
->src_mac_addr_mid
= (conn_info
->src_mac
[3] << 8) |
949 conn_info
->src_mac
[2];
950 con
->src_mac_addr_lo
= (conn_info
->src_mac
[1] << 8) |
951 conn_info
->src_mac
[0];
952 con
->dst_mac_addr_hi
= (conn_info
->dst_mac
[5] << 8) |
953 conn_info
->dst_mac
[4];
954 con
->dst_mac_addr_mid
= (conn_info
->dst_mac
[3] << 8) |
955 conn_info
->dst_mac
[2];
956 con
->dst_mac_addr_lo
= (conn_info
->dst_mac
[1] << 8) |
957 conn_info
->dst_mac
[0];
959 con
->s_id
.addr_hi
= conn_info
->s_id
.addr_hi
;
960 con
->s_id
.addr_mid
= conn_info
->s_id
.addr_mid
;
961 con
->s_id
.addr_lo
= conn_info
->s_id
.addr_lo
;
962 con
->d_id
.addr_hi
= conn_info
->d_id
.addr_hi
;
963 con
->d_id
.addr_mid
= conn_info
->d_id
.addr_mid
;
964 con
->d_id
.addr_lo
= conn_info
->d_id
.addr_lo
;
966 return qed_sp_fcoe_conn_offload(QED_LEADING_HWFN(cdev
), con
,
967 QED_SPQ_MODE_EBLOCK
, NULL
);
970 static int qed_fcoe_destroy_conn(struct qed_dev
*cdev
,
971 u32 handle
, dma_addr_t terminate_params
)
973 struct qed_hash_fcoe_con
*hash_con
;
974 struct qed_fcoe_conn
*con
;
976 hash_con
= qed_fcoe_get_hash(cdev
, handle
);
978 DP_NOTICE(cdev
, "Failed to find connection for handle %d\n",
983 /* Update the connection with information from the params */
985 con
->terminate_params
= terminate_params
;
987 return qed_sp_fcoe_conn_destroy(QED_LEADING_HWFN(cdev
), con
,
988 QED_SPQ_MODE_EBLOCK
, NULL
);
991 static int qed_fcoe_stats(struct qed_dev
*cdev
, struct qed_fcoe_stats
*stats
)
993 return qed_fcoe_get_stats(QED_LEADING_HWFN(cdev
), stats
);
996 void qed_get_protocol_stats_fcoe(struct qed_dev
*cdev
,
997 struct qed_mcp_fcoe_stats
*stats
)
999 struct qed_fcoe_stats proto_stats
;
1001 /* Retrieve FW statistics */
1002 memset(&proto_stats
, 0, sizeof(proto_stats
));
1003 if (qed_fcoe_stats(cdev
, &proto_stats
)) {
1004 DP_VERBOSE(cdev
, QED_MSG_STORAGE
,
1005 "Failed to collect FCoE statistics\n");
1009 /* Translate FW statistics into struct */
1010 stats
->rx_pkts
= proto_stats
.fcoe_rx_data_pkt_cnt
+
1011 proto_stats
.fcoe_rx_xfer_pkt_cnt
+
1012 proto_stats
.fcoe_rx_other_pkt_cnt
;
1013 stats
->tx_pkts
= proto_stats
.fcoe_tx_data_pkt_cnt
+
1014 proto_stats
.fcoe_tx_xfer_pkt_cnt
+
1015 proto_stats
.fcoe_tx_other_pkt_cnt
;
1016 stats
->fcs_err
= proto_stats
.fcoe_silent_drop_pkt_crc_error_cnt
;
1018 /* Request protocol driver to fill-in the rest */
1019 if (cdev
->protocol_ops
.fcoe
&& cdev
->ops_cookie
) {
1020 struct qed_fcoe_cb_ops
*ops
= cdev
->protocol_ops
.fcoe
;
1021 void *cookie
= cdev
->ops_cookie
;
1023 if (ops
->get_login_failures
)
1024 stats
->login_failure
= ops
->get_login_failures(cookie
);
1028 static const struct qed_fcoe_ops qed_fcoe_ops_pass
= {
1029 .common
= &qed_common_ops_pass
,
1030 .ll2
= &qed_ll2_ops_pass
,
1031 .fill_dev_info
= &qed_fill_fcoe_dev_info
,
1032 .start
= &qed_fcoe_start
,
1033 .stop
= &qed_fcoe_stop
,
1034 .register_ops
= &qed_register_fcoe_ops
,
1035 .acquire_conn
= &qed_fcoe_acquire_conn
,
1036 .release_conn
= &qed_fcoe_release_conn
,
1037 .offload_conn
= &qed_fcoe_offload_conn
,
1038 .destroy_conn
= &qed_fcoe_destroy_conn
,
1039 .get_stats
= &qed_fcoe_stats
,
1042 const struct qed_fcoe_ops
*qed_get_fcoe_ops(void)
1044 return &qed_fcoe_ops_pass
;
1046 EXPORT_SYMBOL(qed_get_fcoe_ops
);
1048 void qed_put_fcoe_ops(void)
1051 EXPORT_SYMBOL(qed_put_fcoe_ops
);