1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2018, Intel Corporation. */ 3 4 #include "ice_switch.h" 5 6 #define ICE_ETH_DA_OFFSET 0 7 #define ICE_ETH_ETHTYPE_OFFSET 12 8 #define ICE_ETH_VLAN_TCI_OFFSET 14 9 #define ICE_MAX_VLAN_ID 0xFFF 10 11 /* Dummy ethernet header needed in the ice_aqc_sw_rules_elem 12 * struct to configure any switch filter rules. 13 * {DA (6 bytes), SA(6 bytes), 14 * Ether type (2 bytes for header without VLAN tag) OR 15 * VLAN tag (4 bytes for header with VLAN tag) } 16 * 17 * Word on Hardcoded values 18 * byte 0 = 0x2: to identify it as locally administered DA MAC 19 * byte 6 = 0x2: to identify it as locally administered SA MAC 20 * byte 12 = 0x81 & byte 13 = 0x00: 21 * In case of VLAN filter first two bytes defines ether type (0x8100) 22 * and remaining two bytes are placeholder for programming a given VLAN id 23 * In case of Ether type filter it is treated as header without VLAN tag 24 * and byte 12 and 13 is used to program a given Ether type instead 25 */ 26 #define DUMMY_ETH_HDR_LEN 16 27 static const u8 dummy_eth_header[DUMMY_ETH_HDR_LEN] = { 0x2, 0, 0, 0, 0, 0, 28 0x2, 0, 0, 0, 0, 0, 29 0x81, 0, 0, 0}; 30 31 #define ICE_SW_RULE_RX_TX_ETH_HDR_SIZE \ 32 (sizeof(struct ice_aqc_sw_rules_elem) - \ 33 sizeof(((struct ice_aqc_sw_rules_elem *)0)->pdata) + \ 34 sizeof(struct ice_sw_rule_lkup_rx_tx) + DUMMY_ETH_HDR_LEN - 1) 35 #define ICE_SW_RULE_RX_TX_NO_HDR_SIZE \ 36 (sizeof(struct ice_aqc_sw_rules_elem) - \ 37 sizeof(((struct ice_aqc_sw_rules_elem *)0)->pdata) + \ 38 sizeof(struct ice_sw_rule_lkup_rx_tx) - 1) 39 #define ICE_SW_RULE_LG_ACT_SIZE(n) \ 40 (sizeof(struct ice_aqc_sw_rules_elem) - \ 41 sizeof(((struct ice_aqc_sw_rules_elem *)0)->pdata) + \ 42 sizeof(struct ice_sw_rule_lg_act) - \ 43 sizeof(((struct ice_sw_rule_lg_act *)0)->act) + \ 44 ((n) * sizeof(((struct ice_sw_rule_lg_act *)0)->act))) 45 #define ICE_SW_RULE_VSI_LIST_SIZE(n) \ 46 (sizeof(struct ice_aqc_sw_rules_elem) - \ 47 sizeof(((struct ice_aqc_sw_rules_elem *)0)->pdata) + \ 48 sizeof(struct ice_sw_rule_vsi_list) - \ 49 sizeof(((struct ice_sw_rule_vsi_list *)0)->vsi) + \ 50 ((n) * sizeof(((struct ice_sw_rule_vsi_list *)0)->vsi))) 51 52 /** 53 * ice_aq_alloc_free_res - command to allocate/free resources 54 * @hw: pointer to the hw struct 55 * @num_entries: number of resource entries in buffer 56 * @buf: Indirect buffer to hold data parameters and response 57 * @buf_size: size of buffer for indirect commands 58 * @opc: pass in the command opcode 59 * @cd: pointer to command details structure or NULL 60 * 61 * Helper function to allocate/free resources using the admin queue commands 62 */ 63 static enum ice_status 64 ice_aq_alloc_free_res(struct ice_hw *hw, u16 num_entries, 65 struct ice_aqc_alloc_free_res_elem *buf, u16 buf_size, 66 enum ice_adminq_opc opc, struct ice_sq_cd *cd) 67 { 68 struct ice_aqc_alloc_free_res_cmd *cmd; 69 struct ice_aq_desc desc; 70 71 cmd = &desc.params.sw_res_ctrl; 72 73 if (!buf) 74 return ICE_ERR_PARAM; 75 76 if (buf_size < (num_entries * sizeof(buf->elem[0]))) 77 return ICE_ERR_PARAM; 78 79 ice_fill_dflt_direct_cmd_desc(&desc, opc); 80 81 desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD); 82 83 cmd->num_entries = cpu_to_le16(num_entries); 84 85 return ice_aq_send_cmd(hw, &desc, buf, buf_size, cd); 86 } 87 88 /** 89 * ice_init_def_sw_recp - initialize the recipe book keeping tables 90 * @hw: pointer to the hw struct 91 * 92 * Allocate memory for the entire recipe table and initialize the structures/ 93 * entries corresponding to basic recipes. 94 */ 95 enum ice_status 96 ice_init_def_sw_recp(struct ice_hw *hw) 97 { 98 struct ice_sw_recipe *recps; 99 u8 i; 100 101 recps = devm_kcalloc(ice_hw_to_dev(hw), ICE_MAX_NUM_RECIPES, 102 sizeof(struct ice_sw_recipe), GFP_KERNEL); 103 if (!recps) 104 return ICE_ERR_NO_MEMORY; 105 106 for (i = 0; i < ICE_SW_LKUP_LAST; i++) { 107 recps[i].root_rid = i; 108 INIT_LIST_HEAD(&recps[i].filt_rules); 109 INIT_LIST_HEAD(&recps[i].filt_replay_rules); 110 mutex_init(&recps[i].filt_rule_lock); 111 } 112 113 hw->switch_info->recp_list = recps; 114 115 return 0; 116 } 117 118 /** 119 * ice_aq_get_sw_cfg - get switch configuration 120 * @hw: pointer to the hardware structure 121 * @buf: pointer to the result buffer 122 * @buf_size: length of the buffer available for response 123 * @req_desc: pointer to requested descriptor 124 * @num_elems: pointer to number of elements 125 * @cd: pointer to command details structure or NULL 126 * 127 * Get switch configuration (0x0200) to be placed in 'buff'. 128 * This admin command returns information such as initial VSI/port number 129 * and switch ID it belongs to. 130 * 131 * NOTE: *req_desc is both an input/output parameter. 132 * The caller of this function first calls this function with *request_desc set 133 * to 0. If the response from f/w has *req_desc set to 0, all the switch 134 * configuration information has been returned; if non-zero (meaning not all 135 * the information was returned), the caller should call this function again 136 * with *req_desc set to the previous value returned by f/w to get the 137 * next block of switch configuration information. 138 * 139 * *num_elems is output only parameter. This reflects the number of elements 140 * in response buffer. The caller of this function to use *num_elems while 141 * parsing the response buffer. 142 */ 143 static enum ice_status 144 ice_aq_get_sw_cfg(struct ice_hw *hw, struct ice_aqc_get_sw_cfg_resp *buf, 145 u16 buf_size, u16 *req_desc, u16 *num_elems, 146 struct ice_sq_cd *cd) 147 { 148 struct ice_aqc_get_sw_cfg *cmd; 149 enum ice_status status; 150 struct ice_aq_desc desc; 151 152 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_sw_cfg); 153 cmd = &desc.params.get_sw_conf; 154 cmd->element = cpu_to_le16(*req_desc); 155 156 status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd); 157 if (!status) { 158 *req_desc = le16_to_cpu(cmd->element); 159 *num_elems = le16_to_cpu(cmd->num_elems); 160 } 161 162 return status; 163 } 164 165 /** 166 * ice_aq_add_vsi 167 * @hw: pointer to the hw struct 168 * @vsi_ctx: pointer to a VSI context struct 169 * @cd: pointer to command details structure or NULL 170 * 171 * Add a VSI context to the hardware (0x0210) 172 */ 173 static enum ice_status 174 ice_aq_add_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx, 175 struct ice_sq_cd *cd) 176 { 177 struct ice_aqc_add_update_free_vsi_resp *res; 178 struct ice_aqc_add_get_update_free_vsi *cmd; 179 struct ice_aq_desc desc; 180 enum ice_status status; 181 182 cmd = &desc.params.vsi_cmd; 183 res = &desc.params.add_update_free_vsi_res; 184 185 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_add_vsi); 186 187 if (!vsi_ctx->alloc_from_pool) 188 cmd->vsi_num = cpu_to_le16(vsi_ctx->vsi_num | 189 ICE_AQ_VSI_IS_VALID); 190 cmd->vf_id = vsi_ctx->vf_num; 191 192 cmd->vsi_flags = cpu_to_le16(vsi_ctx->flags); 193 194 desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD); 195 196 status = ice_aq_send_cmd(hw, &desc, &vsi_ctx->info, 197 sizeof(vsi_ctx->info), cd); 198 199 if (!status) { 200 vsi_ctx->vsi_num = le16_to_cpu(res->vsi_num) & ICE_AQ_VSI_NUM_M; 201 vsi_ctx->vsis_allocd = le16_to_cpu(res->vsi_used); 202 vsi_ctx->vsis_unallocated = le16_to_cpu(res->vsi_free); 203 } 204 205 return status; 206 } 207 208 /** 209 * ice_aq_free_vsi 210 * @hw: pointer to the hw struct 211 * @vsi_ctx: pointer to a VSI context struct 212 * @keep_vsi_alloc: keep VSI allocation as part of this PF's resources 213 * @cd: pointer to command details structure or NULL 214 * 215 * Free VSI context info from hardware (0x0213) 216 */ 217 static enum ice_status 218 ice_aq_free_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx, 219 bool keep_vsi_alloc, struct ice_sq_cd *cd) 220 { 221 struct ice_aqc_add_update_free_vsi_resp *resp; 222 struct ice_aqc_add_get_update_free_vsi *cmd; 223 struct ice_aq_desc desc; 224 enum ice_status status; 225 226 cmd = &desc.params.vsi_cmd; 227 resp = &desc.params.add_update_free_vsi_res; 228 229 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_free_vsi); 230 231 cmd->vsi_num = cpu_to_le16(vsi_ctx->vsi_num | ICE_AQ_VSI_IS_VALID); 232 if (keep_vsi_alloc) 233 cmd->cmd_flags = cpu_to_le16(ICE_AQ_VSI_KEEP_ALLOC); 234 235 status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd); 236 if (!status) { 237 vsi_ctx->vsis_allocd = le16_to_cpu(resp->vsi_used); 238 vsi_ctx->vsis_unallocated = le16_to_cpu(resp->vsi_free); 239 } 240 241 return status; 242 } 243 244 /** 245 * ice_aq_update_vsi 246 * @hw: pointer to the hw struct 247 * @vsi_ctx: pointer to a VSI context struct 248 * @cd: pointer to command details structure or NULL 249 * 250 * Update VSI context in the hardware (0x0211) 251 */ 252 static enum ice_status 253 ice_aq_update_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx, 254 struct ice_sq_cd *cd) 255 { 256 struct ice_aqc_add_update_free_vsi_resp *resp; 257 struct ice_aqc_add_get_update_free_vsi *cmd; 258 struct ice_aq_desc desc; 259 enum ice_status status; 260 261 cmd = &desc.params.vsi_cmd; 262 resp = &desc.params.add_update_free_vsi_res; 263 264 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_update_vsi); 265 266 cmd->vsi_num = cpu_to_le16(vsi_ctx->vsi_num | ICE_AQ_VSI_IS_VALID); 267 268 desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD); 269 270 status = ice_aq_send_cmd(hw, &desc, &vsi_ctx->info, 271 sizeof(vsi_ctx->info), cd); 272 273 if (!status) { 274 vsi_ctx->vsis_allocd = le16_to_cpu(resp->vsi_used); 275 vsi_ctx->vsis_unallocated = le16_to_cpu(resp->vsi_free); 276 } 277 278 return status; 279 } 280 281 /** 282 * ice_is_vsi_valid - check whether the VSI is valid or not 283 * @hw: pointer to the hw struct 284 * @vsi_handle: VSI handle 285 * 286 * check whether the VSI is valid or not 287 */ 288 bool ice_is_vsi_valid(struct ice_hw *hw, u16 vsi_handle) 289 { 290 return vsi_handle < ICE_MAX_VSI && hw->vsi_ctx[vsi_handle]; 291 } 292 293 /** 294 * ice_get_hw_vsi_num - return the hw VSI number 295 * @hw: pointer to the hw struct 296 * @vsi_handle: VSI handle 297 * 298 * return the hw VSI number 299 * Caution: call this function only if VSI is valid (ice_is_vsi_valid) 300 */ 301 u16 ice_get_hw_vsi_num(struct ice_hw *hw, u16 vsi_handle) 302 { 303 return hw->vsi_ctx[vsi_handle]->vsi_num; 304 } 305 306 /** 307 * ice_get_vsi_ctx - return the VSI context entry for a given VSI handle 308 * @hw: pointer to the hw struct 309 * @vsi_handle: VSI handle 310 * 311 * return the VSI context entry for a given VSI handle 312 */ 313 struct ice_vsi_ctx *ice_get_vsi_ctx(struct ice_hw *hw, u16 vsi_handle) 314 { 315 return (vsi_handle >= ICE_MAX_VSI) ? NULL : hw->vsi_ctx[vsi_handle]; 316 } 317 318 /** 319 * ice_save_vsi_ctx - save the VSI context for a given VSI handle 320 * @hw: pointer to the hw struct 321 * @vsi_handle: VSI handle 322 * @vsi: VSI context pointer 323 * 324 * save the VSI context entry for a given VSI handle 325 */ 326 static void ice_save_vsi_ctx(struct ice_hw *hw, u16 vsi_handle, 327 struct ice_vsi_ctx *vsi) 328 { 329 hw->vsi_ctx[vsi_handle] = vsi; 330 } 331 332 /** 333 * ice_clear_vsi_ctx - clear the VSI context entry 334 * @hw: pointer to the hw struct 335 * @vsi_handle: VSI handle 336 * 337 * clear the VSI context entry 338 */ 339 static void ice_clear_vsi_ctx(struct ice_hw *hw, u16 vsi_handle) 340 { 341 struct ice_vsi_ctx *vsi; 342 343 vsi = ice_get_vsi_ctx(hw, vsi_handle); 344 if (vsi) { 345 devm_kfree(ice_hw_to_dev(hw), vsi); 346 hw->vsi_ctx[vsi_handle] = NULL; 347 } 348 } 349 350 /** 351 * ice_add_vsi - add VSI context to the hardware and VSI handle list 352 * @hw: pointer to the hw struct 353 * @vsi_handle: unique VSI handle provided by drivers 354 * @vsi_ctx: pointer to a VSI context struct 355 * @cd: pointer to command details structure or NULL 356 * 357 * Add a VSI context to the hardware also add it into the VSI handle list. 358 * If this function gets called after reset for existing VSIs then update 359 * with the new HW VSI number in the corresponding VSI handle list entry. 360 */ 361 enum ice_status 362 ice_add_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx, 363 struct ice_sq_cd *cd) 364 { 365 struct ice_vsi_ctx *tmp_vsi_ctx; 366 enum ice_status status; 367 368 if (vsi_handle >= ICE_MAX_VSI) 369 return ICE_ERR_PARAM; 370 status = ice_aq_add_vsi(hw, vsi_ctx, cd); 371 if (status) 372 return status; 373 tmp_vsi_ctx = ice_get_vsi_ctx(hw, vsi_handle); 374 if (!tmp_vsi_ctx) { 375 /* Create a new vsi context */ 376 tmp_vsi_ctx = devm_kzalloc(ice_hw_to_dev(hw), 377 sizeof(*tmp_vsi_ctx), GFP_KERNEL); 378 if (!tmp_vsi_ctx) { 379 ice_aq_free_vsi(hw, vsi_ctx, false, cd); 380 return ICE_ERR_NO_MEMORY; 381 } 382 *tmp_vsi_ctx = *vsi_ctx; 383 ice_save_vsi_ctx(hw, vsi_handle, tmp_vsi_ctx); 384 } else { 385 /* update with new HW VSI num */ 386 if (tmp_vsi_ctx->vsi_num != vsi_ctx->vsi_num) 387 tmp_vsi_ctx->vsi_num = vsi_ctx->vsi_num; 388 } 389 390 return status; 391 } 392 393 /** 394 * ice_free_vsi- free VSI context from hardware and VSI handle list 395 * @hw: pointer to the hw struct 396 * @vsi_handle: unique VSI handle 397 * @vsi_ctx: pointer to a VSI context struct 398 * @keep_vsi_alloc: keep VSI allocation as part of this PF's resources 399 * @cd: pointer to command details structure or NULL 400 * 401 * Free VSI context info from hardware as well as from VSI handle list 402 */ 403 enum ice_status 404 ice_free_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx, 405 bool keep_vsi_alloc, struct ice_sq_cd *cd) 406 { 407 enum ice_status status; 408 409 if (!ice_is_vsi_valid(hw, vsi_handle)) 410 return ICE_ERR_PARAM; 411 vsi_ctx->vsi_num = ice_get_hw_vsi_num(hw, vsi_handle); 412 status = ice_aq_free_vsi(hw, vsi_ctx, keep_vsi_alloc, cd); 413 if (!status) 414 ice_clear_vsi_ctx(hw, vsi_handle); 415 return status; 416 } 417 418 /** 419 * ice_update_vsi 420 * @hw: pointer to the hw struct 421 * @vsi_handle: unique VSI handle 422 * @vsi_ctx: pointer to a VSI context struct 423 * @cd: pointer to command details structure or NULL 424 * 425 * Update VSI context in the hardware 426 */ 427 enum ice_status 428 ice_update_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx, 429 struct ice_sq_cd *cd) 430 { 431 if (!ice_is_vsi_valid(hw, vsi_handle)) 432 return ICE_ERR_PARAM; 433 vsi_ctx->vsi_num = ice_get_hw_vsi_num(hw, vsi_handle); 434 return ice_aq_update_vsi(hw, vsi_ctx, cd); 435 } 436 437 /** 438 * ice_aq_alloc_free_vsi_list 439 * @hw: pointer to the hw struct 440 * @vsi_list_id: VSI list id returned or used for lookup 441 * @lkup_type: switch rule filter lookup type 442 * @opc: switch rules population command type - pass in the command opcode 443 * 444 * allocates or free a VSI list resource 445 */ 446 static enum ice_status 447 ice_aq_alloc_free_vsi_list(struct ice_hw *hw, u16 *vsi_list_id, 448 enum ice_sw_lkup_type lkup_type, 449 enum ice_adminq_opc opc) 450 { 451 struct ice_aqc_alloc_free_res_elem *sw_buf; 452 struct ice_aqc_res_elem *vsi_ele; 453 enum ice_status status; 454 u16 buf_len; 455 456 buf_len = sizeof(*sw_buf); 457 sw_buf = devm_kzalloc(ice_hw_to_dev(hw), buf_len, GFP_KERNEL); 458 if (!sw_buf) 459 return ICE_ERR_NO_MEMORY; 460 sw_buf->num_elems = cpu_to_le16(1); 461 462 if (lkup_type == ICE_SW_LKUP_MAC || 463 lkup_type == ICE_SW_LKUP_MAC_VLAN || 464 lkup_type == ICE_SW_LKUP_ETHERTYPE || 465 lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC || 466 lkup_type == ICE_SW_LKUP_PROMISC || 467 lkup_type == ICE_SW_LKUP_PROMISC_VLAN) { 468 sw_buf->res_type = cpu_to_le16(ICE_AQC_RES_TYPE_VSI_LIST_REP); 469 } else if (lkup_type == ICE_SW_LKUP_VLAN) { 470 sw_buf->res_type = 471 cpu_to_le16(ICE_AQC_RES_TYPE_VSI_LIST_PRUNE); 472 } else { 473 status = ICE_ERR_PARAM; 474 goto ice_aq_alloc_free_vsi_list_exit; 475 } 476 477 if (opc == ice_aqc_opc_free_res) 478 sw_buf->elem[0].e.sw_resp = cpu_to_le16(*vsi_list_id); 479 480 status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len, opc, NULL); 481 if (status) 482 goto ice_aq_alloc_free_vsi_list_exit; 483 484 if (opc == ice_aqc_opc_alloc_res) { 485 vsi_ele = &sw_buf->elem[0]; 486 *vsi_list_id = le16_to_cpu(vsi_ele->e.sw_resp); 487 } 488 489 ice_aq_alloc_free_vsi_list_exit: 490 devm_kfree(ice_hw_to_dev(hw), sw_buf); 491 return status; 492 } 493 494 /** 495 * ice_aq_sw_rules - add/update/remove switch rules 496 * @hw: pointer to the hw struct 497 * @rule_list: pointer to switch rule population list 498 * @rule_list_sz: total size of the rule list in bytes 499 * @num_rules: number of switch rules in the rule_list 500 * @opc: switch rules population command type - pass in the command opcode 501 * @cd: pointer to command details structure or NULL 502 * 503 * Add(0x02a0)/Update(0x02a1)/Remove(0x02a2) switch rules commands to firmware 504 */ 505 static enum ice_status 506 ice_aq_sw_rules(struct ice_hw *hw, void *rule_list, u16 rule_list_sz, 507 u8 num_rules, enum ice_adminq_opc opc, struct ice_sq_cd *cd) 508 { 509 struct ice_aq_desc desc; 510 511 if (opc != ice_aqc_opc_add_sw_rules && 512 opc != ice_aqc_opc_update_sw_rules && 513 opc != ice_aqc_opc_remove_sw_rules) 514 return ICE_ERR_PARAM; 515 516 ice_fill_dflt_direct_cmd_desc(&desc, opc); 517 518 desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD); 519 desc.params.sw_rules.num_rules_fltr_entry_index = 520 cpu_to_le16(num_rules); 521 return ice_aq_send_cmd(hw, &desc, rule_list, rule_list_sz, cd); 522 } 523 524 /* ice_init_port_info - Initialize port_info with switch configuration data 525 * @pi: pointer to port_info 526 * @vsi_port_num: VSI number or port number 527 * @type: Type of switch element (port or VSI) 528 * @swid: switch ID of the switch the element is attached to 529 * @pf_vf_num: PF or VF number 530 * @is_vf: true if the element is a VF, false otherwise 531 */ 532 static void 533 ice_init_port_info(struct ice_port_info *pi, u16 vsi_port_num, u8 type, 534 u16 swid, u16 pf_vf_num, bool is_vf) 535 { 536 switch (type) { 537 case ICE_AQC_GET_SW_CONF_RESP_PHYS_PORT: 538 pi->lport = (u8)(vsi_port_num & ICE_LPORT_MASK); 539 pi->sw_id = swid; 540 pi->pf_vf_num = pf_vf_num; 541 pi->is_vf = is_vf; 542 pi->dflt_tx_vsi_num = ICE_DFLT_VSI_INVAL; 543 pi->dflt_rx_vsi_num = ICE_DFLT_VSI_INVAL; 544 break; 545 default: 546 ice_debug(pi->hw, ICE_DBG_SW, 547 "incorrect VSI/port type received\n"); 548 break; 549 } 550 } 551 552 /* ice_get_initial_sw_cfg - Get initial port and default VSI data 553 * @hw: pointer to the hardware structure 554 */ 555 enum ice_status ice_get_initial_sw_cfg(struct ice_hw *hw) 556 { 557 struct ice_aqc_get_sw_cfg_resp *rbuf; 558 enum ice_status status; 559 u16 req_desc = 0; 560 u16 num_elems; 561 u16 i; 562 563 rbuf = devm_kzalloc(ice_hw_to_dev(hw), ICE_SW_CFG_MAX_BUF_LEN, 564 GFP_KERNEL); 565 566 if (!rbuf) 567 return ICE_ERR_NO_MEMORY; 568 569 /* Multiple calls to ice_aq_get_sw_cfg may be required 570 * to get all the switch configuration information. The need 571 * for additional calls is indicated by ice_aq_get_sw_cfg 572 * writing a non-zero value in req_desc 573 */ 574 do { 575 status = ice_aq_get_sw_cfg(hw, rbuf, ICE_SW_CFG_MAX_BUF_LEN, 576 &req_desc, &num_elems, NULL); 577 578 if (status) 579 break; 580 581 for (i = 0; i < num_elems; i++) { 582 struct ice_aqc_get_sw_cfg_resp_elem *ele; 583 u16 pf_vf_num, swid, vsi_port_num; 584 bool is_vf = false; 585 u8 type; 586 587 ele = rbuf[i].elements; 588 vsi_port_num = le16_to_cpu(ele->vsi_port_num) & 589 ICE_AQC_GET_SW_CONF_RESP_VSI_PORT_NUM_M; 590 591 pf_vf_num = le16_to_cpu(ele->pf_vf_num) & 592 ICE_AQC_GET_SW_CONF_RESP_FUNC_NUM_M; 593 594 swid = le16_to_cpu(ele->swid); 595 596 if (le16_to_cpu(ele->pf_vf_num) & 597 ICE_AQC_GET_SW_CONF_RESP_IS_VF) 598 is_vf = true; 599 600 type = le16_to_cpu(ele->vsi_port_num) >> 601 ICE_AQC_GET_SW_CONF_RESP_TYPE_S; 602 603 if (type == ICE_AQC_GET_SW_CONF_RESP_VSI) { 604 /* FW VSI is not needed. Just continue. */ 605 continue; 606 } 607 608 ice_init_port_info(hw->port_info, vsi_port_num, 609 type, swid, pf_vf_num, is_vf); 610 } 611 } while (req_desc && !status); 612 613 devm_kfree(ice_hw_to_dev(hw), (void *)rbuf); 614 return status; 615 } 616 617 /** 618 * ice_fill_sw_info - Helper function to populate lb_en and lan_en 619 * @hw: pointer to the hardware structure 620 * @f_info: filter info structure to fill/update 621 * 622 * This helper function populates the lb_en and lan_en elements of the provided 623 * ice_fltr_info struct using the switch's type and characteristics of the 624 * switch rule being configured. 625 */ 626 static void ice_fill_sw_info(struct ice_hw *hw, struct ice_fltr_info *f_info) 627 { 628 f_info->lb_en = false; 629 f_info->lan_en = false; 630 if ((f_info->flag & ICE_FLTR_TX) && 631 (f_info->fltr_act == ICE_FWD_TO_VSI || 632 f_info->fltr_act == ICE_FWD_TO_VSI_LIST || 633 f_info->fltr_act == ICE_FWD_TO_Q || 634 f_info->fltr_act == ICE_FWD_TO_QGRP)) { 635 f_info->lb_en = true; 636 if (!(hw->evb_veb && f_info->lkup_type == ICE_SW_LKUP_MAC && 637 is_unicast_ether_addr(f_info->l_data.mac.mac_addr))) 638 f_info->lan_en = true; 639 } 640 } 641 642 /** 643 * ice_fill_sw_rule - Helper function to fill switch rule structure 644 * @hw: pointer to the hardware structure 645 * @f_info: entry containing packet forwarding information 646 * @s_rule: switch rule structure to be filled in based on mac_entry 647 * @opc: switch rules population command type - pass in the command opcode 648 */ 649 static void 650 ice_fill_sw_rule(struct ice_hw *hw, struct ice_fltr_info *f_info, 651 struct ice_aqc_sw_rules_elem *s_rule, enum ice_adminq_opc opc) 652 { 653 u16 vlan_id = ICE_MAX_VLAN_ID + 1; 654 void *daddr = NULL; 655 u16 eth_hdr_sz; 656 u8 *eth_hdr; 657 u32 act = 0; 658 __be16 *off; 659 u8 q_rgn; 660 661 if (opc == ice_aqc_opc_remove_sw_rules) { 662 s_rule->pdata.lkup_tx_rx.act = 0; 663 s_rule->pdata.lkup_tx_rx.index = 664 cpu_to_le16(f_info->fltr_rule_id); 665 s_rule->pdata.lkup_tx_rx.hdr_len = 0; 666 return; 667 } 668 669 eth_hdr_sz = sizeof(dummy_eth_header); 670 eth_hdr = s_rule->pdata.lkup_tx_rx.hdr; 671 672 /* initialize the ether header with a dummy header */ 673 memcpy(eth_hdr, dummy_eth_header, eth_hdr_sz); 674 ice_fill_sw_info(hw, f_info); 675 676 switch (f_info->fltr_act) { 677 case ICE_FWD_TO_VSI: 678 act |= (f_info->fwd_id.hw_vsi_id << ICE_SINGLE_ACT_VSI_ID_S) & 679 ICE_SINGLE_ACT_VSI_ID_M; 680 if (f_info->lkup_type != ICE_SW_LKUP_VLAN) 681 act |= ICE_SINGLE_ACT_VSI_FORWARDING | 682 ICE_SINGLE_ACT_VALID_BIT; 683 break; 684 case ICE_FWD_TO_VSI_LIST: 685 act |= ICE_SINGLE_ACT_VSI_LIST; 686 act |= (f_info->fwd_id.vsi_list_id << 687 ICE_SINGLE_ACT_VSI_LIST_ID_S) & 688 ICE_SINGLE_ACT_VSI_LIST_ID_M; 689 if (f_info->lkup_type != ICE_SW_LKUP_VLAN) 690 act |= ICE_SINGLE_ACT_VSI_FORWARDING | 691 ICE_SINGLE_ACT_VALID_BIT; 692 break; 693 case ICE_FWD_TO_Q: 694 act |= ICE_SINGLE_ACT_TO_Q; 695 act |= (f_info->fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) & 696 ICE_SINGLE_ACT_Q_INDEX_M; 697 break; 698 case ICE_DROP_PACKET: 699 act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_DROP | 700 ICE_SINGLE_ACT_VALID_BIT; 701 break; 702 case ICE_FWD_TO_QGRP: 703 q_rgn = f_info->qgrp_size > 0 ? 704 (u8)ilog2(f_info->qgrp_size) : 0; 705 act |= ICE_SINGLE_ACT_TO_Q; 706 act |= (f_info->fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) & 707 ICE_SINGLE_ACT_Q_INDEX_M; 708 act |= (q_rgn << ICE_SINGLE_ACT_Q_REGION_S) & 709 ICE_SINGLE_ACT_Q_REGION_M; 710 break; 711 default: 712 return; 713 } 714 715 if (f_info->lb_en) 716 act |= ICE_SINGLE_ACT_LB_ENABLE; 717 if (f_info->lan_en) 718 act |= ICE_SINGLE_ACT_LAN_ENABLE; 719 720 switch (f_info->lkup_type) { 721 case ICE_SW_LKUP_MAC: 722 daddr = f_info->l_data.mac.mac_addr; 723 break; 724 case ICE_SW_LKUP_VLAN: 725 vlan_id = f_info->l_data.vlan.vlan_id; 726 if (f_info->fltr_act == ICE_FWD_TO_VSI || 727 f_info->fltr_act == ICE_FWD_TO_VSI_LIST) { 728 act |= ICE_SINGLE_ACT_PRUNE; 729 act |= ICE_SINGLE_ACT_EGRESS | ICE_SINGLE_ACT_INGRESS; 730 } 731 break; 732 case ICE_SW_LKUP_ETHERTYPE_MAC: 733 daddr = f_info->l_data.ethertype_mac.mac_addr; 734 /* fall-through */ 735 case ICE_SW_LKUP_ETHERTYPE: 736 off = (__be16 *)(eth_hdr + ICE_ETH_ETHTYPE_OFFSET); 737 *off = cpu_to_be16(f_info->l_data.ethertype_mac.ethertype); 738 break; 739 case ICE_SW_LKUP_MAC_VLAN: 740 daddr = f_info->l_data.mac_vlan.mac_addr; 741 vlan_id = f_info->l_data.mac_vlan.vlan_id; 742 break; 743 case ICE_SW_LKUP_PROMISC_VLAN: 744 vlan_id = f_info->l_data.mac_vlan.vlan_id; 745 /* fall-through */ 746 case ICE_SW_LKUP_PROMISC: 747 daddr = f_info->l_data.mac_vlan.mac_addr; 748 break; 749 default: 750 break; 751 } 752 753 s_rule->type = (f_info->flag & ICE_FLTR_RX) ? 754 cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_RX) : 755 cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_TX); 756 757 /* Recipe set depending on lookup type */ 758 s_rule->pdata.lkup_tx_rx.recipe_id = cpu_to_le16(f_info->lkup_type); 759 s_rule->pdata.lkup_tx_rx.src = cpu_to_le16(f_info->src); 760 s_rule->pdata.lkup_tx_rx.act = cpu_to_le32(act); 761 762 if (daddr) 763 ether_addr_copy(eth_hdr + ICE_ETH_DA_OFFSET, daddr); 764 765 if (!(vlan_id > ICE_MAX_VLAN_ID)) { 766 off = (__be16 *)(eth_hdr + ICE_ETH_VLAN_TCI_OFFSET); 767 *off = cpu_to_be16(vlan_id); 768 } 769 770 /* Create the switch rule with the final dummy Ethernet header */ 771 if (opc != ice_aqc_opc_update_sw_rules) 772 s_rule->pdata.lkup_tx_rx.hdr_len = cpu_to_le16(eth_hdr_sz); 773 } 774 775 /** 776 * ice_add_marker_act 777 * @hw: pointer to the hardware structure 778 * @m_ent: the management entry for which sw marker needs to be added 779 * @sw_marker: sw marker to tag the Rx descriptor with 780 * @l_id: large action resource id 781 * 782 * Create a large action to hold software marker and update the switch rule 783 * entry pointed by m_ent with newly created large action 784 */ 785 static enum ice_status 786 ice_add_marker_act(struct ice_hw *hw, struct ice_fltr_mgmt_list_entry *m_ent, 787 u16 sw_marker, u16 l_id) 788 { 789 struct ice_aqc_sw_rules_elem *lg_act, *rx_tx; 790 /* For software marker we need 3 large actions 791 * 1. FWD action: FWD TO VSI or VSI LIST 792 * 2. GENERIC VALUE action to hold the profile id 793 * 3. GENERIC VALUE action to hold the software marker id 794 */ 795 const u16 num_lg_acts = 3; 796 enum ice_status status; 797 u16 lg_act_size; 798 u16 rules_size; 799 u32 act; 800 u16 id; 801 802 if (m_ent->fltr_info.lkup_type != ICE_SW_LKUP_MAC) 803 return ICE_ERR_PARAM; 804 805 /* Create two back-to-back switch rules and submit them to the HW using 806 * one memory buffer: 807 * 1. Large Action 808 * 2. Look up tx rx 809 */ 810 lg_act_size = (u16)ICE_SW_RULE_LG_ACT_SIZE(num_lg_acts); 811 rules_size = lg_act_size + ICE_SW_RULE_RX_TX_ETH_HDR_SIZE; 812 lg_act = devm_kzalloc(ice_hw_to_dev(hw), rules_size, GFP_KERNEL); 813 if (!lg_act) 814 return ICE_ERR_NO_MEMORY; 815 816 rx_tx = (struct ice_aqc_sw_rules_elem *)((u8 *)lg_act + lg_act_size); 817 818 /* Fill in the first switch rule i.e. large action */ 819 lg_act->type = cpu_to_le16(ICE_AQC_SW_RULES_T_LG_ACT); 820 lg_act->pdata.lg_act.index = cpu_to_le16(l_id); 821 lg_act->pdata.lg_act.size = cpu_to_le16(num_lg_acts); 822 823 /* First action VSI forwarding or VSI list forwarding depending on how 824 * many VSIs 825 */ 826 id = (m_ent->vsi_count > 1) ? m_ent->fltr_info.fwd_id.vsi_list_id : 827 m_ent->fltr_info.fwd_id.hw_vsi_id; 828 829 act = ICE_LG_ACT_VSI_FORWARDING | ICE_LG_ACT_VALID_BIT; 830 act |= (id << ICE_LG_ACT_VSI_LIST_ID_S) & 831 ICE_LG_ACT_VSI_LIST_ID_M; 832 if (m_ent->vsi_count > 1) 833 act |= ICE_LG_ACT_VSI_LIST; 834 lg_act->pdata.lg_act.act[0] = cpu_to_le32(act); 835 836 /* Second action descriptor type */ 837 act = ICE_LG_ACT_GENERIC; 838 839 act |= (1 << ICE_LG_ACT_GENERIC_VALUE_S) & ICE_LG_ACT_GENERIC_VALUE_M; 840 lg_act->pdata.lg_act.act[1] = cpu_to_le32(act); 841 842 act = (ICE_LG_ACT_GENERIC_OFF_RX_DESC_PROF_IDX << 843 ICE_LG_ACT_GENERIC_OFFSET_S) & ICE_LG_ACT_GENERIC_OFFSET_M; 844 845 /* Third action Marker value */ 846 act |= ICE_LG_ACT_GENERIC; 847 act |= (sw_marker << ICE_LG_ACT_GENERIC_VALUE_S) & 848 ICE_LG_ACT_GENERIC_VALUE_M; 849 850 lg_act->pdata.lg_act.act[2] = cpu_to_le32(act); 851 852 /* call the fill switch rule to fill the lookup tx rx structure */ 853 ice_fill_sw_rule(hw, &m_ent->fltr_info, rx_tx, 854 ice_aqc_opc_update_sw_rules); 855 856 /* Update the action to point to the large action id */ 857 rx_tx->pdata.lkup_tx_rx.act = 858 cpu_to_le32(ICE_SINGLE_ACT_PTR | 859 ((l_id << ICE_SINGLE_ACT_PTR_VAL_S) & 860 ICE_SINGLE_ACT_PTR_VAL_M)); 861 862 /* Use the filter rule id of the previously created rule with single 863 * act. Once the update happens, hardware will treat this as large 864 * action 865 */ 866 rx_tx->pdata.lkup_tx_rx.index = 867 cpu_to_le16(m_ent->fltr_info.fltr_rule_id); 868 869 status = ice_aq_sw_rules(hw, lg_act, rules_size, 2, 870 ice_aqc_opc_update_sw_rules, NULL); 871 if (!status) { 872 m_ent->lg_act_idx = l_id; 873 m_ent->sw_marker_id = sw_marker; 874 } 875 876 devm_kfree(ice_hw_to_dev(hw), lg_act); 877 return status; 878 } 879 880 /** 881 * ice_create_vsi_list_map 882 * @hw: pointer to the hardware structure 883 * @vsi_handle_arr: array of VSI handles to set in the VSI mapping 884 * @num_vsi: number of VSI handles in the array 885 * @vsi_list_id: VSI list id generated as part of allocate resource 886 * 887 * Helper function to create a new entry of VSI list id to VSI mapping 888 * using the given VSI list id 889 */ 890 static struct ice_vsi_list_map_info * 891 ice_create_vsi_list_map(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi, 892 u16 vsi_list_id) 893 { 894 struct ice_switch_info *sw = hw->switch_info; 895 struct ice_vsi_list_map_info *v_map; 896 int i; 897 898 v_map = devm_kcalloc(ice_hw_to_dev(hw), 1, sizeof(*v_map), GFP_KERNEL); 899 if (!v_map) 900 return NULL; 901 902 v_map->vsi_list_id = vsi_list_id; 903 v_map->ref_cnt = 1; 904 for (i = 0; i < num_vsi; i++) 905 set_bit(vsi_handle_arr[i], v_map->vsi_map); 906 907 list_add(&v_map->list_entry, &sw->vsi_list_map_head); 908 return v_map; 909 } 910 911 /** 912 * ice_update_vsi_list_rule 913 * @hw: pointer to the hardware structure 914 * @vsi_handle_arr: array of VSI handles to form a VSI list 915 * @num_vsi: number of VSI handles in the array 916 * @vsi_list_id: VSI list id generated as part of allocate resource 917 * @remove: Boolean value to indicate if this is a remove action 918 * @opc: switch rules population command type - pass in the command opcode 919 * @lkup_type: lookup type of the filter 920 * 921 * Call AQ command to add a new switch rule or update existing switch rule 922 * using the given VSI list id 923 */ 924 static enum ice_status 925 ice_update_vsi_list_rule(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi, 926 u16 vsi_list_id, bool remove, enum ice_adminq_opc opc, 927 enum ice_sw_lkup_type lkup_type) 928 { 929 struct ice_aqc_sw_rules_elem *s_rule; 930 enum ice_status status; 931 u16 s_rule_size; 932 u16 type; 933 int i; 934 935 if (!num_vsi) 936 return ICE_ERR_PARAM; 937 938 if (lkup_type == ICE_SW_LKUP_MAC || 939 lkup_type == ICE_SW_LKUP_MAC_VLAN || 940 lkup_type == ICE_SW_LKUP_ETHERTYPE || 941 lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC || 942 lkup_type == ICE_SW_LKUP_PROMISC || 943 lkup_type == ICE_SW_LKUP_PROMISC_VLAN) 944 type = remove ? ICE_AQC_SW_RULES_T_VSI_LIST_CLEAR : 945 ICE_AQC_SW_RULES_T_VSI_LIST_SET; 946 else if (lkup_type == ICE_SW_LKUP_VLAN) 947 type = remove ? ICE_AQC_SW_RULES_T_PRUNE_LIST_CLEAR : 948 ICE_AQC_SW_RULES_T_PRUNE_LIST_SET; 949 else 950 return ICE_ERR_PARAM; 951 952 s_rule_size = (u16)ICE_SW_RULE_VSI_LIST_SIZE(num_vsi); 953 s_rule = devm_kzalloc(ice_hw_to_dev(hw), s_rule_size, GFP_KERNEL); 954 if (!s_rule) 955 return ICE_ERR_NO_MEMORY; 956 for (i = 0; i < num_vsi; i++) { 957 if (!ice_is_vsi_valid(hw, vsi_handle_arr[i])) { 958 status = ICE_ERR_PARAM; 959 goto exit; 960 } 961 /* AQ call requires hw_vsi_id(s) */ 962 s_rule->pdata.vsi_list.vsi[i] = 963 cpu_to_le16(ice_get_hw_vsi_num(hw, vsi_handle_arr[i])); 964 } 965 966 s_rule->type = cpu_to_le16(type); 967 s_rule->pdata.vsi_list.number_vsi = cpu_to_le16(num_vsi); 968 s_rule->pdata.vsi_list.index = cpu_to_le16(vsi_list_id); 969 970 status = ice_aq_sw_rules(hw, s_rule, s_rule_size, 1, opc, NULL); 971 972 exit: 973 devm_kfree(ice_hw_to_dev(hw), s_rule); 974 return status; 975 } 976 977 /** 978 * ice_create_vsi_list_rule - Creates and populates a VSI list rule 979 * @hw: pointer to the hw struct 980 * @vsi_handle_arr: array of VSI handles to form a VSI list 981 * @num_vsi: number of VSI handles in the array 982 * @vsi_list_id: stores the ID of the VSI list to be created 983 * @lkup_type: switch rule filter's lookup type 984 */ 985 static enum ice_status 986 ice_create_vsi_list_rule(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi, 987 u16 *vsi_list_id, enum ice_sw_lkup_type lkup_type) 988 { 989 enum ice_status status; 990 991 status = ice_aq_alloc_free_vsi_list(hw, vsi_list_id, lkup_type, 992 ice_aqc_opc_alloc_res); 993 if (status) 994 return status; 995 996 /* Update the newly created VSI list to include the specified VSIs */ 997 return ice_update_vsi_list_rule(hw, vsi_handle_arr, num_vsi, 998 *vsi_list_id, false, 999 ice_aqc_opc_add_sw_rules, lkup_type); 1000 } 1001 1002 /** 1003 * ice_create_pkt_fwd_rule 1004 * @hw: pointer to the hardware structure 1005 * @f_entry: entry containing packet forwarding information 1006 * 1007 * Create switch rule with given filter information and add an entry 1008 * to the corresponding filter management list to track this switch rule 1009 * and VSI mapping 1010 */ 1011 static enum ice_status 1012 ice_create_pkt_fwd_rule(struct ice_hw *hw, 1013 struct ice_fltr_list_entry *f_entry) 1014 { 1015 struct ice_fltr_mgmt_list_entry *fm_entry; 1016 struct ice_aqc_sw_rules_elem *s_rule; 1017 enum ice_sw_lkup_type l_type; 1018 struct ice_sw_recipe *recp; 1019 enum ice_status status; 1020 1021 s_rule = devm_kzalloc(ice_hw_to_dev(hw), 1022 ICE_SW_RULE_RX_TX_ETH_HDR_SIZE, GFP_KERNEL); 1023 if (!s_rule) 1024 return ICE_ERR_NO_MEMORY; 1025 fm_entry = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*fm_entry), 1026 GFP_KERNEL); 1027 if (!fm_entry) { 1028 status = ICE_ERR_NO_MEMORY; 1029 goto ice_create_pkt_fwd_rule_exit; 1030 } 1031 1032 fm_entry->fltr_info = f_entry->fltr_info; 1033 1034 /* Initialize all the fields for the management entry */ 1035 fm_entry->vsi_count = 1; 1036 fm_entry->lg_act_idx = ICE_INVAL_LG_ACT_INDEX; 1037 fm_entry->sw_marker_id = ICE_INVAL_SW_MARKER_ID; 1038 fm_entry->counter_index = ICE_INVAL_COUNTER_ID; 1039 1040 ice_fill_sw_rule(hw, &fm_entry->fltr_info, s_rule, 1041 ice_aqc_opc_add_sw_rules); 1042 1043 status = ice_aq_sw_rules(hw, s_rule, ICE_SW_RULE_RX_TX_ETH_HDR_SIZE, 1, 1044 ice_aqc_opc_add_sw_rules, NULL); 1045 if (status) { 1046 devm_kfree(ice_hw_to_dev(hw), fm_entry); 1047 goto ice_create_pkt_fwd_rule_exit; 1048 } 1049 1050 f_entry->fltr_info.fltr_rule_id = 1051 le16_to_cpu(s_rule->pdata.lkup_tx_rx.index); 1052 fm_entry->fltr_info.fltr_rule_id = 1053 le16_to_cpu(s_rule->pdata.lkup_tx_rx.index); 1054 1055 /* The book keeping entries will get removed when base driver 1056 * calls remove filter AQ command 1057 */ 1058 l_type = fm_entry->fltr_info.lkup_type; 1059 recp = &hw->switch_info->recp_list[l_type]; 1060 list_add(&fm_entry->list_entry, &recp->filt_rules); 1061 1062 ice_create_pkt_fwd_rule_exit: 1063 devm_kfree(ice_hw_to_dev(hw), s_rule); 1064 return status; 1065 } 1066 1067 /** 1068 * ice_update_pkt_fwd_rule 1069 * @hw: pointer to the hardware structure 1070 * @f_info: filter information for switch rule 1071 * 1072 * Call AQ command to update a previously created switch rule with a 1073 * VSI list id 1074 */ 1075 static enum ice_status 1076 ice_update_pkt_fwd_rule(struct ice_hw *hw, struct ice_fltr_info *f_info) 1077 { 1078 struct ice_aqc_sw_rules_elem *s_rule; 1079 enum ice_status status; 1080 1081 s_rule = devm_kzalloc(ice_hw_to_dev(hw), 1082 ICE_SW_RULE_RX_TX_ETH_HDR_SIZE, GFP_KERNEL); 1083 if (!s_rule) 1084 return ICE_ERR_NO_MEMORY; 1085 1086 ice_fill_sw_rule(hw, f_info, s_rule, ice_aqc_opc_update_sw_rules); 1087 1088 s_rule->pdata.lkup_tx_rx.index = cpu_to_le16(f_info->fltr_rule_id); 1089 1090 /* Update switch rule with new rule set to forward VSI list */ 1091 status = ice_aq_sw_rules(hw, s_rule, ICE_SW_RULE_RX_TX_ETH_HDR_SIZE, 1, 1092 ice_aqc_opc_update_sw_rules, NULL); 1093 1094 devm_kfree(ice_hw_to_dev(hw), s_rule); 1095 return status; 1096 } 1097 1098 /** 1099 * ice_update_sw_rule_bridge_mode 1100 * @hw: pointer to the hw struct 1101 * 1102 * Updates unicast switch filter rules based on VEB/VEPA mode 1103 */ 1104 enum ice_status ice_update_sw_rule_bridge_mode(struct ice_hw *hw) 1105 { 1106 struct ice_switch_info *sw = hw->switch_info; 1107 struct ice_fltr_mgmt_list_entry *fm_entry; 1108 enum ice_status status = 0; 1109 struct list_head *rule_head; 1110 struct mutex *rule_lock; /* Lock to protect filter rule list */ 1111 1112 rule_lock = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rule_lock; 1113 rule_head = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rules; 1114 1115 mutex_lock(rule_lock); 1116 list_for_each_entry(fm_entry, rule_head, list_entry) { 1117 struct ice_fltr_info *fi = &fm_entry->fltr_info; 1118 u8 *addr = fi->l_data.mac.mac_addr; 1119 1120 /* Update unicast Tx rules to reflect the selected 1121 * VEB/VEPA mode 1122 */ 1123 if ((fi->flag & ICE_FLTR_TX) && is_unicast_ether_addr(addr) && 1124 (fi->fltr_act == ICE_FWD_TO_VSI || 1125 fi->fltr_act == ICE_FWD_TO_VSI_LIST || 1126 fi->fltr_act == ICE_FWD_TO_Q || 1127 fi->fltr_act == ICE_FWD_TO_QGRP)) { 1128 status = ice_update_pkt_fwd_rule(hw, fi); 1129 if (status) 1130 break; 1131 } 1132 } 1133 1134 mutex_unlock(rule_lock); 1135 1136 return status; 1137 } 1138 1139 /** 1140 * ice_add_update_vsi_list 1141 * @hw: pointer to the hardware structure 1142 * @m_entry: pointer to current filter management list entry 1143 * @cur_fltr: filter information from the book keeping entry 1144 * @new_fltr: filter information with the new VSI to be added 1145 * 1146 * Call AQ command to add or update previously created VSI list with new VSI. 1147 * 1148 * Helper function to do book keeping associated with adding filter information 1149 * The algorithm to do the booking keeping is described below : 1150 * When a VSI needs to subscribe to a given filter( MAC/VLAN/Ethtype etc.) 1151 * if only one VSI has been added till now 1152 * Allocate a new VSI list and add two VSIs 1153 * to this list using switch rule command 1154 * Update the previously created switch rule with the 1155 * newly created VSI list id 1156 * if a VSI list was previously created 1157 * Add the new VSI to the previously created VSI list set 1158 * using the update switch rule command 1159 */ 1160 static enum ice_status 1161 ice_add_update_vsi_list(struct ice_hw *hw, 1162 struct ice_fltr_mgmt_list_entry *m_entry, 1163 struct ice_fltr_info *cur_fltr, 1164 struct ice_fltr_info *new_fltr) 1165 { 1166 enum ice_status status = 0; 1167 u16 vsi_list_id = 0; 1168 1169 if ((cur_fltr->fltr_act == ICE_FWD_TO_Q || 1170 cur_fltr->fltr_act == ICE_FWD_TO_QGRP)) 1171 return ICE_ERR_NOT_IMPL; 1172 1173 if ((new_fltr->fltr_act == ICE_FWD_TO_Q || 1174 new_fltr->fltr_act == ICE_FWD_TO_QGRP) && 1175 (cur_fltr->fltr_act == ICE_FWD_TO_VSI || 1176 cur_fltr->fltr_act == ICE_FWD_TO_VSI_LIST)) 1177 return ICE_ERR_NOT_IMPL; 1178 1179 if (m_entry->vsi_count < 2 && !m_entry->vsi_list_info) { 1180 /* Only one entry existed in the mapping and it was not already 1181 * a part of a VSI list. So, create a VSI list with the old and 1182 * new VSIs. 1183 */ 1184 struct ice_fltr_info tmp_fltr; 1185 u16 vsi_handle_arr[2]; 1186 1187 /* A rule already exists with the new VSI being added */ 1188 if (cur_fltr->fwd_id.hw_vsi_id == new_fltr->fwd_id.hw_vsi_id) 1189 return ICE_ERR_ALREADY_EXISTS; 1190 1191 vsi_handle_arr[0] = cur_fltr->vsi_handle; 1192 vsi_handle_arr[1] = new_fltr->vsi_handle; 1193 status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2, 1194 &vsi_list_id, 1195 new_fltr->lkup_type); 1196 if (status) 1197 return status; 1198 1199 tmp_fltr = *new_fltr; 1200 tmp_fltr.fltr_rule_id = cur_fltr->fltr_rule_id; 1201 tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST; 1202 tmp_fltr.fwd_id.vsi_list_id = vsi_list_id; 1203 /* Update the previous switch rule of "MAC forward to VSI" to 1204 * "MAC fwd to VSI list" 1205 */ 1206 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr); 1207 if (status) 1208 return status; 1209 1210 cur_fltr->fwd_id.vsi_list_id = vsi_list_id; 1211 cur_fltr->fltr_act = ICE_FWD_TO_VSI_LIST; 1212 m_entry->vsi_list_info = 1213 ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2, 1214 vsi_list_id); 1215 1216 /* If this entry was large action then the large action needs 1217 * to be updated to point to FWD to VSI list 1218 */ 1219 if (m_entry->sw_marker_id != ICE_INVAL_SW_MARKER_ID) 1220 status = 1221 ice_add_marker_act(hw, m_entry, 1222 m_entry->sw_marker_id, 1223 m_entry->lg_act_idx); 1224 } else { 1225 u16 vsi_handle = new_fltr->vsi_handle; 1226 enum ice_adminq_opc opcode; 1227 1228 /* A rule already exists with the new VSI being added */ 1229 if (test_bit(vsi_handle, m_entry->vsi_list_info->vsi_map)) 1230 return 0; 1231 1232 /* Update the previously created VSI list set with 1233 * the new VSI id passed in 1234 */ 1235 vsi_list_id = cur_fltr->fwd_id.vsi_list_id; 1236 opcode = ice_aqc_opc_update_sw_rules; 1237 1238 status = ice_update_vsi_list_rule(hw, &vsi_handle, 1, 1239 vsi_list_id, false, opcode, 1240 new_fltr->lkup_type); 1241 /* update VSI list mapping info with new VSI id */ 1242 if (!status) 1243 set_bit(vsi_handle, m_entry->vsi_list_info->vsi_map); 1244 } 1245 if (!status) 1246 m_entry->vsi_count++; 1247 return status; 1248 } 1249 1250 /** 1251 * ice_find_rule_entry - Search a rule entry 1252 * @hw: pointer to the hardware structure 1253 * @recp_id: lookup type for which the specified rule needs to be searched 1254 * @f_info: rule information 1255 * 1256 * Helper function to search for a given rule entry 1257 * Returns pointer to entry storing the rule if found 1258 */ 1259 static struct ice_fltr_mgmt_list_entry * 1260 ice_find_rule_entry(struct ice_hw *hw, u8 recp_id, struct ice_fltr_info *f_info) 1261 { 1262 struct ice_fltr_mgmt_list_entry *list_itr, *ret = NULL; 1263 struct ice_switch_info *sw = hw->switch_info; 1264 struct list_head *list_head; 1265 1266 list_head = &sw->recp_list[recp_id].filt_rules; 1267 list_for_each_entry(list_itr, list_head, list_entry) { 1268 if (!memcmp(&f_info->l_data, &list_itr->fltr_info.l_data, 1269 sizeof(f_info->l_data)) && 1270 f_info->flag == list_itr->fltr_info.flag) { 1271 ret = list_itr; 1272 break; 1273 } 1274 } 1275 return ret; 1276 } 1277 1278 /** 1279 * ice_find_vsi_list_entry - Search VSI list map with VSI count 1 1280 * @hw: pointer to the hardware structure 1281 * @recp_id: lookup type for which VSI lists needs to be searched 1282 * @vsi_handle: VSI handle to be found in VSI list 1283 * @vsi_list_id: VSI list id found containing vsi_handle 1284 * 1285 * Helper function to search a VSI list with single entry containing given VSI 1286 * handle element. This can be extended further to search VSI list with more 1287 * than 1 vsi_count. Returns pointer to VSI list entry if found. 1288 */ 1289 static struct ice_vsi_list_map_info * 1290 ice_find_vsi_list_entry(struct ice_hw *hw, u8 recp_id, u16 vsi_handle, 1291 u16 *vsi_list_id) 1292 { 1293 struct ice_vsi_list_map_info *map_info = NULL; 1294 struct ice_switch_info *sw = hw->switch_info; 1295 struct ice_fltr_mgmt_list_entry *list_itr; 1296 struct list_head *list_head; 1297 1298 list_head = &sw->recp_list[recp_id].filt_rules; 1299 list_for_each_entry(list_itr, list_head, list_entry) { 1300 if (list_itr->vsi_count == 1 && list_itr->vsi_list_info) { 1301 map_info = list_itr->vsi_list_info; 1302 if (test_bit(vsi_handle, map_info->vsi_map)) { 1303 *vsi_list_id = map_info->vsi_list_id; 1304 return map_info; 1305 } 1306 } 1307 } 1308 return NULL; 1309 } 1310 1311 /** 1312 * ice_add_rule_internal - add rule for a given lookup type 1313 * @hw: pointer to the hardware structure 1314 * @recp_id: lookup type (recipe id) for which rule has to be added 1315 * @f_entry: structure containing MAC forwarding information 1316 * 1317 * Adds or updates the rule lists for a given recipe 1318 */ 1319 static enum ice_status 1320 ice_add_rule_internal(struct ice_hw *hw, u8 recp_id, 1321 struct ice_fltr_list_entry *f_entry) 1322 { 1323 struct ice_switch_info *sw = hw->switch_info; 1324 struct ice_fltr_info *new_fltr, *cur_fltr; 1325 struct ice_fltr_mgmt_list_entry *m_entry; 1326 struct mutex *rule_lock; /* Lock to protect filter rule list */ 1327 enum ice_status status = 0; 1328 1329 if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle)) 1330 return ICE_ERR_PARAM; 1331 f_entry->fltr_info.fwd_id.hw_vsi_id = 1332 ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle); 1333 1334 rule_lock = &sw->recp_list[recp_id].filt_rule_lock; 1335 1336 mutex_lock(rule_lock); 1337 new_fltr = &f_entry->fltr_info; 1338 if (new_fltr->flag & ICE_FLTR_RX) 1339 new_fltr->src = hw->port_info->lport; 1340 else if (new_fltr->flag & ICE_FLTR_TX) 1341 new_fltr->src = f_entry->fltr_info.fwd_id.hw_vsi_id; 1342 1343 m_entry = ice_find_rule_entry(hw, recp_id, new_fltr); 1344 if (!m_entry) { 1345 mutex_unlock(rule_lock); 1346 return ice_create_pkt_fwd_rule(hw, f_entry); 1347 } 1348 1349 cur_fltr = &m_entry->fltr_info; 1350 status = ice_add_update_vsi_list(hw, m_entry, cur_fltr, new_fltr); 1351 mutex_unlock(rule_lock); 1352 1353 return status; 1354 } 1355 1356 /** 1357 * ice_remove_vsi_list_rule 1358 * @hw: pointer to the hardware structure 1359 * @vsi_list_id: VSI list id generated as part of allocate resource 1360 * @lkup_type: switch rule filter lookup type 1361 * 1362 * The VSI list should be emptied before this function is called to remove the 1363 * VSI list. 1364 */ 1365 static enum ice_status 1366 ice_remove_vsi_list_rule(struct ice_hw *hw, u16 vsi_list_id, 1367 enum ice_sw_lkup_type lkup_type) 1368 { 1369 struct ice_aqc_sw_rules_elem *s_rule; 1370 enum ice_status status; 1371 u16 s_rule_size; 1372 1373 s_rule_size = (u16)ICE_SW_RULE_VSI_LIST_SIZE(0); 1374 s_rule = devm_kzalloc(ice_hw_to_dev(hw), s_rule_size, GFP_KERNEL); 1375 if (!s_rule) 1376 return ICE_ERR_NO_MEMORY; 1377 1378 s_rule->type = cpu_to_le16(ICE_AQC_SW_RULES_T_VSI_LIST_CLEAR); 1379 s_rule->pdata.vsi_list.index = cpu_to_le16(vsi_list_id); 1380 1381 /* Free the vsi_list resource that we allocated. It is assumed that the 1382 * list is empty at this point. 1383 */ 1384 status = ice_aq_alloc_free_vsi_list(hw, &vsi_list_id, lkup_type, 1385 ice_aqc_opc_free_res); 1386 1387 devm_kfree(ice_hw_to_dev(hw), s_rule); 1388 return status; 1389 } 1390 1391 /** 1392 * ice_rem_update_vsi_list 1393 * @hw: pointer to the hardware structure 1394 * @vsi_handle: VSI handle of the VSI to remove 1395 * @fm_list: filter management entry for which the VSI list management needs to 1396 * be done 1397 */ 1398 static enum ice_status 1399 ice_rem_update_vsi_list(struct ice_hw *hw, u16 vsi_handle, 1400 struct ice_fltr_mgmt_list_entry *fm_list) 1401 { 1402 enum ice_sw_lkup_type lkup_type; 1403 enum ice_status status = 0; 1404 u16 vsi_list_id; 1405 1406 if (fm_list->fltr_info.fltr_act != ICE_FWD_TO_VSI_LIST || 1407 fm_list->vsi_count == 0) 1408 return ICE_ERR_PARAM; 1409 1410 /* A rule with the VSI being removed does not exist */ 1411 if (!test_bit(vsi_handle, fm_list->vsi_list_info->vsi_map)) 1412 return ICE_ERR_DOES_NOT_EXIST; 1413 1414 lkup_type = fm_list->fltr_info.lkup_type; 1415 vsi_list_id = fm_list->fltr_info.fwd_id.vsi_list_id; 1416 status = ice_update_vsi_list_rule(hw, &vsi_handle, 1, vsi_list_id, true, 1417 ice_aqc_opc_update_sw_rules, 1418 lkup_type); 1419 if (status) 1420 return status; 1421 1422 fm_list->vsi_count--; 1423 clear_bit(vsi_handle, fm_list->vsi_list_info->vsi_map); 1424 1425 if (fm_list->vsi_count == 1 && lkup_type != ICE_SW_LKUP_VLAN) { 1426 struct ice_fltr_info tmp_fltr_info = fm_list->fltr_info; 1427 struct ice_vsi_list_map_info *vsi_list_info = 1428 fm_list->vsi_list_info; 1429 u16 rem_vsi_handle; 1430 1431 rem_vsi_handle = find_first_bit(vsi_list_info->vsi_map, 1432 ICE_MAX_VSI); 1433 if (!ice_is_vsi_valid(hw, rem_vsi_handle)) 1434 return ICE_ERR_OUT_OF_RANGE; 1435 1436 /* Make sure VSI list is empty before removing it below */ 1437 status = ice_update_vsi_list_rule(hw, &rem_vsi_handle, 1, 1438 vsi_list_id, true, 1439 ice_aqc_opc_update_sw_rules, 1440 lkup_type); 1441 if (status) 1442 return status; 1443 1444 tmp_fltr_info.fltr_act = ICE_FWD_TO_VSI; 1445 tmp_fltr_info.fwd_id.hw_vsi_id = 1446 ice_get_hw_vsi_num(hw, rem_vsi_handle); 1447 tmp_fltr_info.vsi_handle = rem_vsi_handle; 1448 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr_info); 1449 if (status) { 1450 ice_debug(hw, ICE_DBG_SW, 1451 "Failed to update pkt fwd rule to FWD_TO_VSI on HW VSI %d, error %d\n", 1452 tmp_fltr_info.fwd_id.hw_vsi_id, status); 1453 return status; 1454 } 1455 1456 fm_list->fltr_info = tmp_fltr_info; 1457 } 1458 1459 if ((fm_list->vsi_count == 1 && lkup_type != ICE_SW_LKUP_VLAN) || 1460 (fm_list->vsi_count == 0 && lkup_type == ICE_SW_LKUP_VLAN)) { 1461 struct ice_vsi_list_map_info *vsi_list_info = 1462 fm_list->vsi_list_info; 1463 1464 /* Remove the VSI list since it is no longer used */ 1465 status = ice_remove_vsi_list_rule(hw, vsi_list_id, lkup_type); 1466 if (status) { 1467 ice_debug(hw, ICE_DBG_SW, 1468 "Failed to remove VSI list %d, error %d\n", 1469 vsi_list_id, status); 1470 return status; 1471 } 1472 1473 list_del(&vsi_list_info->list_entry); 1474 devm_kfree(ice_hw_to_dev(hw), vsi_list_info); 1475 fm_list->vsi_list_info = NULL; 1476 } 1477 1478 return status; 1479 } 1480 1481 /** 1482 * ice_remove_rule_internal - Remove a filter rule of a given type 1483 * @hw: pointer to the hardware structure 1484 * @recp_id: recipe id for which the rule needs to removed 1485 * @f_entry: rule entry containing filter information 1486 */ 1487 static enum ice_status 1488 ice_remove_rule_internal(struct ice_hw *hw, u8 recp_id, 1489 struct ice_fltr_list_entry *f_entry) 1490 { 1491 struct ice_switch_info *sw = hw->switch_info; 1492 struct ice_fltr_mgmt_list_entry *list_elem; 1493 struct mutex *rule_lock; /* Lock to protect filter rule list */ 1494 enum ice_status status = 0; 1495 bool remove_rule = false; 1496 u16 vsi_handle; 1497 1498 if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle)) 1499 return ICE_ERR_PARAM; 1500 f_entry->fltr_info.fwd_id.hw_vsi_id = 1501 ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle); 1502 1503 rule_lock = &sw->recp_list[recp_id].filt_rule_lock; 1504 mutex_lock(rule_lock); 1505 list_elem = ice_find_rule_entry(hw, recp_id, &f_entry->fltr_info); 1506 if (!list_elem) { 1507 status = ICE_ERR_DOES_NOT_EXIST; 1508 goto exit; 1509 } 1510 1511 if (list_elem->fltr_info.fltr_act != ICE_FWD_TO_VSI_LIST) { 1512 remove_rule = true; 1513 } else if (!list_elem->vsi_list_info) { 1514 status = ICE_ERR_DOES_NOT_EXIST; 1515 goto exit; 1516 } else { 1517 if (list_elem->vsi_list_info->ref_cnt > 1) 1518 list_elem->vsi_list_info->ref_cnt--; 1519 vsi_handle = f_entry->fltr_info.vsi_handle; 1520 status = ice_rem_update_vsi_list(hw, vsi_handle, list_elem); 1521 if (status) 1522 goto exit; 1523 /* if vsi count goes to zero after updating the vsi list */ 1524 if (list_elem->vsi_count == 0) 1525 remove_rule = true; 1526 } 1527 1528 if (remove_rule) { 1529 /* Remove the lookup rule */ 1530 struct ice_aqc_sw_rules_elem *s_rule; 1531 1532 s_rule = devm_kzalloc(ice_hw_to_dev(hw), 1533 ICE_SW_RULE_RX_TX_NO_HDR_SIZE, 1534 GFP_KERNEL); 1535 if (!s_rule) { 1536 status = ICE_ERR_NO_MEMORY; 1537 goto exit; 1538 } 1539 1540 ice_fill_sw_rule(hw, &list_elem->fltr_info, s_rule, 1541 ice_aqc_opc_remove_sw_rules); 1542 1543 status = ice_aq_sw_rules(hw, s_rule, 1544 ICE_SW_RULE_RX_TX_NO_HDR_SIZE, 1, 1545 ice_aqc_opc_remove_sw_rules, NULL); 1546 if (status) 1547 goto exit; 1548 1549 /* Remove a book keeping from the list */ 1550 devm_kfree(ice_hw_to_dev(hw), s_rule); 1551 1552 list_del(&list_elem->list_entry); 1553 devm_kfree(ice_hw_to_dev(hw), list_elem); 1554 } 1555 exit: 1556 mutex_unlock(rule_lock); 1557 return status; 1558 } 1559 1560 /** 1561 * ice_add_mac - Add a MAC address based filter rule 1562 * @hw: pointer to the hardware structure 1563 * @m_list: list of MAC addresses and forwarding information 1564 * 1565 * IMPORTANT: When the ucast_shared flag is set to false and m_list has 1566 * multiple unicast addresses, the function assumes that all the 1567 * addresses are unique in a given add_mac call. It doesn't 1568 * check for duplicates in this case, removing duplicates from a given 1569 * list should be taken care of in the caller of this function. 1570 */ 1571 enum ice_status 1572 ice_add_mac(struct ice_hw *hw, struct list_head *m_list) 1573 { 1574 struct ice_aqc_sw_rules_elem *s_rule, *r_iter; 1575 struct ice_fltr_list_entry *m_list_itr; 1576 struct list_head *rule_head; 1577 u16 elem_sent, total_elem_left; 1578 struct ice_switch_info *sw; 1579 struct mutex *rule_lock; /* Lock to protect filter rule list */ 1580 enum ice_status status = 0; 1581 u16 num_unicast = 0; 1582 u16 s_rule_size; 1583 1584 if (!m_list || !hw) 1585 return ICE_ERR_PARAM; 1586 1587 s_rule = NULL; 1588 sw = hw->switch_info; 1589 rule_lock = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rule_lock; 1590 list_for_each_entry(m_list_itr, m_list, list_entry) { 1591 u8 *add = &m_list_itr->fltr_info.l_data.mac.mac_addr[0]; 1592 u16 vsi_handle; 1593 u16 hw_vsi_id; 1594 1595 m_list_itr->fltr_info.flag = ICE_FLTR_TX; 1596 vsi_handle = m_list_itr->fltr_info.vsi_handle; 1597 if (!ice_is_vsi_valid(hw, vsi_handle)) 1598 return ICE_ERR_PARAM; 1599 hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle); 1600 m_list_itr->fltr_info.fwd_id.hw_vsi_id = hw_vsi_id; 1601 /* update the src in case it is vsi num */ 1602 if (m_list_itr->fltr_info.src_id != ICE_SRC_ID_VSI) 1603 return ICE_ERR_PARAM; 1604 m_list_itr->fltr_info.src = hw_vsi_id; 1605 if (m_list_itr->fltr_info.lkup_type != ICE_SW_LKUP_MAC || 1606 is_zero_ether_addr(add)) 1607 return ICE_ERR_PARAM; 1608 if (is_unicast_ether_addr(add) && !hw->ucast_shared) { 1609 /* Don't overwrite the unicast address */ 1610 mutex_lock(rule_lock); 1611 if (ice_find_rule_entry(hw, ICE_SW_LKUP_MAC, 1612 &m_list_itr->fltr_info)) { 1613 mutex_unlock(rule_lock); 1614 return ICE_ERR_ALREADY_EXISTS; 1615 } 1616 mutex_unlock(rule_lock); 1617 num_unicast++; 1618 } else if (is_multicast_ether_addr(add) || 1619 (is_unicast_ether_addr(add) && hw->ucast_shared)) { 1620 m_list_itr->status = 1621 ice_add_rule_internal(hw, ICE_SW_LKUP_MAC, 1622 m_list_itr); 1623 if (m_list_itr->status) 1624 return m_list_itr->status; 1625 } 1626 } 1627 1628 mutex_lock(rule_lock); 1629 /* Exit if no suitable entries were found for adding bulk switch rule */ 1630 if (!num_unicast) { 1631 status = 0; 1632 goto ice_add_mac_exit; 1633 } 1634 1635 rule_head = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rules; 1636 1637 /* Allocate switch rule buffer for the bulk update for unicast */ 1638 s_rule_size = ICE_SW_RULE_RX_TX_ETH_HDR_SIZE; 1639 s_rule = devm_kcalloc(ice_hw_to_dev(hw), num_unicast, s_rule_size, 1640 GFP_KERNEL); 1641 if (!s_rule) { 1642 status = ICE_ERR_NO_MEMORY; 1643 goto ice_add_mac_exit; 1644 } 1645 1646 r_iter = s_rule; 1647 list_for_each_entry(m_list_itr, m_list, list_entry) { 1648 struct ice_fltr_info *f_info = &m_list_itr->fltr_info; 1649 u8 *mac_addr = &f_info->l_data.mac.mac_addr[0]; 1650 1651 if (is_unicast_ether_addr(mac_addr)) { 1652 ice_fill_sw_rule(hw, &m_list_itr->fltr_info, r_iter, 1653 ice_aqc_opc_add_sw_rules); 1654 r_iter = (struct ice_aqc_sw_rules_elem *) 1655 ((u8 *)r_iter + s_rule_size); 1656 } 1657 } 1658 1659 /* Call AQ bulk switch rule update for all unicast addresses */ 1660 r_iter = s_rule; 1661 /* Call AQ switch rule in AQ_MAX chunk */ 1662 for (total_elem_left = num_unicast; total_elem_left > 0; 1663 total_elem_left -= elem_sent) { 1664 struct ice_aqc_sw_rules_elem *entry = r_iter; 1665 1666 elem_sent = min(total_elem_left, 1667 (u16)(ICE_AQ_MAX_BUF_LEN / s_rule_size)); 1668 status = ice_aq_sw_rules(hw, entry, elem_sent * s_rule_size, 1669 elem_sent, ice_aqc_opc_add_sw_rules, 1670 NULL); 1671 if (status) 1672 goto ice_add_mac_exit; 1673 r_iter = (struct ice_aqc_sw_rules_elem *) 1674 ((u8 *)r_iter + (elem_sent * s_rule_size)); 1675 } 1676 1677 /* Fill up rule id based on the value returned from FW */ 1678 r_iter = s_rule; 1679 list_for_each_entry(m_list_itr, m_list, list_entry) { 1680 struct ice_fltr_info *f_info = &m_list_itr->fltr_info; 1681 u8 *mac_addr = &f_info->l_data.mac.mac_addr[0]; 1682 struct ice_fltr_mgmt_list_entry *fm_entry; 1683 1684 if (is_unicast_ether_addr(mac_addr)) { 1685 f_info->fltr_rule_id = 1686 le16_to_cpu(r_iter->pdata.lkup_tx_rx.index); 1687 f_info->fltr_act = ICE_FWD_TO_VSI; 1688 /* Create an entry to track this MAC address */ 1689 fm_entry = devm_kzalloc(ice_hw_to_dev(hw), 1690 sizeof(*fm_entry), GFP_KERNEL); 1691 if (!fm_entry) { 1692 status = ICE_ERR_NO_MEMORY; 1693 goto ice_add_mac_exit; 1694 } 1695 fm_entry->fltr_info = *f_info; 1696 fm_entry->vsi_count = 1; 1697 /* The book keeping entries will get removed when 1698 * base driver calls remove filter AQ command 1699 */ 1700 1701 list_add(&fm_entry->list_entry, rule_head); 1702 r_iter = (struct ice_aqc_sw_rules_elem *) 1703 ((u8 *)r_iter + s_rule_size); 1704 } 1705 } 1706 1707 ice_add_mac_exit: 1708 mutex_unlock(rule_lock); 1709 if (s_rule) 1710 devm_kfree(ice_hw_to_dev(hw), s_rule); 1711 return status; 1712 } 1713 1714 /** 1715 * ice_add_vlan_internal - Add one VLAN based filter rule 1716 * @hw: pointer to the hardware structure 1717 * @f_entry: filter entry containing one VLAN information 1718 */ 1719 static enum ice_status 1720 ice_add_vlan_internal(struct ice_hw *hw, struct ice_fltr_list_entry *f_entry) 1721 { 1722 struct ice_switch_info *sw = hw->switch_info; 1723 struct ice_fltr_mgmt_list_entry *v_list_itr; 1724 struct ice_fltr_info *new_fltr, *cur_fltr; 1725 enum ice_sw_lkup_type lkup_type; 1726 u16 vsi_list_id = 0, vsi_handle; 1727 struct mutex *rule_lock; /* Lock to protect filter rule list */ 1728 enum ice_status status = 0; 1729 1730 if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle)) 1731 return ICE_ERR_PARAM; 1732 1733 f_entry->fltr_info.fwd_id.hw_vsi_id = 1734 ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle); 1735 new_fltr = &f_entry->fltr_info; 1736 1737 /* VLAN id should only be 12 bits */ 1738 if (new_fltr->l_data.vlan.vlan_id > ICE_MAX_VLAN_ID) 1739 return ICE_ERR_PARAM; 1740 1741 if (new_fltr->src_id != ICE_SRC_ID_VSI) 1742 return ICE_ERR_PARAM; 1743 1744 new_fltr->src = new_fltr->fwd_id.hw_vsi_id; 1745 lkup_type = new_fltr->lkup_type; 1746 vsi_handle = new_fltr->vsi_handle; 1747 rule_lock = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rule_lock; 1748 mutex_lock(rule_lock); 1749 v_list_itr = ice_find_rule_entry(hw, ICE_SW_LKUP_VLAN, new_fltr); 1750 if (!v_list_itr) { 1751 struct ice_vsi_list_map_info *map_info = NULL; 1752 1753 if (new_fltr->fltr_act == ICE_FWD_TO_VSI) { 1754 /* All VLAN pruning rules use a VSI list. Check if 1755 * there is already a VSI list containing VSI that we 1756 * want to add. If found, use the same vsi_list_id for 1757 * this new VLAN rule or else create a new list. 1758 */ 1759 map_info = ice_find_vsi_list_entry(hw, ICE_SW_LKUP_VLAN, 1760 vsi_handle, 1761 &vsi_list_id); 1762 if (!map_info) { 1763 status = ice_create_vsi_list_rule(hw, 1764 &vsi_handle, 1765 1, 1766 &vsi_list_id, 1767 lkup_type); 1768 if (status) 1769 goto exit; 1770 } 1771 /* Convert the action to forwarding to a VSI list. */ 1772 new_fltr->fltr_act = ICE_FWD_TO_VSI_LIST; 1773 new_fltr->fwd_id.vsi_list_id = vsi_list_id; 1774 } 1775 1776 status = ice_create_pkt_fwd_rule(hw, f_entry); 1777 if (!status) { 1778 v_list_itr = ice_find_rule_entry(hw, ICE_SW_LKUP_VLAN, 1779 new_fltr); 1780 if (!v_list_itr) { 1781 status = ICE_ERR_DOES_NOT_EXIST; 1782 goto exit; 1783 } 1784 /* reuse VSI list for new rule and increment ref_cnt */ 1785 if (map_info) { 1786 v_list_itr->vsi_list_info = map_info; 1787 map_info->ref_cnt++; 1788 } else { 1789 v_list_itr->vsi_list_info = 1790 ice_create_vsi_list_map(hw, &vsi_handle, 1791 1, vsi_list_id); 1792 } 1793 } 1794 } else if (v_list_itr->vsi_list_info->ref_cnt == 1) { 1795 /* Update existing VSI list to add new VSI id only if it used 1796 * by one VLAN rule. 1797 */ 1798 cur_fltr = &v_list_itr->fltr_info; 1799 status = ice_add_update_vsi_list(hw, v_list_itr, cur_fltr, 1800 new_fltr); 1801 } else { 1802 /* If VLAN rule exists and VSI list being used by this rule is 1803 * referenced by more than 1 VLAN rule. Then create a new VSI 1804 * list appending previous VSI with new VSI and update existing 1805 * VLAN rule to point to new VSI list id 1806 */ 1807 struct ice_fltr_info tmp_fltr; 1808 u16 vsi_handle_arr[2]; 1809 u16 cur_handle; 1810 1811 /* Current implementation only supports reusing VSI list with 1812 * one VSI count. We should never hit below condition 1813 */ 1814 if (v_list_itr->vsi_count > 1 && 1815 v_list_itr->vsi_list_info->ref_cnt > 1) { 1816 ice_debug(hw, ICE_DBG_SW, 1817 "Invalid configuration: Optimization to reuse VSI list with more than one VSI is not being done yet\n"); 1818 status = ICE_ERR_CFG; 1819 goto exit; 1820 } 1821 1822 cur_handle = 1823 find_first_bit(v_list_itr->vsi_list_info->vsi_map, 1824 ICE_MAX_VSI); 1825 1826 /* A rule already exists with the new VSI being added */ 1827 if (cur_handle == vsi_handle) { 1828 status = ICE_ERR_ALREADY_EXISTS; 1829 goto exit; 1830 } 1831 1832 vsi_handle_arr[0] = cur_handle; 1833 vsi_handle_arr[1] = vsi_handle; 1834 status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2, 1835 &vsi_list_id, lkup_type); 1836 if (status) 1837 goto exit; 1838 1839 tmp_fltr = v_list_itr->fltr_info; 1840 tmp_fltr.fltr_rule_id = v_list_itr->fltr_info.fltr_rule_id; 1841 tmp_fltr.fwd_id.vsi_list_id = vsi_list_id; 1842 tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST; 1843 /* Update the previous switch rule to a new VSI list which 1844 * includes current VSI thats requested 1845 */ 1846 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr); 1847 if (status) 1848 goto exit; 1849 1850 /* before overriding VSI list map info. decrement ref_cnt of 1851 * previous VSI list 1852 */ 1853 v_list_itr->vsi_list_info->ref_cnt--; 1854 1855 /* now update to newly created list */ 1856 v_list_itr->fltr_info.fwd_id.vsi_list_id = vsi_list_id; 1857 v_list_itr->vsi_list_info = 1858 ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2, 1859 vsi_list_id); 1860 v_list_itr->vsi_count++; 1861 } 1862 1863 exit: 1864 mutex_unlock(rule_lock); 1865 return status; 1866 } 1867 1868 /** 1869 * ice_add_vlan - Add VLAN based filter rule 1870 * @hw: pointer to the hardware structure 1871 * @v_list: list of VLAN entries and forwarding information 1872 */ 1873 enum ice_status 1874 ice_add_vlan(struct ice_hw *hw, struct list_head *v_list) 1875 { 1876 struct ice_fltr_list_entry *v_list_itr; 1877 1878 if (!v_list || !hw) 1879 return ICE_ERR_PARAM; 1880 1881 list_for_each_entry(v_list_itr, v_list, list_entry) { 1882 if (v_list_itr->fltr_info.lkup_type != ICE_SW_LKUP_VLAN) 1883 return ICE_ERR_PARAM; 1884 v_list_itr->fltr_info.flag = ICE_FLTR_TX; 1885 v_list_itr->status = ice_add_vlan_internal(hw, v_list_itr); 1886 if (v_list_itr->status) 1887 return v_list_itr->status; 1888 } 1889 return 0; 1890 } 1891 1892 /** 1893 * ice_rem_sw_rule_info 1894 * @hw: pointer to the hardware structure 1895 * @rule_head: pointer to the switch list structure that we want to delete 1896 */ 1897 static void 1898 ice_rem_sw_rule_info(struct ice_hw *hw, struct list_head *rule_head) 1899 { 1900 if (!list_empty(rule_head)) { 1901 struct ice_fltr_mgmt_list_entry *entry; 1902 struct ice_fltr_mgmt_list_entry *tmp; 1903 1904 list_for_each_entry_safe(entry, tmp, rule_head, list_entry) { 1905 list_del(&entry->list_entry); 1906 devm_kfree(ice_hw_to_dev(hw), entry); 1907 } 1908 } 1909 } 1910 1911 /** 1912 * ice_cfg_dflt_vsi - change state of VSI to set/clear default 1913 * @hw: pointer to the hardware structure 1914 * @vsi_handle: VSI handle to set as default 1915 * @set: true to add the above mentioned switch rule, false to remove it 1916 * @direction: ICE_FLTR_RX or ICE_FLTR_TX 1917 * 1918 * add filter rule to set/unset given VSI as default VSI for the switch 1919 * (represented by swid) 1920 */ 1921 enum ice_status 1922 ice_cfg_dflt_vsi(struct ice_hw *hw, u16 vsi_handle, bool set, u8 direction) 1923 { 1924 struct ice_aqc_sw_rules_elem *s_rule; 1925 struct ice_fltr_info f_info; 1926 enum ice_adminq_opc opcode; 1927 enum ice_status status; 1928 u16 s_rule_size; 1929 u16 hw_vsi_id; 1930 1931 if (!ice_is_vsi_valid(hw, vsi_handle)) 1932 return ICE_ERR_PARAM; 1933 hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle); 1934 1935 s_rule_size = set ? ICE_SW_RULE_RX_TX_ETH_HDR_SIZE : 1936 ICE_SW_RULE_RX_TX_NO_HDR_SIZE; 1937 s_rule = devm_kzalloc(ice_hw_to_dev(hw), s_rule_size, GFP_KERNEL); 1938 if (!s_rule) 1939 return ICE_ERR_NO_MEMORY; 1940 1941 memset(&f_info, 0, sizeof(f_info)); 1942 1943 f_info.lkup_type = ICE_SW_LKUP_DFLT; 1944 f_info.flag = direction; 1945 f_info.fltr_act = ICE_FWD_TO_VSI; 1946 f_info.fwd_id.hw_vsi_id = hw_vsi_id; 1947 1948 if (f_info.flag & ICE_FLTR_RX) { 1949 f_info.src = hw->port_info->lport; 1950 f_info.src_id = ICE_SRC_ID_LPORT; 1951 if (!set) 1952 f_info.fltr_rule_id = 1953 hw->port_info->dflt_rx_vsi_rule_id; 1954 } else if (f_info.flag & ICE_FLTR_TX) { 1955 f_info.src_id = ICE_SRC_ID_VSI; 1956 f_info.src = hw_vsi_id; 1957 if (!set) 1958 f_info.fltr_rule_id = 1959 hw->port_info->dflt_tx_vsi_rule_id; 1960 } 1961 1962 if (set) 1963 opcode = ice_aqc_opc_add_sw_rules; 1964 else 1965 opcode = ice_aqc_opc_remove_sw_rules; 1966 1967 ice_fill_sw_rule(hw, &f_info, s_rule, opcode); 1968 1969 status = ice_aq_sw_rules(hw, s_rule, s_rule_size, 1, opcode, NULL); 1970 if (status || !(f_info.flag & ICE_FLTR_TX_RX)) 1971 goto out; 1972 if (set) { 1973 u16 index = le16_to_cpu(s_rule->pdata.lkup_tx_rx.index); 1974 1975 if (f_info.flag & ICE_FLTR_TX) { 1976 hw->port_info->dflt_tx_vsi_num = hw_vsi_id; 1977 hw->port_info->dflt_tx_vsi_rule_id = index; 1978 } else if (f_info.flag & ICE_FLTR_RX) { 1979 hw->port_info->dflt_rx_vsi_num = hw_vsi_id; 1980 hw->port_info->dflt_rx_vsi_rule_id = index; 1981 } 1982 } else { 1983 if (f_info.flag & ICE_FLTR_TX) { 1984 hw->port_info->dflt_tx_vsi_num = ICE_DFLT_VSI_INVAL; 1985 hw->port_info->dflt_tx_vsi_rule_id = ICE_INVAL_ACT; 1986 } else if (f_info.flag & ICE_FLTR_RX) { 1987 hw->port_info->dflt_rx_vsi_num = ICE_DFLT_VSI_INVAL; 1988 hw->port_info->dflt_rx_vsi_rule_id = ICE_INVAL_ACT; 1989 } 1990 } 1991 1992 out: 1993 devm_kfree(ice_hw_to_dev(hw), s_rule); 1994 return status; 1995 } 1996 1997 /** 1998 * ice_remove_mac - remove a MAC address based filter rule 1999 * @hw: pointer to the hardware structure 2000 * @m_list: list of MAC addresses and forwarding information 2001 * 2002 * This function removes either a MAC filter rule or a specific VSI from a 2003 * VSI list for a multicast MAC address. 2004 * 2005 * Returns ICE_ERR_DOES_NOT_EXIST if a given entry was not added by 2006 * ice_add_mac. Caller should be aware that this call will only work if all 2007 * the entries passed into m_list were added previously. It will not attempt to 2008 * do a partial remove of entries that were found. 2009 */ 2010 enum ice_status 2011 ice_remove_mac(struct ice_hw *hw, struct list_head *m_list) 2012 { 2013 struct ice_fltr_list_entry *list_itr, *tmp; 2014 2015 if (!m_list) 2016 return ICE_ERR_PARAM; 2017 2018 list_for_each_entry_safe(list_itr, tmp, m_list, list_entry) { 2019 enum ice_sw_lkup_type l_type = list_itr->fltr_info.lkup_type; 2020 2021 if (l_type != ICE_SW_LKUP_MAC) 2022 return ICE_ERR_PARAM; 2023 list_itr->status = ice_remove_rule_internal(hw, 2024 ICE_SW_LKUP_MAC, 2025 list_itr); 2026 if (list_itr->status) 2027 return list_itr->status; 2028 } 2029 return 0; 2030 } 2031 2032 /** 2033 * ice_remove_vlan - Remove VLAN based filter rule 2034 * @hw: pointer to the hardware structure 2035 * @v_list: list of VLAN entries and forwarding information 2036 */ 2037 enum ice_status 2038 ice_remove_vlan(struct ice_hw *hw, struct list_head *v_list) 2039 { 2040 struct ice_fltr_list_entry *v_list_itr, *tmp; 2041 2042 if (!v_list || !hw) 2043 return ICE_ERR_PARAM; 2044 2045 list_for_each_entry_safe(v_list_itr, tmp, v_list, list_entry) { 2046 enum ice_sw_lkup_type l_type = v_list_itr->fltr_info.lkup_type; 2047 2048 if (l_type != ICE_SW_LKUP_VLAN) 2049 return ICE_ERR_PARAM; 2050 v_list_itr->status = ice_remove_rule_internal(hw, 2051 ICE_SW_LKUP_VLAN, 2052 v_list_itr); 2053 if (v_list_itr->status) 2054 return v_list_itr->status; 2055 } 2056 return 0; 2057 } 2058 2059 /** 2060 * ice_vsi_uses_fltr - Determine if given VSI uses specified filter 2061 * @fm_entry: filter entry to inspect 2062 * @vsi_handle: VSI handle to compare with filter info 2063 */ 2064 static bool 2065 ice_vsi_uses_fltr(struct ice_fltr_mgmt_list_entry *fm_entry, u16 vsi_handle) 2066 { 2067 return ((fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI && 2068 fm_entry->fltr_info.vsi_handle == vsi_handle) || 2069 (fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI_LIST && 2070 (test_bit(vsi_handle, fm_entry->vsi_list_info->vsi_map)))); 2071 } 2072 2073 /** 2074 * ice_add_entry_to_vsi_fltr_list - Add copy of fltr_list_entry to remove list 2075 * @hw: pointer to the hardware structure 2076 * @vsi_handle: VSI handle to remove filters from 2077 * @vsi_list_head: pointer to the list to add entry to 2078 * @fi: pointer to fltr_info of filter entry to copy & add 2079 * 2080 * Helper function, used when creating a list of filters to remove from 2081 * a specific VSI. The entry added to vsi_list_head is a COPY of the 2082 * original filter entry, with the exception of fltr_info.fltr_act and 2083 * fltr_info.fwd_id fields. These are set such that later logic can 2084 * extract which VSI to remove the fltr from, and pass on that information. 2085 */ 2086 static enum ice_status 2087 ice_add_entry_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_handle, 2088 struct list_head *vsi_list_head, 2089 struct ice_fltr_info *fi) 2090 { 2091 struct ice_fltr_list_entry *tmp; 2092 2093 /* this memory is freed up in the caller function 2094 * once filters for this VSI are removed 2095 */ 2096 tmp = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*tmp), GFP_KERNEL); 2097 if (!tmp) 2098 return ICE_ERR_NO_MEMORY; 2099 2100 tmp->fltr_info = *fi; 2101 2102 /* Overwrite these fields to indicate which VSI to remove filter from, 2103 * so find and remove logic can extract the information from the 2104 * list entries. Note that original entries will still have proper 2105 * values. 2106 */ 2107 tmp->fltr_info.fltr_act = ICE_FWD_TO_VSI; 2108 tmp->fltr_info.vsi_handle = vsi_handle; 2109 tmp->fltr_info.fwd_id.hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle); 2110 2111 list_add(&tmp->list_entry, vsi_list_head); 2112 2113 return 0; 2114 } 2115 2116 /** 2117 * ice_add_to_vsi_fltr_list - Add VSI filters to the list 2118 * @hw: pointer to the hardware structure 2119 * @vsi_handle: VSI handle to remove filters from 2120 * @lkup_list_head: pointer to the list that has certain lookup type filters 2121 * @vsi_list_head: pointer to the list pertaining to VSI with vsi_handle 2122 * 2123 * Locates all filters in lkup_list_head that are used by the given VSI, 2124 * and adds COPIES of those entries to vsi_list_head (intended to be used 2125 * to remove the listed filters). 2126 * Note that this means all entries in vsi_list_head must be explicitly 2127 * deallocated by the caller when done with list. 2128 */ 2129 static enum ice_status 2130 ice_add_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_handle, 2131 struct list_head *lkup_list_head, 2132 struct list_head *vsi_list_head) 2133 { 2134 struct ice_fltr_mgmt_list_entry *fm_entry; 2135 enum ice_status status = 0; 2136 2137 /* check to make sure VSI id is valid and within boundary */ 2138 if (!ice_is_vsi_valid(hw, vsi_handle)) 2139 return ICE_ERR_PARAM; 2140 2141 list_for_each_entry(fm_entry, lkup_list_head, list_entry) { 2142 struct ice_fltr_info *fi; 2143 2144 fi = &fm_entry->fltr_info; 2145 if (!fi || !ice_vsi_uses_fltr(fm_entry, vsi_handle)) 2146 continue; 2147 2148 status = ice_add_entry_to_vsi_fltr_list(hw, vsi_handle, 2149 vsi_list_head, fi); 2150 if (status) 2151 return status; 2152 } 2153 return status; 2154 } 2155 2156 /** 2157 * ice_remove_vsi_lkup_fltr - Remove lookup type filters for a VSI 2158 * @hw: pointer to the hardware structure 2159 * @vsi_handle: VSI handle to remove filters from 2160 * @lkup: switch rule filter lookup type 2161 */ 2162 static void 2163 ice_remove_vsi_lkup_fltr(struct ice_hw *hw, u16 vsi_handle, 2164 enum ice_sw_lkup_type lkup) 2165 { 2166 struct ice_switch_info *sw = hw->switch_info; 2167 struct ice_fltr_list_entry *fm_entry; 2168 struct list_head remove_list_head; 2169 struct list_head *rule_head; 2170 struct ice_fltr_list_entry *tmp; 2171 struct mutex *rule_lock; /* Lock to protect filter rule list */ 2172 enum ice_status status; 2173 2174 INIT_LIST_HEAD(&remove_list_head); 2175 rule_lock = &sw->recp_list[lkup].filt_rule_lock; 2176 rule_head = &sw->recp_list[lkup].filt_rules; 2177 mutex_lock(rule_lock); 2178 status = ice_add_to_vsi_fltr_list(hw, vsi_handle, rule_head, 2179 &remove_list_head); 2180 mutex_unlock(rule_lock); 2181 if (status) 2182 return; 2183 2184 switch (lkup) { 2185 case ICE_SW_LKUP_MAC: 2186 ice_remove_mac(hw, &remove_list_head); 2187 break; 2188 case ICE_SW_LKUP_VLAN: 2189 ice_remove_vlan(hw, &remove_list_head); 2190 break; 2191 case ICE_SW_LKUP_MAC_VLAN: 2192 case ICE_SW_LKUP_ETHERTYPE: 2193 case ICE_SW_LKUP_ETHERTYPE_MAC: 2194 case ICE_SW_LKUP_PROMISC: 2195 case ICE_SW_LKUP_DFLT: 2196 case ICE_SW_LKUP_PROMISC_VLAN: 2197 case ICE_SW_LKUP_LAST: 2198 default: 2199 ice_debug(hw, ICE_DBG_SW, "Unsupported lookup type %d\n", lkup); 2200 break; 2201 } 2202 2203 list_for_each_entry_safe(fm_entry, tmp, &remove_list_head, list_entry) { 2204 list_del(&fm_entry->list_entry); 2205 devm_kfree(ice_hw_to_dev(hw), fm_entry); 2206 } 2207 } 2208 2209 /** 2210 * ice_remove_vsi_fltr - Remove all filters for a VSI 2211 * @hw: pointer to the hardware structure 2212 * @vsi_handle: VSI handle to remove filters from 2213 */ 2214 void ice_remove_vsi_fltr(struct ice_hw *hw, u16 vsi_handle) 2215 { 2216 ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_MAC); 2217 ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_MAC_VLAN); 2218 ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_PROMISC); 2219 ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_VLAN); 2220 ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_DFLT); 2221 ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_ETHERTYPE); 2222 ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_ETHERTYPE_MAC); 2223 ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_PROMISC_VLAN); 2224 } 2225 2226 /** 2227 * ice_replay_vsi_fltr - Replay filters for requested VSI 2228 * @hw: pointer to the hardware structure 2229 * @vsi_handle: driver VSI handle 2230 * @recp_id: Recipe id for which rules need to be replayed 2231 * @list_head: list for which filters need to be replayed 2232 * 2233 * Replays the filter of recipe recp_id for a VSI represented via vsi_handle. 2234 * It is required to pass valid VSI handle. 2235 */ 2236 static enum ice_status 2237 ice_replay_vsi_fltr(struct ice_hw *hw, u16 vsi_handle, u8 recp_id, 2238 struct list_head *list_head) 2239 { 2240 struct ice_fltr_mgmt_list_entry *itr; 2241 enum ice_status status = 0; 2242 u16 hw_vsi_id; 2243 2244 if (list_empty(list_head)) 2245 return status; 2246 hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle); 2247 2248 list_for_each_entry(itr, list_head, list_entry) { 2249 struct ice_fltr_list_entry f_entry; 2250 2251 f_entry.fltr_info = itr->fltr_info; 2252 if (itr->vsi_count < 2 && recp_id != ICE_SW_LKUP_VLAN && 2253 itr->fltr_info.vsi_handle == vsi_handle) { 2254 /* update the src in case it is vsi num */ 2255 if (f_entry.fltr_info.src_id == ICE_SRC_ID_VSI) 2256 f_entry.fltr_info.src = hw_vsi_id; 2257 status = ice_add_rule_internal(hw, recp_id, &f_entry); 2258 if (status) 2259 goto end; 2260 continue; 2261 } 2262 if (!itr->vsi_list_info || 2263 !test_bit(vsi_handle, itr->vsi_list_info->vsi_map)) 2264 continue; 2265 /* Clearing it so that the logic can add it back */ 2266 clear_bit(vsi_handle, itr->vsi_list_info->vsi_map); 2267 f_entry.fltr_info.vsi_handle = vsi_handle; 2268 f_entry.fltr_info.fltr_act = ICE_FWD_TO_VSI; 2269 /* update the src in case it is vsi num */ 2270 if (f_entry.fltr_info.src_id == ICE_SRC_ID_VSI) 2271 f_entry.fltr_info.src = hw_vsi_id; 2272 if (recp_id == ICE_SW_LKUP_VLAN) 2273 status = ice_add_vlan_internal(hw, &f_entry); 2274 else 2275 status = ice_add_rule_internal(hw, recp_id, &f_entry); 2276 if (status) 2277 goto end; 2278 } 2279 end: 2280 return status; 2281 } 2282 2283 /** 2284 * ice_replay_vsi_all_fltr - replay all filters stored in bookkeeping lists 2285 * @hw: pointer to the hardware structure 2286 * @vsi_handle: driver VSI handle 2287 * 2288 * Replays filters for requested VSI via vsi_handle. 2289 */ 2290 enum ice_status ice_replay_vsi_all_fltr(struct ice_hw *hw, u16 vsi_handle) 2291 { 2292 struct ice_switch_info *sw = hw->switch_info; 2293 enum ice_status status = 0; 2294 u8 i; 2295 2296 for (i = 0; i < ICE_SW_LKUP_LAST; i++) { 2297 struct list_head *head; 2298 2299 head = &sw->recp_list[i].filt_replay_rules; 2300 status = ice_replay_vsi_fltr(hw, vsi_handle, i, head); 2301 if (status) 2302 return status; 2303 } 2304 return status; 2305 } 2306 2307 /** 2308 * ice_rm_all_sw_replay_rule_info - deletes filter replay rules 2309 * @hw: pointer to the hw struct 2310 * 2311 * Deletes the filter replay rules. 2312 */ 2313 void ice_rm_all_sw_replay_rule_info(struct ice_hw *hw) 2314 { 2315 struct ice_switch_info *sw = hw->switch_info; 2316 u8 i; 2317 2318 if (!sw) 2319 return; 2320 2321 for (i = 0; i < ICE_SW_LKUP_LAST; i++) { 2322 if (!list_empty(&sw->recp_list[i].filt_replay_rules)) { 2323 struct list_head *l_head; 2324 2325 l_head = &sw->recp_list[i].filt_replay_rules; 2326 ice_rem_sw_rule_info(hw, l_head); 2327 } 2328 } 2329 } 2330