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