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