1 /* SPDX-License-Identifier: BSD-3-Clause */ 2 /* Copyright (c) 2024, Intel Corporation 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * 3. Neither the name of the Intel Corporation nor the names of its 16 * contributors may be used to endorse or promote products derived from 17 * this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #include "ice_common.h" 33 #include "ice_switch.h" 34 #include "ice_flex_type.h" 35 #include "ice_flow.h" 36 37 #define ICE_ETH_DA_OFFSET 0 38 #define ICE_ETH_ETHTYPE_OFFSET 12 39 #define ICE_ETH_VLAN_TCI_OFFSET 14 40 #define ICE_MAX_VLAN_ID 0xFFF 41 #define ICE_IPV6_ETHER_ID 0x86DD 42 #define ICE_PPP_IPV6_PROTO_ID 0x0057 43 #define ICE_ETH_P_8021Q 0x8100 44 45 /* Dummy ethernet header needed in the ice_sw_rule_* 46 * struct to configure any switch filter rules. 47 * {DA (6 bytes), SA(6 bytes), 48 * Ether type (2 bytes for header without VLAN tag) OR 49 * VLAN tag (4 bytes for header with VLAN tag) } 50 * 51 * Word on Hardcoded values 52 * byte 0 = 0x2: to identify it as locally administered DA MAC 53 * byte 6 = 0x2: to identify it as locally administered SA MAC 54 * byte 12 = 0x81 & byte 13 = 0x00: 55 * In case of VLAN filter first two bytes defines ether type (0x8100) 56 * and remaining two bytes are placeholder for programming a given VLAN ID 57 * In case of Ether type filter it is treated as header without VLAN tag 58 * and byte 12 and 13 is used to program a given Ether type instead 59 */ 60 static const u8 dummy_eth_header[DUMMY_ETH_HDR_LEN] = { 0x2, 0, 0, 0, 0, 0, 61 0x2, 0, 0, 0, 0, 0, 62 0x81, 0, 0, 0}; 63 64 static bool 65 ice_vsi_uses_fltr(struct ice_fltr_mgmt_list_entry *fm_entry, u16 vsi_handle); 66 67 /** 68 * ice_init_def_sw_recp - initialize the recipe book keeping tables 69 * @hw: pointer to the HW struct 70 * @recp_list: pointer to sw recipe list 71 * 72 * Allocate memory for the entire recipe table and initialize the structures/ 73 * entries corresponding to basic recipes. 74 */ 75 int 76 ice_init_def_sw_recp(struct ice_hw *hw, struct ice_sw_recipe **recp_list) 77 { 78 struct ice_sw_recipe *recps; 79 u8 i; 80 81 recps = (struct ice_sw_recipe *) 82 ice_calloc(hw, ICE_MAX_NUM_RECIPES, sizeof(*recps)); 83 if (!recps) 84 return ICE_ERR_NO_MEMORY; 85 86 for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) { 87 recps[i].root_rid = i; 88 INIT_LIST_HEAD(&recps[i].filt_rules); 89 INIT_LIST_HEAD(&recps[i].filt_replay_rules); 90 INIT_LIST_HEAD(&recps[i].rg_list); 91 ice_init_lock(&recps[i].filt_rule_lock); 92 } 93 94 *recp_list = recps; 95 96 return 0; 97 } 98 99 /** 100 * ice_aq_get_sw_cfg - get switch configuration 101 * @hw: pointer to the hardware structure 102 * @buf: pointer to the result buffer 103 * @buf_size: length of the buffer available for response 104 * @req_desc: pointer to requested descriptor 105 * @num_elems: pointer to number of elements 106 * @cd: pointer to command details structure or NULL 107 * 108 * Get switch configuration (0x0200) to be placed in buf. 109 * This admin command returns information such as initial VSI/port number 110 * and switch ID it belongs to. 111 * 112 * NOTE: *req_desc is both an input/output parameter. 113 * The caller of this function first calls this function with *request_desc set 114 * to 0. If the response from f/w has *req_desc set to 0, all the switch 115 * configuration information has been returned; if non-zero (meaning not all 116 * the information was returned), the caller should call this function again 117 * with *req_desc set to the previous value returned by f/w to get the 118 * next block of switch configuration information. 119 * 120 * *num_elems is output only parameter. This reflects the number of elements 121 * in response buffer. The caller of this function to use *num_elems while 122 * parsing the response buffer. 123 */ 124 static int 125 ice_aq_get_sw_cfg(struct ice_hw *hw, struct ice_aqc_get_sw_cfg_resp_elem *buf, 126 u16 buf_size, u16 *req_desc, u16 *num_elems, 127 struct ice_sq_cd *cd) 128 { 129 struct ice_aqc_get_sw_cfg *cmd; 130 struct ice_aq_desc desc; 131 int status; 132 133 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_sw_cfg); 134 cmd = &desc.params.get_sw_conf; 135 cmd->element = CPU_TO_LE16(*req_desc); 136 137 status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd); 138 if (!status) { 139 *req_desc = LE16_TO_CPU(cmd->element); 140 *num_elems = LE16_TO_CPU(cmd->num_elems); 141 } 142 143 return status; 144 } 145 146 /** 147 * ice_alloc_rss_global_lut - allocate a RSS global LUT 148 * @hw: pointer to the HW struct 149 * @shared_res: true to allocate as a shared resource and false to allocate as a dedicated resource 150 * @global_lut_id: output parameter for the RSS global LUT's ID 151 */ 152 int ice_alloc_rss_global_lut(struct ice_hw *hw, bool shared_res, u16 *global_lut_id) 153 { 154 struct ice_aqc_alloc_free_res_elem *sw_buf; 155 int status; 156 u16 buf_len; 157 158 buf_len = ice_struct_size(sw_buf, elem, 1); 159 sw_buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len); 160 if (!sw_buf) 161 return ICE_ERR_NO_MEMORY; 162 163 sw_buf->num_elems = CPU_TO_LE16(1); 164 sw_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_GLOBAL_RSS_HASH | 165 (shared_res ? ICE_AQC_RES_TYPE_FLAG_SHARED : 166 ICE_AQC_RES_TYPE_FLAG_DEDICATED)); 167 168 status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len, ice_aqc_opc_alloc_res, NULL); 169 if (status) { 170 ice_debug(hw, ICE_DBG_RES, "Failed to allocate %s RSS global LUT, status %d\n", 171 shared_res ? "shared" : "dedicated", status); 172 goto ice_alloc_global_lut_exit; 173 } 174 175 *global_lut_id = LE16_TO_CPU(sw_buf->elem[0].e.sw_resp); 176 177 ice_alloc_global_lut_exit: 178 ice_free(hw, sw_buf); 179 return status; 180 } 181 182 /** 183 * ice_free_rss_global_lut - free a RSS global LUT 184 * @hw: pointer to the HW struct 185 * @global_lut_id: ID of the RSS global LUT to free 186 */ 187 int ice_free_rss_global_lut(struct ice_hw *hw, u16 global_lut_id) 188 { 189 struct ice_aqc_alloc_free_res_elem *sw_buf; 190 u16 buf_len, num_elems = 1; 191 int status; 192 193 buf_len = ice_struct_size(sw_buf, elem, num_elems); 194 sw_buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len); 195 if (!sw_buf) 196 return ICE_ERR_NO_MEMORY; 197 198 sw_buf->num_elems = CPU_TO_LE16(num_elems); 199 sw_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_GLOBAL_RSS_HASH); 200 sw_buf->elem[0].e.sw_resp = CPU_TO_LE16(global_lut_id); 201 202 status = ice_aq_alloc_free_res(hw, num_elems, sw_buf, buf_len, ice_aqc_opc_free_res, NULL); 203 if (status) 204 ice_debug(hw, ICE_DBG_RES, "Failed to free RSS global LUT %d, status %d\n", 205 global_lut_id, status); 206 207 ice_free(hw, sw_buf); 208 return status; 209 } 210 211 /** 212 * ice_alloc_sw - allocate resources specific to switch 213 * @hw: pointer to the HW struct 214 * @ena_stats: true to turn on VEB stats 215 * @shared_res: true for shared resource, false for dedicated resource 216 * @sw_id: switch ID returned 217 * @counter_id: VEB counter ID returned 218 * 219 * allocates switch resources (SWID and VEB counter) (0x0208) 220 */ 221 int 222 ice_alloc_sw(struct ice_hw *hw, bool ena_stats, bool shared_res, u16 *sw_id, 223 u16 *counter_id) 224 { 225 struct ice_aqc_alloc_free_res_elem *sw_buf; 226 struct ice_aqc_res_elem *sw_ele; 227 u16 buf_len; 228 int status; 229 230 buf_len = ice_struct_size(sw_buf, elem, 1); 231 sw_buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len); 232 if (!sw_buf) 233 return ICE_ERR_NO_MEMORY; 234 235 /* Prepare buffer for switch ID. 236 * The number of resource entries in buffer is passed as 1 since only a 237 * single switch/VEB instance is allocated, and hence a single sw_id 238 * is requested. 239 */ 240 sw_buf->num_elems = CPU_TO_LE16(1); 241 sw_buf->res_type = 242 CPU_TO_LE16(ICE_AQC_RES_TYPE_SWID | 243 (shared_res ? ICE_AQC_RES_TYPE_FLAG_SHARED : 244 ICE_AQC_RES_TYPE_FLAG_DEDICATED)); 245 246 status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len, 247 ice_aqc_opc_alloc_res, NULL); 248 249 if (status) 250 goto ice_alloc_sw_exit; 251 252 sw_ele = &sw_buf->elem[0]; 253 *sw_id = LE16_TO_CPU(sw_ele->e.sw_resp); 254 255 if (ena_stats) { 256 /* Prepare buffer for VEB Counter */ 257 enum ice_adminq_opc opc = ice_aqc_opc_alloc_res; 258 struct ice_aqc_alloc_free_res_elem *counter_buf; 259 struct ice_aqc_res_elem *counter_ele; 260 261 counter_buf = (struct ice_aqc_alloc_free_res_elem *) 262 ice_malloc(hw, buf_len); 263 if (!counter_buf) { 264 status = ICE_ERR_NO_MEMORY; 265 goto ice_alloc_sw_exit; 266 } 267 268 /* The number of resource entries in buffer is passed as 1 since 269 * only a single switch/VEB instance is allocated, and hence a 270 * single VEB counter is requested. 271 */ 272 counter_buf->num_elems = CPU_TO_LE16(1); 273 counter_buf->res_type = 274 CPU_TO_LE16(ICE_AQC_RES_TYPE_VEB_COUNTER | 275 ICE_AQC_RES_TYPE_FLAG_DEDICATED); 276 status = ice_aq_alloc_free_res(hw, 1, counter_buf, buf_len, 277 opc, NULL); 278 279 if (status) { 280 ice_free(hw, counter_buf); 281 goto ice_alloc_sw_exit; 282 } 283 counter_ele = &counter_buf->elem[0]; 284 *counter_id = LE16_TO_CPU(counter_ele->e.sw_resp); 285 ice_free(hw, counter_buf); 286 } 287 288 ice_alloc_sw_exit: 289 ice_free(hw, sw_buf); 290 return status; 291 } 292 293 /** 294 * ice_free_sw - free resources specific to switch 295 * @hw: pointer to the HW struct 296 * @sw_id: switch ID returned 297 * @counter_id: VEB counter ID returned 298 * 299 * free switch resources (SWID and VEB counter) (0x0209) 300 * 301 * NOTE: This function frees multiple resources. It continues 302 * releasing other resources even after it encounters error. 303 * The error code returned is the last error it encountered. 304 */ 305 int ice_free_sw(struct ice_hw *hw, u16 sw_id, u16 counter_id) 306 { 307 struct ice_aqc_alloc_free_res_elem *sw_buf, *counter_buf; 308 int status, ret_status; 309 u16 buf_len; 310 311 buf_len = ice_struct_size(sw_buf, elem, 1); 312 sw_buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len); 313 if (!sw_buf) 314 return ICE_ERR_NO_MEMORY; 315 316 /* Prepare buffer to free for switch ID res. 317 * The number of resource entries in buffer is passed as 1 since only a 318 * single switch/VEB instance is freed, and hence a single sw_id 319 * is released. 320 */ 321 sw_buf->num_elems = CPU_TO_LE16(1); 322 sw_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_SWID); 323 sw_buf->elem[0].e.sw_resp = CPU_TO_LE16(sw_id); 324 325 ret_status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len, 326 ice_aqc_opc_free_res, NULL); 327 328 if (ret_status) 329 ice_debug(hw, ICE_DBG_SW, "CQ CMD Buffer:\n"); 330 331 /* Prepare buffer to free for VEB Counter resource */ 332 counter_buf = (struct ice_aqc_alloc_free_res_elem *) 333 ice_malloc(hw, buf_len); 334 if (!counter_buf) { 335 ice_free(hw, sw_buf); 336 return ICE_ERR_NO_MEMORY; 337 } 338 339 /* The number of resource entries in buffer is passed as 1 since only a 340 * single switch/VEB instance is freed, and hence a single VEB counter 341 * is released 342 */ 343 counter_buf->num_elems = CPU_TO_LE16(1); 344 counter_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_VEB_COUNTER); 345 counter_buf->elem[0].e.sw_resp = CPU_TO_LE16(counter_id); 346 347 status = ice_aq_alloc_free_res(hw, 1, counter_buf, buf_len, 348 ice_aqc_opc_free_res, NULL); 349 if (status) { 350 ice_debug(hw, ICE_DBG_SW, "VEB counter resource could not be freed\n"); 351 ret_status = status; 352 } 353 354 ice_free(hw, counter_buf); 355 ice_free(hw, sw_buf); 356 return ret_status; 357 } 358 359 /** 360 * ice_aq_add_vsi 361 * @hw: pointer to the HW struct 362 * @vsi_ctx: pointer to a VSI context struct 363 * @cd: pointer to command details structure or NULL 364 * 365 * Add a VSI context to the hardware (0x0210) 366 */ 367 int 368 ice_aq_add_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx, 369 struct ice_sq_cd *cd) 370 { 371 struct ice_aqc_add_update_free_vsi_resp *res; 372 struct ice_aqc_add_get_update_free_vsi *cmd; 373 struct ice_aq_desc desc; 374 int status; 375 376 cmd = &desc.params.vsi_cmd; 377 res = &desc.params.add_update_free_vsi_res; 378 379 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_add_vsi); 380 381 if (!vsi_ctx->alloc_from_pool) 382 cmd->vsi_num = CPU_TO_LE16(vsi_ctx->vsi_num | 383 ICE_AQ_VSI_IS_VALID); 384 cmd->vf_id = vsi_ctx->vf_num; 385 386 cmd->vsi_flags = CPU_TO_LE16(vsi_ctx->flags); 387 388 desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD); 389 390 status = ice_aq_send_cmd(hw, &desc, &vsi_ctx->info, 391 sizeof(vsi_ctx->info), cd); 392 393 if (!status) { 394 vsi_ctx->vsi_num = LE16_TO_CPU(res->vsi_num) & ICE_AQ_VSI_NUM_M; 395 vsi_ctx->vsis_allocd = LE16_TO_CPU(res->vsi_used); 396 vsi_ctx->vsis_unallocated = LE16_TO_CPU(res->vsi_free); 397 } 398 399 return status; 400 } 401 402 /** 403 * ice_aq_free_vsi 404 * @hw: pointer to the HW struct 405 * @vsi_ctx: pointer to a VSI context struct 406 * @keep_vsi_alloc: keep VSI allocation as part of this PF's resources 407 * @cd: pointer to command details structure or NULL 408 * 409 * Free VSI context info from hardware (0x0213) 410 */ 411 int 412 ice_aq_free_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx, 413 bool keep_vsi_alloc, struct ice_sq_cd *cd) 414 { 415 struct ice_aqc_add_update_free_vsi_resp *resp; 416 struct ice_aqc_add_get_update_free_vsi *cmd; 417 struct ice_aq_desc desc; 418 int status; 419 420 cmd = &desc.params.vsi_cmd; 421 resp = &desc.params.add_update_free_vsi_res; 422 423 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_free_vsi); 424 425 cmd->vsi_num = CPU_TO_LE16(vsi_ctx->vsi_num | ICE_AQ_VSI_IS_VALID); 426 if (keep_vsi_alloc) 427 cmd->cmd_flags = CPU_TO_LE16(ICE_AQ_VSI_KEEP_ALLOC); 428 429 status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd); 430 if (!status) { 431 vsi_ctx->vsis_allocd = LE16_TO_CPU(resp->vsi_used); 432 vsi_ctx->vsis_unallocated = LE16_TO_CPU(resp->vsi_free); 433 } 434 435 return status; 436 } 437 438 /** 439 * ice_aq_update_vsi 440 * @hw: pointer to the HW struct 441 * @vsi_ctx: pointer to a VSI context struct 442 * @cd: pointer to command details structure or NULL 443 * 444 * Update VSI context in the hardware (0x0211) 445 */ 446 int 447 ice_aq_update_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx, 448 struct ice_sq_cd *cd) 449 { 450 struct ice_aqc_add_update_free_vsi_resp *resp; 451 struct ice_aqc_add_get_update_free_vsi *cmd; 452 struct ice_aq_desc desc; 453 int status; 454 455 cmd = &desc.params.vsi_cmd; 456 resp = &desc.params.add_update_free_vsi_res; 457 458 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_update_vsi); 459 460 cmd->vsi_num = CPU_TO_LE16(vsi_ctx->vsi_num | ICE_AQ_VSI_IS_VALID); 461 462 desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD); 463 464 status = ice_aq_send_cmd(hw, &desc, &vsi_ctx->info, 465 sizeof(vsi_ctx->info), cd); 466 467 if (!status) { 468 vsi_ctx->vsis_allocd = LE16_TO_CPU(resp->vsi_used); 469 vsi_ctx->vsis_unallocated = LE16_TO_CPU(resp->vsi_free); 470 } 471 472 return status; 473 } 474 475 /** 476 * ice_is_vsi_valid - check whether the VSI is valid or not 477 * @hw: pointer to the HW struct 478 * @vsi_handle: VSI handle 479 * 480 * check whether the VSI is valid or not 481 */ 482 bool ice_is_vsi_valid(struct ice_hw *hw, u16 vsi_handle) 483 { 484 return vsi_handle < ICE_MAX_VSI && hw->vsi_ctx[vsi_handle]; 485 } 486 487 /** 488 * ice_get_hw_vsi_num - return the HW VSI number 489 * @hw: pointer to the HW struct 490 * @vsi_handle: VSI handle 491 * 492 * return the HW VSI number 493 * Caution: call this function only if VSI is valid (ice_is_vsi_valid) 494 */ 495 u16 ice_get_hw_vsi_num(struct ice_hw *hw, u16 vsi_handle) 496 { 497 return hw->vsi_ctx[vsi_handle]->vsi_num; 498 } 499 500 /** 501 * ice_get_vsi_ctx - return the VSI context entry for a given VSI handle 502 * @hw: pointer to the HW struct 503 * @vsi_handle: VSI handle 504 * 505 * return the VSI context entry for a given VSI handle 506 */ 507 struct ice_vsi_ctx *ice_get_vsi_ctx(struct ice_hw *hw, u16 vsi_handle) 508 { 509 return (vsi_handle >= ICE_MAX_VSI) ? NULL : hw->vsi_ctx[vsi_handle]; 510 } 511 512 /** 513 * ice_save_vsi_ctx - save the VSI context for a given VSI handle 514 * @hw: pointer to the HW struct 515 * @vsi_handle: VSI handle 516 * @vsi: VSI context pointer 517 * 518 * save the VSI context entry for a given VSI handle 519 */ 520 static void 521 ice_save_vsi_ctx(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi) 522 { 523 hw->vsi_ctx[vsi_handle] = vsi; 524 } 525 526 /** 527 * ice_clear_vsi_q_ctx - clear VSI queue contexts for all TCs 528 * @hw: pointer to the HW struct 529 * @vsi_handle: VSI handle 530 */ 531 void ice_clear_vsi_q_ctx(struct ice_hw *hw, u16 vsi_handle) 532 { 533 struct ice_vsi_ctx *vsi; 534 u8 i; 535 536 vsi = ice_get_vsi_ctx(hw, vsi_handle); 537 if (!vsi) 538 return; 539 ice_for_each_traffic_class(i) { 540 if (vsi->lan_q_ctx[i]) { 541 ice_free(hw, vsi->lan_q_ctx[i]); 542 vsi->lan_q_ctx[i] = NULL; 543 } 544 if (vsi->rdma_q_ctx[i]) { 545 ice_free(hw, vsi->rdma_q_ctx[i]); 546 vsi->rdma_q_ctx[i] = NULL; 547 } 548 } 549 } 550 551 /** 552 * ice_clear_vsi_ctx - clear the VSI context entry 553 * @hw: pointer to the HW struct 554 * @vsi_handle: VSI handle 555 * 556 * clear the VSI context entry 557 */ 558 static void ice_clear_vsi_ctx(struct ice_hw *hw, u16 vsi_handle) 559 { 560 struct ice_vsi_ctx *vsi; 561 562 vsi = ice_get_vsi_ctx(hw, vsi_handle); 563 if (vsi) { 564 ice_clear_vsi_q_ctx(hw, vsi_handle); 565 ice_free(hw, vsi); 566 hw->vsi_ctx[vsi_handle] = NULL; 567 } 568 } 569 570 /** 571 * ice_clear_all_vsi_ctx - clear all the VSI context entries 572 * @hw: pointer to the HW struct 573 */ 574 void ice_clear_all_vsi_ctx(struct ice_hw *hw) 575 { 576 u16 i; 577 578 for (i = 0; i < ICE_MAX_VSI; i++) 579 ice_clear_vsi_ctx(hw, i); 580 } 581 582 /** 583 * ice_add_vsi - add VSI context to the hardware and VSI handle list 584 * @hw: pointer to the HW struct 585 * @vsi_handle: unique VSI handle provided by drivers 586 * @vsi_ctx: pointer to a VSI context struct 587 * @cd: pointer to command details structure or NULL 588 * 589 * Add a VSI context to the hardware also add it into the VSI handle list. 590 * If this function gets called after reset for existing VSIs then update 591 * with the new HW VSI number in the corresponding VSI handle list entry. 592 */ 593 int 594 ice_add_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx, 595 struct ice_sq_cd *cd) 596 { 597 struct ice_vsi_ctx *tmp_vsi_ctx; 598 int status; 599 600 if (vsi_handle >= ICE_MAX_VSI) 601 return ICE_ERR_PARAM; 602 status = ice_aq_add_vsi(hw, vsi_ctx, cd); 603 if (status) 604 return status; 605 tmp_vsi_ctx = ice_get_vsi_ctx(hw, vsi_handle); 606 if (!tmp_vsi_ctx) { 607 /* Create a new VSI context */ 608 tmp_vsi_ctx = (struct ice_vsi_ctx *) 609 ice_malloc(hw, sizeof(*tmp_vsi_ctx)); 610 if (!tmp_vsi_ctx) { 611 ice_aq_free_vsi(hw, vsi_ctx, false, cd); 612 return ICE_ERR_NO_MEMORY; 613 } 614 *tmp_vsi_ctx = *vsi_ctx; 615 616 ice_save_vsi_ctx(hw, vsi_handle, tmp_vsi_ctx); 617 } else { 618 /* update with new HW VSI num */ 619 tmp_vsi_ctx->vsi_num = vsi_ctx->vsi_num; 620 } 621 622 return 0; 623 } 624 625 /** 626 * ice_free_vsi- free VSI context from hardware and VSI handle list 627 * @hw: pointer to the HW struct 628 * @vsi_handle: unique VSI handle 629 * @vsi_ctx: pointer to a VSI context struct 630 * @keep_vsi_alloc: keep VSI allocation as part of this PF's resources 631 * @cd: pointer to command details structure or NULL 632 * 633 * Free VSI context info from hardware as well as from VSI handle list 634 */ 635 int 636 ice_free_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx, 637 bool keep_vsi_alloc, struct ice_sq_cd *cd) 638 { 639 int status; 640 641 if (!ice_is_vsi_valid(hw, vsi_handle)) 642 return ICE_ERR_PARAM; 643 vsi_ctx->vsi_num = ice_get_hw_vsi_num(hw, vsi_handle); 644 status = ice_aq_free_vsi(hw, vsi_ctx, keep_vsi_alloc, cd); 645 if (!status) 646 ice_clear_vsi_ctx(hw, vsi_handle); 647 return status; 648 } 649 650 /** 651 * ice_update_vsi 652 * @hw: pointer to the HW struct 653 * @vsi_handle: unique VSI handle 654 * @vsi_ctx: pointer to a VSI context struct 655 * @cd: pointer to command details structure or NULL 656 * 657 * Update VSI context in the hardware 658 */ 659 int 660 ice_update_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx, 661 struct ice_sq_cd *cd) 662 { 663 if (!ice_is_vsi_valid(hw, vsi_handle)) 664 return ICE_ERR_PARAM; 665 vsi_ctx->vsi_num = ice_get_hw_vsi_num(hw, vsi_handle); 666 return ice_aq_update_vsi(hw, vsi_ctx, cd); 667 } 668 669 /** 670 * ice_cfg_iwarp_fltr - enable/disable iWARP filtering on VSI 671 * @hw: pointer to HW struct 672 * @vsi_handle: VSI SW index 673 * @enable: boolean for enable/disable 674 */ 675 int 676 ice_cfg_iwarp_fltr(struct ice_hw *hw, u16 vsi_handle, bool enable) 677 { 678 struct ice_vsi_ctx *ctx, *cached_ctx; 679 int status; 680 681 cached_ctx = ice_get_vsi_ctx(hw, vsi_handle); 682 if (!cached_ctx) 683 return ICE_ERR_DOES_NOT_EXIST; 684 685 ctx = (struct ice_vsi_ctx *)ice_calloc(hw, 1, sizeof(*ctx)); 686 if (!ctx) 687 return ICE_ERR_NO_MEMORY; 688 689 ctx->info.q_opt_rss = cached_ctx->info.q_opt_rss; 690 ctx->info.q_opt_tc = cached_ctx->info.q_opt_tc; 691 ctx->info.q_opt_flags = cached_ctx->info.q_opt_flags; 692 693 ctx->info.valid_sections = CPU_TO_LE16(ICE_AQ_VSI_PROP_Q_OPT_VALID); 694 695 if (enable) 696 ctx->info.q_opt_flags |= ICE_AQ_VSI_Q_OPT_PE_FLTR_EN; 697 else 698 ctx->info.q_opt_flags &= ~ICE_AQ_VSI_Q_OPT_PE_FLTR_EN; 699 700 status = ice_update_vsi(hw, vsi_handle, ctx, NULL); 701 if (!status) { 702 cached_ctx->info.q_opt_flags = ctx->info.q_opt_flags; 703 cached_ctx->info.valid_sections |= ctx->info.valid_sections; 704 } 705 706 ice_free(hw, ctx); 707 return status; 708 } 709 710 /** 711 * ice_aq_get_vsi_params 712 * @hw: pointer to the HW struct 713 * @vsi_ctx: pointer to a VSI context struct 714 * @cd: pointer to command details structure or NULL 715 * 716 * Get VSI context info from hardware (0x0212) 717 */ 718 int 719 ice_aq_get_vsi_params(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx, 720 struct ice_sq_cd *cd) 721 { 722 struct ice_aqc_add_get_update_free_vsi *cmd; 723 struct ice_aqc_get_vsi_resp *resp; 724 struct ice_aq_desc desc; 725 int status; 726 727 cmd = &desc.params.vsi_cmd; 728 resp = &desc.params.get_vsi_resp; 729 730 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_vsi_params); 731 732 cmd->vsi_num = CPU_TO_LE16(vsi_ctx->vsi_num | ICE_AQ_VSI_IS_VALID); 733 734 status = ice_aq_send_cmd(hw, &desc, &vsi_ctx->info, 735 sizeof(vsi_ctx->info), cd); 736 if (!status) { 737 vsi_ctx->vsi_num = LE16_TO_CPU(resp->vsi_num) & 738 ICE_AQ_VSI_NUM_M; 739 vsi_ctx->vf_num = resp->vf_id; 740 vsi_ctx->vsis_allocd = LE16_TO_CPU(resp->vsi_used); 741 vsi_ctx->vsis_unallocated = LE16_TO_CPU(resp->vsi_free); 742 } 743 744 return status; 745 } 746 747 /** 748 * ice_aq_add_update_mir_rule - add/update a mirror rule 749 * @hw: pointer to the HW struct 750 * @rule_type: Rule Type 751 * @dest_vsi: VSI number to which packets will be mirrored 752 * @count: length of the list 753 * @mr_buf: buffer for list of mirrored VSI numbers 754 * @cd: pointer to command details structure or NULL 755 * @rule_id: Rule ID 756 * 757 * Add/Update Mirror Rule (0x260). 758 */ 759 int 760 ice_aq_add_update_mir_rule(struct ice_hw *hw, u16 rule_type, u16 dest_vsi, 761 u16 count, struct ice_mir_rule_buf *mr_buf, 762 struct ice_sq_cd *cd, u16 *rule_id) 763 { 764 struct ice_aqc_add_update_mir_rule *cmd; 765 struct ice_aq_desc desc; 766 __le16 *mr_list = NULL; 767 u16 buf_size = 0; 768 int status; 769 770 switch (rule_type) { 771 case ICE_AQC_RULE_TYPE_VPORT_INGRESS: 772 case ICE_AQC_RULE_TYPE_VPORT_EGRESS: 773 /* Make sure count and mr_buf are set for these rule_types */ 774 if (!(count && mr_buf)) 775 return ICE_ERR_PARAM; 776 777 buf_size = count * sizeof(__le16); 778 mr_list = (_FORCE_ __le16 *)ice_malloc(hw, buf_size); 779 if (!mr_list) 780 return ICE_ERR_NO_MEMORY; 781 break; 782 case ICE_AQC_RULE_TYPE_PPORT_INGRESS: 783 case ICE_AQC_RULE_TYPE_PPORT_EGRESS: 784 /* Make sure count and mr_buf are not set for these 785 * rule_types 786 */ 787 if (count || mr_buf) 788 return ICE_ERR_PARAM; 789 break; 790 default: 791 ice_debug(hw, ICE_DBG_SW, "Error due to unsupported rule_type %u\n", rule_type); 792 return ICE_ERR_OUT_OF_RANGE; 793 } 794 795 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_add_update_mir_rule); 796 797 /* Pre-process 'mr_buf' items for add/update of virtual port 798 * ingress/egress mirroring (but not physical port ingress/egress 799 * mirroring) 800 */ 801 if (mr_buf) { 802 int i; 803 804 for (i = 0; i < count; i++) { 805 u16 id; 806 807 id = mr_buf[i].vsi_idx & ICE_AQC_RULE_MIRRORED_VSI_M; 808 809 /* Validate specified VSI number, make sure it is less 810 * than ICE_MAX_VSI, if not return with error. 811 */ 812 if (id >= ICE_MAX_VSI) { 813 ice_debug(hw, ICE_DBG_SW, "Error VSI index (%u) out-of-range\n", 814 id); 815 ice_free(hw, mr_list); 816 return ICE_ERR_OUT_OF_RANGE; 817 } 818 819 /* add VSI to mirror rule */ 820 if (mr_buf[i].add) 821 mr_list[i] = 822 CPU_TO_LE16(id | ICE_AQC_RULE_ACT_M); 823 else /* remove VSI from mirror rule */ 824 mr_list[i] = CPU_TO_LE16(id); 825 } 826 827 desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD); 828 } 829 830 cmd = &desc.params.add_update_rule; 831 if ((*rule_id) != ICE_INVAL_MIRROR_RULE_ID) 832 cmd->rule_id = CPU_TO_LE16(((*rule_id) & ICE_AQC_RULE_ID_M) | 833 ICE_AQC_RULE_ID_VALID_M); 834 cmd->rule_type = CPU_TO_LE16(rule_type & ICE_AQC_RULE_TYPE_M); 835 cmd->num_entries = CPU_TO_LE16(count); 836 cmd->dest = CPU_TO_LE16(dest_vsi); 837 838 status = ice_aq_send_cmd(hw, &desc, mr_list, buf_size, cd); 839 if (!status) 840 *rule_id = LE16_TO_CPU(cmd->rule_id) & ICE_AQC_RULE_ID_M; 841 842 ice_free(hw, mr_list); 843 844 return status; 845 } 846 847 /** 848 * ice_aq_delete_mir_rule - delete a mirror rule 849 * @hw: pointer to the HW struct 850 * @rule_id: Mirror rule ID (to be deleted) 851 * @keep_allocd: if set, the VSI stays part of the PF allocated res, 852 * otherwise it is returned to the shared pool 853 * @cd: pointer to command details structure or NULL 854 * 855 * Delete Mirror Rule (0x261). 856 */ 857 int 858 ice_aq_delete_mir_rule(struct ice_hw *hw, u16 rule_id, bool keep_allocd, 859 struct ice_sq_cd *cd) 860 { 861 struct ice_aqc_delete_mir_rule *cmd; 862 struct ice_aq_desc desc; 863 864 /* rule_id should be in the range 0...63 */ 865 if (rule_id >= ICE_MAX_NUM_MIRROR_RULES) 866 return ICE_ERR_OUT_OF_RANGE; 867 868 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_del_mir_rule); 869 870 cmd = &desc.params.del_rule; 871 rule_id |= ICE_AQC_RULE_ID_VALID_M; 872 cmd->rule_id = CPU_TO_LE16(rule_id); 873 874 if (keep_allocd) 875 cmd->flags = CPU_TO_LE16(ICE_AQC_FLAG_KEEP_ALLOCD_M); 876 877 return ice_aq_send_cmd(hw, &desc, NULL, 0, cd); 878 } 879 880 /** 881 * ice_aq_alloc_free_vsi_list 882 * @hw: pointer to the HW struct 883 * @vsi_list_id: VSI list ID returned or used for lookup 884 * @lkup_type: switch rule filter lookup type 885 * @opc: switch rules population command type - pass in the command opcode 886 * 887 * allocates or free a VSI list resource 888 */ 889 static int 890 ice_aq_alloc_free_vsi_list(struct ice_hw *hw, u16 *vsi_list_id, 891 enum ice_sw_lkup_type lkup_type, 892 enum ice_adminq_opc opc) 893 { 894 struct ice_aqc_alloc_free_res_elem *sw_buf; 895 struct ice_aqc_res_elem *vsi_ele; 896 u16 buf_len; 897 int status; 898 899 buf_len = ice_struct_size(sw_buf, elem, 1); 900 sw_buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len); 901 if (!sw_buf) 902 return ICE_ERR_NO_MEMORY; 903 sw_buf->num_elems = CPU_TO_LE16(1); 904 905 if (lkup_type == ICE_SW_LKUP_MAC || 906 lkup_type == ICE_SW_LKUP_MAC_VLAN || 907 lkup_type == ICE_SW_LKUP_ETHERTYPE || 908 lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC || 909 lkup_type == ICE_SW_LKUP_PROMISC || 910 lkup_type == ICE_SW_LKUP_PROMISC_VLAN || 911 lkup_type == ICE_SW_LKUP_DFLT || 912 lkup_type == ICE_SW_LKUP_LAST) { 913 sw_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_VSI_LIST_REP); 914 } else if (lkup_type == ICE_SW_LKUP_VLAN) { 915 sw_buf->res_type = 916 CPU_TO_LE16(ICE_AQC_RES_TYPE_VSI_LIST_PRUNE); 917 } else { 918 status = ICE_ERR_PARAM; 919 goto ice_aq_alloc_free_vsi_list_exit; 920 } 921 922 if (opc == ice_aqc_opc_free_res) 923 sw_buf->elem[0].e.sw_resp = CPU_TO_LE16(*vsi_list_id); 924 925 status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len, opc, NULL); 926 if (status) 927 goto ice_aq_alloc_free_vsi_list_exit; 928 929 if (opc == ice_aqc_opc_alloc_res) { 930 vsi_ele = &sw_buf->elem[0]; 931 *vsi_list_id = LE16_TO_CPU(vsi_ele->e.sw_resp); 932 } 933 934 ice_aq_alloc_free_vsi_list_exit: 935 ice_free(hw, sw_buf); 936 return status; 937 } 938 939 /** 940 * ice_aq_set_storm_ctrl - Sets storm control configuration 941 * @hw: pointer to the HW struct 942 * @bcast_thresh: represents the upper threshold for broadcast storm control 943 * @mcast_thresh: represents the upper threshold for multicast storm control 944 * @ctl_bitmask: storm control knobs 945 * 946 * Sets the storm control configuration (0x0280) 947 */ 948 int 949 ice_aq_set_storm_ctrl(struct ice_hw *hw, u32 bcast_thresh, u32 mcast_thresh, 950 u32 ctl_bitmask) 951 { 952 struct ice_aqc_storm_cfg *cmd; 953 struct ice_aq_desc desc; 954 955 cmd = &desc.params.storm_conf; 956 957 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_storm_cfg); 958 959 cmd->bcast_thresh_size = CPU_TO_LE32(bcast_thresh & ICE_AQ_THRESHOLD_M); 960 cmd->mcast_thresh_size = CPU_TO_LE32(mcast_thresh & ICE_AQ_THRESHOLD_M); 961 cmd->storm_ctrl_ctrl = CPU_TO_LE32(ctl_bitmask); 962 963 return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL); 964 } 965 966 /** 967 * ice_aq_get_storm_ctrl - gets storm control configuration 968 * @hw: pointer to the HW struct 969 * @bcast_thresh: represents the upper threshold for broadcast storm control 970 * @mcast_thresh: represents the upper threshold for multicast storm control 971 * @ctl_bitmask: storm control knobs 972 * 973 * Gets the storm control configuration (0x0281) 974 */ 975 int 976 ice_aq_get_storm_ctrl(struct ice_hw *hw, u32 *bcast_thresh, u32 *mcast_thresh, 977 u32 *ctl_bitmask) 978 { 979 struct ice_aq_desc desc; 980 int status; 981 982 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_storm_cfg); 983 984 status = ice_aq_send_cmd(hw, &desc, NULL, 0, NULL); 985 if (!status) { 986 struct ice_aqc_storm_cfg *resp = &desc.params.storm_conf; 987 988 if (bcast_thresh) 989 *bcast_thresh = LE32_TO_CPU(resp->bcast_thresh_size) & 990 ICE_AQ_THRESHOLD_M; 991 if (mcast_thresh) 992 *mcast_thresh = LE32_TO_CPU(resp->mcast_thresh_size) & 993 ICE_AQ_THRESHOLD_M; 994 if (ctl_bitmask) 995 *ctl_bitmask = LE32_TO_CPU(resp->storm_ctrl_ctrl); 996 } 997 998 return status; 999 } 1000 1001 /** 1002 * ice_aq_sw_rules - add/update/remove switch rules 1003 * @hw: pointer to the HW struct 1004 * @rule_list: pointer to switch rule population list 1005 * @rule_list_sz: total size of the rule list in bytes 1006 * @num_rules: number of switch rules in the rule_list 1007 * @opc: switch rules population command type - pass in the command opcode 1008 * @cd: pointer to command details structure or NULL 1009 * 1010 * Add(0x02a0)/Update(0x02a1)/Remove(0x02a2) switch rules commands to firmware 1011 */ 1012 int 1013 ice_aq_sw_rules(struct ice_hw *hw, void *rule_list, u16 rule_list_sz, 1014 u8 num_rules, enum ice_adminq_opc opc, struct ice_sq_cd *cd) 1015 { 1016 struct ice_aq_desc desc; 1017 int status; 1018 1019 ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__); 1020 1021 if (opc != ice_aqc_opc_add_sw_rules && 1022 opc != ice_aqc_opc_update_sw_rules && 1023 opc != ice_aqc_opc_remove_sw_rules) 1024 return ICE_ERR_PARAM; 1025 1026 ice_fill_dflt_direct_cmd_desc(&desc, opc); 1027 1028 desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD); 1029 desc.params.sw_rules.num_rules_fltr_entry_index = 1030 CPU_TO_LE16(num_rules); 1031 status = ice_aq_send_cmd(hw, &desc, rule_list, rule_list_sz, cd); 1032 if (opc != ice_aqc_opc_add_sw_rules && 1033 hw->adminq.sq_last_status == ICE_AQ_RC_ENOENT) 1034 status = ICE_ERR_DOES_NOT_EXIST; 1035 1036 return status; 1037 } 1038 1039 /* ice_init_port_info - Initialize port_info with switch configuration data 1040 * @pi: pointer to port_info 1041 * @vsi_port_num: VSI number or port number 1042 * @type: Type of switch element (port or VSI) 1043 * @swid: switch ID of the switch the element is attached to 1044 * @pf_vf_num: PF or VF number 1045 * @is_vf: true if the element is a VF, false otherwise 1046 */ 1047 static void 1048 ice_init_port_info(struct ice_port_info *pi, u16 vsi_port_num, u8 type, 1049 u16 swid, u16 pf_vf_num, bool is_vf) 1050 { 1051 switch (type) { 1052 case ICE_AQC_GET_SW_CONF_RESP_PHYS_PORT: 1053 pi->lport = (u8)(vsi_port_num & ICE_LPORT_MASK); 1054 pi->sw_id = swid; 1055 pi->pf_vf_num = pf_vf_num; 1056 pi->is_vf = is_vf; 1057 break; 1058 default: 1059 ice_debug(pi->hw, ICE_DBG_SW, "incorrect VSI/port type received\n"); 1060 break; 1061 } 1062 } 1063 1064 /* ice_get_initial_sw_cfg - Get initial port and default VSI data 1065 * @hw: pointer to the hardware structure 1066 */ 1067 int ice_get_initial_sw_cfg(struct ice_hw *hw) 1068 { 1069 struct ice_aqc_get_sw_cfg_resp_elem *rbuf; 1070 u8 num_total_ports; 1071 u16 req_desc = 0; 1072 u16 num_elems; 1073 int status; 1074 u8 j = 0; 1075 u16 i; 1076 1077 num_total_ports = 1; 1078 1079 rbuf = (struct ice_aqc_get_sw_cfg_resp_elem *) 1080 ice_malloc(hw, ICE_SW_CFG_MAX_BUF_LEN); 1081 1082 if (!rbuf) 1083 return ICE_ERR_NO_MEMORY; 1084 1085 /* Multiple calls to ice_aq_get_sw_cfg may be required 1086 * to get all the switch configuration information. The need 1087 * for additional calls is indicated by ice_aq_get_sw_cfg 1088 * writing a non-zero value in req_desc 1089 */ 1090 do { 1091 struct ice_aqc_get_sw_cfg_resp_elem *ele; 1092 1093 status = ice_aq_get_sw_cfg(hw, rbuf, ICE_SW_CFG_MAX_BUF_LEN, 1094 &req_desc, &num_elems, NULL); 1095 1096 if (status) 1097 break; 1098 1099 for (i = 0, ele = rbuf; i < num_elems; i++, ele++) { 1100 u16 pf_vf_num, swid, vsi_port_num; 1101 bool is_vf = false; 1102 u8 res_type; 1103 1104 vsi_port_num = LE16_TO_CPU(ele->vsi_port_num) & 1105 ICE_AQC_GET_SW_CONF_RESP_VSI_PORT_NUM_M; 1106 1107 pf_vf_num = LE16_TO_CPU(ele->pf_vf_num) & 1108 ICE_AQC_GET_SW_CONF_RESP_FUNC_NUM_M; 1109 1110 swid = LE16_TO_CPU(ele->swid); 1111 1112 if (LE16_TO_CPU(ele->pf_vf_num) & 1113 ICE_AQC_GET_SW_CONF_RESP_IS_VF) 1114 is_vf = true; 1115 1116 res_type = (u8)(LE16_TO_CPU(ele->vsi_port_num) >> 1117 ICE_AQC_GET_SW_CONF_RESP_TYPE_S); 1118 1119 switch (res_type) { 1120 case ICE_AQC_GET_SW_CONF_RESP_VSI: 1121 if (hw->fw_vsi_num != ICE_DFLT_VSI_INVAL) 1122 ice_debug(hw, ICE_DBG_SW, "fw_vsi_num %d -> %d\n", 1123 hw->fw_vsi_num, vsi_port_num); 1124 hw->fw_vsi_num = vsi_port_num; 1125 break; 1126 case ICE_AQC_GET_SW_CONF_RESP_PHYS_PORT: 1127 case ICE_AQC_GET_SW_CONF_RESP_VIRT_PORT: 1128 if (j == num_total_ports) { 1129 ice_debug(hw, ICE_DBG_SW, "more ports than expected\n"); 1130 status = ICE_ERR_CFG; 1131 goto out; 1132 } 1133 ice_init_port_info(hw->port_info, 1134 vsi_port_num, res_type, swid, 1135 pf_vf_num, is_vf); 1136 j++; 1137 break; 1138 default: 1139 break; 1140 } 1141 } 1142 } while (req_desc && !status); 1143 1144 out: 1145 ice_free(hw, rbuf); 1146 return status; 1147 } 1148 1149 /** 1150 * ice_fill_sw_info - Helper function to populate lb_en and lan_en 1151 * @hw: pointer to the hardware structure 1152 * @fi: filter info structure to fill/update 1153 * 1154 * This helper function populates the lb_en and lan_en elements of the provided 1155 * ice_fltr_info struct using the switch's type and characteristics of the 1156 * switch rule being configured. 1157 */ 1158 static void ice_fill_sw_info(struct ice_hw *hw, struct ice_fltr_info *fi) 1159 { 1160 fi->lb_en = false; 1161 fi->lan_en = false; 1162 if ((fi->flag & ICE_FLTR_TX) && 1163 (fi->fltr_act == ICE_FWD_TO_VSI || 1164 fi->fltr_act == ICE_FWD_TO_VSI_LIST || 1165 fi->fltr_act == ICE_FWD_TO_Q || 1166 fi->fltr_act == ICE_FWD_TO_QGRP)) { 1167 /* Setting LB for prune actions will result in replicated 1168 * packets to the internal switch that will be dropped. 1169 */ 1170 if (fi->lkup_type != ICE_SW_LKUP_VLAN) 1171 fi->lb_en = true; 1172 1173 /* Set lan_en to TRUE if 1174 * 1. The switch is a VEB AND 1175 * 2 1176 * 2.1 The lookup is a directional lookup like ethertype, 1177 * promiscuous, ethertype-MAC, promiscuous-VLAN 1178 * and default-port OR 1179 * 2.2 The lookup is VLAN, OR 1180 * 2.3 The lookup is MAC with mcast or bcast addr for MAC, OR 1181 * 2.4 The lookup is MAC_VLAN with mcast or bcast addr for MAC. 1182 * 1183 * OR 1184 * 1185 * The switch is a VEPA. 1186 * 1187 * In all other cases, the LAN enable has to be set to false. 1188 */ 1189 1190 if (hw->evb_veb) { 1191 if (fi->lkup_type == ICE_SW_LKUP_ETHERTYPE || 1192 fi->lkup_type == ICE_SW_LKUP_PROMISC || 1193 fi->lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC || 1194 fi->lkup_type == ICE_SW_LKUP_PROMISC_VLAN || 1195 fi->lkup_type == ICE_SW_LKUP_DFLT || 1196 fi->lkup_type == ICE_SW_LKUP_VLAN || 1197 (fi->lkup_type == ICE_SW_LKUP_MAC && 1198 !IS_UNICAST_ETHER_ADDR(fi->l_data.mac.mac_addr)) || 1199 (fi->lkup_type == ICE_SW_LKUP_MAC_VLAN && 1200 !IS_UNICAST_ETHER_ADDR(fi->l_data.mac.mac_addr))) { 1201 if (!fi->fltVeb_en) 1202 fi->lan_en = true; 1203 } 1204 } else { 1205 fi->lan_en = true; 1206 } 1207 } 1208 /* To be able to receive packets coming from the VF on the same PF, 1209 * unicast filter needs to be added without LB_EN bit 1210 */ 1211 if (fi->flag & ICE_FLTR_RX_LB) { 1212 fi->lb_en = false; 1213 fi->lan_en = true; 1214 } 1215 } 1216 1217 /** 1218 * ice_fill_sw_rule - Helper function to fill switch rule structure 1219 * @hw: pointer to the hardware structure 1220 * @f_info: entry containing packet forwarding information 1221 * @s_rule: switch rule structure to be filled in based on mac_entry 1222 * @opc: switch rules population command type - pass in the command opcode 1223 */ 1224 static void 1225 ice_fill_sw_rule(struct ice_hw *hw, struct ice_fltr_info *f_info, 1226 struct ice_sw_rule_lkup_rx_tx *s_rule, 1227 enum ice_adminq_opc opc) 1228 { 1229 u16 vlan_id = ICE_MAX_VLAN_ID + 1; 1230 u16 vlan_tpid = ICE_ETH_P_8021Q; 1231 void *daddr = NULL; 1232 u16 eth_hdr_sz; 1233 u8 *eth_hdr; 1234 u32 act = 0; 1235 __be16 *off; 1236 u8 q_rgn; 1237 1238 if (opc == ice_aqc_opc_remove_sw_rules) { 1239 s_rule->act = 0; 1240 s_rule->index = CPU_TO_LE16(f_info->fltr_rule_id); 1241 s_rule->hdr_len = 0; 1242 return; 1243 } 1244 1245 eth_hdr_sz = sizeof(dummy_eth_header); 1246 eth_hdr = s_rule->hdr_data; 1247 1248 /* initialize the ether header with a dummy header */ 1249 ice_memcpy(eth_hdr, dummy_eth_header, eth_hdr_sz, ICE_NONDMA_TO_NONDMA); 1250 ice_fill_sw_info(hw, f_info); 1251 1252 switch (f_info->fltr_act) { 1253 case ICE_FWD_TO_VSI: 1254 act |= (f_info->fwd_id.hw_vsi_id << ICE_SINGLE_ACT_VSI_ID_S) & 1255 ICE_SINGLE_ACT_VSI_ID_M; 1256 if (f_info->lkup_type != ICE_SW_LKUP_VLAN) 1257 act |= ICE_SINGLE_ACT_VSI_FORWARDING | 1258 ICE_SINGLE_ACT_VALID_BIT; 1259 break; 1260 case ICE_FWD_TO_VSI_LIST: 1261 act |= ICE_SINGLE_ACT_VSI_LIST; 1262 act |= (f_info->fwd_id.vsi_list_id << 1263 ICE_SINGLE_ACT_VSI_LIST_ID_S) & 1264 ICE_SINGLE_ACT_VSI_LIST_ID_M; 1265 if (f_info->lkup_type != ICE_SW_LKUP_VLAN) 1266 act |= ICE_SINGLE_ACT_VSI_FORWARDING | 1267 ICE_SINGLE_ACT_VALID_BIT; 1268 break; 1269 case ICE_FWD_TO_Q: 1270 act |= ICE_SINGLE_ACT_TO_Q; 1271 act |= (f_info->fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) & 1272 ICE_SINGLE_ACT_Q_INDEX_M; 1273 break; 1274 case ICE_DROP_PACKET: 1275 act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_DROP | 1276 ICE_SINGLE_ACT_VALID_BIT; 1277 break; 1278 case ICE_FWD_TO_QGRP: 1279 q_rgn = f_info->qgrp_size > 0 ? 1280 (u8)ice_ilog2(f_info->qgrp_size) : 0; 1281 act |= ICE_SINGLE_ACT_TO_Q; 1282 act |= (f_info->fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) & 1283 ICE_SINGLE_ACT_Q_INDEX_M; 1284 act |= (q_rgn << ICE_SINGLE_ACT_Q_REGION_S) & 1285 ICE_SINGLE_ACT_Q_REGION_M; 1286 break; 1287 default: 1288 return; 1289 } 1290 1291 if (f_info->lb_en) 1292 act |= ICE_SINGLE_ACT_LB_ENABLE; 1293 if (f_info->lan_en) 1294 act |= ICE_SINGLE_ACT_LAN_ENABLE; 1295 1296 switch (f_info->lkup_type) { 1297 case ICE_SW_LKUP_MAC: 1298 daddr = f_info->l_data.mac.mac_addr; 1299 break; 1300 case ICE_SW_LKUP_VLAN: 1301 vlan_id = f_info->l_data.vlan.vlan_id; 1302 if (f_info->l_data.vlan.tpid_valid) 1303 vlan_tpid = f_info->l_data.vlan.tpid; 1304 if (f_info->fltr_act == ICE_FWD_TO_VSI || 1305 f_info->fltr_act == ICE_FWD_TO_VSI_LIST) { 1306 act |= ICE_SINGLE_ACT_PRUNE; 1307 act |= ICE_SINGLE_ACT_EGRESS | ICE_SINGLE_ACT_INGRESS; 1308 } 1309 break; 1310 case ICE_SW_LKUP_ETHERTYPE_MAC: 1311 daddr = f_info->l_data.ethertype_mac.mac_addr; 1312 /* fall-through */ 1313 case ICE_SW_LKUP_ETHERTYPE: 1314 off = (_FORCE_ __be16 *)(eth_hdr + ICE_ETH_ETHTYPE_OFFSET); 1315 *off = CPU_TO_BE16(f_info->l_data.ethertype_mac.ethertype); 1316 break; 1317 case ICE_SW_LKUP_MAC_VLAN: 1318 daddr = f_info->l_data.mac_vlan.mac_addr; 1319 vlan_id = f_info->l_data.mac_vlan.vlan_id; 1320 break; 1321 case ICE_SW_LKUP_PROMISC_VLAN: 1322 vlan_id = f_info->l_data.mac_vlan.vlan_id; 1323 /* fall-through */ 1324 case ICE_SW_LKUP_PROMISC: 1325 daddr = f_info->l_data.mac_vlan.mac_addr; 1326 break; 1327 default: 1328 break; 1329 } 1330 1331 s_rule->hdr.type = (f_info->flag & ICE_FLTR_RX) ? 1332 CPU_TO_LE16(ICE_AQC_SW_RULES_T_LKUP_RX) : 1333 CPU_TO_LE16(ICE_AQC_SW_RULES_T_LKUP_TX); 1334 1335 /* Recipe set depending on lookup type */ 1336 s_rule->recipe_id = CPU_TO_LE16(f_info->lkup_type); 1337 s_rule->src = CPU_TO_LE16(f_info->src); 1338 s_rule->act = CPU_TO_LE32(act); 1339 1340 if (daddr) 1341 ice_memcpy(eth_hdr + ICE_ETH_DA_OFFSET, daddr, ETH_ALEN, 1342 ICE_NONDMA_TO_NONDMA); 1343 1344 if (!(vlan_id > ICE_MAX_VLAN_ID)) { 1345 off = (_FORCE_ __be16 *)(eth_hdr + ICE_ETH_VLAN_TCI_OFFSET); 1346 *off = CPU_TO_BE16(vlan_id); 1347 off = (_FORCE_ __be16 *)(eth_hdr + ICE_ETH_ETHTYPE_OFFSET); 1348 *off = CPU_TO_BE16(vlan_tpid); 1349 } 1350 1351 /* Create the switch rule with the final dummy Ethernet header */ 1352 if (opc != ice_aqc_opc_update_sw_rules) 1353 s_rule->hdr_len = CPU_TO_LE16(eth_hdr_sz); 1354 } 1355 1356 /** 1357 * ice_add_marker_act 1358 * @hw: pointer to the hardware structure 1359 * @m_ent: the management entry for which sw marker needs to be added 1360 * @sw_marker: sw marker to tag the Rx descriptor with 1361 * @l_id: large action resource ID 1362 * 1363 * Create a large action to hold software marker and update the switch rule 1364 * entry pointed by m_ent with newly created large action 1365 */ 1366 static int 1367 ice_add_marker_act(struct ice_hw *hw, struct ice_fltr_mgmt_list_entry *m_ent, 1368 u16 sw_marker, u16 l_id) 1369 { 1370 struct ice_sw_rule_lkup_rx_tx *rx_tx; 1371 struct ice_sw_rule_lg_act *lg_act; 1372 /* For software marker we need 3 large actions 1373 * 1. FWD action: FWD TO VSI or VSI LIST 1374 * 2. GENERIC VALUE action to hold the profile ID 1375 * 3. GENERIC VALUE action to hold the software marker ID 1376 */ 1377 const u16 num_lg_acts = 3; 1378 u16 lg_act_size; 1379 u16 rules_size; 1380 int status; 1381 u32 act; 1382 u16 id; 1383 1384 if (m_ent->fltr_info.lkup_type != ICE_SW_LKUP_MAC) 1385 return ICE_ERR_PARAM; 1386 1387 /* Create two back-to-back switch rules and submit them to the HW using 1388 * one memory buffer: 1389 * 1. Large Action 1390 * 2. Look up Tx Rx 1391 */ 1392 lg_act_size = (u16)ice_struct_size(lg_act, act, num_lg_acts); 1393 rules_size = lg_act_size + 1394 ice_struct_size(rx_tx, hdr_data, DUMMY_ETH_HDR_LEN); 1395 lg_act = (struct ice_sw_rule_lg_act *)ice_malloc(hw, rules_size); 1396 if (!lg_act) 1397 return ICE_ERR_NO_MEMORY; 1398 1399 rx_tx = (struct ice_sw_rule_lkup_rx_tx *)((u8 *)lg_act + lg_act_size); 1400 1401 /* Fill in the first switch rule i.e. large action */ 1402 lg_act->hdr.type = CPU_TO_LE16(ICE_AQC_SW_RULES_T_LG_ACT); 1403 lg_act->index = CPU_TO_LE16(l_id); 1404 lg_act->size = CPU_TO_LE16(num_lg_acts); 1405 1406 /* First action VSI forwarding or VSI list forwarding depending on how 1407 * many VSIs 1408 */ 1409 id = (m_ent->vsi_count > 1) ? m_ent->fltr_info.fwd_id.vsi_list_id : 1410 m_ent->fltr_info.fwd_id.hw_vsi_id; 1411 1412 act = ICE_LG_ACT_VSI_FORWARDING | ICE_LG_ACT_VALID_BIT; 1413 act |= (id << ICE_LG_ACT_VSI_LIST_ID_S) & ICE_LG_ACT_VSI_LIST_ID_M; 1414 if (m_ent->vsi_count > 1) 1415 act |= ICE_LG_ACT_VSI_LIST; 1416 lg_act->act[0] = CPU_TO_LE32(act); 1417 1418 /* Second action descriptor type */ 1419 act = ICE_LG_ACT_GENERIC; 1420 1421 act |= (1 << ICE_LG_ACT_GENERIC_VALUE_S) & ICE_LG_ACT_GENERIC_VALUE_M; 1422 lg_act->act[1] = CPU_TO_LE32(act); 1423 1424 act = (ICE_LG_ACT_GENERIC_OFF_RX_DESC_PROF_IDX << 1425 ICE_LG_ACT_GENERIC_OFFSET_S) & ICE_LG_ACT_GENERIC_OFFSET_M; 1426 1427 /* Third action Marker value */ 1428 act |= ICE_LG_ACT_GENERIC; 1429 act |= (sw_marker << ICE_LG_ACT_GENERIC_VALUE_S) & 1430 ICE_LG_ACT_GENERIC_VALUE_M; 1431 1432 lg_act->act[2] = CPU_TO_LE32(act); 1433 1434 /* call the fill switch rule to fill the lookup Tx Rx structure */ 1435 ice_fill_sw_rule(hw, &m_ent->fltr_info, rx_tx, 1436 ice_aqc_opc_update_sw_rules); 1437 1438 /* Update the action to point to the large action ID */ 1439 rx_tx->act = CPU_TO_LE32(ICE_SINGLE_ACT_PTR | 1440 ((l_id << ICE_SINGLE_ACT_PTR_VAL_S) & 1441 ICE_SINGLE_ACT_PTR_VAL_M)); 1442 1443 /* Use the filter rule ID of the previously created rule with single 1444 * act. Once the update happens, hardware will treat this as large 1445 * action 1446 */ 1447 rx_tx->index = CPU_TO_LE16(m_ent->fltr_info.fltr_rule_id); 1448 1449 status = ice_aq_sw_rules(hw, lg_act, rules_size, 2, 1450 ice_aqc_opc_update_sw_rules, NULL); 1451 if (!status) { 1452 m_ent->lg_act_idx = l_id; 1453 m_ent->sw_marker_id = sw_marker; 1454 } 1455 1456 ice_free(hw, lg_act); 1457 return status; 1458 } 1459 1460 /** 1461 * ice_add_counter_act - add/update filter rule with counter action 1462 * @hw: pointer to the hardware structure 1463 * @m_ent: the management entry for which counter needs to be added 1464 * @counter_id: VLAN counter ID returned as part of allocate resource 1465 * @l_id: large action resource ID 1466 */ 1467 static int 1468 ice_add_counter_act(struct ice_hw *hw, struct ice_fltr_mgmt_list_entry *m_ent, 1469 u16 counter_id, u16 l_id) 1470 { 1471 struct ice_sw_rule_lkup_rx_tx *rx_tx; 1472 struct ice_sw_rule_lg_act *lg_act; 1473 /* 2 actions will be added while adding a large action counter */ 1474 const int num_acts = 2; 1475 u16 lg_act_size; 1476 u16 rules_size; 1477 u16 f_rule_id; 1478 u32 act; 1479 int status; 1480 u16 id; 1481 1482 if (m_ent->fltr_info.lkup_type != ICE_SW_LKUP_MAC) 1483 return ICE_ERR_PARAM; 1484 1485 /* Create two back-to-back switch rules and submit them to the HW using 1486 * one memory buffer: 1487 * 1. Large Action 1488 * 2. Look up Tx Rx 1489 */ 1490 lg_act_size = (u16)ice_struct_size(lg_act, act, num_acts); 1491 rules_size = lg_act_size + 1492 ice_struct_size(rx_tx, hdr_data, DUMMY_ETH_HDR_LEN); 1493 lg_act = (struct ice_sw_rule_lg_act *)ice_malloc(hw, rules_size); 1494 if (!lg_act) 1495 return ICE_ERR_NO_MEMORY; 1496 1497 rx_tx = (struct ice_sw_rule_lkup_rx_tx *)((u8 *)lg_act + 1498 lg_act_size); 1499 1500 /* Fill in the first switch rule i.e. large action */ 1501 lg_act->hdr.type = CPU_TO_LE16(ICE_AQC_SW_RULES_T_LG_ACT); 1502 lg_act->index = CPU_TO_LE16(l_id); 1503 lg_act->size = CPU_TO_LE16(num_acts); 1504 1505 /* First action VSI forwarding or VSI list forwarding depending on how 1506 * many VSIs 1507 */ 1508 id = (m_ent->vsi_count > 1) ? m_ent->fltr_info.fwd_id.vsi_list_id : 1509 m_ent->fltr_info.fwd_id.hw_vsi_id; 1510 1511 act = ICE_LG_ACT_VSI_FORWARDING | ICE_LG_ACT_VALID_BIT; 1512 act |= (id << ICE_LG_ACT_VSI_LIST_ID_S) & 1513 ICE_LG_ACT_VSI_LIST_ID_M; 1514 if (m_ent->vsi_count > 1) 1515 act |= ICE_LG_ACT_VSI_LIST; 1516 lg_act->act[0] = CPU_TO_LE32(act); 1517 1518 /* Second action counter ID */ 1519 act = ICE_LG_ACT_STAT_COUNT; 1520 act |= (counter_id << ICE_LG_ACT_STAT_COUNT_S) & 1521 ICE_LG_ACT_STAT_COUNT_M; 1522 lg_act->act[1] = CPU_TO_LE32(act); 1523 1524 /* call the fill switch rule to fill the lookup Tx Rx structure */ 1525 ice_fill_sw_rule(hw, &m_ent->fltr_info, rx_tx, 1526 ice_aqc_opc_update_sw_rules); 1527 1528 act = ICE_SINGLE_ACT_PTR; 1529 act |= (l_id << ICE_SINGLE_ACT_PTR_VAL_S) & ICE_SINGLE_ACT_PTR_VAL_M; 1530 rx_tx->act = CPU_TO_LE32(act); 1531 1532 /* Use the filter rule ID of the previously created rule with single 1533 * act. Once the update happens, hardware will treat this as large 1534 * action 1535 */ 1536 f_rule_id = m_ent->fltr_info.fltr_rule_id; 1537 rx_tx->index = CPU_TO_LE16(f_rule_id); 1538 1539 status = ice_aq_sw_rules(hw, lg_act, rules_size, 2, 1540 ice_aqc_opc_update_sw_rules, NULL); 1541 if (!status) { 1542 m_ent->lg_act_idx = l_id; 1543 m_ent->counter_index = (u8)counter_id; 1544 } 1545 1546 ice_free(hw, lg_act); 1547 return status; 1548 } 1549 1550 /** 1551 * ice_create_vsi_list_map 1552 * @hw: pointer to the hardware structure 1553 * @vsi_handle_arr: array of VSI handles to set in the VSI mapping 1554 * @num_vsi: number of VSI handles in the array 1555 * @vsi_list_id: VSI list ID generated as part of allocate resource 1556 * 1557 * Helper function to create a new entry of VSI list ID to VSI mapping 1558 * using the given VSI list ID 1559 */ 1560 static struct ice_vsi_list_map_info * 1561 ice_create_vsi_list_map(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi, 1562 u16 vsi_list_id) 1563 { 1564 struct ice_switch_info *sw = hw->switch_info; 1565 struct ice_vsi_list_map_info *v_map; 1566 int i; 1567 1568 v_map = (struct ice_vsi_list_map_info *)ice_malloc(hw, sizeof(*v_map)); 1569 if (!v_map) 1570 return NULL; 1571 1572 v_map->vsi_list_id = vsi_list_id; 1573 v_map->ref_cnt = 1; 1574 for (i = 0; i < num_vsi; i++) 1575 ice_set_bit(vsi_handle_arr[i], v_map->vsi_map); 1576 1577 LIST_ADD(&v_map->list_entry, &sw->vsi_list_map_head); 1578 return v_map; 1579 } 1580 1581 /** 1582 * ice_update_vsi_list_rule 1583 * @hw: pointer to the hardware structure 1584 * @vsi_handle_arr: array of VSI handles to form a VSI list 1585 * @num_vsi: number of VSI handles in the array 1586 * @vsi_list_id: VSI list ID generated as part of allocate resource 1587 * @remove: Boolean value to indicate if this is a remove action 1588 * @opc: switch rules population command type - pass in the command opcode 1589 * @lkup_type: lookup type of the filter 1590 * 1591 * Call AQ command to add a new switch rule or update existing switch rule 1592 * using the given VSI list ID 1593 */ 1594 static int 1595 ice_update_vsi_list_rule(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi, 1596 u16 vsi_list_id, bool remove, enum ice_adminq_opc opc, 1597 enum ice_sw_lkup_type lkup_type) 1598 { 1599 struct ice_sw_rule_vsi_list *s_rule; 1600 u16 s_rule_size; 1601 u16 rule_type; 1602 int status; 1603 int i; 1604 1605 if (!num_vsi) 1606 return ICE_ERR_PARAM; 1607 1608 if (lkup_type == ICE_SW_LKUP_MAC || 1609 lkup_type == ICE_SW_LKUP_MAC_VLAN || 1610 lkup_type == ICE_SW_LKUP_ETHERTYPE || 1611 lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC || 1612 lkup_type == ICE_SW_LKUP_PROMISC || 1613 lkup_type == ICE_SW_LKUP_PROMISC_VLAN || 1614 lkup_type == ICE_SW_LKUP_DFLT || 1615 lkup_type == ICE_SW_LKUP_LAST) 1616 rule_type = remove ? ICE_AQC_SW_RULES_T_VSI_LIST_CLEAR : 1617 ICE_AQC_SW_RULES_T_VSI_LIST_SET; 1618 else if (lkup_type == ICE_SW_LKUP_VLAN) 1619 rule_type = remove ? ICE_AQC_SW_RULES_T_PRUNE_LIST_CLEAR : 1620 ICE_AQC_SW_RULES_T_PRUNE_LIST_SET; 1621 else 1622 return ICE_ERR_PARAM; 1623 1624 s_rule_size = (u16)ice_struct_size(s_rule, vsi, num_vsi); 1625 s_rule = (struct ice_sw_rule_vsi_list *)ice_malloc(hw, s_rule_size); 1626 if (!s_rule) 1627 return ICE_ERR_NO_MEMORY; 1628 for (i = 0; i < num_vsi; i++) { 1629 if (!ice_is_vsi_valid(hw, vsi_handle_arr[i])) { 1630 status = ICE_ERR_PARAM; 1631 goto exit; 1632 } 1633 /* AQ call requires hw_vsi_id(s) */ 1634 s_rule->vsi[i] = 1635 CPU_TO_LE16(ice_get_hw_vsi_num(hw, vsi_handle_arr[i])); 1636 } 1637 1638 s_rule->hdr.type = CPU_TO_LE16(rule_type); 1639 s_rule->number_vsi = CPU_TO_LE16(num_vsi); 1640 s_rule->index = CPU_TO_LE16(vsi_list_id); 1641 1642 status = ice_aq_sw_rules(hw, s_rule, s_rule_size, 1, opc, NULL); 1643 1644 exit: 1645 ice_free(hw, s_rule); 1646 return status; 1647 } 1648 1649 /** 1650 * ice_create_vsi_list_rule - Creates and populates a VSI list rule 1651 * @hw: pointer to the HW struct 1652 * @vsi_handle_arr: array of VSI handles to form a VSI list 1653 * @num_vsi: number of VSI handles in the array 1654 * @vsi_list_id: stores the ID of the VSI list to be created 1655 * @lkup_type: switch rule filter's lookup type 1656 */ 1657 static int 1658 ice_create_vsi_list_rule(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi, 1659 u16 *vsi_list_id, enum ice_sw_lkup_type lkup_type) 1660 { 1661 int status; 1662 1663 status = ice_aq_alloc_free_vsi_list(hw, vsi_list_id, lkup_type, 1664 ice_aqc_opc_alloc_res); 1665 if (status) 1666 return status; 1667 1668 /* Update the newly created VSI list to include the specified VSIs */ 1669 return ice_update_vsi_list_rule(hw, vsi_handle_arr, num_vsi, 1670 *vsi_list_id, false, 1671 ice_aqc_opc_add_sw_rules, lkup_type); 1672 } 1673 1674 /** 1675 * ice_create_pkt_fwd_rule 1676 * @hw: pointer to the hardware structure 1677 * @recp_list: corresponding filter management list 1678 * @f_entry: entry containing packet forwarding information 1679 * 1680 * Create switch rule with given filter information and add an entry 1681 * to the corresponding filter management list to track this switch rule 1682 * and VSI mapping 1683 */ 1684 static int 1685 ice_create_pkt_fwd_rule(struct ice_hw *hw, struct ice_sw_recipe *recp_list, 1686 struct ice_fltr_list_entry *f_entry) 1687 { 1688 struct ice_fltr_mgmt_list_entry *fm_entry; 1689 struct ice_sw_rule_lkup_rx_tx *s_rule; 1690 int status; 1691 1692 s_rule = (struct ice_sw_rule_lkup_rx_tx *) 1693 ice_malloc(hw, ice_struct_size(s_rule, hdr_data, 1694 DUMMY_ETH_HDR_LEN)); 1695 if (!s_rule) 1696 return ICE_ERR_NO_MEMORY; 1697 fm_entry = (struct ice_fltr_mgmt_list_entry *) 1698 ice_malloc(hw, sizeof(*fm_entry)); 1699 if (!fm_entry) { 1700 status = ICE_ERR_NO_MEMORY; 1701 goto ice_create_pkt_fwd_rule_exit; 1702 } 1703 1704 fm_entry->fltr_info = f_entry->fltr_info; 1705 1706 /* Initialize all the fields for the management entry */ 1707 fm_entry->vsi_count = 1; 1708 fm_entry->lg_act_idx = ICE_INVAL_LG_ACT_INDEX; 1709 fm_entry->sw_marker_id = ICE_INVAL_SW_MARKER_ID; 1710 fm_entry->counter_index = ICE_INVAL_COUNTER_ID; 1711 1712 ice_fill_sw_rule(hw, &fm_entry->fltr_info, s_rule, 1713 ice_aqc_opc_add_sw_rules); 1714 1715 status = ice_aq_sw_rules(hw, s_rule, 1716 ice_struct_size(s_rule, hdr_data, 1717 DUMMY_ETH_HDR_LEN), 1718 1, ice_aqc_opc_add_sw_rules, NULL); 1719 if (status) { 1720 ice_free(hw, fm_entry); 1721 goto ice_create_pkt_fwd_rule_exit; 1722 } 1723 1724 f_entry->fltr_info.fltr_rule_id = LE16_TO_CPU(s_rule->index); 1725 fm_entry->fltr_info.fltr_rule_id = LE16_TO_CPU(s_rule->index); 1726 1727 /* The book keeping entries will get removed when base driver 1728 * calls remove filter AQ command 1729 */ 1730 LIST_ADD(&fm_entry->list_entry, &recp_list->filt_rules); 1731 1732 ice_create_pkt_fwd_rule_exit: 1733 ice_free(hw, s_rule); 1734 return status; 1735 } 1736 1737 /** 1738 * ice_update_pkt_fwd_rule 1739 * @hw: pointer to the hardware structure 1740 * @f_info: filter information for switch rule 1741 * 1742 * Call AQ command to update a previously created switch rule with a 1743 * VSI list ID 1744 */ 1745 static int 1746 ice_update_pkt_fwd_rule(struct ice_hw *hw, struct ice_fltr_info *f_info) 1747 { 1748 struct ice_sw_rule_lkup_rx_tx *s_rule; 1749 int status; 1750 1751 s_rule = (struct ice_sw_rule_lkup_rx_tx *) 1752 ice_malloc(hw, ice_struct_size(s_rule, hdr_data, 1753 DUMMY_ETH_HDR_LEN)); 1754 if (!s_rule) 1755 return ICE_ERR_NO_MEMORY; 1756 1757 ice_fill_sw_rule(hw, f_info, s_rule, ice_aqc_opc_update_sw_rules); 1758 1759 s_rule->index = CPU_TO_LE16(f_info->fltr_rule_id); 1760 1761 /* Update switch rule with new rule set to forward VSI list */ 1762 status = ice_aq_sw_rules(hw, s_rule, 1763 ice_struct_size(s_rule, hdr_data, 1764 DUMMY_ETH_HDR_LEN), 1765 1, ice_aqc_opc_update_sw_rules, NULL); 1766 1767 ice_free(hw, s_rule); 1768 return status; 1769 } 1770 1771 /** 1772 * ice_update_sw_rule_bridge_mode 1773 * @hw: pointer to the HW struct 1774 * 1775 * Updates unicast switch filter rules based on VEB/VEPA mode 1776 */ 1777 int ice_update_sw_rule_bridge_mode(struct ice_hw *hw) 1778 { 1779 struct ice_fltr_mgmt_list_entry *fm_entry; 1780 struct LIST_HEAD_TYPE *rule_head; 1781 struct ice_lock *rule_lock; /* Lock to protect filter rule list */ 1782 struct ice_switch_info *sw; 1783 int status = 0; 1784 1785 sw = hw->switch_info; 1786 1787 rule_lock = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rule_lock; 1788 rule_head = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rules; 1789 1790 ice_acquire_lock(rule_lock); 1791 LIST_FOR_EACH_ENTRY(fm_entry, rule_head, ice_fltr_mgmt_list_entry, 1792 list_entry) { 1793 struct ice_fltr_info *fi = &fm_entry->fltr_info; 1794 u8 *addr = fi->l_data.mac.mac_addr; 1795 1796 /* Update unicast Tx rules to reflect the selected 1797 * VEB/VEPA mode 1798 */ 1799 if ((fi->flag & ICE_FLTR_TX) && IS_UNICAST_ETHER_ADDR(addr) && 1800 (fi->fltr_act == ICE_FWD_TO_VSI || 1801 fi->fltr_act == ICE_FWD_TO_VSI_LIST || 1802 fi->fltr_act == ICE_FWD_TO_Q || 1803 fi->fltr_act == ICE_FWD_TO_QGRP)) { 1804 status = ice_update_pkt_fwd_rule(hw, fi); 1805 if (status) 1806 break; 1807 } 1808 } 1809 1810 ice_release_lock(rule_lock); 1811 1812 return status; 1813 } 1814 1815 /** 1816 * ice_add_update_vsi_list 1817 * @hw: pointer to the hardware structure 1818 * @m_entry: pointer to current filter management list entry 1819 * @cur_fltr: filter information from the book keeping entry 1820 * @new_fltr: filter information with the new VSI to be added 1821 * 1822 * Call AQ command to add or update previously created VSI list with new VSI. 1823 * 1824 * Helper function to do book keeping associated with adding filter information 1825 * The algorithm to do the book keeping is described below : 1826 * When a VSI needs to subscribe to a given filter (MAC/VLAN/Ethtype etc.) 1827 * if only one VSI has been added till now 1828 * Allocate a new VSI list and add two VSIs 1829 * to this list using switch rule command 1830 * Update the previously created switch rule with the 1831 * newly created VSI list ID 1832 * if a VSI list was previously created 1833 * Add the new VSI to the previously created VSI list set 1834 * using the update switch rule command 1835 */ 1836 static int 1837 ice_add_update_vsi_list(struct ice_hw *hw, 1838 struct ice_fltr_mgmt_list_entry *m_entry, 1839 struct ice_fltr_info *cur_fltr, 1840 struct ice_fltr_info *new_fltr) 1841 { 1842 u16 vsi_list_id = 0; 1843 int status = 0; 1844 1845 if ((cur_fltr->fltr_act == ICE_FWD_TO_Q || 1846 cur_fltr->fltr_act == ICE_FWD_TO_QGRP)) 1847 return ICE_ERR_NOT_IMPL; 1848 1849 if ((new_fltr->fltr_act == ICE_FWD_TO_Q || 1850 new_fltr->fltr_act == ICE_FWD_TO_QGRP) && 1851 (cur_fltr->fltr_act == ICE_FWD_TO_VSI || 1852 cur_fltr->fltr_act == ICE_FWD_TO_VSI_LIST)) 1853 return ICE_ERR_NOT_IMPL; 1854 1855 if (m_entry->vsi_count < 2 && !m_entry->vsi_list_info) { 1856 /* Only one entry existed in the mapping and it was not already 1857 * a part of a VSI list. So, create a VSI list with the old and 1858 * new VSIs. 1859 */ 1860 struct ice_fltr_info tmp_fltr; 1861 u16 vsi_handle_arr[2]; 1862 1863 /* A rule already exists with the new VSI being added */ 1864 if (cur_fltr->vsi_handle == new_fltr->vsi_handle) 1865 return ICE_ERR_ALREADY_EXISTS; 1866 1867 vsi_handle_arr[0] = cur_fltr->vsi_handle; 1868 vsi_handle_arr[1] = new_fltr->vsi_handle; 1869 status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2, 1870 &vsi_list_id, 1871 new_fltr->lkup_type); 1872 if (status) 1873 return status; 1874 1875 tmp_fltr = *new_fltr; 1876 tmp_fltr.fltr_rule_id = cur_fltr->fltr_rule_id; 1877 tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST; 1878 tmp_fltr.fwd_id.vsi_list_id = vsi_list_id; 1879 /* Update the previous switch rule of "MAC forward to VSI" to 1880 * "MAC fwd to VSI list" 1881 */ 1882 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr); 1883 if (status) 1884 return status; 1885 1886 cur_fltr->fwd_id.vsi_list_id = vsi_list_id; 1887 cur_fltr->fltr_act = ICE_FWD_TO_VSI_LIST; 1888 m_entry->vsi_list_info = 1889 ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2, 1890 vsi_list_id); 1891 1892 if (!m_entry->vsi_list_info) 1893 return ICE_ERR_NO_MEMORY; 1894 1895 /* If this entry was large action then the large action needs 1896 * to be updated to point to FWD to VSI list 1897 */ 1898 if (m_entry->sw_marker_id != ICE_INVAL_SW_MARKER_ID) 1899 status = 1900 ice_add_marker_act(hw, m_entry, 1901 m_entry->sw_marker_id, 1902 m_entry->lg_act_idx); 1903 } else { 1904 u16 vsi_handle = new_fltr->vsi_handle; 1905 enum ice_adminq_opc opcode; 1906 1907 if (!m_entry->vsi_list_info) 1908 return ICE_ERR_CFG; 1909 1910 /* A rule already exists with the new VSI being added */ 1911 if (ice_is_bit_set(m_entry->vsi_list_info->vsi_map, vsi_handle)) 1912 return ICE_ERR_ALREADY_EXISTS; 1913 1914 /* Update the previously created VSI list set with 1915 * the new VSI ID passed in 1916 */ 1917 vsi_list_id = cur_fltr->fwd_id.vsi_list_id; 1918 opcode = ice_aqc_opc_update_sw_rules; 1919 1920 status = ice_update_vsi_list_rule(hw, &vsi_handle, 1, 1921 vsi_list_id, false, opcode, 1922 new_fltr->lkup_type); 1923 /* update VSI list mapping info with new VSI ID */ 1924 if (!status) 1925 ice_set_bit(vsi_handle, 1926 m_entry->vsi_list_info->vsi_map); 1927 } 1928 if (!status) 1929 m_entry->vsi_count++; 1930 return status; 1931 } 1932 1933 /** 1934 * ice_find_rule_entry - Search a rule entry 1935 * @list_head: head of rule list 1936 * @f_info: rule information 1937 * 1938 * Helper function to search for a given rule entry 1939 * Returns pointer to entry storing the rule if found 1940 */ 1941 static struct ice_fltr_mgmt_list_entry * 1942 ice_find_rule_entry(struct LIST_HEAD_TYPE *list_head, 1943 struct ice_fltr_info *f_info) 1944 { 1945 struct ice_fltr_mgmt_list_entry *list_itr, *ret = NULL; 1946 1947 LIST_FOR_EACH_ENTRY(list_itr, list_head, ice_fltr_mgmt_list_entry, 1948 list_entry) { 1949 if (!memcmp(&f_info->l_data, &list_itr->fltr_info.l_data, 1950 sizeof(f_info->l_data)) && 1951 f_info->flag == list_itr->fltr_info.flag) { 1952 ret = list_itr; 1953 break; 1954 } 1955 } 1956 return ret; 1957 } 1958 1959 /** 1960 * ice_find_vsi_list_entry - Search VSI list map with VSI count 1 1961 * @recp_list: VSI lists needs to be searched 1962 * @vsi_handle: VSI handle to be found in VSI list 1963 * @vsi_list_id: VSI list ID found containing vsi_handle 1964 * 1965 * Helper function to search a VSI list with single entry containing given VSI 1966 * handle element. This can be extended further to search VSI list with more 1967 * than 1 vsi_count. Returns pointer to VSI list entry if found. 1968 */ 1969 struct ice_vsi_list_map_info * 1970 ice_find_vsi_list_entry(struct ice_sw_recipe *recp_list, u16 vsi_handle, 1971 u16 *vsi_list_id) 1972 { 1973 struct ice_vsi_list_map_info *map_info = NULL; 1974 struct LIST_HEAD_TYPE *list_head; 1975 1976 list_head = &recp_list->filt_rules; 1977 if (recp_list->adv_rule) { 1978 struct ice_adv_fltr_mgmt_list_entry *list_itr; 1979 1980 LIST_FOR_EACH_ENTRY(list_itr, list_head, 1981 ice_adv_fltr_mgmt_list_entry, 1982 list_entry) { 1983 if (list_itr->vsi_list_info) { 1984 map_info = list_itr->vsi_list_info; 1985 if (ice_is_bit_set(map_info->vsi_map, 1986 vsi_handle)) { 1987 *vsi_list_id = map_info->vsi_list_id; 1988 return map_info; 1989 } 1990 } 1991 } 1992 } else { 1993 struct ice_fltr_mgmt_list_entry *list_itr; 1994 1995 LIST_FOR_EACH_ENTRY(list_itr, list_head, 1996 ice_fltr_mgmt_list_entry, 1997 list_entry) { 1998 if (list_itr->vsi_count == 1 && 1999 list_itr->vsi_list_info) { 2000 map_info = list_itr->vsi_list_info; 2001 if (ice_is_bit_set(map_info->vsi_map, 2002 vsi_handle)) { 2003 *vsi_list_id = map_info->vsi_list_id; 2004 return map_info; 2005 } 2006 } 2007 } 2008 } 2009 return NULL; 2010 } 2011 2012 /** 2013 * ice_add_rule_internal - add rule for a given lookup type 2014 * @hw: pointer to the hardware structure 2015 * @recp_list: recipe list for which rule has to be added 2016 * @lport: logic port number on which function add rule 2017 * @f_entry: structure containing MAC forwarding information 2018 * 2019 * Adds or updates the rule lists for a given recipe 2020 */ 2021 static int 2022 ice_add_rule_internal(struct ice_hw *hw, struct ice_sw_recipe *recp_list, 2023 u8 lport, struct ice_fltr_list_entry *f_entry) 2024 { 2025 struct ice_fltr_info *new_fltr, *cur_fltr; 2026 struct ice_fltr_mgmt_list_entry *m_entry; 2027 struct ice_lock *rule_lock; /* Lock to protect filter rule list */ 2028 int status = 0; 2029 2030 if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle)) 2031 return ICE_ERR_PARAM; 2032 2033 /* Load the hw_vsi_id only if the fwd action is fwd to VSI */ 2034 if (f_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI) 2035 f_entry->fltr_info.fwd_id.hw_vsi_id = 2036 ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle); 2037 2038 rule_lock = &recp_list->filt_rule_lock; 2039 2040 ice_acquire_lock(rule_lock); 2041 new_fltr = &f_entry->fltr_info; 2042 if (new_fltr->flag & ICE_FLTR_RX) 2043 new_fltr->src = lport; 2044 else if (new_fltr->flag & (ICE_FLTR_TX | ICE_FLTR_RX_LB)) 2045 new_fltr->src = 2046 ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle); 2047 2048 m_entry = ice_find_rule_entry(&recp_list->filt_rules, new_fltr); 2049 if (!m_entry) { 2050 status = ice_create_pkt_fwd_rule(hw, recp_list, f_entry); 2051 goto exit_add_rule_internal; 2052 } 2053 2054 cur_fltr = &m_entry->fltr_info; 2055 status = ice_add_update_vsi_list(hw, m_entry, cur_fltr, new_fltr); 2056 2057 exit_add_rule_internal: 2058 ice_release_lock(rule_lock); 2059 return status; 2060 } 2061 2062 /** 2063 * ice_remove_vsi_list_rule 2064 * @hw: pointer to the hardware structure 2065 * @vsi_list_id: VSI list ID generated as part of allocate resource 2066 * @lkup_type: switch rule filter lookup type 2067 * 2068 * The VSI list should be emptied before this function is called to remove the 2069 * VSI list. 2070 */ 2071 static int 2072 ice_remove_vsi_list_rule(struct ice_hw *hw, u16 vsi_list_id, 2073 enum ice_sw_lkup_type lkup_type) 2074 { 2075 /* Free the vsi_list resource that we allocated. It is assumed that the 2076 * list is empty at this point. 2077 */ 2078 return ice_aq_alloc_free_vsi_list(hw, &vsi_list_id, lkup_type, 2079 ice_aqc_opc_free_res); 2080 } 2081 2082 /** 2083 * ice_rem_update_vsi_list 2084 * @hw: pointer to the hardware structure 2085 * @vsi_handle: VSI handle of the VSI to remove 2086 * @fm_list: filter management entry for which the VSI list management needs to 2087 * be done 2088 */ 2089 static int 2090 ice_rem_update_vsi_list(struct ice_hw *hw, u16 vsi_handle, 2091 struct ice_fltr_mgmt_list_entry *fm_list) 2092 { 2093 enum ice_sw_lkup_type lkup_type; 2094 u16 vsi_list_id; 2095 int status = 0; 2096 2097 if (fm_list->fltr_info.fltr_act != ICE_FWD_TO_VSI_LIST || 2098 fm_list->vsi_count == 0) 2099 return ICE_ERR_PARAM; 2100 2101 /* A rule with the VSI being removed does not exist */ 2102 if (!ice_is_bit_set(fm_list->vsi_list_info->vsi_map, vsi_handle)) 2103 return ICE_ERR_DOES_NOT_EXIST; 2104 2105 lkup_type = fm_list->fltr_info.lkup_type; 2106 vsi_list_id = fm_list->fltr_info.fwd_id.vsi_list_id; 2107 status = ice_update_vsi_list_rule(hw, &vsi_handle, 1, vsi_list_id, true, 2108 ice_aqc_opc_update_sw_rules, 2109 lkup_type); 2110 if (status) 2111 return status; 2112 2113 fm_list->vsi_count--; 2114 ice_clear_bit(vsi_handle, fm_list->vsi_list_info->vsi_map); 2115 2116 if (fm_list->vsi_count == 1 && lkup_type != ICE_SW_LKUP_VLAN) { 2117 struct ice_fltr_info tmp_fltr_info = fm_list->fltr_info; 2118 struct ice_vsi_list_map_info *vsi_list_info = 2119 fm_list->vsi_list_info; 2120 u16 rem_vsi_handle; 2121 2122 rem_vsi_handle = ice_find_first_bit(vsi_list_info->vsi_map, 2123 ICE_MAX_VSI); 2124 if (!ice_is_vsi_valid(hw, rem_vsi_handle)) 2125 return ICE_ERR_OUT_OF_RANGE; 2126 2127 /* Make sure VSI list is empty before removing it below */ 2128 status = ice_update_vsi_list_rule(hw, &rem_vsi_handle, 1, 2129 vsi_list_id, true, 2130 ice_aqc_opc_update_sw_rules, 2131 lkup_type); 2132 if (status) 2133 return status; 2134 2135 tmp_fltr_info.fltr_act = ICE_FWD_TO_VSI; 2136 tmp_fltr_info.fwd_id.hw_vsi_id = 2137 ice_get_hw_vsi_num(hw, rem_vsi_handle); 2138 tmp_fltr_info.vsi_handle = rem_vsi_handle; 2139 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr_info); 2140 if (status) { 2141 ice_debug(hw, ICE_DBG_SW, "Failed to update pkt fwd rule to FWD_TO_VSI on HW VSI %d, error %d\n", 2142 tmp_fltr_info.fwd_id.hw_vsi_id, status); 2143 return status; 2144 } 2145 2146 fm_list->fltr_info = tmp_fltr_info; 2147 } 2148 2149 if ((fm_list->vsi_count == 1 && lkup_type != ICE_SW_LKUP_VLAN) || 2150 (fm_list->vsi_count == 0 && lkup_type == ICE_SW_LKUP_VLAN)) { 2151 struct ice_vsi_list_map_info *vsi_list_info = 2152 fm_list->vsi_list_info; 2153 2154 /* Remove the VSI list since it is no longer used */ 2155 status = ice_remove_vsi_list_rule(hw, vsi_list_id, lkup_type); 2156 if (status) { 2157 ice_debug(hw, ICE_DBG_SW, "Failed to remove VSI list %d, error %d\n", 2158 vsi_list_id, status); 2159 return status; 2160 } 2161 2162 LIST_DEL(&vsi_list_info->list_entry); 2163 ice_free(hw, vsi_list_info); 2164 fm_list->vsi_list_info = NULL; 2165 } 2166 2167 return status; 2168 } 2169 2170 /** 2171 * ice_remove_rule_internal - Remove a filter rule of a given type 2172 * @hw: pointer to the hardware structure 2173 * @recp_list: recipe list for which the rule needs to removed 2174 * @f_entry: rule entry containing filter information 2175 */ 2176 static int 2177 ice_remove_rule_internal(struct ice_hw *hw, struct ice_sw_recipe *recp_list, 2178 struct ice_fltr_list_entry *f_entry) 2179 { 2180 struct ice_fltr_mgmt_list_entry *list_elem; 2181 struct ice_lock *rule_lock; /* Lock to protect filter rule list */ 2182 bool remove_rule = false; 2183 int status = 0; 2184 u16 vsi_handle; 2185 2186 if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle)) 2187 return ICE_ERR_PARAM; 2188 f_entry->fltr_info.fwd_id.hw_vsi_id = 2189 ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle); 2190 2191 rule_lock = &recp_list->filt_rule_lock; 2192 ice_acquire_lock(rule_lock); 2193 2194 list_elem = ice_find_rule_entry(&recp_list->filt_rules, 2195 &f_entry->fltr_info); 2196 if (!list_elem) { 2197 status = ICE_ERR_DOES_NOT_EXIST; 2198 goto exit; 2199 } 2200 2201 if (list_elem->fltr_info.fltr_act != ICE_FWD_TO_VSI_LIST) { 2202 remove_rule = true; 2203 } else if (!list_elem->vsi_list_info) { 2204 status = ICE_ERR_DOES_NOT_EXIST; 2205 goto exit; 2206 } else if (list_elem->vsi_list_info->ref_cnt > 1) { 2207 /* a ref_cnt > 1 indicates that the vsi_list is being 2208 * shared by multiple rules. Decrement the ref_cnt and 2209 * remove this rule, but do not modify the list, as it 2210 * is in-use by other rules. 2211 */ 2212 list_elem->vsi_list_info->ref_cnt--; 2213 remove_rule = true; 2214 } else { 2215 /* a ref_cnt of 1 indicates the vsi_list is only used 2216 * by one rule. However, the original removal request is only 2217 * for a single VSI. Update the vsi_list first, and only 2218 * remove the rule if there are no further VSIs in this list. 2219 */ 2220 vsi_handle = f_entry->fltr_info.vsi_handle; 2221 status = ice_rem_update_vsi_list(hw, vsi_handle, list_elem); 2222 if (status) 2223 goto exit; 2224 /* if VSI count goes to zero after updating the VSI list */ 2225 if (list_elem->vsi_count == 0) 2226 remove_rule = true; 2227 } 2228 2229 if (remove_rule) { 2230 /* Remove the lookup rule */ 2231 struct ice_sw_rule_lkup_rx_tx *s_rule; 2232 2233 s_rule = (struct ice_sw_rule_lkup_rx_tx *) 2234 ice_malloc(hw, ice_struct_size(s_rule, hdr_data, 0)); 2235 if (!s_rule) { 2236 status = ICE_ERR_NO_MEMORY; 2237 goto exit; 2238 } 2239 2240 ice_fill_sw_rule(hw, &list_elem->fltr_info, s_rule, 2241 ice_aqc_opc_remove_sw_rules); 2242 2243 status = ice_aq_sw_rules(hw, s_rule, 2244 ice_struct_size(s_rule, hdr_data, 0), 2245 1, ice_aqc_opc_remove_sw_rules, NULL); 2246 2247 /* Remove a book keeping from the list */ 2248 ice_free(hw, s_rule); 2249 2250 if (status) 2251 goto exit; 2252 2253 LIST_DEL(&list_elem->list_entry); 2254 ice_free(hw, list_elem); 2255 } 2256 exit: 2257 ice_release_lock(rule_lock); 2258 return status; 2259 } 2260 2261 /** 2262 * ice_aq_get_res_alloc - get allocated resources 2263 * @hw: pointer to the HW struct 2264 * @num_entries: pointer to u16 to store the number of resource entries returned 2265 * @buf: pointer to buffer 2266 * @buf_size: size of buf 2267 * @cd: pointer to command details structure or NULL 2268 * 2269 * The caller-supplied buffer must be large enough to store the resource 2270 * information for all resource types. Each resource type is an 2271 * ice_aqc_get_res_resp_elem structure. 2272 */ 2273 int 2274 ice_aq_get_res_alloc(struct ice_hw *hw, u16 *num_entries, 2275 struct ice_aqc_get_res_resp_elem *buf, u16 buf_size, 2276 struct ice_sq_cd *cd) 2277 { 2278 struct ice_aqc_get_res_alloc *resp; 2279 struct ice_aq_desc desc; 2280 int status; 2281 2282 if (!buf) 2283 return ICE_ERR_BAD_PTR; 2284 2285 if (buf_size < ICE_AQ_GET_RES_ALLOC_BUF_LEN) 2286 return ICE_ERR_INVAL_SIZE; 2287 2288 resp = &desc.params.get_res; 2289 2290 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_res_alloc); 2291 status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd); 2292 2293 if (!status && num_entries) 2294 *num_entries = LE16_TO_CPU(resp->resp_elem_num); 2295 2296 return status; 2297 } 2298 2299 /** 2300 * ice_aq_get_res_descs - get allocated resource descriptors 2301 * @hw: pointer to the hardware structure 2302 * @num_entries: number of resource entries in buffer 2303 * @buf: structure to hold response data buffer 2304 * @buf_size: size of buffer 2305 * @res_type: resource type 2306 * @res_shared: is resource shared 2307 * @desc_id: input - first desc ID to start; output - next desc ID 2308 * @cd: pointer to command details structure or NULL 2309 */ 2310 int 2311 ice_aq_get_res_descs(struct ice_hw *hw, u16 num_entries, 2312 struct ice_aqc_res_elem *buf, u16 buf_size, u16 res_type, 2313 bool res_shared, u16 *desc_id, struct ice_sq_cd *cd) 2314 { 2315 struct ice_aqc_get_allocd_res_desc *cmd; 2316 struct ice_aq_desc desc; 2317 int status; 2318 2319 ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__); 2320 2321 cmd = &desc.params.get_res_desc; 2322 2323 if (!buf) 2324 return ICE_ERR_PARAM; 2325 2326 if (buf_size != (num_entries * sizeof(*buf))) 2327 return ICE_ERR_PARAM; 2328 2329 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_allocd_res_desc); 2330 2331 cmd->ops.cmd.res = CPU_TO_LE16(((res_type << ICE_AQC_RES_TYPE_S) & 2332 ICE_AQC_RES_TYPE_M) | (res_shared ? 2333 ICE_AQC_RES_TYPE_FLAG_SHARED : 0)); 2334 cmd->ops.cmd.first_desc = CPU_TO_LE16(*desc_id); 2335 2336 status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd); 2337 if (!status) 2338 *desc_id = LE16_TO_CPU(cmd->ops.resp.next_desc); 2339 2340 return status; 2341 } 2342 2343 /** 2344 * ice_add_mac_rule - Add a MAC address based filter rule 2345 * @hw: pointer to the hardware structure 2346 * @m_list: list of MAC addresses and forwarding information 2347 * @sw: pointer to switch info struct for which function add rule 2348 * @lport: logic port number on which function add rule 2349 * 2350 * IMPORTANT: When the umac_shared flag is set to false and m_list has 2351 * multiple unicast addresses, the function assumes that all the 2352 * addresses are unique in a given add_mac call. It doesn't 2353 * check for duplicates in this case, removing duplicates from a given 2354 * list should be taken care of in the caller of this function. 2355 */ 2356 static int 2357 ice_add_mac_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *m_list, 2358 struct ice_switch_info *sw, u8 lport) 2359 { 2360 struct ice_sw_recipe *recp_list = &sw->recp_list[ICE_SW_LKUP_MAC]; 2361 struct ice_sw_rule_lkup_rx_tx *s_rule, *r_iter; 2362 struct ice_fltr_list_entry *m_list_itr; 2363 struct LIST_HEAD_TYPE *rule_head; 2364 u16 total_elem_left, s_rule_size; 2365 struct ice_lock *rule_lock; /* Lock to protect filter rule list */ 2366 u16 num_unicast = 0; 2367 int status = 0; 2368 u8 elem_sent; 2369 2370 s_rule = NULL; 2371 rule_lock = &recp_list->filt_rule_lock; 2372 rule_head = &recp_list->filt_rules; 2373 2374 LIST_FOR_EACH_ENTRY(m_list_itr, m_list, ice_fltr_list_entry, 2375 list_entry) { 2376 u8 *add = &m_list_itr->fltr_info.l_data.mac.mac_addr[0]; 2377 u16 vsi_handle; 2378 u16 hw_vsi_id; 2379 2380 m_list_itr->fltr_info.flag = ICE_FLTR_TX; 2381 vsi_handle = m_list_itr->fltr_info.vsi_handle; 2382 if (!ice_is_vsi_valid(hw, vsi_handle)) 2383 return ICE_ERR_PARAM; 2384 hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle); 2385 if (m_list_itr->fltr_info.fltr_act == ICE_FWD_TO_VSI) 2386 m_list_itr->fltr_info.fwd_id.hw_vsi_id = hw_vsi_id; 2387 /* update the src in case it is VSI num */ 2388 if (m_list_itr->fltr_info.src_id != ICE_SRC_ID_VSI) 2389 return ICE_ERR_PARAM; 2390 m_list_itr->fltr_info.src = hw_vsi_id; 2391 if (m_list_itr->fltr_info.lkup_type != ICE_SW_LKUP_MAC || 2392 IS_ZERO_ETHER_ADDR(add)) 2393 return ICE_ERR_PARAM; 2394 if (IS_UNICAST_ETHER_ADDR(add) && !hw->umac_shared) { 2395 /* Don't overwrite the unicast address */ 2396 ice_acquire_lock(rule_lock); 2397 if (ice_find_rule_entry(rule_head, 2398 &m_list_itr->fltr_info)) { 2399 ice_release_lock(rule_lock); 2400 continue; 2401 } 2402 ice_release_lock(rule_lock); 2403 num_unicast++; 2404 } else if (IS_MULTICAST_ETHER_ADDR(add) || 2405 (IS_UNICAST_ETHER_ADDR(add) && hw->umac_shared)) { 2406 m_list_itr->status = 2407 ice_add_rule_internal(hw, recp_list, lport, 2408 m_list_itr); 2409 if (m_list_itr->status) 2410 return m_list_itr->status; 2411 } 2412 } 2413 2414 ice_acquire_lock(rule_lock); 2415 /* Exit if no suitable entries were found for adding bulk switch rule */ 2416 if (!num_unicast) { 2417 status = 0; 2418 goto ice_add_mac_exit; 2419 } 2420 2421 /* Allocate switch rule buffer for the bulk update for unicast */ 2422 s_rule_size = ice_struct_size(s_rule, hdr_data, DUMMY_ETH_HDR_LEN); 2423 s_rule = (struct ice_sw_rule_lkup_rx_tx *) 2424 ice_calloc(hw, num_unicast, s_rule_size); 2425 if (!s_rule) { 2426 status = ICE_ERR_NO_MEMORY; 2427 goto ice_add_mac_exit; 2428 } 2429 2430 r_iter = s_rule; 2431 LIST_FOR_EACH_ENTRY(m_list_itr, m_list, ice_fltr_list_entry, 2432 list_entry) { 2433 struct ice_fltr_info *f_info = &m_list_itr->fltr_info; 2434 u8 *mac_addr = &f_info->l_data.mac.mac_addr[0]; 2435 2436 if (IS_UNICAST_ETHER_ADDR(mac_addr)) { 2437 ice_fill_sw_rule(hw, &m_list_itr->fltr_info, r_iter, 2438 ice_aqc_opc_add_sw_rules); 2439 r_iter = (struct ice_sw_rule_lkup_rx_tx *) 2440 ((u8 *)r_iter + s_rule_size); 2441 } 2442 } 2443 2444 /* Call AQ bulk switch rule update for all unicast addresses */ 2445 r_iter = s_rule; 2446 /* Call AQ switch rule in AQ_MAX chunk */ 2447 for (total_elem_left = num_unicast; total_elem_left > 0; 2448 total_elem_left -= elem_sent) { 2449 struct ice_sw_rule_lkup_rx_tx *entry = r_iter; 2450 2451 elem_sent = MIN_T(u8, total_elem_left, 2452 (ICE_AQ_MAX_BUF_LEN / s_rule_size)); 2453 status = ice_aq_sw_rules(hw, entry, elem_sent * s_rule_size, 2454 elem_sent, ice_aqc_opc_add_sw_rules, 2455 NULL); 2456 if (status) 2457 goto ice_add_mac_exit; 2458 r_iter = (struct ice_sw_rule_lkup_rx_tx *) 2459 ((u8 *)r_iter + (elem_sent * s_rule_size)); 2460 } 2461 2462 /* Fill up rule ID based on the value returned from FW */ 2463 r_iter = s_rule; 2464 LIST_FOR_EACH_ENTRY(m_list_itr, m_list, ice_fltr_list_entry, 2465 list_entry) { 2466 struct ice_fltr_info *f_info = &m_list_itr->fltr_info; 2467 u8 *mac_addr = &f_info->l_data.mac.mac_addr[0]; 2468 struct ice_fltr_mgmt_list_entry *fm_entry; 2469 2470 if (IS_UNICAST_ETHER_ADDR(mac_addr)) { 2471 f_info->fltr_rule_id = 2472 LE16_TO_CPU(r_iter->index); 2473 f_info->fltr_act = ICE_FWD_TO_VSI; 2474 /* Create an entry to track this MAC address */ 2475 fm_entry = (struct ice_fltr_mgmt_list_entry *) 2476 ice_malloc(hw, sizeof(*fm_entry)); 2477 if (!fm_entry) { 2478 status = ICE_ERR_NO_MEMORY; 2479 goto ice_add_mac_exit; 2480 } 2481 fm_entry->fltr_info = *f_info; 2482 fm_entry->vsi_count = 1; 2483 /* The book keeping entries will get removed when 2484 * base driver calls remove filter AQ command 2485 */ 2486 2487 LIST_ADD(&fm_entry->list_entry, rule_head); 2488 r_iter = (struct ice_sw_rule_lkup_rx_tx *) 2489 ((u8 *)r_iter + s_rule_size); 2490 } 2491 } 2492 2493 ice_add_mac_exit: 2494 ice_release_lock(rule_lock); 2495 if (s_rule) 2496 ice_free(hw, s_rule); 2497 return status; 2498 } 2499 2500 /** 2501 * ice_add_mac - Add a MAC address based filter rule 2502 * @hw: pointer to the hardware structure 2503 * @m_list: list of MAC addresses and forwarding information 2504 * 2505 * Function add MAC rule for logical port from HW struct 2506 */ 2507 int ice_add_mac(struct ice_hw *hw, struct LIST_HEAD_TYPE *m_list) 2508 { 2509 if (!m_list || !hw) 2510 return ICE_ERR_PARAM; 2511 2512 return ice_add_mac_rule(hw, m_list, hw->switch_info, 2513 hw->port_info->lport); 2514 } 2515 2516 /** 2517 * ice_add_vlan_internal - Add one VLAN based filter rule 2518 * @hw: pointer to the hardware structure 2519 * @recp_list: recipe list for which rule has to be added 2520 * @f_entry: filter entry containing one VLAN information 2521 */ 2522 static int 2523 ice_add_vlan_internal(struct ice_hw *hw, struct ice_sw_recipe *recp_list, 2524 struct ice_fltr_list_entry *f_entry) 2525 { 2526 struct ice_fltr_mgmt_list_entry *v_list_itr; 2527 struct ice_fltr_info *new_fltr, *cur_fltr; 2528 enum ice_sw_lkup_type lkup_type; 2529 u16 vsi_list_id = 0, vsi_handle; 2530 struct ice_lock *rule_lock; /* Lock to protect filter rule list */ 2531 int status = 0; 2532 2533 if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle)) 2534 return ICE_ERR_PARAM; 2535 2536 f_entry->fltr_info.fwd_id.hw_vsi_id = 2537 ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle); 2538 new_fltr = &f_entry->fltr_info; 2539 2540 /* VLAN ID should only be 12 bits */ 2541 if (new_fltr->l_data.vlan.vlan_id > ICE_MAX_VLAN_ID) 2542 return ICE_ERR_PARAM; 2543 2544 if (new_fltr->src_id != ICE_SRC_ID_VSI) 2545 return ICE_ERR_PARAM; 2546 2547 new_fltr->src = new_fltr->fwd_id.hw_vsi_id; 2548 lkup_type = new_fltr->lkup_type; 2549 vsi_handle = new_fltr->vsi_handle; 2550 rule_lock = &recp_list->filt_rule_lock; 2551 ice_acquire_lock(rule_lock); 2552 v_list_itr = ice_find_rule_entry(&recp_list->filt_rules, new_fltr); 2553 if (!v_list_itr) { 2554 struct ice_vsi_list_map_info *map_info = NULL; 2555 2556 if (new_fltr->fltr_act == ICE_FWD_TO_VSI) { 2557 /* All VLAN pruning rules use a VSI list. Check if 2558 * there is already a VSI list containing VSI that we 2559 * want to add. If found, use the same vsi_list_id for 2560 * this new VLAN rule or else create a new list. 2561 */ 2562 map_info = ice_find_vsi_list_entry(recp_list, 2563 vsi_handle, 2564 &vsi_list_id); 2565 if (!map_info) { 2566 status = ice_create_vsi_list_rule(hw, 2567 &vsi_handle, 2568 1, 2569 &vsi_list_id, 2570 lkup_type); 2571 if (status) 2572 goto exit; 2573 } 2574 /* Convert the action to forwarding to a VSI list. */ 2575 new_fltr->fltr_act = ICE_FWD_TO_VSI_LIST; 2576 new_fltr->fwd_id.vsi_list_id = vsi_list_id; 2577 } 2578 2579 status = ice_create_pkt_fwd_rule(hw, recp_list, f_entry); 2580 if (!status) { 2581 v_list_itr = ice_find_rule_entry(&recp_list->filt_rules, 2582 new_fltr); 2583 if (!v_list_itr) { 2584 status = ICE_ERR_DOES_NOT_EXIST; 2585 goto exit; 2586 } 2587 /* reuse VSI list for new rule and increment ref_cnt */ 2588 if (map_info) { 2589 v_list_itr->vsi_list_info = map_info; 2590 map_info->ref_cnt++; 2591 } else { 2592 v_list_itr->vsi_list_info = 2593 ice_create_vsi_list_map(hw, &vsi_handle, 2594 1, vsi_list_id); 2595 } 2596 } 2597 } else if (v_list_itr->vsi_list_info->ref_cnt == 1) { 2598 /* Update existing VSI list to add new VSI ID only if it used 2599 * by one VLAN rule. 2600 */ 2601 cur_fltr = &v_list_itr->fltr_info; 2602 status = ice_add_update_vsi_list(hw, v_list_itr, cur_fltr, 2603 new_fltr); 2604 } else { 2605 /* If VLAN rule exists and VSI list being used by this rule is 2606 * referenced by more than 1 VLAN rule. Then create a new VSI 2607 * list appending previous VSI with new VSI and update existing 2608 * VLAN rule to point to new VSI list ID 2609 */ 2610 struct ice_fltr_info tmp_fltr; 2611 u16 vsi_handle_arr[2]; 2612 u16 cur_handle; 2613 2614 /* Current implementation only supports reusing VSI list with 2615 * one VSI count. We should never hit below condition 2616 */ 2617 if (v_list_itr->vsi_count > 1 && 2618 v_list_itr->vsi_list_info->ref_cnt > 1) { 2619 ice_debug(hw, ICE_DBG_SW, "Invalid configuration: Optimization to reuse VSI list with more than one VSI is not being done yet\n"); 2620 status = ICE_ERR_CFG; 2621 goto exit; 2622 } 2623 2624 cur_handle = 2625 ice_find_first_bit(v_list_itr->vsi_list_info->vsi_map, 2626 ICE_MAX_VSI); 2627 2628 /* A rule already exists with the new VSI being added */ 2629 if (cur_handle == vsi_handle) { 2630 status = ICE_ERR_ALREADY_EXISTS; 2631 goto exit; 2632 } 2633 2634 vsi_handle_arr[0] = cur_handle; 2635 vsi_handle_arr[1] = vsi_handle; 2636 status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2, 2637 &vsi_list_id, lkup_type); 2638 if (status) 2639 goto exit; 2640 2641 tmp_fltr = v_list_itr->fltr_info; 2642 tmp_fltr.fltr_rule_id = v_list_itr->fltr_info.fltr_rule_id; 2643 tmp_fltr.fwd_id.vsi_list_id = vsi_list_id; 2644 tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST; 2645 /* Update the previous switch rule to a new VSI list which 2646 * includes current VSI that is requested 2647 */ 2648 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr); 2649 if (status) 2650 goto exit; 2651 2652 /* before overriding VSI list map info. decrement ref_cnt of 2653 * previous VSI list 2654 */ 2655 v_list_itr->vsi_list_info->ref_cnt--; 2656 2657 /* now update to newly created list */ 2658 v_list_itr->fltr_info.fwd_id.vsi_list_id = vsi_list_id; 2659 v_list_itr->vsi_list_info = 2660 ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2, 2661 vsi_list_id); 2662 v_list_itr->vsi_count++; 2663 } 2664 2665 exit: 2666 ice_release_lock(rule_lock); 2667 return status; 2668 } 2669 2670 /** 2671 * ice_add_vlan_rule - Add VLAN based filter rule 2672 * @hw: pointer to the hardware structure 2673 * @v_list: list of VLAN entries and forwarding information 2674 * @sw: pointer to switch info struct for which function add rule 2675 */ 2676 static int 2677 ice_add_vlan_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *v_list, 2678 struct ice_switch_info *sw) 2679 { 2680 struct ice_fltr_list_entry *v_list_itr; 2681 struct ice_sw_recipe *recp_list; 2682 2683 recp_list = &sw->recp_list[ICE_SW_LKUP_VLAN]; 2684 LIST_FOR_EACH_ENTRY(v_list_itr, v_list, ice_fltr_list_entry, 2685 list_entry) { 2686 if (v_list_itr->fltr_info.lkup_type != ICE_SW_LKUP_VLAN) 2687 return ICE_ERR_PARAM; 2688 v_list_itr->fltr_info.flag = ICE_FLTR_TX; 2689 v_list_itr->status = ice_add_vlan_internal(hw, recp_list, 2690 v_list_itr); 2691 if (v_list_itr->status) 2692 return v_list_itr->status; 2693 } 2694 return 0; 2695 } 2696 2697 /** 2698 * ice_add_vlan - Add a VLAN based filter rule 2699 * @hw: pointer to the hardware structure 2700 * @v_list: list of VLAN and forwarding information 2701 * 2702 * Function add VLAN rule for logical port from HW struct 2703 */ 2704 int ice_add_vlan(struct ice_hw *hw, struct LIST_HEAD_TYPE *v_list) 2705 { 2706 if (!v_list || !hw) 2707 return ICE_ERR_PARAM; 2708 2709 return ice_add_vlan_rule(hw, v_list, hw->switch_info); 2710 } 2711 2712 /** 2713 * ice_add_eth_mac_rule - Add ethertype and MAC based filter rule 2714 * @hw: pointer to the hardware structure 2715 * @em_list: list of ether type MAC filter, MAC is optional 2716 * @sw: pointer to switch info struct for which function add rule 2717 * @lport: logic port number on which function add rule 2718 * 2719 * This function requires the caller to populate the entries in 2720 * the filter list with the necessary fields (including flags to 2721 * indicate Tx or Rx rules). 2722 */ 2723 static int 2724 ice_add_eth_mac_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *em_list, 2725 struct ice_switch_info *sw, u8 lport) 2726 { 2727 struct ice_fltr_list_entry *em_list_itr; 2728 2729 LIST_FOR_EACH_ENTRY(em_list_itr, em_list, ice_fltr_list_entry, 2730 list_entry) { 2731 struct ice_sw_recipe *recp_list; 2732 enum ice_sw_lkup_type l_type; 2733 2734 l_type = em_list_itr->fltr_info.lkup_type; 2735 recp_list = &sw->recp_list[l_type]; 2736 2737 if (l_type != ICE_SW_LKUP_ETHERTYPE_MAC && 2738 l_type != ICE_SW_LKUP_ETHERTYPE) 2739 return ICE_ERR_PARAM; 2740 2741 em_list_itr->status = ice_add_rule_internal(hw, recp_list, 2742 lport, 2743 em_list_itr); 2744 if (em_list_itr->status) 2745 return em_list_itr->status; 2746 } 2747 return 0; 2748 } 2749 2750 /** 2751 * ice_add_eth_mac - Add a ethertype based filter rule 2752 * @hw: pointer to the hardware structure 2753 * @em_list: list of ethertype and forwarding information 2754 * 2755 * Function add ethertype rule for logical port from HW struct 2756 */ 2757 int 2758 ice_add_eth_mac(struct ice_hw *hw, struct LIST_HEAD_TYPE *em_list) 2759 { 2760 if (!em_list || !hw) 2761 return ICE_ERR_PARAM; 2762 2763 return ice_add_eth_mac_rule(hw, em_list, hw->switch_info, 2764 hw->port_info->lport); 2765 } 2766 2767 /** 2768 * ice_remove_eth_mac_rule - Remove an ethertype (or MAC) based filter rule 2769 * @hw: pointer to the hardware structure 2770 * @em_list: list of ethertype or ethertype MAC entries 2771 * @sw: pointer to switch info struct for which function add rule 2772 */ 2773 static int 2774 ice_remove_eth_mac_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *em_list, 2775 struct ice_switch_info *sw) 2776 { 2777 struct ice_fltr_list_entry *em_list_itr, *tmp; 2778 2779 LIST_FOR_EACH_ENTRY_SAFE(em_list_itr, tmp, em_list, ice_fltr_list_entry, 2780 list_entry) { 2781 struct ice_sw_recipe *recp_list; 2782 enum ice_sw_lkup_type l_type; 2783 2784 l_type = em_list_itr->fltr_info.lkup_type; 2785 2786 if (l_type != ICE_SW_LKUP_ETHERTYPE_MAC && 2787 l_type != ICE_SW_LKUP_ETHERTYPE) 2788 return ICE_ERR_PARAM; 2789 2790 recp_list = &sw->recp_list[l_type]; 2791 em_list_itr->status = ice_remove_rule_internal(hw, recp_list, 2792 em_list_itr); 2793 if (em_list_itr->status) 2794 return em_list_itr->status; 2795 } 2796 return 0; 2797 } 2798 2799 /** 2800 * ice_remove_eth_mac - remove a ethertype based filter rule 2801 * @hw: pointer to the hardware structure 2802 * @em_list: list of ethertype and forwarding information 2803 * 2804 */ 2805 int 2806 ice_remove_eth_mac(struct ice_hw *hw, struct LIST_HEAD_TYPE *em_list) 2807 { 2808 if (!em_list || !hw) 2809 return ICE_ERR_PARAM; 2810 2811 return ice_remove_eth_mac_rule(hw, em_list, hw->switch_info); 2812 } 2813 2814 /** 2815 * ice_get_lg_act_aqc_res_type - get resource type for a large action 2816 * @res_type: resource type to be filled in case of function success 2817 * @num_acts: number of actions to hold with a large action entry 2818 * 2819 * Get resource type for a large action depending on the number 2820 * of single actions that it contains. 2821 */ 2822 static int 2823 ice_get_lg_act_aqc_res_type(u16 *res_type, int num_acts) 2824 { 2825 if (!res_type) 2826 return ICE_ERR_BAD_PTR; 2827 2828 /* If num_acts is 1, use ICE_AQC_RES_TYPE_WIDE_TABLE_1. 2829 * If num_acts is 2, use ICE_AQC_RES_TYPE_WIDE_TABLE_3. 2830 * If num_acts is greater than 2, then use 2831 * ICE_AQC_RES_TYPE_WIDE_TABLE_4. 2832 * The num_acts cannot be equal to 0 or greater than 4. 2833 */ 2834 switch (num_acts) { 2835 case 1: 2836 *res_type = ICE_AQC_RES_TYPE_WIDE_TABLE_1; 2837 break; 2838 case 2: 2839 *res_type = ICE_AQC_RES_TYPE_WIDE_TABLE_2; 2840 break; 2841 case 3: 2842 case 4: 2843 *res_type = ICE_AQC_RES_TYPE_WIDE_TABLE_4; 2844 break; 2845 default: 2846 return ICE_ERR_PARAM; 2847 } 2848 2849 return 0; 2850 } 2851 2852 /** 2853 * ice_alloc_res_lg_act - add large action resource 2854 * @hw: pointer to the hardware structure 2855 * @l_id: large action ID to fill it in 2856 * @num_acts: number of actions to hold with a large action entry 2857 */ 2858 static int 2859 ice_alloc_res_lg_act(struct ice_hw *hw, u16 *l_id, u16 num_acts) 2860 { 2861 struct ice_aqc_alloc_free_res_elem *sw_buf; 2862 u16 buf_len, res_type; 2863 int status; 2864 2865 if (!l_id) 2866 return ICE_ERR_BAD_PTR; 2867 2868 status = ice_get_lg_act_aqc_res_type(&res_type, num_acts); 2869 if (status) 2870 return status; 2871 2872 /* Allocate resource for large action */ 2873 buf_len = ice_struct_size(sw_buf, elem, 1); 2874 sw_buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len); 2875 if (!sw_buf) 2876 return ICE_ERR_NO_MEMORY; 2877 2878 sw_buf->res_type = CPU_TO_LE16(res_type); 2879 sw_buf->num_elems = CPU_TO_LE16(1); 2880 2881 status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len, 2882 ice_aqc_opc_alloc_res, NULL); 2883 if (!status) 2884 *l_id = LE16_TO_CPU(sw_buf->elem[0].e.sw_resp); 2885 2886 ice_free(hw, sw_buf); 2887 2888 return status; 2889 } 2890 2891 /** 2892 * ice_rem_sw_rule_info 2893 * @hw: pointer to the hardware structure 2894 * @rule_head: pointer to the switch list structure that we want to delete 2895 */ 2896 static void 2897 ice_rem_sw_rule_info(struct ice_hw *hw, struct LIST_HEAD_TYPE *rule_head) 2898 { 2899 if (!LIST_EMPTY(rule_head)) { 2900 struct ice_fltr_mgmt_list_entry *entry; 2901 struct ice_fltr_mgmt_list_entry *tmp; 2902 2903 LIST_FOR_EACH_ENTRY_SAFE(entry, tmp, rule_head, 2904 ice_fltr_mgmt_list_entry, list_entry) { 2905 LIST_DEL(&entry->list_entry); 2906 ice_free(hw, entry); 2907 } 2908 } 2909 } 2910 2911 /** 2912 * ice_rem_all_sw_rules_info 2913 * @hw: pointer to the hardware structure 2914 */ 2915 void ice_rem_all_sw_rules_info(struct ice_hw *hw) 2916 { 2917 struct ice_switch_info *sw = hw->switch_info; 2918 u8 i; 2919 2920 for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) { 2921 struct LIST_HEAD_TYPE *rule_head; 2922 2923 rule_head = &sw->recp_list[i].filt_rules; 2924 if (!sw->recp_list[i].adv_rule) 2925 ice_rem_sw_rule_info(hw, rule_head); 2926 } 2927 } 2928 2929 /** 2930 * ice_cfg_dflt_vsi - change state of VSI to set/clear default 2931 * @pi: pointer to the port_info structure 2932 * @vsi_handle: VSI handle to set as default 2933 * @set: true to add the above mentioned switch rule, false to remove it 2934 * @direction: ICE_FLTR_RX or ICE_FLTR_TX 2935 * 2936 * add filter rule to set/unset given VSI as default VSI for the switch 2937 * (represented by swid) 2938 */ 2939 int 2940 ice_cfg_dflt_vsi(struct ice_port_info *pi, u16 vsi_handle, bool set, 2941 u8 direction) 2942 { 2943 struct ice_fltr_list_entry f_list_entry; 2944 struct ice_sw_recipe *recp_list = NULL; 2945 struct ice_fltr_info f_info; 2946 struct ice_hw *hw = pi->hw; 2947 u8 lport = pi->lport; 2948 u16 hw_vsi_id; 2949 int status; 2950 2951 recp_list = &pi->hw->switch_info->recp_list[ICE_SW_LKUP_DFLT]; 2952 2953 if (!ice_is_vsi_valid(hw, vsi_handle)) 2954 return ICE_ERR_PARAM; 2955 2956 hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle); 2957 2958 ice_memset(&f_info, 0, sizeof(f_info), ICE_NONDMA_MEM); 2959 2960 f_info.lkup_type = ICE_SW_LKUP_DFLT; 2961 f_info.flag = direction; 2962 f_info.fltr_act = ICE_FWD_TO_VSI; 2963 f_info.fwd_id.hw_vsi_id = hw_vsi_id; 2964 f_info.vsi_handle = vsi_handle; 2965 2966 if (f_info.flag & ICE_FLTR_RX) { 2967 f_info.src = pi->lport; 2968 f_info.src_id = ICE_SRC_ID_LPORT; 2969 } else if (f_info.flag & ICE_FLTR_TX) { 2970 f_info.src_id = ICE_SRC_ID_VSI; 2971 f_info.src = hw_vsi_id; 2972 } 2973 f_list_entry.fltr_info = f_info; 2974 2975 if (set) 2976 status = ice_add_rule_internal(hw, recp_list, lport, 2977 &f_list_entry); 2978 else 2979 status = ice_remove_rule_internal(hw, recp_list, 2980 &f_list_entry); 2981 2982 return status; 2983 } 2984 2985 /** 2986 * ice_check_if_dflt_vsi - check if VSI is default VSI 2987 * @pi: pointer to the port_info structure 2988 * @vsi_handle: vsi handle to check for in filter list 2989 * @rule_exists: indicates if there are any VSI's in the rule list 2990 * 2991 * checks if the VSI is in a default VSI list, and also indicates 2992 * if the default VSI list is empty 2993 */ 2994 bool ice_check_if_dflt_vsi(struct ice_port_info *pi, u16 vsi_handle, 2995 bool *rule_exists) 2996 { 2997 struct ice_fltr_mgmt_list_entry *fm_entry; 2998 struct LIST_HEAD_TYPE *rule_head; 2999 struct ice_sw_recipe *recp_list; 3000 struct ice_lock *rule_lock; 3001 bool ret = false; 3002 recp_list = &pi->hw->switch_info->recp_list[ICE_SW_LKUP_DFLT]; 3003 rule_lock = &recp_list->filt_rule_lock; 3004 rule_head = &recp_list->filt_rules; 3005 3006 ice_acquire_lock(rule_lock); 3007 3008 if (rule_exists && !LIST_EMPTY(rule_head)) 3009 *rule_exists = true; 3010 3011 LIST_FOR_EACH_ENTRY(fm_entry, rule_head, 3012 ice_fltr_mgmt_list_entry, list_entry) { 3013 if (ice_vsi_uses_fltr(fm_entry, vsi_handle)) { 3014 ret = true; 3015 break; 3016 } 3017 } 3018 3019 ice_release_lock(rule_lock); 3020 return ret; 3021 } 3022 3023 /** 3024 * ice_find_ucast_rule_entry - Search for a unicast MAC filter rule entry 3025 * @list_head: head of rule list 3026 * @f_info: rule information 3027 * 3028 * Helper function to search for a unicast rule entry - this is to be used 3029 * to remove unicast MAC filter that is not shared with other VSIs on the 3030 * PF switch. 3031 * 3032 * Returns pointer to entry storing the rule if found 3033 */ 3034 static struct ice_fltr_mgmt_list_entry * 3035 ice_find_ucast_rule_entry(struct LIST_HEAD_TYPE *list_head, 3036 struct ice_fltr_info *f_info) 3037 { 3038 struct ice_fltr_mgmt_list_entry *list_itr; 3039 3040 LIST_FOR_EACH_ENTRY(list_itr, list_head, ice_fltr_mgmt_list_entry, 3041 list_entry) { 3042 if (!memcmp(&f_info->l_data, &list_itr->fltr_info.l_data, 3043 sizeof(f_info->l_data)) && 3044 f_info->fwd_id.hw_vsi_id == 3045 list_itr->fltr_info.fwd_id.hw_vsi_id && 3046 f_info->flag == list_itr->fltr_info.flag) 3047 return list_itr; 3048 } 3049 return NULL; 3050 } 3051 3052 /** 3053 * ice_remove_mac_rule - remove a MAC based filter rule 3054 * @hw: pointer to the hardware structure 3055 * @m_list: list of MAC addresses and forwarding information 3056 * @recp_list: list from which function remove MAC address 3057 * 3058 * This function removes either a MAC filter rule or a specific VSI from a 3059 * VSI list for a multicast MAC address. 3060 * 3061 * Returns ICE_ERR_DOES_NOT_EXIST if a given entry was not added by 3062 * ice_add_mac. Caller should be aware that this call will only work if all 3063 * the entries passed into m_list were added previously. It will not attempt to 3064 * do a partial remove of entries that were found. 3065 */ 3066 static int 3067 ice_remove_mac_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *m_list, 3068 struct ice_sw_recipe *recp_list) 3069 { 3070 struct ice_fltr_list_entry *list_itr, *tmp; 3071 struct ice_lock *rule_lock; /* Lock to protect filter rule list */ 3072 3073 if (!m_list) 3074 return ICE_ERR_PARAM; 3075 3076 rule_lock = &recp_list->filt_rule_lock; 3077 LIST_FOR_EACH_ENTRY_SAFE(list_itr, tmp, m_list, ice_fltr_list_entry, 3078 list_entry) { 3079 enum ice_sw_lkup_type l_type = list_itr->fltr_info.lkup_type; 3080 u8 *add = &list_itr->fltr_info.l_data.mac.mac_addr[0]; 3081 u16 vsi_handle; 3082 3083 if (l_type != ICE_SW_LKUP_MAC) 3084 return ICE_ERR_PARAM; 3085 3086 vsi_handle = list_itr->fltr_info.vsi_handle; 3087 if (!ice_is_vsi_valid(hw, vsi_handle)) 3088 return ICE_ERR_PARAM; 3089 3090 list_itr->fltr_info.fwd_id.hw_vsi_id = 3091 ice_get_hw_vsi_num(hw, vsi_handle); 3092 if (IS_UNICAST_ETHER_ADDR(add) && !hw->umac_shared) { 3093 /* Don't remove the unicast address that belongs to 3094 * another VSI on the switch, since it is not being 3095 * shared... 3096 */ 3097 ice_acquire_lock(rule_lock); 3098 if (!ice_find_ucast_rule_entry(&recp_list->filt_rules, 3099 &list_itr->fltr_info)) { 3100 ice_release_lock(rule_lock); 3101 return ICE_ERR_DOES_NOT_EXIST; 3102 } 3103 ice_release_lock(rule_lock); 3104 } 3105 list_itr->status = ice_remove_rule_internal(hw, recp_list, 3106 list_itr); 3107 if (list_itr->status) 3108 return list_itr->status; 3109 } 3110 return 0; 3111 } 3112 3113 /** 3114 * ice_remove_mac - remove a MAC address based filter rule 3115 * @hw: pointer to the hardware structure 3116 * @m_list: list of MAC addresses and forwarding information 3117 * 3118 */ 3119 int ice_remove_mac(struct ice_hw *hw, struct LIST_HEAD_TYPE *m_list) 3120 { 3121 struct ice_sw_recipe *recp_list; 3122 3123 recp_list = &hw->switch_info->recp_list[ICE_SW_LKUP_MAC]; 3124 return ice_remove_mac_rule(hw, m_list, recp_list); 3125 } 3126 3127 /** 3128 * ice_remove_vlan_rule - Remove VLAN based filter rule 3129 * @hw: pointer to the hardware structure 3130 * @v_list: list of VLAN entries and forwarding information 3131 * @recp_list: list from which function remove VLAN 3132 */ 3133 static int 3134 ice_remove_vlan_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *v_list, 3135 struct ice_sw_recipe *recp_list) 3136 { 3137 struct ice_fltr_list_entry *v_list_itr, *tmp; 3138 3139 LIST_FOR_EACH_ENTRY_SAFE(v_list_itr, tmp, v_list, ice_fltr_list_entry, 3140 list_entry) { 3141 enum ice_sw_lkup_type l_type = v_list_itr->fltr_info.lkup_type; 3142 3143 if (l_type != ICE_SW_LKUP_VLAN) 3144 return ICE_ERR_PARAM; 3145 v_list_itr->status = ice_remove_rule_internal(hw, recp_list, 3146 v_list_itr); 3147 if (v_list_itr->status) 3148 return v_list_itr->status; 3149 } 3150 return 0; 3151 } 3152 3153 /** 3154 * ice_remove_vlan - remove a VLAN address based filter rule 3155 * @hw: pointer to the hardware structure 3156 * @v_list: list of VLAN and forwarding information 3157 * 3158 */ 3159 int 3160 ice_remove_vlan(struct ice_hw *hw, struct LIST_HEAD_TYPE *v_list) 3161 { 3162 struct ice_sw_recipe *recp_list; 3163 3164 if (!v_list || !hw) 3165 return ICE_ERR_PARAM; 3166 3167 recp_list = &hw->switch_info->recp_list[ICE_SW_LKUP_VLAN]; 3168 return ice_remove_vlan_rule(hw, v_list, recp_list); 3169 } 3170 3171 /** 3172 * ice_vsi_uses_fltr - Determine if given VSI uses specified filter 3173 * @fm_entry: filter entry to inspect 3174 * @vsi_handle: VSI handle to compare with filter info 3175 */ 3176 static bool 3177 ice_vsi_uses_fltr(struct ice_fltr_mgmt_list_entry *fm_entry, u16 vsi_handle) 3178 { 3179 return ((fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI && 3180 fm_entry->fltr_info.vsi_handle == vsi_handle) || 3181 (fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI_LIST && 3182 fm_entry->vsi_list_info && 3183 (ice_is_bit_set(fm_entry->vsi_list_info->vsi_map, 3184 vsi_handle)))); 3185 } 3186 3187 /** 3188 * ice_add_entry_to_vsi_fltr_list - Add copy of fltr_list_entry to remove list 3189 * @hw: pointer to the hardware structure 3190 * @vsi_handle: VSI handle to remove filters from 3191 * @vsi_list_head: pointer to the list to add entry to 3192 * @fi: pointer to fltr_info of filter entry to copy & add 3193 * 3194 * Helper function, used when creating a list of filters to remove from 3195 * a specific VSI. The entry added to vsi_list_head is a COPY of the 3196 * original filter entry, with the exception of fltr_info.fltr_act and 3197 * fltr_info.fwd_id fields. These are set such that later logic can 3198 * extract which VSI to remove the fltr from, and pass on that information. 3199 */ 3200 static int 3201 ice_add_entry_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_handle, 3202 struct LIST_HEAD_TYPE *vsi_list_head, 3203 struct ice_fltr_info *fi) 3204 { 3205 struct ice_fltr_list_entry *tmp; 3206 3207 /* this memory is freed up in the caller function 3208 * once filters for this VSI are removed 3209 */ 3210 tmp = (struct ice_fltr_list_entry *)ice_malloc(hw, sizeof(*tmp)); 3211 if (!tmp) 3212 return ICE_ERR_NO_MEMORY; 3213 3214 tmp->fltr_info = *fi; 3215 3216 /* Overwrite these fields to indicate which VSI to remove filter from, 3217 * so find and remove logic can extract the information from the 3218 * list entries. Note that original entries will still have proper 3219 * values. 3220 */ 3221 tmp->fltr_info.fltr_act = ICE_FWD_TO_VSI; 3222 tmp->fltr_info.vsi_handle = vsi_handle; 3223 tmp->fltr_info.fwd_id.hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle); 3224 3225 LIST_ADD(&tmp->list_entry, vsi_list_head); 3226 3227 return 0; 3228 } 3229 3230 /** 3231 * ice_add_to_vsi_fltr_list - Add VSI filters to the list 3232 * @hw: pointer to the hardware structure 3233 * @vsi_handle: VSI handle to remove filters from 3234 * @lkup_list_head: pointer to the list that has certain lookup type filters 3235 * @vsi_list_head: pointer to the list pertaining to VSI with vsi_handle 3236 * 3237 * Locates all filters in lkup_list_head that are used by the given VSI, 3238 * and adds COPIES of those entries to vsi_list_head (intended to be used 3239 * to remove the listed filters). 3240 * Note that this means all entries in vsi_list_head must be explicitly 3241 * deallocated by the caller when done with list. 3242 */ 3243 static int 3244 ice_add_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_handle, 3245 struct LIST_HEAD_TYPE *lkup_list_head, 3246 struct LIST_HEAD_TYPE *vsi_list_head) 3247 { 3248 struct ice_fltr_mgmt_list_entry *fm_entry; 3249 int status = 0; 3250 3251 /* check to make sure VSI ID is valid and within boundary */ 3252 if (!ice_is_vsi_valid(hw, vsi_handle)) 3253 return ICE_ERR_PARAM; 3254 3255 LIST_FOR_EACH_ENTRY(fm_entry, lkup_list_head, 3256 ice_fltr_mgmt_list_entry, list_entry) { 3257 if (!ice_vsi_uses_fltr(fm_entry, vsi_handle)) 3258 continue; 3259 3260 status = ice_add_entry_to_vsi_fltr_list(hw, vsi_handle, 3261 vsi_list_head, 3262 &fm_entry->fltr_info); 3263 if (status) 3264 return status; 3265 } 3266 return status; 3267 } 3268 3269 /** 3270 * ice_determine_promisc_mask 3271 * @fi: filter info to parse 3272 * @promisc_mask: pointer to mask to be filled in 3273 * 3274 * Helper function to determine which ICE_PROMISC_ mask corresponds 3275 * to given filter into. 3276 */ 3277 static void ice_determine_promisc_mask(struct ice_fltr_info *fi, 3278 ice_bitmap_t *promisc_mask) 3279 { 3280 u16 vid = fi->l_data.mac_vlan.vlan_id; 3281 u8 *macaddr = fi->l_data.mac.mac_addr; 3282 bool is_rx_lb_fltr = false; 3283 bool is_tx_fltr = false; 3284 3285 ice_zero_bitmap(promisc_mask, ICE_PROMISC_MAX); 3286 3287 if (fi->flag == ICE_FLTR_TX) 3288 is_tx_fltr = true; 3289 if (fi->flag == ICE_FLTR_RX_LB) 3290 is_rx_lb_fltr = true; 3291 3292 if (IS_BROADCAST_ETHER_ADDR(macaddr)) { 3293 ice_set_bit(is_tx_fltr ? ICE_PROMISC_BCAST_TX 3294 : ICE_PROMISC_BCAST_RX, promisc_mask); 3295 } else if (IS_MULTICAST_ETHER_ADDR(macaddr)) { 3296 ice_set_bit(is_tx_fltr ? ICE_PROMISC_MCAST_TX 3297 : ICE_PROMISC_MCAST_RX, promisc_mask); 3298 } else if (IS_UNICAST_ETHER_ADDR(macaddr)) { 3299 if (is_tx_fltr) 3300 ice_set_bit(ICE_PROMISC_UCAST_TX, promisc_mask); 3301 else if (is_rx_lb_fltr) 3302 ice_set_bit(ICE_PROMISC_UCAST_RX_LB, promisc_mask); 3303 else 3304 ice_set_bit(ICE_PROMISC_UCAST_RX, promisc_mask); 3305 } 3306 3307 if (vid) { 3308 ice_set_bit(is_tx_fltr ? ICE_PROMISC_VLAN_TX 3309 : ICE_PROMISC_VLAN_RX, promisc_mask); 3310 } 3311 } 3312 3313 /** 3314 * _ice_get_vsi_promisc - get promiscuous mode of given VSI 3315 * @hw: pointer to the hardware structure 3316 * @vsi_handle: VSI handle to retrieve info from 3317 * @promisc_mask: pointer to mask to be filled in 3318 * @vid: VLAN ID of promisc VLAN VSI 3319 * @sw: pointer to switch info struct for which function add rule 3320 * @lkup: switch rule filter lookup type 3321 */ 3322 static int 3323 _ice_get_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, 3324 ice_bitmap_t *promisc_mask, u16 *vid, 3325 struct ice_switch_info *sw, enum ice_sw_lkup_type lkup) 3326 { 3327 ice_declare_bitmap(fltr_promisc_mask, ICE_PROMISC_MAX); 3328 struct ice_fltr_mgmt_list_entry *itr; 3329 struct LIST_HEAD_TYPE *rule_head; 3330 struct ice_lock *rule_lock; /* Lock to protect filter rule list */ 3331 3332 if (!ice_is_vsi_valid(hw, vsi_handle) || 3333 (lkup != ICE_SW_LKUP_PROMISC && lkup != ICE_SW_LKUP_PROMISC_VLAN)) 3334 return ICE_ERR_PARAM; 3335 3336 *vid = 0; 3337 rule_head = &sw->recp_list[lkup].filt_rules; 3338 rule_lock = &sw->recp_list[lkup].filt_rule_lock; 3339 3340 ice_zero_bitmap(promisc_mask, ICE_PROMISC_MAX); 3341 3342 ice_acquire_lock(rule_lock); 3343 LIST_FOR_EACH_ENTRY(itr, rule_head, 3344 ice_fltr_mgmt_list_entry, list_entry) { 3345 /* Continue if this filter doesn't apply to this VSI or the 3346 * VSI ID is not in the VSI map for this filter 3347 */ 3348 if (!ice_vsi_uses_fltr(itr, vsi_handle)) 3349 continue; 3350 3351 ice_determine_promisc_mask(&itr->fltr_info, fltr_promisc_mask); 3352 ice_or_bitmap(promisc_mask, promisc_mask, fltr_promisc_mask, 3353 ICE_PROMISC_MAX); 3354 3355 } 3356 ice_release_lock(rule_lock); 3357 3358 return 0; 3359 } 3360 3361 /** 3362 * ice_get_vsi_promisc - get promiscuous mode of given VSI 3363 * @hw: pointer to the hardware structure 3364 * @vsi_handle: VSI handle to retrieve info from 3365 * @promisc_mask: pointer to mask to be filled in 3366 * @vid: VLAN ID of promisc VLAN VSI 3367 */ 3368 int 3369 ice_get_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, 3370 ice_bitmap_t *promisc_mask, u16 *vid) 3371 { 3372 if (!vid || !promisc_mask || !hw) 3373 return ICE_ERR_PARAM; 3374 3375 return _ice_get_vsi_promisc(hw, vsi_handle, promisc_mask, 3376 vid, hw->switch_info, ICE_SW_LKUP_PROMISC); 3377 } 3378 3379 /** 3380 * ice_get_vsi_vlan_promisc - get VLAN promiscuous mode of given VSI 3381 * @hw: pointer to the hardware structure 3382 * @vsi_handle: VSI handle to retrieve info from 3383 * @promisc_mask: pointer to mask to be filled in 3384 * @vid: VLAN ID of promisc VLAN VSI 3385 */ 3386 int 3387 ice_get_vsi_vlan_promisc(struct ice_hw *hw, u16 vsi_handle, 3388 ice_bitmap_t *promisc_mask, u16 *vid) 3389 { 3390 if (!hw || !promisc_mask || !vid) 3391 return ICE_ERR_PARAM; 3392 3393 return _ice_get_vsi_promisc(hw, vsi_handle, promisc_mask, 3394 vid, hw->switch_info, 3395 ICE_SW_LKUP_PROMISC_VLAN); 3396 } 3397 3398 /** 3399 * ice_remove_promisc - Remove promisc based filter rules 3400 * @hw: pointer to the hardware structure 3401 * @recp_id: recipe ID for which the rule needs to removed 3402 * @v_list: list of promisc entries 3403 */ 3404 static int 3405 ice_remove_promisc(struct ice_hw *hw, u8 recp_id, 3406 struct LIST_HEAD_TYPE *v_list) 3407 { 3408 struct ice_fltr_list_entry *v_list_itr, *tmp; 3409 struct ice_sw_recipe *recp_list; 3410 3411 recp_list = &hw->switch_info->recp_list[recp_id]; 3412 LIST_FOR_EACH_ENTRY_SAFE(v_list_itr, tmp, v_list, ice_fltr_list_entry, 3413 list_entry) { 3414 v_list_itr->status = 3415 ice_remove_rule_internal(hw, recp_list, v_list_itr); 3416 if (v_list_itr->status) 3417 return v_list_itr->status; 3418 } 3419 return 0; 3420 } 3421 3422 /** 3423 * _ice_clear_vsi_promisc - clear specified promiscuous mode(s) 3424 * @hw: pointer to the hardware structure 3425 * @vsi_handle: VSI handle to clear mode 3426 * @promisc_mask: pointer to mask of promiscuous config bits to clear 3427 * @vid: VLAN ID to clear VLAN promiscuous 3428 * @sw: pointer to switch info struct for which function add rule 3429 */ 3430 static int 3431 _ice_clear_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, 3432 ice_bitmap_t *promisc_mask, u16 vid, 3433 struct ice_switch_info *sw) 3434 { 3435 ice_declare_bitmap(compl_promisc_mask, ICE_PROMISC_MAX); 3436 ice_declare_bitmap(fltr_promisc_mask, ICE_PROMISC_MAX); 3437 struct ice_fltr_list_entry *fm_entry, *tmp; 3438 struct LIST_HEAD_TYPE remove_list_head; 3439 struct ice_fltr_mgmt_list_entry *itr; 3440 struct LIST_HEAD_TYPE *rule_head; 3441 struct ice_lock *rule_lock; /* Lock to protect filter rule list */ 3442 int status = 0; 3443 u8 recipe_id; 3444 3445 if (!ice_is_vsi_valid(hw, vsi_handle)) 3446 return ICE_ERR_PARAM; 3447 3448 if (ice_is_bit_set(promisc_mask, ICE_PROMISC_VLAN_RX) && 3449 ice_is_bit_set(promisc_mask, ICE_PROMISC_VLAN_TX)) 3450 recipe_id = ICE_SW_LKUP_PROMISC_VLAN; 3451 else 3452 recipe_id = ICE_SW_LKUP_PROMISC; 3453 3454 rule_head = &sw->recp_list[recipe_id].filt_rules; 3455 rule_lock = &sw->recp_list[recipe_id].filt_rule_lock; 3456 3457 INIT_LIST_HEAD(&remove_list_head); 3458 3459 ice_acquire_lock(rule_lock); 3460 LIST_FOR_EACH_ENTRY(itr, rule_head, 3461 ice_fltr_mgmt_list_entry, list_entry) { 3462 struct ice_fltr_info *fltr_info; 3463 ice_zero_bitmap(compl_promisc_mask, ICE_PROMISC_MAX); 3464 3465 if (!ice_vsi_uses_fltr(itr, vsi_handle)) 3466 continue; 3467 fltr_info = &itr->fltr_info; 3468 3469 if (recipe_id == ICE_SW_LKUP_PROMISC_VLAN && 3470 vid != fltr_info->l_data.mac_vlan.vlan_id) 3471 continue; 3472 3473 ice_determine_promisc_mask(fltr_info, fltr_promisc_mask); 3474 ice_andnot_bitmap(compl_promisc_mask, fltr_promisc_mask, 3475 promisc_mask, ICE_PROMISC_MAX); 3476 3477 /* Skip if filter is not completely specified by given mask */ 3478 if (ice_is_any_bit_set(compl_promisc_mask, ICE_PROMISC_MAX)) 3479 continue; 3480 3481 status = ice_add_entry_to_vsi_fltr_list(hw, vsi_handle, 3482 &remove_list_head, 3483 fltr_info); 3484 if (status) { 3485 ice_release_lock(rule_lock); 3486 goto free_fltr_list; 3487 } 3488 } 3489 ice_release_lock(rule_lock); 3490 3491 status = ice_remove_promisc(hw, recipe_id, &remove_list_head); 3492 3493 free_fltr_list: 3494 LIST_FOR_EACH_ENTRY_SAFE(fm_entry, tmp, &remove_list_head, 3495 ice_fltr_list_entry, list_entry) { 3496 LIST_DEL(&fm_entry->list_entry); 3497 ice_free(hw, fm_entry); 3498 } 3499 3500 return status; 3501 } 3502 3503 /** 3504 * ice_clear_vsi_promisc - clear specified promiscuous mode(s) for given VSI 3505 * @hw: pointer to the hardware structure 3506 * @vsi_handle: VSI handle to clear mode 3507 * @promisc_mask: pointer to mask of promiscuous config bits to clear 3508 * @vid: VLAN ID to clear VLAN promiscuous 3509 */ 3510 int 3511 ice_clear_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, 3512 ice_bitmap_t *promisc_mask, u16 vid) 3513 { 3514 if (!hw || !promisc_mask) 3515 return ICE_ERR_PARAM; 3516 3517 return _ice_clear_vsi_promisc(hw, vsi_handle, promisc_mask, 3518 vid, hw->switch_info); 3519 } 3520 3521 /** 3522 * _ice_set_vsi_promisc - set given VSI to given promiscuous mode(s) 3523 * @hw: pointer to the hardware structure 3524 * @vsi_handle: VSI handle to configure 3525 * @promisc_mask: pointer to mask of promiscuous config bits 3526 * @vid: VLAN ID to set VLAN promiscuous 3527 * @lport: logical port number to configure promisc mode 3528 * @sw: pointer to switch info struct for which function add rule 3529 */ 3530 static int 3531 _ice_set_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, 3532 ice_bitmap_t *promisc_mask, u16 vid, u8 lport, 3533 struct ice_switch_info *sw) 3534 { 3535 enum { UCAST_FLTR = 1, MCAST_FLTR, BCAST_FLTR }; 3536 ice_declare_bitmap(p_mask, ICE_PROMISC_MAX); 3537 struct ice_fltr_list_entry f_list_entry; 3538 bool is_tx_fltr, is_rx_lb_fltr; 3539 struct ice_fltr_info new_fltr; 3540 int status = 0; 3541 u16 hw_vsi_id; 3542 int pkt_type; 3543 u8 recipe_id; 3544 3545 ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__); 3546 3547 if (!ice_is_vsi_valid(hw, vsi_handle)) 3548 return ICE_ERR_PARAM; 3549 hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle); 3550 3551 ice_memset(&new_fltr, 0, sizeof(new_fltr), ICE_NONDMA_MEM); 3552 3553 /* Do not modify original bitmap */ 3554 ice_cp_bitmap(p_mask, promisc_mask, ICE_PROMISC_MAX); 3555 3556 if (ice_is_bit_set(p_mask, ICE_PROMISC_VLAN_RX) && 3557 ice_is_bit_set(p_mask, ICE_PROMISC_VLAN_TX)) { 3558 new_fltr.lkup_type = ICE_SW_LKUP_PROMISC_VLAN; 3559 new_fltr.l_data.mac_vlan.vlan_id = vid; 3560 recipe_id = ICE_SW_LKUP_PROMISC_VLAN; 3561 } else { 3562 new_fltr.lkup_type = ICE_SW_LKUP_PROMISC; 3563 recipe_id = ICE_SW_LKUP_PROMISC; 3564 } 3565 3566 /* Separate filters must be set for each direction/packet type 3567 * combination, so we will loop over the mask value, store the 3568 * individual type, and clear it out in the input mask as it 3569 * is found. 3570 */ 3571 while (ice_is_any_bit_set(p_mask, ICE_PROMISC_MAX)) { 3572 struct ice_sw_recipe *recp_list; 3573 u8 *mac_addr; 3574 3575 pkt_type = 0; 3576 is_tx_fltr = false; 3577 is_rx_lb_fltr = false; 3578 3579 if (ice_test_and_clear_bit(ICE_PROMISC_UCAST_RX, 3580 p_mask)) { 3581 pkt_type = UCAST_FLTR; 3582 } else if (ice_test_and_clear_bit(ICE_PROMISC_UCAST_TX, 3583 p_mask)) { 3584 pkt_type = UCAST_FLTR; 3585 is_tx_fltr = true; 3586 } else if (ice_test_and_clear_bit(ICE_PROMISC_MCAST_RX, 3587 p_mask)) { 3588 pkt_type = MCAST_FLTR; 3589 } else if (ice_test_and_clear_bit(ICE_PROMISC_MCAST_TX, 3590 p_mask)) { 3591 pkt_type = MCAST_FLTR; 3592 is_tx_fltr = true; 3593 } else if (ice_test_and_clear_bit(ICE_PROMISC_BCAST_RX, 3594 p_mask)) { 3595 pkt_type = BCAST_FLTR; 3596 } else if (ice_test_and_clear_bit(ICE_PROMISC_BCAST_TX, 3597 p_mask)) { 3598 pkt_type = BCAST_FLTR; 3599 is_tx_fltr = true; 3600 } else if (ice_test_and_clear_bit(ICE_PROMISC_UCAST_RX_LB, 3601 p_mask)) { 3602 pkt_type = UCAST_FLTR; 3603 is_rx_lb_fltr = true; 3604 } 3605 3606 /* Check for VLAN promiscuous flag */ 3607 if (ice_is_bit_set(p_mask, ICE_PROMISC_VLAN_RX)) { 3608 ice_clear_bit(ICE_PROMISC_VLAN_RX, p_mask); 3609 } else if (ice_test_and_clear_bit(ICE_PROMISC_VLAN_TX, 3610 p_mask)) { 3611 is_tx_fltr = true; 3612 } 3613 /* Set filter DA based on packet type */ 3614 mac_addr = new_fltr.l_data.mac.mac_addr; 3615 if (pkt_type == BCAST_FLTR) { 3616 ice_memset(mac_addr, 0xff, ETH_ALEN, ICE_NONDMA_MEM); 3617 } else if (pkt_type == MCAST_FLTR || 3618 pkt_type == UCAST_FLTR) { 3619 /* Use the dummy ether header DA */ 3620 ice_memcpy(mac_addr, dummy_eth_header, ETH_ALEN, 3621 ICE_NONDMA_TO_NONDMA); 3622 if (pkt_type == MCAST_FLTR) 3623 mac_addr[0] |= 0x1; /* Set multicast bit */ 3624 } 3625 3626 /* Need to reset this to zero for all iterations */ 3627 new_fltr.flag = 0; 3628 if (is_tx_fltr) { 3629 new_fltr.flag |= ICE_FLTR_TX; 3630 new_fltr.src = hw_vsi_id; 3631 } else if (is_rx_lb_fltr) { 3632 new_fltr.flag |= ICE_FLTR_RX_LB; 3633 new_fltr.src = hw_vsi_id; 3634 } else { 3635 new_fltr.flag |= ICE_FLTR_RX; 3636 new_fltr.src = lport; 3637 } 3638 3639 new_fltr.fltr_act = ICE_FWD_TO_VSI; 3640 new_fltr.vsi_handle = vsi_handle; 3641 new_fltr.fwd_id.hw_vsi_id = hw_vsi_id; 3642 f_list_entry.fltr_info = new_fltr; 3643 recp_list = &sw->recp_list[recipe_id]; 3644 3645 status = ice_add_rule_internal(hw, recp_list, lport, 3646 &f_list_entry); 3647 if (status) 3648 goto set_promisc_exit; 3649 } 3650 3651 set_promisc_exit: 3652 return status; 3653 } 3654 3655 /** 3656 * ice_set_vsi_promisc - set given VSI to given promiscuous mode(s) 3657 * @hw: pointer to the hardware structure 3658 * @vsi_handle: VSI handle to configure 3659 * @promisc_mask: pointer to mask of promiscuous config bits 3660 * @vid: VLAN ID to set VLAN promiscuous 3661 */ 3662 int 3663 ice_set_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, 3664 ice_bitmap_t *promisc_mask, u16 vid) 3665 { 3666 if (!hw || !promisc_mask) 3667 return ICE_ERR_PARAM; 3668 3669 return _ice_set_vsi_promisc(hw, vsi_handle, promisc_mask, vid, 3670 hw->port_info->lport, 3671 hw->switch_info); 3672 } 3673 3674 /** 3675 * _ice_set_vlan_vsi_promisc 3676 * @hw: pointer to the hardware structure 3677 * @vsi_handle: VSI handle to configure 3678 * @promisc_mask: pointer to mask of promiscuous config bits 3679 * @rm_vlan_promisc: Clear VLANs VSI promisc mode 3680 * @lport: logical port number to configure promisc mode 3681 * @sw: pointer to switch info struct for which function add rule 3682 * 3683 * Configure VSI with all associated VLANs to given promiscuous mode(s) 3684 */ 3685 static int 3686 _ice_set_vlan_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, 3687 ice_bitmap_t *promisc_mask, bool rm_vlan_promisc, 3688 u8 lport, struct ice_switch_info *sw) 3689 { 3690 struct ice_fltr_list_entry *list_itr, *tmp; 3691 struct LIST_HEAD_TYPE vsi_list_head; 3692 struct LIST_HEAD_TYPE *vlan_head; 3693 struct ice_lock *vlan_lock; /* Lock to protect filter rule list */ 3694 int status; 3695 u16 vlan_id; 3696 3697 INIT_LIST_HEAD(&vsi_list_head); 3698 vlan_lock = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rule_lock; 3699 vlan_head = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rules; 3700 ice_acquire_lock(vlan_lock); 3701 status = ice_add_to_vsi_fltr_list(hw, vsi_handle, vlan_head, 3702 &vsi_list_head); 3703 ice_release_lock(vlan_lock); 3704 if (status) 3705 goto free_fltr_list; 3706 3707 LIST_FOR_EACH_ENTRY(list_itr, &vsi_list_head, ice_fltr_list_entry, 3708 list_entry) { 3709 /* Avoid enabling or disabling vlan zero twice when in double 3710 * vlan mode 3711 */ 3712 if (ice_is_dvm_ena(hw) && 3713 list_itr->fltr_info.l_data.vlan.tpid == 0) 3714 continue; 3715 3716 vlan_id = list_itr->fltr_info.l_data.vlan.vlan_id; 3717 if (rm_vlan_promisc) 3718 status = _ice_clear_vsi_promisc(hw, vsi_handle, 3719 promisc_mask, 3720 vlan_id, sw); 3721 else 3722 status = _ice_set_vsi_promisc(hw, vsi_handle, 3723 promisc_mask, vlan_id, 3724 lport, sw); 3725 if (status && status != ICE_ERR_ALREADY_EXISTS) 3726 break; 3727 } 3728 3729 free_fltr_list: 3730 LIST_FOR_EACH_ENTRY_SAFE(list_itr, tmp, &vsi_list_head, 3731 ice_fltr_list_entry, list_entry) { 3732 LIST_DEL(&list_itr->list_entry); 3733 ice_free(hw, list_itr); 3734 } 3735 return status; 3736 } 3737 3738 /** 3739 * ice_set_vlan_vsi_promisc 3740 * @hw: pointer to the hardware structure 3741 * @vsi_handle: VSI handle to configure 3742 * @promisc_mask: mask of promiscuous config bits 3743 * @rm_vlan_promisc: Clear VLANs VSI promisc mode 3744 * 3745 * Configure VSI with all associated VLANs to given promiscuous mode(s) 3746 */ 3747 int 3748 ice_set_vlan_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, 3749 ice_bitmap_t *promisc_mask, bool rm_vlan_promisc) 3750 { 3751 if (!hw || !promisc_mask) 3752 return ICE_ERR_PARAM; 3753 3754 return _ice_set_vlan_vsi_promisc(hw, vsi_handle, promisc_mask, 3755 rm_vlan_promisc, hw->port_info->lport, 3756 hw->switch_info); 3757 } 3758 3759 /** 3760 * ice_remove_vsi_lkup_fltr - Remove lookup type filters for a VSI 3761 * @hw: pointer to the hardware structure 3762 * @vsi_handle: VSI handle to remove filters from 3763 * @recp_list: recipe list from which function remove fltr 3764 * @lkup: switch rule filter lookup type 3765 */ 3766 static void 3767 ice_remove_vsi_lkup_fltr(struct ice_hw *hw, u16 vsi_handle, 3768 struct ice_sw_recipe *recp_list, 3769 enum ice_sw_lkup_type lkup) 3770 { 3771 struct ice_fltr_list_entry *fm_entry; 3772 struct LIST_HEAD_TYPE remove_list_head; 3773 struct LIST_HEAD_TYPE *rule_head; 3774 struct ice_fltr_list_entry *tmp; 3775 struct ice_lock *rule_lock; /* Lock to protect filter rule list */ 3776 int status; 3777 3778 INIT_LIST_HEAD(&remove_list_head); 3779 rule_lock = &recp_list[lkup].filt_rule_lock; 3780 rule_head = &recp_list[lkup].filt_rules; 3781 ice_acquire_lock(rule_lock); 3782 status = ice_add_to_vsi_fltr_list(hw, vsi_handle, rule_head, 3783 &remove_list_head); 3784 ice_release_lock(rule_lock); 3785 if (status) 3786 goto free_fltr_list; 3787 3788 switch (lkup) { 3789 case ICE_SW_LKUP_MAC: 3790 ice_remove_mac_rule(hw, &remove_list_head, &recp_list[lkup]); 3791 break; 3792 case ICE_SW_LKUP_VLAN: 3793 ice_remove_vlan_rule(hw, &remove_list_head, &recp_list[lkup]); 3794 break; 3795 case ICE_SW_LKUP_PROMISC: 3796 case ICE_SW_LKUP_PROMISC_VLAN: 3797 ice_remove_promisc(hw, (u8)lkup, &remove_list_head); 3798 break; 3799 case ICE_SW_LKUP_MAC_VLAN: 3800 ice_debug(hw, ICE_DBG_SW, "MAC VLAN look up is not supported yet\n"); 3801 break; 3802 case ICE_SW_LKUP_ETHERTYPE: 3803 case ICE_SW_LKUP_ETHERTYPE_MAC: 3804 ice_remove_eth_mac(hw, &remove_list_head); 3805 break; 3806 case ICE_SW_LKUP_DFLT: 3807 ice_debug(hw, ICE_DBG_SW, "Remove filters for this lookup type hasn't been implemented yet\n"); 3808 break; 3809 case ICE_SW_LKUP_LAST: 3810 ice_debug(hw, ICE_DBG_SW, "Unsupported lookup type\n"); 3811 break; 3812 } 3813 3814 free_fltr_list: 3815 LIST_FOR_EACH_ENTRY_SAFE(fm_entry, tmp, &remove_list_head, 3816 ice_fltr_list_entry, list_entry) { 3817 LIST_DEL(&fm_entry->list_entry); 3818 ice_free(hw, fm_entry); 3819 } 3820 } 3821 3822 /** 3823 * ice_remove_vsi_fltr_rule - Remove all filters for a VSI 3824 * @hw: pointer to the hardware structure 3825 * @vsi_handle: VSI handle to remove filters from 3826 * @sw: pointer to switch info struct 3827 */ 3828 static void 3829 ice_remove_vsi_fltr_rule(struct ice_hw *hw, u16 vsi_handle, 3830 struct ice_switch_info *sw) 3831 { 3832 ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__); 3833 3834 ice_remove_vsi_lkup_fltr(hw, vsi_handle, 3835 sw->recp_list, ICE_SW_LKUP_MAC); 3836 ice_remove_vsi_lkup_fltr(hw, vsi_handle, 3837 sw->recp_list, ICE_SW_LKUP_MAC_VLAN); 3838 ice_remove_vsi_lkup_fltr(hw, vsi_handle, 3839 sw->recp_list, ICE_SW_LKUP_PROMISC); 3840 ice_remove_vsi_lkup_fltr(hw, vsi_handle, 3841 sw->recp_list, ICE_SW_LKUP_VLAN); 3842 ice_remove_vsi_lkup_fltr(hw, vsi_handle, 3843 sw->recp_list, ICE_SW_LKUP_DFLT); 3844 ice_remove_vsi_lkup_fltr(hw, vsi_handle, 3845 sw->recp_list, ICE_SW_LKUP_ETHERTYPE); 3846 ice_remove_vsi_lkup_fltr(hw, vsi_handle, 3847 sw->recp_list, ICE_SW_LKUP_ETHERTYPE_MAC); 3848 ice_remove_vsi_lkup_fltr(hw, vsi_handle, 3849 sw->recp_list, ICE_SW_LKUP_PROMISC_VLAN); 3850 } 3851 3852 /** 3853 * ice_remove_vsi_fltr - Remove all filters for a VSI 3854 * @hw: pointer to the hardware structure 3855 * @vsi_handle: VSI handle to remove filters from 3856 */ 3857 void ice_remove_vsi_fltr(struct ice_hw *hw, u16 vsi_handle) 3858 { 3859 ice_remove_vsi_fltr_rule(hw, vsi_handle, hw->switch_info); 3860 } 3861 3862 /** 3863 * ice_alloc_res_cntr - allocating resource counter 3864 * @hw: pointer to the hardware structure 3865 * @type: type of resource 3866 * @alloc_shared: if set it is shared else dedicated 3867 * @num_items: number of entries requested for FD resource type 3868 * @counter_id: counter index returned by AQ call 3869 */ 3870 static int 3871 ice_alloc_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items, 3872 u16 *counter_id) 3873 { 3874 struct ice_aqc_alloc_free_res_elem *buf; 3875 u16 buf_len; 3876 int status; 3877 3878 /* Allocate resource */ 3879 buf_len = ice_struct_size(buf, elem, 1); 3880 buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len); 3881 if (!buf) 3882 return ICE_ERR_NO_MEMORY; 3883 3884 buf->num_elems = CPU_TO_LE16(num_items); 3885 buf->res_type = CPU_TO_LE16(((type << ICE_AQC_RES_TYPE_S) & 3886 ICE_AQC_RES_TYPE_M) | alloc_shared); 3887 3888 status = ice_aq_alloc_free_res(hw, 1, buf, buf_len, 3889 ice_aqc_opc_alloc_res, NULL); 3890 if (status) 3891 goto exit; 3892 3893 *counter_id = LE16_TO_CPU(buf->elem[0].e.sw_resp); 3894 3895 exit: 3896 ice_free(hw, buf); 3897 return status; 3898 } 3899 3900 /** 3901 * ice_free_res_cntr - free resource counter 3902 * @hw: pointer to the hardware structure 3903 * @type: type of resource 3904 * @alloc_shared: if set it is shared else dedicated 3905 * @num_items: number of entries to be freed for FD resource type 3906 * @counter_id: counter ID resource which needs to be freed 3907 */ 3908 static int 3909 ice_free_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items, 3910 u16 counter_id) 3911 { 3912 struct ice_aqc_alloc_free_res_elem *buf; 3913 u16 buf_len; 3914 int status; 3915 3916 /* Free resource */ 3917 buf_len = ice_struct_size(buf, elem, 1); 3918 buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len); 3919 if (!buf) 3920 return ICE_ERR_NO_MEMORY; 3921 3922 buf->num_elems = CPU_TO_LE16(num_items); 3923 buf->res_type = CPU_TO_LE16(((type << ICE_AQC_RES_TYPE_S) & 3924 ICE_AQC_RES_TYPE_M) | alloc_shared); 3925 buf->elem[0].e.sw_resp = CPU_TO_LE16(counter_id); 3926 3927 status = ice_aq_alloc_free_res(hw, 1, buf, buf_len, 3928 ice_aqc_opc_free_res, NULL); 3929 if (status) 3930 ice_debug(hw, ICE_DBG_SW, "counter resource could not be freed\n"); 3931 3932 ice_free(hw, buf); 3933 return status; 3934 } 3935 3936 /** 3937 * ice_alloc_vlan_res_counter - obtain counter resource for VLAN type 3938 * @hw: pointer to the hardware structure 3939 * @counter_id: returns counter index 3940 */ 3941 int ice_alloc_vlan_res_counter(struct ice_hw *hw, u16 *counter_id) 3942 { 3943 return ice_alloc_res_cntr(hw, ICE_AQC_RES_TYPE_VLAN_COUNTER, 3944 ICE_AQC_RES_TYPE_FLAG_DEDICATED, 1, 3945 counter_id); 3946 } 3947 3948 /** 3949 * ice_free_vlan_res_counter - Free counter resource for VLAN type 3950 * @hw: pointer to the hardware structure 3951 * @counter_id: counter index to be freed 3952 */ 3953 int ice_free_vlan_res_counter(struct ice_hw *hw, u16 counter_id) 3954 { 3955 return ice_free_res_cntr(hw, ICE_AQC_RES_TYPE_VLAN_COUNTER, 3956 ICE_AQC_RES_TYPE_FLAG_DEDICATED, 1, 3957 counter_id); 3958 } 3959 3960 /** 3961 * ice_add_mac_with_sw_marker - add filter with sw marker 3962 * @hw: pointer to the hardware structure 3963 * @f_info: filter info structure containing the MAC filter information 3964 * @sw_marker: sw marker to tag the Rx descriptor with 3965 */ 3966 int 3967 ice_add_mac_with_sw_marker(struct ice_hw *hw, struct ice_fltr_info *f_info, 3968 u16 sw_marker) 3969 { 3970 struct ice_fltr_mgmt_list_entry *m_entry; 3971 struct ice_fltr_list_entry fl_info; 3972 struct ice_sw_recipe *recp_list; 3973 struct LIST_HEAD_TYPE l_head; 3974 struct ice_lock *rule_lock; /* Lock to protect filter rule list */ 3975 bool entry_exists; 3976 u16 lg_act_id; 3977 int ret; 3978 3979 if (f_info->fltr_act != ICE_FWD_TO_VSI) 3980 return ICE_ERR_PARAM; 3981 3982 if (f_info->lkup_type != ICE_SW_LKUP_MAC) 3983 return ICE_ERR_PARAM; 3984 3985 if (sw_marker == ICE_INVAL_SW_MARKER_ID) 3986 return ICE_ERR_PARAM; 3987 3988 if (!ice_is_vsi_valid(hw, f_info->vsi_handle)) 3989 return ICE_ERR_PARAM; 3990 f_info->fwd_id.hw_vsi_id = ice_get_hw_vsi_num(hw, f_info->vsi_handle); 3991 3992 /* Add filter if it doesn't exist so then the adding of large 3993 * action always results in update 3994 */ 3995 3996 INIT_LIST_HEAD(&l_head); 3997 fl_info.fltr_info = *f_info; 3998 LIST_ADD(&fl_info.list_entry, &l_head); 3999 4000 entry_exists = false; 4001 ret = ice_add_mac_rule(hw, &l_head, hw->switch_info, 4002 hw->port_info->lport); 4003 if (ret == ICE_ERR_ALREADY_EXISTS) 4004 entry_exists = true; 4005 else if (ret) 4006 return ret; 4007 4008 recp_list = &hw->switch_info->recp_list[ICE_SW_LKUP_MAC]; 4009 rule_lock = &recp_list->filt_rule_lock; 4010 ice_acquire_lock(rule_lock); 4011 /* Get the book keeping entry for the filter */ 4012 m_entry = ice_find_rule_entry(&recp_list->filt_rules, f_info); 4013 if (!m_entry) 4014 goto exit_error; 4015 4016 /* If counter action was enabled for this rule then don't enable 4017 * sw marker large action 4018 */ 4019 if (m_entry->counter_index != ICE_INVAL_COUNTER_ID) { 4020 ret = ICE_ERR_PARAM; 4021 goto exit_error; 4022 } 4023 4024 /* if same marker was added before */ 4025 if (m_entry->sw_marker_id == sw_marker) { 4026 ret = ICE_ERR_ALREADY_EXISTS; 4027 goto exit_error; 4028 } 4029 4030 /* Allocate a hardware table entry to hold large act. Three actions 4031 * for marker based large action 4032 */ 4033 ret = ice_alloc_res_lg_act(hw, &lg_act_id, 3); 4034 if (ret) 4035 goto exit_error; 4036 4037 if (lg_act_id == ICE_INVAL_LG_ACT_INDEX) 4038 goto exit_error; 4039 4040 /* Update the switch rule to add the marker action */ 4041 ret = ice_add_marker_act(hw, m_entry, sw_marker, lg_act_id); 4042 if (!ret) { 4043 ice_release_lock(rule_lock); 4044 return ret; 4045 } 4046 4047 exit_error: 4048 ice_release_lock(rule_lock); 4049 /* only remove entry if it did not exist previously */ 4050 if (!entry_exists) 4051 ret = ice_remove_mac(hw, &l_head); 4052 4053 return ret; 4054 } 4055 4056 /** 4057 * ice_add_mac_with_counter - add filter with counter enabled 4058 * @hw: pointer to the hardware structure 4059 * @f_info: pointer to filter info structure containing the MAC filter 4060 * information 4061 */ 4062 int 4063 ice_add_mac_with_counter(struct ice_hw *hw, struct ice_fltr_info *f_info) 4064 { 4065 struct ice_fltr_mgmt_list_entry *m_entry; 4066 struct ice_fltr_list_entry fl_info; 4067 struct ice_sw_recipe *recp_list; 4068 struct LIST_HEAD_TYPE l_head; 4069 struct ice_lock *rule_lock; /* Lock to protect filter rule list */ 4070 bool entry_exist; 4071 u16 counter_id; 4072 u16 lg_act_id; 4073 int ret; 4074 4075 if (f_info->fltr_act != ICE_FWD_TO_VSI) 4076 return ICE_ERR_PARAM; 4077 4078 if (f_info->lkup_type != ICE_SW_LKUP_MAC) 4079 return ICE_ERR_PARAM; 4080 4081 if (!ice_is_vsi_valid(hw, f_info->vsi_handle)) 4082 return ICE_ERR_PARAM; 4083 f_info->fwd_id.hw_vsi_id = ice_get_hw_vsi_num(hw, f_info->vsi_handle); 4084 recp_list = &hw->switch_info->recp_list[ICE_SW_LKUP_MAC]; 4085 4086 entry_exist = false; 4087 4088 rule_lock = &recp_list->filt_rule_lock; 4089 4090 /* Add filter if it doesn't exist so then the adding of large 4091 * action always results in update 4092 */ 4093 INIT_LIST_HEAD(&l_head); 4094 4095 fl_info.fltr_info = *f_info; 4096 LIST_ADD(&fl_info.list_entry, &l_head); 4097 4098 ret = ice_add_mac_rule(hw, &l_head, hw->switch_info, 4099 hw->port_info->lport); 4100 if (ret == ICE_ERR_ALREADY_EXISTS) 4101 entry_exist = true; 4102 else if (ret) 4103 return ret; 4104 4105 ice_acquire_lock(rule_lock); 4106 m_entry = ice_find_rule_entry(&recp_list->filt_rules, f_info); 4107 if (!m_entry) { 4108 ret = ICE_ERR_BAD_PTR; 4109 goto exit_error; 4110 } 4111 4112 /* Don't enable counter for a filter for which sw marker was enabled */ 4113 if (m_entry->sw_marker_id != ICE_INVAL_SW_MARKER_ID) { 4114 ret = ICE_ERR_PARAM; 4115 goto exit_error; 4116 } 4117 4118 /* If a counter was already enabled then don't need to add again */ 4119 if (m_entry->counter_index != ICE_INVAL_COUNTER_ID) { 4120 ret = ICE_ERR_ALREADY_EXISTS; 4121 goto exit_error; 4122 } 4123 4124 /* Allocate a hardware table entry to VLAN counter */ 4125 ret = ice_alloc_vlan_res_counter(hw, &counter_id); 4126 if (ret) 4127 goto exit_error; 4128 4129 /* Allocate a hardware table entry to hold large act. Two actions for 4130 * counter based large action 4131 */ 4132 ret = ice_alloc_res_lg_act(hw, &lg_act_id, 2); 4133 if (ret) 4134 goto exit_error; 4135 4136 if (lg_act_id == ICE_INVAL_LG_ACT_INDEX) 4137 goto exit_error; 4138 4139 /* Update the switch rule to add the counter action */ 4140 ret = ice_add_counter_act(hw, m_entry, counter_id, lg_act_id); 4141 if (!ret) { 4142 ice_release_lock(rule_lock); 4143 return ret; 4144 } 4145 4146 exit_error: 4147 ice_release_lock(rule_lock); 4148 /* only remove entry if it did not exist previously */ 4149 if (!entry_exist) 4150 ret = ice_remove_mac(hw, &l_head); 4151 4152 return ret; 4153 } 4154 4155 /** 4156 * ice_replay_fltr - Replay all the filters stored by a specific list head 4157 * @hw: pointer to the hardware structure 4158 * @list_head: list for which filters needs to be replayed 4159 * @recp_id: Recipe ID for which rules need to be replayed 4160 */ 4161 static int 4162 ice_replay_fltr(struct ice_hw *hw, u8 recp_id, struct LIST_HEAD_TYPE *list_head) 4163 { 4164 struct ice_fltr_mgmt_list_entry *itr; 4165 struct ice_sw_recipe *recp_list; 4166 u8 lport = hw->port_info->lport; 4167 struct LIST_HEAD_TYPE l_head; 4168 int status = 0; 4169 4170 if (LIST_EMPTY(list_head)) 4171 return status; 4172 4173 recp_list = &hw->switch_info->recp_list[recp_id]; 4174 /* Move entries from the given list_head to a temporary l_head so that 4175 * they can be replayed. Otherwise when trying to re-add the same 4176 * filter, the function will return already exists 4177 */ 4178 LIST_REPLACE_INIT(list_head, &l_head); 4179 4180 /* Mark the given list_head empty by reinitializing it so filters 4181 * could be added again by *handler 4182 */ 4183 LIST_FOR_EACH_ENTRY(itr, &l_head, ice_fltr_mgmt_list_entry, 4184 list_entry) { 4185 struct ice_fltr_list_entry f_entry; 4186 u16 vsi_handle; 4187 4188 f_entry.fltr_info = itr->fltr_info; 4189 if (itr->vsi_count < 2 && recp_id != ICE_SW_LKUP_VLAN) { 4190 status = ice_add_rule_internal(hw, recp_list, lport, 4191 &f_entry); 4192 if (status) 4193 goto end; 4194 continue; 4195 } 4196 4197 /* Add a filter per VSI separately */ 4198 ice_for_each_set_bit(vsi_handle, itr->vsi_list_info->vsi_map, 4199 ICE_MAX_VSI) { 4200 if (!ice_is_vsi_valid(hw, vsi_handle)) 4201 break; 4202 4203 ice_clear_bit(vsi_handle, itr->vsi_list_info->vsi_map); 4204 f_entry.fltr_info.vsi_handle = vsi_handle; 4205 f_entry.fltr_info.fwd_id.hw_vsi_id = 4206 ice_get_hw_vsi_num(hw, vsi_handle); 4207 f_entry.fltr_info.fltr_act = ICE_FWD_TO_VSI; 4208 if (recp_id == ICE_SW_LKUP_VLAN) 4209 status = ice_add_vlan_internal(hw, recp_list, 4210 &f_entry); 4211 else 4212 status = ice_add_rule_internal(hw, recp_list, 4213 lport, 4214 &f_entry); 4215 if (status) 4216 goto end; 4217 } 4218 } 4219 end: 4220 /* Clear the filter management list */ 4221 ice_rem_sw_rule_info(hw, &l_head); 4222 return status; 4223 } 4224 4225 /** 4226 * ice_replay_all_fltr - replay all filters stored in bookkeeping lists 4227 * @hw: pointer to the hardware structure 4228 * 4229 * NOTE: This function does not clean up partially added filters on error. 4230 * It is up to caller of the function to issue a reset or fail early. 4231 */ 4232 int ice_replay_all_fltr(struct ice_hw *hw) 4233 { 4234 struct ice_switch_info *sw = hw->switch_info; 4235 int status = ICE_SUCCESS; 4236 u8 i; 4237 4238 for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) { 4239 struct LIST_HEAD_TYPE *head = &sw->recp_list[i].filt_rules; 4240 4241 status = ice_replay_fltr(hw, i, head); 4242 if (status != ICE_SUCCESS) 4243 return status; 4244 } 4245 return status; 4246 } 4247 4248 /** 4249 * ice_replay_vsi_fltr - Replay filters for requested VSI 4250 * @hw: pointer to the hardware structure 4251 * @pi: pointer to port information structure 4252 * @sw: pointer to switch info struct for which function replays filters 4253 * @vsi_handle: driver VSI handle 4254 * @recp_id: Recipe ID for which rules need to be replayed 4255 * @list_head: list for which filters need to be replayed 4256 * 4257 * Replays the filter of recipe recp_id for a VSI represented via vsi_handle. 4258 * It is required to pass valid VSI handle. 4259 */ 4260 static int 4261 ice_replay_vsi_fltr(struct ice_hw *hw, struct ice_port_info *pi, 4262 struct ice_switch_info *sw, u16 vsi_handle, u8 recp_id, 4263 struct LIST_HEAD_TYPE *list_head) 4264 { 4265 struct ice_fltr_mgmt_list_entry *itr; 4266 struct ice_sw_recipe *recp_list; 4267 int status = 0; 4268 u16 hw_vsi_id; 4269 4270 if (LIST_EMPTY(list_head)) 4271 return status; 4272 recp_list = &sw->recp_list[recp_id]; 4273 hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle); 4274 4275 LIST_FOR_EACH_ENTRY(itr, list_head, ice_fltr_mgmt_list_entry, 4276 list_entry) { 4277 struct ice_fltr_list_entry f_entry; 4278 4279 f_entry.fltr_info = itr->fltr_info; 4280 if (itr->vsi_count < 2 && recp_id != ICE_SW_LKUP_VLAN && 4281 itr->fltr_info.vsi_handle == vsi_handle) { 4282 /* update the src in case it is VSI num */ 4283 if (f_entry.fltr_info.src_id == ICE_SRC_ID_VSI) 4284 f_entry.fltr_info.src = hw_vsi_id; 4285 status = ice_add_rule_internal(hw, recp_list, 4286 pi->lport, 4287 &f_entry); 4288 if (status) 4289 goto end; 4290 continue; 4291 } 4292 if (!itr->vsi_list_info || 4293 !ice_is_bit_set(itr->vsi_list_info->vsi_map, vsi_handle)) 4294 continue; 4295 f_entry.fltr_info.vsi_handle = vsi_handle; 4296 f_entry.fltr_info.fltr_act = ICE_FWD_TO_VSI; 4297 /* update the src in case it is VSI num */ 4298 if (f_entry.fltr_info.src_id == ICE_SRC_ID_VSI) 4299 f_entry.fltr_info.src = hw_vsi_id; 4300 if (recp_id == ICE_SW_LKUP_VLAN) 4301 status = ice_add_vlan_internal(hw, recp_list, &f_entry); 4302 else 4303 status = ice_add_rule_internal(hw, recp_list, 4304 pi->lport, 4305 &f_entry); 4306 if (status) 4307 goto end; 4308 } 4309 end: 4310 return status; 4311 } 4312 4313 /** 4314 * ice_replay_vsi_all_fltr - replay all filters stored in bookkeeping lists 4315 * @hw: pointer to the hardware structure 4316 * @pi: pointer to port information structure 4317 * @vsi_handle: driver VSI handle 4318 * 4319 * Replays filters for requested VSI via vsi_handle. 4320 */ 4321 int 4322 ice_replay_vsi_all_fltr(struct ice_hw *hw, struct ice_port_info *pi, 4323 u16 vsi_handle) 4324 { 4325 struct ice_switch_info *sw = NULL; 4326 int status = 0; 4327 u8 i; 4328 4329 sw = hw->switch_info; 4330 4331 /* Update the recipes that were created */ 4332 for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) { 4333 struct LIST_HEAD_TYPE *head; 4334 4335 head = &sw->recp_list[i].filt_replay_rules; 4336 if (!sw->recp_list[i].adv_rule) 4337 status = ice_replay_vsi_fltr(hw, pi, sw, vsi_handle, i, 4338 head); 4339 if (status) 4340 return status; 4341 } 4342 4343 return 0; 4344 } 4345 4346 /** 4347 * ice_rm_sw_replay_rule_info - helper function to delete filter replay rules 4348 * @hw: pointer to the HW struct 4349 * @sw: pointer to switch info struct for which function removes filters 4350 * 4351 * Deletes the filter replay rules for given switch 4352 */ 4353 void ice_rm_sw_replay_rule_info(struct ice_hw *hw, struct ice_switch_info *sw) 4354 { 4355 u8 i; 4356 4357 if (!sw) 4358 return; 4359 4360 for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) { 4361 if (!LIST_EMPTY(&sw->recp_list[i].filt_replay_rules)) { 4362 struct LIST_HEAD_TYPE *l_head; 4363 4364 l_head = &sw->recp_list[i].filt_replay_rules; 4365 if (!sw->recp_list[i].adv_rule) 4366 ice_rem_sw_rule_info(hw, l_head); 4367 } 4368 } 4369 } 4370 4371 /** 4372 * ice_rm_all_sw_replay_rule_info - deletes filter replay rules 4373 * @hw: pointer to the HW struct 4374 * 4375 * Deletes the filter replay rules. 4376 */ 4377 void ice_rm_all_sw_replay_rule_info(struct ice_hw *hw) 4378 { 4379 ice_rm_sw_replay_rule_info(hw, hw->switch_info); 4380 } 4381 4382