1 /* QLogic qed NIC Driver 2 * Copyright (c) 2015-2017 QLogic Corporation 3 * 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: 9 * 10 * Redistribution and use in source and binary forms, with or 11 * without modification, are permitted provided that the following 12 * conditions are met: 13 * 14 * - Redistributions of source code must retain the above 15 * copyright notice, this list of conditions and the following 16 * disclaimer. 17 * 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. 22 * 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 30 * SOFTWARE. 31 */ 32 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__ 52 #include "qed.h" 53 #include "qed_cxt.h" 54 #include "qed_dev_api.h" 55 #include "qed_fcoe.h" 56 #include "qed_hsi.h" 57 #include "qed_hw.h" 58 #include "qed_int.h" 59 #include "qed_ll2.h" 60 #include "qed_mcp.h" 61 #include "qed_reg_addr.h" 62 #include "qed_sp.h" 63 #include "qed_sriov.h" 64 #include <linux/qed/qed_fcoe_if.h> 65 66 struct qed_fcoe_conn { 67 struct list_head list_entry; 68 bool free_on_delete; 69 70 u16 conn_id; 71 u32 icid; 72 u32 fw_cid; 73 u8 layer_code; 74 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]; 86 87 dma_addr_t terminate_params; 88 89 u16 dst_mac_addr_lo; 90 u16 dst_mac_addr_mid; 91 u16 dst_mac_addr_hi; 92 u16 src_mac_addr_lo; 93 u16 src_mac_addr_mid; 94 u16 src_mac_addr_hi; 95 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; 100 u16 vlan_tag; 101 u16 physical_q0; 102 103 struct fc_addr_nw s_id; 104 u8 max_conc_seqs_c3; 105 struct fc_addr_nw d_id; 106 u8 flags; 107 u8 def_q_idx; 108 }; 109 110 static int 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) 114 { 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 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; 122 u32 dummy_cid; 123 int rc = 0; 124 u16 tmp; 125 u8 i; 126 127 /* Get SPQ entry */ 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; 133 134 rc = qed_sp_init_request(p_hwfn, &p_ent, 135 FCOE_RAMROD_CMD_ID_INIT_FUNC, 136 PROTOCOLID_FCOE, &init_data); 137 if (rc) 138 return rc; 139 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; 143 144 /* Sanity */ 145 if (fcoe_pf_params->num_cqs > p_hwfn->hw_info.feat_num[QED_FCOE_CQ]) { 146 DP_ERR(p_hwfn, 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]); 150 return -EINVAL; 151 } 152 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; 156 157 rc = qed_cxt_acquire_cid(p_hwfn, PROTOCOLID_FCOE, &dummy_cid); 158 if (rc) 159 return rc; 160 161 cxt_info.iid = dummy_cid; 162 rc = qed_cxt_get_cid_info(p_hwfn, &cxt_info); 163 if (rc) { 164 DP_NOTICE(p_hwfn, "Cannot find context info for dummy cid=%d\n", 165 dummy_cid); 166 return rc; 167 } 168 p_cxt = cxt_info.p_cxt; 169 SET_FIELD(p_cxt->tstorm_ag_context.flags3, 170 TSTORM_FCOE_CONN_AG_CTX_DUMMY_TIMER_CF_EN, 1); 171 172 fcoe_pf_params->dummy_icid = (u16)dummy_cid; 173 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; 178 179 DMA_REGPAIR_LE(p_data->q_params.glbl_q_params_addr, 180 fcoe_pf_params->glbl_q_params_addr); 181 182 tmp = cpu_to_le16(fcoe_pf_params->cq_num_entries); 183 p_data->q_params.cq_num_entries = tmp; 184 185 tmp = cpu_to_le16(fcoe_pf_params->cmdq_num_entries); 186 p_data->q_params.cmdq_num_entries = tmp; 187 188 tmp = fcoe_pf_params->num_cqs; 189 p_data->q_params.num_queues = (u8)tmp; 190 191 tmp = (u16)p_hwfn->hw_info.resc_start[QED_CMDQS_CQS]; 192 p_data->q_params.queue_relative_offset = (u8)tmp; 193 194 for (i = 0; i < fcoe_pf_params->num_cqs; i++) { 195 u16 igu_sb_id; 196 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; 200 } 201 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; 204 205 p_data->q_params.bdq_resource_id = (u8)RESC_START(p_hwfn, QED_BDQ); 206 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); 215 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); 226 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); 235 } else { 236 SET_FIELD(p_data->q_params.q_validity, 237 SCSI_INIT_FUNC_QUEUES_RQ_VALID, 1); 238 } 239 240 rc = qed_spq_post(p_hwfn, p_ent, NULL); 241 242 return rc; 243 } 244 245 static int 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) 250 { 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; 256 int rc; 257 258 /* Get SPQ entry */ 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; 264 265 rc = qed_sp_init_request(p_hwfn, &p_ent, 266 FCOE_RAMROD_CMD_ID_OFFLOAD_CONN, 267 PROTOCOLID_FCOE, &init_data); 268 if (rc) 269 return rc; 270 271 p_ramrod = &p_ent->ramrod.fcoe_conn_ofld; 272 p_data = &p_ramrod->offload_ramrod_data; 273 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); 278 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]); 286 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]); 290 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); 297 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; 306 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; 317 318 return qed_spq_post(p_hwfn, p_ent, NULL); 319 } 320 321 static int 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) 326 { 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; 330 int rc = 0; 331 332 /* Get SPQ entry */ 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; 338 339 rc = qed_sp_init_request(p_hwfn, &p_ent, 340 FCOE_RAMROD_CMD_ID_TERMINATE_CONN, 341 PROTOCOLID_FCOE, &init_data); 342 if (rc) 343 return rc; 344 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); 348 349 return qed_spq_post(p_hwfn, p_ent, NULL); 350 } 351 352 static int 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) 357 { 358 struct qed_spq_entry *p_ent = NULL; 359 struct qed_sp_init_data init_data; 360 u32 active_segs = 0; 361 int rc = 0; 362 363 /* Get SPQ entry */ 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; 369 370 rc = qed_sp_init_request(p_hwfn, &p_ent, 371 FCOE_RAMROD_CMD_ID_DESTROY_FUNC, 372 PROTOCOLID_FCOE, &init_data); 373 if (rc) 374 return rc; 375 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); 379 380 return qed_spq_post(p_hwfn, p_ent, NULL); 381 } 382 383 static int 384 qed_fcoe_allocate_connection(struct qed_hwfn *p_hwfn, 385 struct qed_fcoe_conn **p_out_conn) 386 { 387 struct qed_fcoe_conn *p_conn = NULL; 388 void *p_addr; 389 u32 i; 390 391 spin_lock_bh(&p_hwfn->p_fcoe_info->lock); 392 if (!list_empty(&p_hwfn->p_fcoe_info->free_list)) 393 p_conn = 394 list_first_entry(&p_hwfn->p_fcoe_info->free_list, 395 struct qed_fcoe_conn, list_entry); 396 if (p_conn) { 397 list_del(&p_conn->list_entry); 398 spin_unlock_bh(&p_hwfn->p_fcoe_info->lock); 399 *p_out_conn = p_conn; 400 return 0; 401 } 402 spin_unlock_bh(&p_hwfn->p_fcoe_info->lock); 403 404 p_conn = kzalloc(sizeof(*p_conn), GFP_KERNEL); 405 if (!p_conn) 406 return -ENOMEM; 407 408 p_addr = dma_alloc_coherent(&p_hwfn->cdev->pdev->dev, 409 QED_CHAIN_PAGE_SIZE, 410 &p_conn->xferq_pbl_addr, GFP_KERNEL); 411 if (!p_addr) 412 goto nomem_pbl_xferq; 413 p_conn->xferq_pbl_addr_virt_addr = p_addr; 414 415 for (i = 0; i < ARRAY_SIZE(p_conn->xferq_addr); i++) { 416 p_addr = dma_alloc_coherent(&p_hwfn->cdev->pdev->dev, 417 QED_CHAIN_PAGE_SIZE, 418 &p_conn->xferq_addr[i], GFP_KERNEL); 419 if (!p_addr) 420 goto nomem_xferq; 421 p_conn->xferq_addr_virt_addr[i] = p_addr; 422 423 p_addr = p_conn->xferq_pbl_addr_virt_addr; 424 ((dma_addr_t *)p_addr)[i] = p_conn->xferq_addr[i]; 425 } 426 427 p_addr = dma_alloc_coherent(&p_hwfn->cdev->pdev->dev, 428 QED_CHAIN_PAGE_SIZE, 429 &p_conn->confq_pbl_addr, GFP_KERNEL); 430 if (!p_addr) 431 goto nomem_xferq; 432 p_conn->confq_pbl_addr_virt_addr = p_addr; 433 434 for (i = 0; i < ARRAY_SIZE(p_conn->confq_addr); i++) { 435 p_addr = dma_alloc_coherent(&p_hwfn->cdev->pdev->dev, 436 QED_CHAIN_PAGE_SIZE, 437 &p_conn->confq_addr[i], GFP_KERNEL); 438 if (!p_addr) 439 goto nomem_confq; 440 p_conn->confq_addr_virt_addr[i] = p_addr; 441 442 p_addr = p_conn->confq_pbl_addr_virt_addr; 443 ((dma_addr_t *)p_addr)[i] = p_conn->confq_addr[i]; 444 } 445 446 p_conn->free_on_delete = true; 447 *p_out_conn = p_conn; 448 return 0; 449 450 nomem_confq: 451 dma_free_coherent(&p_hwfn->cdev->pdev->dev, 452 QED_CHAIN_PAGE_SIZE, 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, 458 QED_CHAIN_PAGE_SIZE, 459 p_conn->confq_addr_virt_addr[i], 460 p_conn->confq_addr[i]); 461 nomem_xferq: 462 dma_free_coherent(&p_hwfn->cdev->pdev->dev, 463 QED_CHAIN_PAGE_SIZE, 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, 469 QED_CHAIN_PAGE_SIZE, 470 p_conn->xferq_addr_virt_addr[i], 471 p_conn->xferq_addr[i]); 472 nomem_pbl_xferq: 473 kfree(p_conn); 474 return -ENOMEM; 475 } 476 477 static void qed_fcoe_free_connection(struct qed_hwfn *p_hwfn, 478 struct qed_fcoe_conn *p_conn) 479 { 480 u32 i; 481 482 if (!p_conn) 483 return; 484 485 if (p_conn->confq_pbl_addr_virt_addr) 486 dma_free_coherent(&p_hwfn->cdev->pdev->dev, 487 QED_CHAIN_PAGE_SIZE, 488 p_conn->confq_pbl_addr_virt_addr, 489 p_conn->confq_pbl_addr); 490 491 for (i = 0; i < ARRAY_SIZE(p_conn->confq_addr); i++) { 492 if (!p_conn->confq_addr_virt_addr[i]) 493 continue; 494 dma_free_coherent(&p_hwfn->cdev->pdev->dev, 495 QED_CHAIN_PAGE_SIZE, 496 p_conn->confq_addr_virt_addr[i], 497 p_conn->confq_addr[i]); 498 } 499 500 if (p_conn->xferq_pbl_addr_virt_addr) 501 dma_free_coherent(&p_hwfn->cdev->pdev->dev, 502 QED_CHAIN_PAGE_SIZE, 503 p_conn->xferq_pbl_addr_virt_addr, 504 p_conn->xferq_pbl_addr); 505 506 for (i = 0; i < ARRAY_SIZE(p_conn->xferq_addr); i++) { 507 if (!p_conn->xferq_addr_virt_addr[i]) 508 continue; 509 dma_free_coherent(&p_hwfn->cdev->pdev->dev, 510 QED_CHAIN_PAGE_SIZE, 511 p_conn->xferq_addr_virt_addr[i], 512 p_conn->xferq_addr[i]); 513 } 514 kfree(p_conn); 515 } 516 517 static void __iomem *qed_fcoe_get_db_addr(struct qed_hwfn *p_hwfn, u32 cid) 518 { 519 return (u8 __iomem *)p_hwfn->doorbells + 520 qed_db_addr(cid, DQ_DEMS_LEGACY); 521 } 522 523 static void __iomem *qed_fcoe_get_primary_bdq_prod(struct qed_hwfn *p_hwfn, 524 u8 bdq_id) 525 { 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, 530 QED_BDQ), 531 bdq_id); 532 } else { 533 DP_NOTICE(p_hwfn, "BDQ is not allocated!\n"); 534 return NULL; 535 } 536 } 537 538 static void __iomem *qed_fcoe_get_secondary_bdq_prod(struct qed_hwfn *p_hwfn, 539 u8 bdq_id) 540 { 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, 545 QED_BDQ), 546 bdq_id); 547 } else { 548 DP_NOTICE(p_hwfn, "BDQ is not allocated!\n"); 549 return NULL; 550 } 551 } 552 553 int qed_fcoe_alloc(struct qed_hwfn *p_hwfn) 554 { 555 struct qed_fcoe_info *p_fcoe_info; 556 557 /* Allocate LL2's set struct */ 558 p_fcoe_info = kzalloc(sizeof(*p_fcoe_info), GFP_KERNEL); 559 if (!p_fcoe_info) { 560 DP_NOTICE(p_hwfn, "Failed to allocate qed_fcoe_info'\n"); 561 return -ENOMEM; 562 } 563 INIT_LIST_HEAD(&p_fcoe_info->free_list); 564 565 p_hwfn->p_fcoe_info = p_fcoe_info; 566 return 0; 567 } 568 569 void qed_fcoe_setup(struct qed_hwfn *p_hwfn) 570 { 571 struct fcoe_task_context *p_task_ctx = NULL; 572 int rc; 573 u32 i; 574 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, 578 QED_CTX_WORKING_MEM, 579 (void **)&p_task_ctx); 580 if (rc) 581 continue; 582 583 memset(p_task_ctx, 0, sizeof(struct 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 TSTORM_FCOE_TASK_AG_CTX_CONNECTION_TYPE, 1); 590 } 591 } 592 593 void qed_fcoe_free(struct qed_hwfn *p_hwfn) 594 { 595 struct qed_fcoe_conn *p_conn = NULL; 596 597 if (!p_hwfn->p_fcoe_info) 598 return; 599 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); 603 if (!p_conn) 604 break; 605 list_del(&p_conn->list_entry); 606 qed_fcoe_free_connection(p_hwfn, p_conn); 607 } 608 609 kfree(p_hwfn->p_fcoe_info); 610 p_hwfn->p_fcoe_info = NULL; 611 } 612 613 static int 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) 617 { 618 struct qed_fcoe_conn *p_conn = NULL; 619 int rc = 0; 620 u32 icid; 621 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); 625 if (rc) 626 return rc; 627 628 /* Use input connection [if provided] or allocate a new one */ 629 if (p_in_conn) { 630 p_conn = p_in_conn; 631 } else { 632 rc = qed_fcoe_allocate_connection(p_hwfn, &p_conn); 633 if (rc) { 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); 637 return rc; 638 } 639 } 640 641 p_conn->icid = icid; 642 p_conn->fw_cid = (p_hwfn->hw_info.opaque_fid << 16) | icid; 643 *p_out_conn = p_conn; 644 645 return rc; 646 } 647 648 static void qed_fcoe_release_connection(struct qed_hwfn *p_hwfn, 649 struct qed_fcoe_conn *p_conn) 650 { 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); 655 } 656 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) 660 { 661 struct fcoe_rx_stat tstats; 662 u32 tstats_addr; 663 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)); 668 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); 676 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); 687 } 688 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) 692 { 693 struct fcoe_tx_stat pstats; 694 u32 pstats_addr; 695 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)); 700 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); 708 } 709 710 static int qed_fcoe_get_stats(struct qed_hwfn *p_hwfn, 711 struct qed_fcoe_stats *p_stats) 712 { 713 struct qed_ptt *p_ptt; 714 715 memset(p_stats, 0, sizeof(*p_stats)); 716 717 p_ptt = qed_ptt_acquire(p_hwfn); 718 719 if (!p_ptt) { 720 DP_ERR(p_hwfn, "Failed to acquire ptt\n"); 721 return -EINVAL; 722 } 723 724 _qed_fcoe_get_tstats(p_hwfn, p_ptt, p_stats); 725 _qed_fcoe_get_pstats(p_hwfn, p_ptt, p_stats); 726 727 qed_ptt_release(p_hwfn, p_ptt); 728 729 return 0; 730 } 731 732 struct qed_hash_fcoe_con { 733 struct hlist_node node; 734 struct qed_fcoe_conn *con; 735 }; 736 737 static int qed_fill_fcoe_dev_info(struct qed_dev *cdev, 738 struct qed_dev_fcoe_info *info) 739 { 740 struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 741 int rc; 742 743 memset(info, 0, sizeof(*info)); 744 rc = qed_fill_dev_info(cdev, &info->common); 745 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); 750 751 info->wwpn = hwfn->mcp_info->func_info.wwn_port; 752 info->wwnn = hwfn->mcp_info->func_info.wwn_node; 753 754 info->num_cqs = FEAT_NUM(hwfn, QED_FCOE_CQ); 755 756 return rc; 757 } 758 759 static void qed_register_fcoe_ops(struct qed_dev *cdev, 760 struct qed_fcoe_cb_ops *ops, void *cookie) 761 { 762 cdev->protocol_ops.fcoe = ops; 763 cdev->ops_cookie = cookie; 764 } 765 766 static struct qed_hash_fcoe_con *qed_fcoe_get_hash(struct qed_dev *cdev, 767 u32 handle) 768 { 769 struct qed_hash_fcoe_con *hash_con = NULL; 770 771 if (!(cdev->flags & QED_FLAG_STORAGE_STARTED)) 772 return NULL; 773 774 hash_for_each_possible(cdev->connections, hash_con, node, handle) { 775 if (hash_con->con->icid == handle) 776 break; 777 } 778 779 if (!hash_con || (hash_con->con->icid != handle)) 780 return NULL; 781 782 return hash_con; 783 } 784 785 static int qed_fcoe_stop(struct qed_dev *cdev) 786 { 787 struct qed_ptt *p_ptt; 788 int rc; 789 790 if (!(cdev->flags & QED_FLAG_STORAGE_STARTED)) { 791 DP_NOTICE(cdev, "fcoe already stopped\n"); 792 return 0; 793 } 794 795 if (!hash_empty(cdev->connections)) { 796 DP_NOTICE(cdev, 797 "Can't stop fcoe - not all connections were returned\n"); 798 return -EINVAL; 799 } 800 801 p_ptt = qed_ptt_acquire(QED_LEADING_HWFN(cdev)); 802 if (!p_ptt) 803 return -EAGAIN; 804 805 /* Stop the fcoe */ 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); 810 811 return rc; 812 } 813 814 static int qed_fcoe_start(struct qed_dev *cdev, struct qed_fcoe_tid *tasks) 815 { 816 int rc; 817 818 if (cdev->flags & QED_FLAG_STORAGE_STARTED) { 819 DP_NOTICE(cdev, "fcoe already started;\n"); 820 return 0; 821 } 822 823 rc = qed_sp_fcoe_func_start(QED_LEADING_HWFN(cdev), 824 QED_SPQ_MODE_EBLOCK, NULL); 825 if (rc) { 826 DP_NOTICE(cdev, "Failed to start fcoe\n"); 827 return rc; 828 } 829 830 cdev->flags |= QED_FLAG_STORAGE_STARTED; 831 hash_init(cdev->connections); 832 833 if (tasks) { 834 struct qed_tid_mem *tid_info = kzalloc(sizeof(*tid_info), 835 GFP_ATOMIC); 836 837 if (!tid_info) { 838 DP_NOTICE(cdev, 839 "Failed to allocate tasks information\n"); 840 qed_fcoe_stop(cdev); 841 return -ENOMEM; 842 } 843 844 rc = qed_cxt_get_tid_mem_info(QED_LEADING_HWFN(cdev), tid_info); 845 if (rc) { 846 DP_NOTICE(cdev, "Failed to gather task information\n"); 847 qed_fcoe_stop(cdev); 848 kfree(tid_info); 849 return rc; 850 } 851 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 *)); 857 858 kfree(tid_info); 859 } 860 861 return 0; 862 } 863 864 static int qed_fcoe_acquire_conn(struct qed_dev *cdev, 865 u32 *handle, 866 u32 *fw_cid, void __iomem **p_doorbell) 867 { 868 struct qed_hash_fcoe_con *hash_con; 869 int rc; 870 871 /* Allocate a hashed connection */ 872 hash_con = kzalloc(sizeof(*hash_con), GFP_KERNEL); 873 if (!hash_con) { 874 DP_NOTICE(cdev, "Failed to allocate hashed connection\n"); 875 return -ENOMEM; 876 } 877 878 /* Acquire the connection */ 879 rc = qed_fcoe_acquire_connection(QED_LEADING_HWFN(cdev), NULL, 880 &hash_con->con); 881 if (rc) { 882 DP_NOTICE(cdev, "Failed to acquire Connection\n"); 883 kfree(hash_con); 884 return rc; 885 } 886 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); 891 892 if (p_doorbell) 893 *p_doorbell = qed_fcoe_get_db_addr(QED_LEADING_HWFN(cdev), 894 *handle); 895 896 return 0; 897 } 898 899 static int qed_fcoe_release_conn(struct qed_dev *cdev, u32 handle) 900 { 901 struct qed_hash_fcoe_con *hash_con; 902 903 hash_con = qed_fcoe_get_hash(cdev, handle); 904 if (!hash_con) { 905 DP_NOTICE(cdev, "Failed to find connection for handle %d\n", 906 handle); 907 return -EINVAL; 908 } 909 910 hlist_del(&hash_con->node); 911 qed_fcoe_release_connection(QED_LEADING_HWFN(cdev), hash_con->con); 912 kfree(hash_con); 913 914 return 0; 915 } 916 917 static int qed_fcoe_offload_conn(struct qed_dev *cdev, 918 u32 handle, 919 struct qed_fcoe_params_offload *conn_info) 920 { 921 struct qed_hash_fcoe_con *hash_con; 922 struct qed_fcoe_conn *con; 923 924 hash_con = qed_fcoe_get_hash(cdev, handle); 925 if (!hash_con) { 926 DP_NOTICE(cdev, "Failed to find connection for handle %d\n", 927 handle); 928 return -EINVAL; 929 } 930 931 /* Update the connection with information from the params */ 932 con = hash_con->con; 933 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; 945 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]; 958 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; 965 966 return qed_sp_fcoe_conn_offload(QED_LEADING_HWFN(cdev), con, 967 QED_SPQ_MODE_EBLOCK, NULL); 968 } 969 970 static int qed_fcoe_destroy_conn(struct qed_dev *cdev, 971 u32 handle, dma_addr_t terminate_params) 972 { 973 struct qed_hash_fcoe_con *hash_con; 974 struct qed_fcoe_conn *con; 975 976 hash_con = qed_fcoe_get_hash(cdev, handle); 977 if (!hash_con) { 978 DP_NOTICE(cdev, "Failed to find connection for handle %d\n", 979 handle); 980 return -EINVAL; 981 } 982 983 /* Update the connection with information from the params */ 984 con = hash_con->con; 985 con->terminate_params = terminate_params; 986 987 return qed_sp_fcoe_conn_destroy(QED_LEADING_HWFN(cdev), con, 988 QED_SPQ_MODE_EBLOCK, NULL); 989 } 990 991 static int qed_fcoe_stats(struct qed_dev *cdev, struct qed_fcoe_stats *stats) 992 { 993 return qed_fcoe_get_stats(QED_LEADING_HWFN(cdev), stats); 994 } 995 996 void qed_get_protocol_stats_fcoe(struct qed_dev *cdev, 997 struct qed_mcp_fcoe_stats *stats) 998 { 999 struct qed_fcoe_stats proto_stats; 1000 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"); 1006 return; 1007 } 1008 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; 1017 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; 1022 1023 if (ops->get_login_failures) 1024 stats->login_failure = ops->get_login_failures(cookie); 1025 } 1026 } 1027 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, 1040 }; 1041 1042 const struct qed_fcoe_ops *qed_get_fcoe_ops(void) 1043 { 1044 return &qed_fcoe_ops_pass; 1045 } 1046 EXPORT_SYMBOL(qed_get_fcoe_ops); 1047 1048 void qed_put_fcoe_ops(void) 1049 { 1050 } 1051 EXPORT_SYMBOL(qed_put_fcoe_ops); 1052