1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2001-2021 Intel Corporation 3 */ 4 5 #include "ice_common.h" 6 #include "ice_flex_pipe.h" 7 #include "ice_protocol_type.h" 8 #include "ice_flow.h" 9 10 /* For supporting double VLAN mode, it is necessary to enable or disable certain 11 * boost tcam entries. The metadata labels names that match the following 12 * prefixes will be saved to allow enabling double VLAN mode. 13 */ 14 #define ICE_DVM_PRE "BOOST_MAC_VLAN_DVM" /* enable these entries */ 15 #define ICE_SVM_PRE "BOOST_MAC_VLAN_SVM" /* disable these entries */ 16 17 /* To support tunneling entries by PF, the package will append the PF number to 18 * the label; for example TNL_VXLAN_PF0, TNL_VXLAN_PF1, TNL_VXLAN_PF2, etc. 19 */ 20 #define ICE_TNL_PRE "TNL_" 21 static const struct ice_tunnel_type_scan tnls[] = { 22 { TNL_VXLAN, "TNL_VXLAN_PF" }, 23 { TNL_GENEVE, "TNL_GENEVE_PF" }, 24 { TNL_ECPRI, "TNL_UDP_ECPRI_PF" }, 25 { TNL_LAST, "" } 26 }; 27 28 static const u32 ice_sect_lkup[ICE_BLK_COUNT][ICE_SECT_COUNT] = { 29 /* SWITCH */ 30 { 31 ICE_SID_XLT0_SW, 32 ICE_SID_XLT_KEY_BUILDER_SW, 33 ICE_SID_XLT1_SW, 34 ICE_SID_XLT2_SW, 35 ICE_SID_PROFID_TCAM_SW, 36 ICE_SID_PROFID_REDIR_SW, 37 ICE_SID_FLD_VEC_SW, 38 ICE_SID_CDID_KEY_BUILDER_SW, 39 ICE_SID_CDID_REDIR_SW 40 }, 41 42 /* ACL */ 43 { 44 ICE_SID_XLT0_ACL, 45 ICE_SID_XLT_KEY_BUILDER_ACL, 46 ICE_SID_XLT1_ACL, 47 ICE_SID_XLT2_ACL, 48 ICE_SID_PROFID_TCAM_ACL, 49 ICE_SID_PROFID_REDIR_ACL, 50 ICE_SID_FLD_VEC_ACL, 51 ICE_SID_CDID_KEY_BUILDER_ACL, 52 ICE_SID_CDID_REDIR_ACL 53 }, 54 55 /* FD */ 56 { 57 ICE_SID_XLT0_FD, 58 ICE_SID_XLT_KEY_BUILDER_FD, 59 ICE_SID_XLT1_FD, 60 ICE_SID_XLT2_FD, 61 ICE_SID_PROFID_TCAM_FD, 62 ICE_SID_PROFID_REDIR_FD, 63 ICE_SID_FLD_VEC_FD, 64 ICE_SID_CDID_KEY_BUILDER_FD, 65 ICE_SID_CDID_REDIR_FD 66 }, 67 68 /* RSS */ 69 { 70 ICE_SID_XLT0_RSS, 71 ICE_SID_XLT_KEY_BUILDER_RSS, 72 ICE_SID_XLT1_RSS, 73 ICE_SID_XLT2_RSS, 74 ICE_SID_PROFID_TCAM_RSS, 75 ICE_SID_PROFID_REDIR_RSS, 76 ICE_SID_FLD_VEC_RSS, 77 ICE_SID_CDID_KEY_BUILDER_RSS, 78 ICE_SID_CDID_REDIR_RSS 79 }, 80 81 /* PE */ 82 { 83 ICE_SID_XLT0_PE, 84 ICE_SID_XLT_KEY_BUILDER_PE, 85 ICE_SID_XLT1_PE, 86 ICE_SID_XLT2_PE, 87 ICE_SID_PROFID_TCAM_PE, 88 ICE_SID_PROFID_REDIR_PE, 89 ICE_SID_FLD_VEC_PE, 90 ICE_SID_CDID_KEY_BUILDER_PE, 91 ICE_SID_CDID_REDIR_PE 92 } 93 }; 94 95 /** 96 * ice_sect_id - returns section ID 97 * @blk: block type 98 * @sect: section type 99 * 100 * This helper function returns the proper section ID given a block type and a 101 * section type. 102 */ 103 static u32 ice_sect_id(enum ice_block blk, enum ice_sect sect) 104 { 105 return ice_sect_lkup[blk][sect]; 106 } 107 108 /** 109 * ice_pkg_val_buf 110 * @buf: pointer to the ice buffer 111 * 112 * This helper function validates a buffer's header. 113 */ 114 static struct ice_buf_hdr *ice_pkg_val_buf(struct ice_buf *buf) 115 { 116 struct ice_buf_hdr *hdr; 117 u16 section_count; 118 u16 data_end; 119 120 hdr = (struct ice_buf_hdr *)buf->buf; 121 /* verify data */ 122 section_count = LE16_TO_CPU(hdr->section_count); 123 if (section_count < ICE_MIN_S_COUNT || section_count > ICE_MAX_S_COUNT) 124 return NULL; 125 126 data_end = LE16_TO_CPU(hdr->data_end); 127 if (data_end < ICE_MIN_S_DATA_END || data_end > ICE_MAX_S_DATA_END) 128 return NULL; 129 130 return hdr; 131 } 132 133 /** 134 * ice_find_buf_table 135 * @ice_seg: pointer to the ice segment 136 * 137 * Returns the address of the buffer table within the ice segment. 138 */ 139 static struct ice_buf_table *ice_find_buf_table(struct ice_seg *ice_seg) 140 { 141 struct ice_nvm_table *nvms; 142 143 nvms = (struct ice_nvm_table *) 144 (ice_seg->device_table + 145 LE32_TO_CPU(ice_seg->device_table_count)); 146 147 return (_FORCE_ struct ice_buf_table *) 148 (nvms->vers + LE32_TO_CPU(nvms->table_count)); 149 } 150 151 /** 152 * ice_pkg_enum_buf 153 * @ice_seg: pointer to the ice segment (or NULL on subsequent calls) 154 * @state: pointer to the enum state 155 * 156 * This function will enumerate all the buffers in the ice segment. The first 157 * call is made with the ice_seg parameter non-NULL; on subsequent calls, 158 * ice_seg is set to NULL which continues the enumeration. When the function 159 * returns a NULL pointer, then the end of the buffers has been reached, or an 160 * unexpected value has been detected (for example an invalid section count or 161 * an invalid buffer end value). 162 */ 163 static struct ice_buf_hdr * 164 ice_pkg_enum_buf(struct ice_seg *ice_seg, struct ice_pkg_enum *state) 165 { 166 if (ice_seg) { 167 state->buf_table = ice_find_buf_table(ice_seg); 168 if (!state->buf_table) 169 return NULL; 170 171 state->buf_idx = 0; 172 return ice_pkg_val_buf(state->buf_table->buf_array); 173 } 174 175 if (++state->buf_idx < LE32_TO_CPU(state->buf_table->buf_count)) 176 return ice_pkg_val_buf(state->buf_table->buf_array + 177 state->buf_idx); 178 else 179 return NULL; 180 } 181 182 /** 183 * ice_pkg_advance_sect 184 * @ice_seg: pointer to the ice segment (or NULL on subsequent calls) 185 * @state: pointer to the enum state 186 * 187 * This helper function will advance the section within the ice segment, 188 * also advancing the buffer if needed. 189 */ 190 static bool 191 ice_pkg_advance_sect(struct ice_seg *ice_seg, struct ice_pkg_enum *state) 192 { 193 if (!ice_seg && !state->buf) 194 return false; 195 196 if (!ice_seg && state->buf) 197 if (++state->sect_idx < LE16_TO_CPU(state->buf->section_count)) 198 return true; 199 200 state->buf = ice_pkg_enum_buf(ice_seg, state); 201 if (!state->buf) 202 return false; 203 204 /* start of new buffer, reset section index */ 205 state->sect_idx = 0; 206 return true; 207 } 208 209 /** 210 * ice_pkg_enum_section 211 * @ice_seg: pointer to the ice segment (or NULL on subsequent calls) 212 * @state: pointer to the enum state 213 * @sect_type: section type to enumerate 214 * 215 * This function will enumerate all the sections of a particular type in the 216 * ice segment. The first call is made with the ice_seg parameter non-NULL; 217 * on subsequent calls, ice_seg is set to NULL which continues the enumeration. 218 * When the function returns a NULL pointer, then the end of the matching 219 * sections has been reached. 220 */ 221 void * 222 ice_pkg_enum_section(struct ice_seg *ice_seg, struct ice_pkg_enum *state, 223 u32 sect_type) 224 { 225 u16 offset, size; 226 227 if (ice_seg) 228 state->type = sect_type; 229 230 if (!ice_pkg_advance_sect(ice_seg, state)) 231 return NULL; 232 233 /* scan for next matching section */ 234 while (state->buf->section_entry[state->sect_idx].type != 235 CPU_TO_LE32(state->type)) 236 if (!ice_pkg_advance_sect(NULL, state)) 237 return NULL; 238 239 /* validate section */ 240 offset = LE16_TO_CPU(state->buf->section_entry[state->sect_idx].offset); 241 if (offset < ICE_MIN_S_OFF || offset > ICE_MAX_S_OFF) 242 return NULL; 243 244 size = LE16_TO_CPU(state->buf->section_entry[state->sect_idx].size); 245 if (size < ICE_MIN_S_SZ || size > ICE_MAX_S_SZ) 246 return NULL; 247 248 /* make sure the section fits in the buffer */ 249 if (offset + size > ICE_PKG_BUF_SIZE) 250 return NULL; 251 252 state->sect_type = 253 LE32_TO_CPU(state->buf->section_entry[state->sect_idx].type); 254 255 /* calc pointer to this section */ 256 state->sect = ((u8 *)state->buf) + 257 LE16_TO_CPU(state->buf->section_entry[state->sect_idx].offset); 258 259 return state->sect; 260 } 261 262 /** 263 * ice_pkg_enum_entry 264 * @ice_seg: pointer to the ice segment (or NULL on subsequent calls) 265 * @state: pointer to the enum state 266 * @sect_type: section type to enumerate 267 * @offset: pointer to variable that receives the offset in the table (optional) 268 * @handler: function that handles access to the entries into the section type 269 * 270 * This function will enumerate all the entries in particular section type in 271 * the ice segment. The first call is made with the ice_seg parameter non-NULL; 272 * on subsequent calls, ice_seg is set to NULL which continues the enumeration. 273 * When the function returns a NULL pointer, then the end of the entries has 274 * been reached. 275 * 276 * Since each section may have a different header and entry size, the handler 277 * function is needed to determine the number and location entries in each 278 * section. 279 * 280 * The offset parameter is optional, but should be used for sections that 281 * contain an offset for each section table. For such cases, the section handler 282 * function must return the appropriate offset + index to give the absolution 283 * offset for each entry. For example, if the base for a section's header 284 * indicates a base offset of 10, and the index for the entry is 2, then 285 * section handler function should set the offset to 10 + 2 = 12. 286 */ 287 void * 288 ice_pkg_enum_entry(struct ice_seg *ice_seg, struct ice_pkg_enum *state, 289 u32 sect_type, u32 *offset, 290 void *(*handler)(u32 sect_type, void *section, 291 u32 index, u32 *offset)) 292 { 293 void *entry; 294 295 if (ice_seg) { 296 if (!handler) 297 return NULL; 298 299 if (!ice_pkg_enum_section(ice_seg, state, sect_type)) 300 return NULL; 301 302 state->entry_idx = 0; 303 state->handler = handler; 304 } else { 305 state->entry_idx++; 306 } 307 308 if (!state->handler) 309 return NULL; 310 311 /* get entry */ 312 entry = state->handler(state->sect_type, state->sect, state->entry_idx, 313 offset); 314 if (!entry) { 315 /* end of a section, look for another section of this type */ 316 if (!ice_pkg_enum_section(NULL, state, 0)) 317 return NULL; 318 319 state->entry_idx = 0; 320 entry = state->handler(state->sect_type, state->sect, 321 state->entry_idx, offset); 322 } 323 324 return entry; 325 } 326 327 /** 328 * ice_hw_ptype_ena - check if the PTYPE is enabled or not 329 * @hw: pointer to the HW structure 330 * @ptype: the hardware PTYPE 331 */ 332 bool ice_hw_ptype_ena(struct ice_hw *hw, u16 ptype) 333 { 334 return ptype < ICE_FLOW_PTYPE_MAX && 335 ice_is_bit_set(hw->hw_ptype, ptype); 336 } 337 338 /** 339 * ice_marker_ptype_tcam_handler 340 * @sect_type: section type 341 * @section: pointer to section 342 * @index: index of the Marker PType TCAM entry to be returned 343 * @offset: pointer to receive absolute offset, always 0 for ptype TCAM sections 344 * 345 * This is a callback function that can be passed to ice_pkg_enum_entry. 346 * Handles enumeration of individual Marker PType TCAM entries. 347 */ 348 static void * 349 ice_marker_ptype_tcam_handler(u32 sect_type, void *section, u32 index, 350 u32 *offset) 351 { 352 struct ice_marker_ptype_tcam_section *marker_ptype; 353 354 if (!section) 355 return NULL; 356 357 if (sect_type != ICE_SID_RXPARSER_MARKER_PTYPE) 358 return NULL; 359 360 if (index > ICE_MAX_MARKER_PTYPE_TCAMS_IN_BUF) 361 return NULL; 362 363 if (offset) 364 *offset = 0; 365 366 marker_ptype = (struct ice_marker_ptype_tcam_section *)section; 367 if (index >= LE16_TO_CPU(marker_ptype->count)) 368 return NULL; 369 370 return marker_ptype->tcam + index; 371 } 372 373 /** 374 * ice_fill_hw_ptype - fill the enabled PTYPE bit information 375 * @hw: pointer to the HW structure 376 */ 377 static void 378 ice_fill_hw_ptype(struct ice_hw *hw) 379 { 380 struct ice_marker_ptype_tcam_entry *tcam; 381 struct ice_seg *seg = hw->seg; 382 struct ice_pkg_enum state; 383 384 ice_zero_bitmap(hw->hw_ptype, ICE_FLOW_PTYPE_MAX); 385 if (!seg) 386 return; 387 388 ice_memset(&state, 0, sizeof(state), ICE_NONDMA_MEM); 389 390 do { 391 tcam = (struct ice_marker_ptype_tcam_entry *) 392 ice_pkg_enum_entry(seg, &state, 393 ICE_SID_RXPARSER_MARKER_PTYPE, NULL, 394 ice_marker_ptype_tcam_handler); 395 if (tcam && 396 LE16_TO_CPU(tcam->addr) < ICE_MARKER_PTYPE_TCAM_ADDR_MAX && 397 LE16_TO_CPU(tcam->ptype) < ICE_FLOW_PTYPE_MAX) 398 ice_set_bit(LE16_TO_CPU(tcam->ptype), hw->hw_ptype); 399 400 seg = NULL; 401 } while (tcam); 402 } 403 404 /** 405 * ice_boost_tcam_handler 406 * @sect_type: section type 407 * @section: pointer to section 408 * @index: index of the boost TCAM entry to be returned 409 * @offset: pointer to receive absolute offset, always 0 for boost TCAM sections 410 * 411 * This is a callback function that can be passed to ice_pkg_enum_entry. 412 * Handles enumeration of individual boost TCAM entries. 413 */ 414 static void * 415 ice_boost_tcam_handler(u32 sect_type, void *section, u32 index, u32 *offset) 416 { 417 struct ice_boost_tcam_section *boost; 418 419 if (!section) 420 return NULL; 421 422 if (sect_type != ICE_SID_RXPARSER_BOOST_TCAM) 423 return NULL; 424 425 if (index > ICE_MAX_BST_TCAMS_IN_BUF) 426 return NULL; 427 428 if (offset) 429 *offset = 0; 430 431 boost = (struct ice_boost_tcam_section *)section; 432 if (index >= LE16_TO_CPU(boost->count)) 433 return NULL; 434 435 return boost->tcam + index; 436 } 437 438 /** 439 * ice_find_boost_entry 440 * @ice_seg: pointer to the ice segment (non-NULL) 441 * @addr: Boost TCAM address of entry to search for 442 * @entry: returns pointer to the entry 443 * 444 * Finds a particular Boost TCAM entry and returns a pointer to that entry 445 * if it is found. The ice_seg parameter must not be NULL since the first call 446 * to ice_pkg_enum_entry requires a pointer to an actual ice_segment structure. 447 */ 448 static enum ice_status 449 ice_find_boost_entry(struct ice_seg *ice_seg, u16 addr, 450 struct ice_boost_tcam_entry **entry) 451 { 452 struct ice_boost_tcam_entry *tcam; 453 struct ice_pkg_enum state; 454 455 ice_memset(&state, 0, sizeof(state), ICE_NONDMA_MEM); 456 457 if (!ice_seg) 458 return ICE_ERR_PARAM; 459 460 do { 461 tcam = (struct ice_boost_tcam_entry *) 462 ice_pkg_enum_entry(ice_seg, &state, 463 ICE_SID_RXPARSER_BOOST_TCAM, NULL, 464 ice_boost_tcam_handler); 465 if (tcam && LE16_TO_CPU(tcam->addr) == addr) { 466 *entry = tcam; 467 return ICE_SUCCESS; 468 } 469 470 ice_seg = NULL; 471 } while (tcam); 472 473 *entry = NULL; 474 return ICE_ERR_CFG; 475 } 476 477 /** 478 * ice_label_enum_handler 479 * @sect_type: section type 480 * @section: pointer to section 481 * @index: index of the label entry to be returned 482 * @offset: pointer to receive absolute offset, always zero for label sections 483 * 484 * This is a callback function that can be passed to ice_pkg_enum_entry. 485 * Handles enumeration of individual label entries. 486 */ 487 static void * 488 ice_label_enum_handler(u32 __ALWAYS_UNUSED sect_type, void *section, u32 index, 489 u32 *offset) 490 { 491 struct ice_label_section *labels; 492 493 if (!section) 494 return NULL; 495 496 if (index > ICE_MAX_LABELS_IN_BUF) 497 return NULL; 498 499 if (offset) 500 *offset = 0; 501 502 labels = (struct ice_label_section *)section; 503 if (index >= LE16_TO_CPU(labels->count)) 504 return NULL; 505 506 return labels->label + index; 507 } 508 509 /** 510 * ice_enum_labels 511 * @ice_seg: pointer to the ice segment (NULL on subsequent calls) 512 * @type: the section type that will contain the label (0 on subsequent calls) 513 * @state: ice_pkg_enum structure that will hold the state of the enumeration 514 * @value: pointer to a value that will return the label's value if found 515 * 516 * Enumerates a list of labels in the package. The caller will call 517 * ice_enum_labels(ice_seg, type, ...) to start the enumeration, then call 518 * ice_enum_labels(NULL, 0, ...) to continue. When the function returns a NULL 519 * the end of the list has been reached. 520 */ 521 static char * 522 ice_enum_labels(struct ice_seg *ice_seg, u32 type, struct ice_pkg_enum *state, 523 u16 *value) 524 { 525 struct ice_label *label; 526 527 /* Check for valid label section on first call */ 528 if (type && !(type >= ICE_SID_LBL_FIRST && type <= ICE_SID_LBL_LAST)) 529 return NULL; 530 531 label = (struct ice_label *)ice_pkg_enum_entry(ice_seg, state, type, 532 NULL, 533 ice_label_enum_handler); 534 if (!label) 535 return NULL; 536 537 *value = LE16_TO_CPU(label->value); 538 return label->name; 539 } 540 541 /** 542 * ice_add_tunnel_hint 543 * @hw: pointer to the HW structure 544 * @label_name: label text 545 * @val: value of the tunnel port boost entry 546 */ 547 static void ice_add_tunnel_hint(struct ice_hw *hw, char *label_name, u16 val) 548 { 549 if (hw->tnl.count < ICE_TUNNEL_MAX_ENTRIES) { 550 u16 i; 551 552 for (i = 0; tnls[i].type != TNL_LAST; i++) { 553 size_t len = strlen(tnls[i].label_prefix); 554 555 /* Look for matching label start, before continuing */ 556 if (strncmp(label_name, tnls[i].label_prefix, len)) 557 continue; 558 559 /* Make sure this label matches our PF. Note that the PF 560 * character ('0' - '7') will be located where our 561 * prefix string's null terminator is located. 562 */ 563 if ((label_name[len] - '0') == hw->pf_id) { 564 hw->tnl.tbl[hw->tnl.count].type = tnls[i].type; 565 hw->tnl.tbl[hw->tnl.count].valid = false; 566 hw->tnl.tbl[hw->tnl.count].in_use = false; 567 hw->tnl.tbl[hw->tnl.count].marked = false; 568 hw->tnl.tbl[hw->tnl.count].boost_addr = val; 569 hw->tnl.tbl[hw->tnl.count].port = 0; 570 hw->tnl.count++; 571 break; 572 } 573 } 574 } 575 } 576 577 /** 578 * ice_add_dvm_hint 579 * @hw: pointer to the HW structure 580 * @val: value of the boost entry 581 * @enable: true if entry needs to be enabled, or false if needs to be disabled 582 */ 583 static void ice_add_dvm_hint(struct ice_hw *hw, u16 val, bool enable) 584 { 585 if (hw->dvm_upd.count < ICE_DVM_MAX_ENTRIES) { 586 hw->dvm_upd.tbl[hw->dvm_upd.count].boost_addr = val; 587 hw->dvm_upd.tbl[hw->dvm_upd.count].enable = enable; 588 hw->dvm_upd.count++; 589 } 590 } 591 592 /** 593 * ice_init_pkg_hints 594 * @hw: pointer to the HW structure 595 * @ice_seg: pointer to the segment of the package scan (non-NULL) 596 * 597 * This function will scan the package and save off relevant information 598 * (hints or metadata) for driver use. The ice_seg parameter must not be NULL 599 * since the first call to ice_enum_labels requires a pointer to an actual 600 * ice_seg structure. 601 */ 602 static void ice_init_pkg_hints(struct ice_hw *hw, struct ice_seg *ice_seg) 603 { 604 struct ice_pkg_enum state; 605 char *label_name; 606 u16 val; 607 int i; 608 609 ice_memset(&hw->tnl, 0, sizeof(hw->tnl), ICE_NONDMA_MEM); 610 ice_memset(&state, 0, sizeof(state), ICE_NONDMA_MEM); 611 612 if (!ice_seg) 613 return; 614 615 label_name = ice_enum_labels(ice_seg, ICE_SID_LBL_RXPARSER_TMEM, &state, 616 &val); 617 618 while (label_name) { 619 if (!strncmp(label_name, ICE_TNL_PRE, strlen(ICE_TNL_PRE))) 620 /* check for a tunnel entry */ 621 ice_add_tunnel_hint(hw, label_name, val); 622 623 /* check for a dvm mode entry */ 624 else if (!strncmp(label_name, ICE_DVM_PRE, strlen(ICE_DVM_PRE))) 625 ice_add_dvm_hint(hw, val, true); 626 627 /* check for a svm mode entry */ 628 else if (!strncmp(label_name, ICE_SVM_PRE, strlen(ICE_SVM_PRE))) 629 ice_add_dvm_hint(hw, val, false); 630 631 label_name = ice_enum_labels(NULL, 0, &state, &val); 632 } 633 634 /* Cache the appropriate boost TCAM entry pointers for tunnels */ 635 for (i = 0; i < hw->tnl.count; i++) { 636 ice_find_boost_entry(ice_seg, hw->tnl.tbl[i].boost_addr, 637 &hw->tnl.tbl[i].boost_entry); 638 if (hw->tnl.tbl[i].boost_entry) 639 hw->tnl.tbl[i].valid = true; 640 } 641 642 /* Cache the appropriate boost TCAM entry pointers for DVM and SVM */ 643 for (i = 0; i < hw->dvm_upd.count; i++) 644 ice_find_boost_entry(ice_seg, hw->dvm_upd.tbl[i].boost_addr, 645 &hw->dvm_upd.tbl[i].boost_entry); 646 } 647 648 /* Key creation */ 649 650 #define ICE_DC_KEY 0x1 /* don't care */ 651 #define ICE_DC_KEYINV 0x1 652 #define ICE_NM_KEY 0x0 /* never match */ 653 #define ICE_NM_KEYINV 0x0 654 #define ICE_0_KEY 0x1 /* match 0 */ 655 #define ICE_0_KEYINV 0x0 656 #define ICE_1_KEY 0x0 /* match 1 */ 657 #define ICE_1_KEYINV 0x1 658 659 /** 660 * ice_gen_key_word - generate 16-bits of a key/mask word 661 * @val: the value 662 * @valid: valid bits mask (change only the valid bits) 663 * @dont_care: don't care mask 664 * @nvr_mtch: never match mask 665 * @key: pointer to an array of where the resulting key portion 666 * @key_inv: pointer to an array of where the resulting key invert portion 667 * 668 * This function generates 16-bits from a 8-bit value, an 8-bit don't care mask 669 * and an 8-bit never match mask. The 16-bits of output are divided into 8 bits 670 * of key and 8 bits of key invert. 671 * 672 * '0' = b01, always match a 0 bit 673 * '1' = b10, always match a 1 bit 674 * '?' = b11, don't care bit (always matches) 675 * '~' = b00, never match bit 676 * 677 * Input: 678 * val: b0 1 0 1 0 1 679 * dont_care: b0 0 1 1 0 0 680 * never_mtch: b0 0 0 0 1 1 681 * ------------------------------ 682 * Result: key: b01 10 11 11 00 00 683 */ 684 static enum ice_status 685 ice_gen_key_word(u8 val, u8 valid, u8 dont_care, u8 nvr_mtch, u8 *key, 686 u8 *key_inv) 687 { 688 u8 in_key = *key, in_key_inv = *key_inv; 689 u8 i; 690 691 /* 'dont_care' and 'nvr_mtch' masks cannot overlap */ 692 if ((dont_care ^ nvr_mtch) != (dont_care | nvr_mtch)) 693 return ICE_ERR_CFG; 694 695 *key = 0; 696 *key_inv = 0; 697 698 /* encode the 8 bits into 8-bit key and 8-bit key invert */ 699 for (i = 0; i < 8; i++) { 700 *key >>= 1; 701 *key_inv >>= 1; 702 703 if (!(valid & 0x1)) { /* change only valid bits */ 704 *key |= (in_key & 0x1) << 7; 705 *key_inv |= (in_key_inv & 0x1) << 7; 706 } else if (dont_care & 0x1) { /* don't care bit */ 707 *key |= ICE_DC_KEY << 7; 708 *key_inv |= ICE_DC_KEYINV << 7; 709 } else if (nvr_mtch & 0x1) { /* never match bit */ 710 *key |= ICE_NM_KEY << 7; 711 *key_inv |= ICE_NM_KEYINV << 7; 712 } else if (val & 0x01) { /* exact 1 match */ 713 *key |= ICE_1_KEY << 7; 714 *key_inv |= ICE_1_KEYINV << 7; 715 } else { /* exact 0 match */ 716 *key |= ICE_0_KEY << 7; 717 *key_inv |= ICE_0_KEYINV << 7; 718 } 719 720 dont_care >>= 1; 721 nvr_mtch >>= 1; 722 valid >>= 1; 723 val >>= 1; 724 in_key >>= 1; 725 in_key_inv >>= 1; 726 } 727 728 return ICE_SUCCESS; 729 } 730 731 /** 732 * ice_bits_max_set - determine if the number of bits set is within a maximum 733 * @mask: pointer to the byte array which is the mask 734 * @size: the number of bytes in the mask 735 * @max: the max number of set bits 736 * 737 * This function determines if there are at most 'max' number of bits set in an 738 * array. Returns true if the number for bits set is <= max or will return false 739 * otherwise. 740 */ 741 static bool ice_bits_max_set(const u8 *mask, u16 size, u16 max) 742 { 743 u16 count = 0; 744 u16 i; 745 746 /* check each byte */ 747 for (i = 0; i < size; i++) { 748 /* if 0, go to next byte */ 749 if (!mask[i]) 750 continue; 751 752 /* We know there is at least one set bit in this byte because of 753 * the above check; if we already have found 'max' number of 754 * bits set, then we can return failure now. 755 */ 756 if (count == max) 757 return false; 758 759 /* count the bits in this byte, checking threshold */ 760 count += ice_hweight8(mask[i]); 761 if (count > max) 762 return false; 763 } 764 765 return true; 766 } 767 768 /** 769 * ice_set_key - generate a variable sized key with multiples of 16-bits 770 * @key: pointer to where the key will be stored 771 * @size: the size of the complete key in bytes (must be even) 772 * @val: array of 8-bit values that makes up the value portion of the key 773 * @upd: array of 8-bit masks that determine what key portion to update 774 * @dc: array of 8-bit masks that make up the don't care mask 775 * @nm: array of 8-bit masks that make up the never match mask 776 * @off: the offset of the first byte in the key to update 777 * @len: the number of bytes in the key update 778 * 779 * This function generates a key from a value, a don't care mask and a never 780 * match mask. 781 * upd, dc, and nm are optional parameters, and can be NULL: 782 * upd == NULL --> upd mask is all 1's (update all bits) 783 * dc == NULL --> dc mask is all 0's (no don't care bits) 784 * nm == NULL --> nm mask is all 0's (no never match bits) 785 */ 786 enum ice_status 787 ice_set_key(u8 *key, u16 size, u8 *val, u8 *upd, u8 *dc, u8 *nm, u16 off, 788 u16 len) 789 { 790 u16 half_size; 791 u16 i; 792 793 /* size must be a multiple of 2 bytes. */ 794 if (size % 2) 795 return ICE_ERR_CFG; 796 half_size = size / 2; 797 798 if (off + len > half_size) 799 return ICE_ERR_CFG; 800 801 /* Make sure at most one bit is set in the never match mask. Having more 802 * than one never match mask bit set will cause HW to consume excessive 803 * power otherwise; this is a power management efficiency check. 804 */ 805 #define ICE_NVR_MTCH_BITS_MAX 1 806 if (nm && !ice_bits_max_set(nm, len, ICE_NVR_MTCH_BITS_MAX)) 807 return ICE_ERR_CFG; 808 809 for (i = 0; i < len; i++) 810 if (ice_gen_key_word(val[i], upd ? upd[i] : 0xff, 811 dc ? dc[i] : 0, nm ? nm[i] : 0, 812 key + off + i, key + half_size + off + i)) 813 return ICE_ERR_CFG; 814 815 return ICE_SUCCESS; 816 } 817 818 /** 819 * ice_acquire_global_cfg_lock 820 * @hw: pointer to the HW structure 821 * @access: access type (read or write) 822 * 823 * This function will request ownership of the global config lock for reading 824 * or writing of the package. When attempting to obtain write access, the 825 * caller must check for the following two return values: 826 * 827 * ICE_SUCCESS - Means the caller has acquired the global config lock 828 * and can perform writing of the package. 829 * ICE_ERR_AQ_NO_WORK - Indicates another driver has already written the 830 * package or has found that no update was necessary; in 831 * this case, the caller can just skip performing any 832 * update of the package. 833 */ 834 static enum ice_status 835 ice_acquire_global_cfg_lock(struct ice_hw *hw, 836 enum ice_aq_res_access_type access) 837 { 838 enum ice_status status; 839 840 ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__); 841 842 status = ice_acquire_res(hw, ICE_GLOBAL_CFG_LOCK_RES_ID, access, 843 ICE_GLOBAL_CFG_LOCK_TIMEOUT); 844 845 if (status == ICE_ERR_AQ_NO_WORK) 846 ice_debug(hw, ICE_DBG_PKG, "Global config lock: No work to do\n"); 847 848 return status; 849 } 850 851 /** 852 * ice_release_global_cfg_lock 853 * @hw: pointer to the HW structure 854 * 855 * This function will release the global config lock. 856 */ 857 static void ice_release_global_cfg_lock(struct ice_hw *hw) 858 { 859 ice_release_res(hw, ICE_GLOBAL_CFG_LOCK_RES_ID); 860 } 861 862 /** 863 * ice_acquire_change_lock 864 * @hw: pointer to the HW structure 865 * @access: access type (read or write) 866 * 867 * This function will request ownership of the change lock. 868 */ 869 enum ice_status 870 ice_acquire_change_lock(struct ice_hw *hw, enum ice_aq_res_access_type access) 871 { 872 ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__); 873 874 return ice_acquire_res(hw, ICE_CHANGE_LOCK_RES_ID, access, 875 ICE_CHANGE_LOCK_TIMEOUT); 876 } 877 878 /** 879 * ice_release_change_lock 880 * @hw: pointer to the HW structure 881 * 882 * This function will release the change lock using the proper Admin Command. 883 */ 884 void ice_release_change_lock(struct ice_hw *hw) 885 { 886 ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__); 887 888 ice_release_res(hw, ICE_CHANGE_LOCK_RES_ID); 889 } 890 891 /** 892 * ice_aq_download_pkg 893 * @hw: pointer to the hardware structure 894 * @pkg_buf: the package buffer to transfer 895 * @buf_size: the size of the package buffer 896 * @last_buf: last buffer indicator 897 * @error_offset: returns error offset 898 * @error_info: returns error information 899 * @cd: pointer to command details structure or NULL 900 * 901 * Download Package (0x0C40) 902 */ 903 static enum ice_status 904 ice_aq_download_pkg(struct ice_hw *hw, struct ice_buf_hdr *pkg_buf, 905 u16 buf_size, bool last_buf, u32 *error_offset, 906 u32 *error_info, struct ice_sq_cd *cd) 907 { 908 struct ice_aqc_download_pkg *cmd; 909 struct ice_aq_desc desc; 910 enum ice_status status; 911 912 ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__); 913 914 if (error_offset) 915 *error_offset = 0; 916 if (error_info) 917 *error_info = 0; 918 919 cmd = &desc.params.download_pkg; 920 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_download_pkg); 921 desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD); 922 923 if (last_buf) 924 cmd->flags |= ICE_AQC_DOWNLOAD_PKG_LAST_BUF; 925 926 status = ice_aq_send_cmd(hw, &desc, pkg_buf, buf_size, cd); 927 if (status == ICE_ERR_AQ_ERROR) { 928 /* Read error from buffer only when the FW returned an error */ 929 struct ice_aqc_download_pkg_resp *resp; 930 931 resp = (struct ice_aqc_download_pkg_resp *)pkg_buf; 932 if (error_offset) 933 *error_offset = LE32_TO_CPU(resp->error_offset); 934 if (error_info) 935 *error_info = LE32_TO_CPU(resp->error_info); 936 } 937 938 return status; 939 } 940 941 /** 942 * ice_aq_upload_section 943 * @hw: pointer to the hardware structure 944 * @pkg_buf: the package buffer which will receive the section 945 * @buf_size: the size of the package buffer 946 * @cd: pointer to command details structure or NULL 947 * 948 * Upload Section (0x0C41) 949 */ 950 enum ice_status 951 ice_aq_upload_section(struct ice_hw *hw, struct ice_buf_hdr *pkg_buf, 952 u16 buf_size, struct ice_sq_cd *cd) 953 { 954 struct ice_aq_desc desc; 955 956 ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__); 957 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_upload_section); 958 desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD); 959 960 return ice_aq_send_cmd(hw, &desc, pkg_buf, buf_size, cd); 961 } 962 963 /** 964 * ice_aq_update_pkg 965 * @hw: pointer to the hardware structure 966 * @pkg_buf: the package cmd buffer 967 * @buf_size: the size of the package cmd buffer 968 * @last_buf: last buffer indicator 969 * @error_offset: returns error offset 970 * @error_info: returns error information 971 * @cd: pointer to command details structure or NULL 972 * 973 * Update Package (0x0C42) 974 */ 975 static enum ice_status 976 ice_aq_update_pkg(struct ice_hw *hw, struct ice_buf_hdr *pkg_buf, u16 buf_size, 977 bool last_buf, u32 *error_offset, u32 *error_info, 978 struct ice_sq_cd *cd) 979 { 980 struct ice_aqc_download_pkg *cmd; 981 struct ice_aq_desc desc; 982 enum ice_status status; 983 984 ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__); 985 986 if (error_offset) 987 *error_offset = 0; 988 if (error_info) 989 *error_info = 0; 990 991 cmd = &desc.params.download_pkg; 992 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_update_pkg); 993 desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD); 994 995 if (last_buf) 996 cmd->flags |= ICE_AQC_DOWNLOAD_PKG_LAST_BUF; 997 998 status = ice_aq_send_cmd(hw, &desc, pkg_buf, buf_size, cd); 999 if (status == ICE_ERR_AQ_ERROR) { 1000 /* Read error from buffer only when the FW returned an error */ 1001 struct ice_aqc_download_pkg_resp *resp; 1002 1003 resp = (struct ice_aqc_download_pkg_resp *)pkg_buf; 1004 if (error_offset) 1005 *error_offset = LE32_TO_CPU(resp->error_offset); 1006 if (error_info) 1007 *error_info = LE32_TO_CPU(resp->error_info); 1008 } 1009 1010 return status; 1011 } 1012 1013 /** 1014 * ice_find_seg_in_pkg 1015 * @hw: pointer to the hardware structure 1016 * @seg_type: the segment type to search for (i.e., SEGMENT_TYPE_CPK) 1017 * @pkg_hdr: pointer to the package header to be searched 1018 * 1019 * This function searches a package file for a particular segment type. On 1020 * success it returns a pointer to the segment header, otherwise it will 1021 * return NULL. 1022 */ 1023 static struct ice_generic_seg_hdr * 1024 ice_find_seg_in_pkg(struct ice_hw *hw, u32 seg_type, 1025 struct ice_pkg_hdr *pkg_hdr) 1026 { 1027 u32 i; 1028 1029 ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__); 1030 ice_debug(hw, ICE_DBG_PKG, "Package format version: %d.%d.%d.%d\n", 1031 pkg_hdr->pkg_format_ver.major, pkg_hdr->pkg_format_ver.minor, 1032 pkg_hdr->pkg_format_ver.update, 1033 pkg_hdr->pkg_format_ver.draft); 1034 1035 /* Search all package segments for the requested segment type */ 1036 for (i = 0; i < LE32_TO_CPU(pkg_hdr->seg_count); i++) { 1037 struct ice_generic_seg_hdr *seg; 1038 1039 seg = (struct ice_generic_seg_hdr *) 1040 ((u8 *)pkg_hdr + LE32_TO_CPU(pkg_hdr->seg_offset[i])); 1041 1042 if (LE32_TO_CPU(seg->seg_type) == seg_type) 1043 return seg; 1044 } 1045 1046 return NULL; 1047 } 1048 1049 /** 1050 * ice_update_pkg_no_lock 1051 * @hw: pointer to the hardware structure 1052 * @bufs: pointer to an array of buffers 1053 * @count: the number of buffers in the array 1054 */ 1055 static enum ice_status 1056 ice_update_pkg_no_lock(struct ice_hw *hw, struct ice_buf *bufs, u32 count) 1057 { 1058 enum ice_status status = ICE_SUCCESS; 1059 u32 i; 1060 1061 for (i = 0; i < count; i++) { 1062 struct ice_buf_hdr *bh = (struct ice_buf_hdr *)(bufs + i); 1063 bool last = ((i + 1) == count); 1064 u32 offset, info; 1065 1066 status = ice_aq_update_pkg(hw, bh, LE16_TO_CPU(bh->data_end), 1067 last, &offset, &info, NULL); 1068 1069 if (status) { 1070 ice_debug(hw, ICE_DBG_PKG, "Update pkg failed: err %d off %d inf %d\n", 1071 status, offset, info); 1072 break; 1073 } 1074 } 1075 1076 return status; 1077 } 1078 1079 /** 1080 * ice_update_pkg 1081 * @hw: pointer to the hardware structure 1082 * @bufs: pointer to an array of buffers 1083 * @count: the number of buffers in the array 1084 * 1085 * Obtains change lock and updates package. 1086 */ 1087 enum ice_status 1088 ice_update_pkg(struct ice_hw *hw, struct ice_buf *bufs, u32 count) 1089 { 1090 enum ice_status status; 1091 1092 status = ice_acquire_change_lock(hw, ICE_RES_WRITE); 1093 if (status) 1094 return status; 1095 1096 status = ice_update_pkg_no_lock(hw, bufs, count); 1097 1098 ice_release_change_lock(hw); 1099 1100 return status; 1101 } 1102 1103 /** 1104 * ice_dwnld_cfg_bufs 1105 * @hw: pointer to the hardware structure 1106 * @bufs: pointer to an array of buffers 1107 * @count: the number of buffers in the array 1108 * 1109 * Obtains global config lock and downloads the package configuration buffers 1110 * to the firmware. Metadata buffers are skipped, and the first metadata buffer 1111 * found indicates that the rest of the buffers are all metadata buffers. 1112 */ 1113 static enum ice_status 1114 ice_dwnld_cfg_bufs(struct ice_hw *hw, struct ice_buf *bufs, u32 count) 1115 { 1116 enum ice_status status; 1117 struct ice_buf_hdr *bh; 1118 u32 offset, info, i; 1119 1120 if (!bufs || !count) 1121 return ICE_ERR_PARAM; 1122 1123 /* If the first buffer's first section has its metadata bit set 1124 * then there are no buffers to be downloaded, and the operation is 1125 * considered a success. 1126 */ 1127 bh = (struct ice_buf_hdr *)bufs; 1128 if (LE32_TO_CPU(bh->section_entry[0].type) & ICE_METADATA_BUF) 1129 return ICE_SUCCESS; 1130 1131 /* reset pkg_dwnld_status in case this function is called in the 1132 * reset/rebuild flow 1133 */ 1134 hw->pkg_dwnld_status = ICE_AQ_RC_OK; 1135 1136 status = ice_acquire_global_cfg_lock(hw, ICE_RES_WRITE); 1137 if (status) { 1138 if (status == ICE_ERR_AQ_NO_WORK) 1139 hw->pkg_dwnld_status = ICE_AQ_RC_EEXIST; 1140 else 1141 hw->pkg_dwnld_status = hw->adminq.sq_last_status; 1142 return status; 1143 } 1144 1145 for (i = 0; i < count; i++) { 1146 bool last = ((i + 1) == count); 1147 1148 if (!last) { 1149 /* check next buffer for metadata flag */ 1150 bh = (struct ice_buf_hdr *)(bufs + i + 1); 1151 1152 /* A set metadata flag in the next buffer will signal 1153 * that the current buffer will be the last buffer 1154 * downloaded 1155 */ 1156 if (LE16_TO_CPU(bh->section_count)) 1157 if (LE32_TO_CPU(bh->section_entry[0].type) & 1158 ICE_METADATA_BUF) 1159 last = true; 1160 } 1161 1162 bh = (struct ice_buf_hdr *)(bufs + i); 1163 1164 status = ice_aq_download_pkg(hw, bh, ICE_PKG_BUF_SIZE, last, 1165 &offset, &info, NULL); 1166 1167 /* Save AQ status from download package */ 1168 hw->pkg_dwnld_status = hw->adminq.sq_last_status; 1169 if (status) { 1170 ice_debug(hw, ICE_DBG_PKG, "Pkg download failed: err %d off %d inf %d\n", 1171 status, offset, info); 1172 break; 1173 } 1174 1175 if (last) 1176 break; 1177 } 1178 1179 if (!status) { 1180 status = ice_set_vlan_mode(hw); 1181 if (status) 1182 ice_debug(hw, ICE_DBG_PKG, "Failed to set VLAN mode: err %d\n", 1183 status); 1184 } 1185 1186 ice_release_global_cfg_lock(hw); 1187 1188 return status; 1189 } 1190 1191 /** 1192 * ice_aq_get_pkg_info_list 1193 * @hw: pointer to the hardware structure 1194 * @pkg_info: the buffer which will receive the information list 1195 * @buf_size: the size of the pkg_info information buffer 1196 * @cd: pointer to command details structure or NULL 1197 * 1198 * Get Package Info List (0x0C43) 1199 */ 1200 static enum ice_status 1201 ice_aq_get_pkg_info_list(struct ice_hw *hw, 1202 struct ice_aqc_get_pkg_info_resp *pkg_info, 1203 u16 buf_size, struct ice_sq_cd *cd) 1204 { 1205 struct ice_aq_desc desc; 1206 1207 ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__); 1208 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_pkg_info_list); 1209 1210 return ice_aq_send_cmd(hw, &desc, pkg_info, buf_size, cd); 1211 } 1212 1213 /** 1214 * ice_download_pkg 1215 * @hw: pointer to the hardware structure 1216 * @ice_seg: pointer to the segment of the package to be downloaded 1217 * 1218 * Handles the download of a complete package. 1219 */ 1220 static enum ice_status 1221 ice_download_pkg(struct ice_hw *hw, struct ice_seg *ice_seg) 1222 { 1223 struct ice_buf_table *ice_buf_tbl; 1224 enum ice_status status; 1225 1226 ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__); 1227 ice_debug(hw, ICE_DBG_PKG, "Segment format version: %d.%d.%d.%d\n", 1228 ice_seg->hdr.seg_format_ver.major, 1229 ice_seg->hdr.seg_format_ver.minor, 1230 ice_seg->hdr.seg_format_ver.update, 1231 ice_seg->hdr.seg_format_ver.draft); 1232 1233 ice_debug(hw, ICE_DBG_PKG, "Seg: type 0x%X, size %d, name %s\n", 1234 LE32_TO_CPU(ice_seg->hdr.seg_type), 1235 LE32_TO_CPU(ice_seg->hdr.seg_size), ice_seg->hdr.seg_id); 1236 1237 ice_buf_tbl = ice_find_buf_table(ice_seg); 1238 1239 ice_debug(hw, ICE_DBG_PKG, "Seg buf count: %d\n", 1240 LE32_TO_CPU(ice_buf_tbl->buf_count)); 1241 1242 status = ice_dwnld_cfg_bufs(hw, ice_buf_tbl->buf_array, 1243 LE32_TO_CPU(ice_buf_tbl->buf_count)); 1244 1245 ice_post_pkg_dwnld_vlan_mode_cfg(hw); 1246 1247 return status; 1248 } 1249 1250 /** 1251 * ice_init_pkg_info 1252 * @hw: pointer to the hardware structure 1253 * @pkg_hdr: pointer to the driver's package hdr 1254 * 1255 * Saves off the package details into the HW structure. 1256 */ 1257 static enum ice_status 1258 ice_init_pkg_info(struct ice_hw *hw, struct ice_pkg_hdr *pkg_hdr) 1259 { 1260 struct ice_generic_seg_hdr *seg_hdr; 1261 1262 ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__); 1263 if (!pkg_hdr) 1264 return ICE_ERR_PARAM; 1265 1266 hw->pkg_seg_id = SEGMENT_TYPE_ICE_E810; 1267 1268 ice_debug(hw, ICE_DBG_INIT, "Pkg using segment id: 0x%08X\n", 1269 hw->pkg_seg_id); 1270 1271 seg_hdr = (struct ice_generic_seg_hdr *) 1272 ice_find_seg_in_pkg(hw, hw->pkg_seg_id, pkg_hdr); 1273 if (seg_hdr) { 1274 struct ice_meta_sect *meta; 1275 struct ice_pkg_enum state; 1276 1277 ice_memset(&state, 0, sizeof(state), ICE_NONDMA_MEM); 1278 1279 /* Get package information from the Metadata Section */ 1280 meta = (struct ice_meta_sect *) 1281 ice_pkg_enum_section((struct ice_seg *)seg_hdr, &state, 1282 ICE_SID_METADATA); 1283 if (!meta) { 1284 ice_debug(hw, ICE_DBG_INIT, "Did not find ice metadata section in package\n"); 1285 return ICE_ERR_CFG; 1286 } 1287 1288 hw->pkg_ver = meta->ver; 1289 ice_memcpy(hw->pkg_name, meta->name, sizeof(meta->name), 1290 ICE_NONDMA_TO_NONDMA); 1291 1292 ice_debug(hw, ICE_DBG_PKG, "Pkg: %d.%d.%d.%d, %s\n", 1293 meta->ver.major, meta->ver.minor, meta->ver.update, 1294 meta->ver.draft, meta->name); 1295 1296 hw->ice_seg_fmt_ver = seg_hdr->seg_format_ver; 1297 ice_memcpy(hw->ice_seg_id, seg_hdr->seg_id, 1298 sizeof(hw->ice_seg_id), ICE_NONDMA_TO_NONDMA); 1299 1300 ice_debug(hw, ICE_DBG_PKG, "Ice Seg: %d.%d.%d.%d, %s\n", 1301 seg_hdr->seg_format_ver.major, 1302 seg_hdr->seg_format_ver.minor, 1303 seg_hdr->seg_format_ver.update, 1304 seg_hdr->seg_format_ver.draft, 1305 seg_hdr->seg_id); 1306 } else { 1307 ice_debug(hw, ICE_DBG_INIT, "Did not find ice segment in driver package\n"); 1308 return ICE_ERR_CFG; 1309 } 1310 1311 return ICE_SUCCESS; 1312 } 1313 1314 /** 1315 * ice_get_pkg_info 1316 * @hw: pointer to the hardware structure 1317 * 1318 * Store details of the package currently loaded in HW into the HW structure. 1319 */ 1320 static enum ice_status ice_get_pkg_info(struct ice_hw *hw) 1321 { 1322 struct ice_aqc_get_pkg_info_resp *pkg_info; 1323 enum ice_status status; 1324 u16 size; 1325 u32 i; 1326 1327 ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__); 1328 1329 size = ice_struct_size(pkg_info, pkg_info, ICE_PKG_CNT); 1330 pkg_info = (struct ice_aqc_get_pkg_info_resp *)ice_malloc(hw, size); 1331 if (!pkg_info) 1332 return ICE_ERR_NO_MEMORY; 1333 1334 status = ice_aq_get_pkg_info_list(hw, pkg_info, size, NULL); 1335 if (status) 1336 goto init_pkg_free_alloc; 1337 1338 for (i = 0; i < LE32_TO_CPU(pkg_info->count); i++) { 1339 #define ICE_PKG_FLAG_COUNT 4 1340 char flags[ICE_PKG_FLAG_COUNT + 1] = { 0 }; 1341 u8 place = 0; 1342 1343 if (pkg_info->pkg_info[i].is_active) { 1344 flags[place++] = 'A'; 1345 hw->active_pkg_ver = pkg_info->pkg_info[i].ver; 1346 hw->active_track_id = 1347 LE32_TO_CPU(pkg_info->pkg_info[i].track_id); 1348 ice_memcpy(hw->active_pkg_name, 1349 pkg_info->pkg_info[i].name, 1350 sizeof(pkg_info->pkg_info[i].name), 1351 ICE_NONDMA_TO_NONDMA); 1352 hw->active_pkg_in_nvm = pkg_info->pkg_info[i].is_in_nvm; 1353 } 1354 if (pkg_info->pkg_info[i].is_active_at_boot) 1355 flags[place++] = 'B'; 1356 if (pkg_info->pkg_info[i].is_modified) 1357 flags[place++] = 'M'; 1358 if (pkg_info->pkg_info[i].is_in_nvm) 1359 flags[place++] = 'N'; 1360 1361 ice_debug(hw, ICE_DBG_PKG, "Pkg[%d]: %d.%d.%d.%d,%s,%s\n", 1362 i, pkg_info->pkg_info[i].ver.major, 1363 pkg_info->pkg_info[i].ver.minor, 1364 pkg_info->pkg_info[i].ver.update, 1365 pkg_info->pkg_info[i].ver.draft, 1366 pkg_info->pkg_info[i].name, flags); 1367 } 1368 1369 init_pkg_free_alloc: 1370 ice_free(hw, pkg_info); 1371 1372 return status; 1373 } 1374 1375 /** 1376 * ice_verify_pkg - verify package 1377 * @pkg: pointer to the package buffer 1378 * @len: size of the package buffer 1379 * 1380 * Verifies various attributes of the package file, including length, format 1381 * version, and the requirement of at least one segment. 1382 */ 1383 static enum ice_status ice_verify_pkg(struct ice_pkg_hdr *pkg, u32 len) 1384 { 1385 u32 seg_count; 1386 u32 i; 1387 1388 if (len < ice_struct_size(pkg, seg_offset, 1)) 1389 return ICE_ERR_BUF_TOO_SHORT; 1390 1391 if (pkg->pkg_format_ver.major != ICE_PKG_FMT_VER_MAJ || 1392 pkg->pkg_format_ver.minor != ICE_PKG_FMT_VER_MNR || 1393 pkg->pkg_format_ver.update != ICE_PKG_FMT_VER_UPD || 1394 pkg->pkg_format_ver.draft != ICE_PKG_FMT_VER_DFT) 1395 return ICE_ERR_CFG; 1396 1397 /* pkg must have at least one segment */ 1398 seg_count = LE32_TO_CPU(pkg->seg_count); 1399 if (seg_count < 1) 1400 return ICE_ERR_CFG; 1401 1402 /* make sure segment array fits in package length */ 1403 if (len < ice_struct_size(pkg, seg_offset, seg_count)) 1404 return ICE_ERR_BUF_TOO_SHORT; 1405 1406 /* all segments must fit within length */ 1407 for (i = 0; i < seg_count; i++) { 1408 u32 off = LE32_TO_CPU(pkg->seg_offset[i]); 1409 struct ice_generic_seg_hdr *seg; 1410 1411 /* segment header must fit */ 1412 if (len < off + sizeof(*seg)) 1413 return ICE_ERR_BUF_TOO_SHORT; 1414 1415 seg = (struct ice_generic_seg_hdr *)((u8 *)pkg + off); 1416 1417 /* segment body must fit */ 1418 if (len < off + LE32_TO_CPU(seg->seg_size)) 1419 return ICE_ERR_BUF_TOO_SHORT; 1420 } 1421 1422 return ICE_SUCCESS; 1423 } 1424 1425 /** 1426 * ice_free_seg - free package segment pointer 1427 * @hw: pointer to the hardware structure 1428 * 1429 * Frees the package segment pointer in the proper manner, depending on if the 1430 * segment was allocated or just the passed in pointer was stored. 1431 */ 1432 void ice_free_seg(struct ice_hw *hw) 1433 { 1434 if (hw->pkg_copy) { 1435 ice_free(hw, hw->pkg_copy); 1436 hw->pkg_copy = NULL; 1437 hw->pkg_size = 0; 1438 } 1439 hw->seg = NULL; 1440 } 1441 1442 /** 1443 * ice_init_pkg_regs - initialize additional package registers 1444 * @hw: pointer to the hardware structure 1445 */ 1446 static void ice_init_pkg_regs(struct ice_hw *hw) 1447 { 1448 #define ICE_SW_BLK_INP_MASK_L 0xFFFFFFFF 1449 #define ICE_SW_BLK_INP_MASK_H 0x0000FFFF 1450 #define ICE_SW_BLK_IDX 0 1451 if (hw->dcf_enabled) 1452 return; 1453 1454 /* setup Switch block input mask, which is 48-bits in two parts */ 1455 wr32(hw, GL_PREEXT_L2_PMASK0(ICE_SW_BLK_IDX), ICE_SW_BLK_INP_MASK_L); 1456 wr32(hw, GL_PREEXT_L2_PMASK1(ICE_SW_BLK_IDX), ICE_SW_BLK_INP_MASK_H); 1457 } 1458 1459 /** 1460 * ice_chk_pkg_version - check package version for compatibility with driver 1461 * @pkg_ver: pointer to a version structure to check 1462 * 1463 * Check to make sure that the package about to be downloaded is compatible with 1464 * the driver. To be compatible, the major and minor components of the package 1465 * version must match our ICE_PKG_SUPP_VER_MAJ and ICE_PKG_SUPP_VER_MNR 1466 * definitions. 1467 */ 1468 static enum ice_status ice_chk_pkg_version(struct ice_pkg_ver *pkg_ver) 1469 { 1470 if (pkg_ver->major != ICE_PKG_SUPP_VER_MAJ || 1471 pkg_ver->minor != ICE_PKG_SUPP_VER_MNR) 1472 return ICE_ERR_NOT_SUPPORTED; 1473 1474 return ICE_SUCCESS; 1475 } 1476 1477 /** 1478 * ice_chk_pkg_compat 1479 * @hw: pointer to the hardware structure 1480 * @ospkg: pointer to the package hdr 1481 * @seg: pointer to the package segment hdr 1482 * 1483 * This function checks the package version compatibility with driver and NVM 1484 */ 1485 static enum ice_status 1486 ice_chk_pkg_compat(struct ice_hw *hw, struct ice_pkg_hdr *ospkg, 1487 struct ice_seg **seg) 1488 { 1489 struct ice_aqc_get_pkg_info_resp *pkg; 1490 enum ice_status status; 1491 u16 size; 1492 u32 i; 1493 1494 ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__); 1495 1496 /* Check package version compatibility */ 1497 status = ice_chk_pkg_version(&hw->pkg_ver); 1498 if (status) { 1499 ice_debug(hw, ICE_DBG_INIT, "Package version check failed.\n"); 1500 return status; 1501 } 1502 1503 /* find ICE segment in given package */ 1504 *seg = (struct ice_seg *)ice_find_seg_in_pkg(hw, hw->pkg_seg_id, 1505 ospkg); 1506 if (!*seg) { 1507 ice_debug(hw, ICE_DBG_INIT, "no ice segment in package.\n"); 1508 return ICE_ERR_CFG; 1509 } 1510 1511 /* Check if FW is compatible with the OS package */ 1512 size = ice_struct_size(pkg, pkg_info, ICE_PKG_CNT); 1513 pkg = (struct ice_aqc_get_pkg_info_resp *)ice_malloc(hw, size); 1514 if (!pkg) 1515 return ICE_ERR_NO_MEMORY; 1516 1517 status = ice_aq_get_pkg_info_list(hw, pkg, size, NULL); 1518 if (status) 1519 goto fw_ddp_compat_free_alloc; 1520 1521 for (i = 0; i < LE32_TO_CPU(pkg->count); i++) { 1522 /* loop till we find the NVM package */ 1523 if (!pkg->pkg_info[i].is_in_nvm) 1524 continue; 1525 if ((*seg)->hdr.seg_format_ver.major != 1526 pkg->pkg_info[i].ver.major || 1527 (*seg)->hdr.seg_format_ver.minor > 1528 pkg->pkg_info[i].ver.minor) { 1529 status = ICE_ERR_FW_DDP_MISMATCH; 1530 ice_debug(hw, ICE_DBG_INIT, "OS package is not compatible with NVM.\n"); 1531 } 1532 /* done processing NVM package so break */ 1533 break; 1534 } 1535 fw_ddp_compat_free_alloc: 1536 ice_free(hw, pkg); 1537 return status; 1538 } 1539 1540 /** 1541 * ice_sw_fv_handler 1542 * @sect_type: section type 1543 * @section: pointer to section 1544 * @index: index of the field vector entry to be returned 1545 * @offset: ptr to variable that receives the offset in the field vector table 1546 * 1547 * This is a callback function that can be passed to ice_pkg_enum_entry. 1548 * This function treats the given section as of type ice_sw_fv_section and 1549 * enumerates offset field. "offset" is an index into the field vector table. 1550 */ 1551 static void * 1552 ice_sw_fv_handler(u32 sect_type, void *section, u32 index, u32 *offset) 1553 { 1554 struct ice_sw_fv_section *fv_section = 1555 (struct ice_sw_fv_section *)section; 1556 1557 if (!section || sect_type != ICE_SID_FLD_VEC_SW) 1558 return NULL; 1559 if (index >= LE16_TO_CPU(fv_section->count)) 1560 return NULL; 1561 if (offset) 1562 /* "index" passed in to this function is relative to a given 1563 * 4k block. To get to the true index into the field vector 1564 * table need to add the relative index to the base_offset 1565 * field of this section 1566 */ 1567 *offset = LE16_TO_CPU(fv_section->base_offset) + index; 1568 return fv_section->fv + index; 1569 } 1570 1571 /** 1572 * ice_get_prof_index_max - get the max profile index for used profile 1573 * @hw: pointer to the HW struct 1574 * 1575 * Calling this function will get the max profile index for used profile 1576 * and store the index number in struct ice_switch_info *switch_info 1577 * in hw for following use. 1578 */ 1579 static int ice_get_prof_index_max(struct ice_hw *hw) 1580 { 1581 u16 prof_index = 0, j, max_prof_index = 0; 1582 struct ice_pkg_enum state; 1583 struct ice_seg *ice_seg; 1584 bool flag = false; 1585 struct ice_fv *fv; 1586 u32 offset; 1587 1588 ice_memset(&state, 0, sizeof(state), ICE_NONDMA_MEM); 1589 1590 if (!hw->seg) 1591 return ICE_ERR_PARAM; 1592 1593 ice_seg = hw->seg; 1594 1595 do { 1596 fv = (struct ice_fv *) 1597 ice_pkg_enum_entry(ice_seg, &state, ICE_SID_FLD_VEC_SW, 1598 &offset, ice_sw_fv_handler); 1599 if (!fv) 1600 break; 1601 ice_seg = NULL; 1602 1603 /* in the profile that not be used, the prot_id is set to 0xff 1604 * and the off is set to 0x1ff for all the field vectors. 1605 */ 1606 for (j = 0; j < hw->blk[ICE_BLK_SW].es.fvw; j++) 1607 if (fv->ew[j].prot_id != ICE_PROT_INVALID || 1608 fv->ew[j].off != ICE_FV_OFFSET_INVAL) 1609 flag = true; 1610 if (flag && prof_index > max_prof_index) 1611 max_prof_index = prof_index; 1612 1613 prof_index++; 1614 flag = false; 1615 } while (fv); 1616 1617 hw->switch_info->max_used_prof_index = max_prof_index; 1618 1619 return ICE_SUCCESS; 1620 } 1621 1622 /** 1623 * ice_init_pkg - initialize/download package 1624 * @hw: pointer to the hardware structure 1625 * @buf: pointer to the package buffer 1626 * @len: size of the package buffer 1627 * 1628 * This function initializes a package. The package contains HW tables 1629 * required to do packet processing. First, the function extracts package 1630 * information such as version. Then it finds the ice configuration segment 1631 * within the package; this function then saves a copy of the segment pointer 1632 * within the supplied package buffer. Next, the function will cache any hints 1633 * from the package, followed by downloading the package itself. Note, that if 1634 * a previous PF driver has already downloaded the package successfully, then 1635 * the current driver will not have to download the package again. 1636 * 1637 * The local package contents will be used to query default behavior and to 1638 * update specific sections of the HW's version of the package (e.g. to update 1639 * the parse graph to understand new protocols). 1640 * 1641 * This function stores a pointer to the package buffer memory, and it is 1642 * expected that the supplied buffer will not be freed immediately. If the 1643 * package buffer needs to be freed, such as when read from a file, use 1644 * ice_copy_and_init_pkg() instead of directly calling ice_init_pkg() in this 1645 * case. 1646 */ 1647 enum ice_status ice_init_pkg(struct ice_hw *hw, u8 *buf, u32 len) 1648 { 1649 struct ice_pkg_hdr *pkg; 1650 enum ice_status status; 1651 struct ice_seg *seg; 1652 1653 if (!buf || !len) 1654 return ICE_ERR_PARAM; 1655 1656 pkg = (struct ice_pkg_hdr *)buf; 1657 status = ice_verify_pkg(pkg, len); 1658 if (status) { 1659 ice_debug(hw, ICE_DBG_INIT, "failed to verify pkg (err: %d)\n", 1660 status); 1661 return status; 1662 } 1663 1664 /* initialize package info */ 1665 status = ice_init_pkg_info(hw, pkg); 1666 if (status) 1667 return status; 1668 1669 /* before downloading the package, check package version for 1670 * compatibility with driver 1671 */ 1672 status = ice_chk_pkg_compat(hw, pkg, &seg); 1673 if (status) 1674 return status; 1675 1676 /* initialize package hints and then download package */ 1677 ice_init_pkg_hints(hw, seg); 1678 status = ice_download_pkg(hw, seg); 1679 if (status == ICE_ERR_AQ_NO_WORK) { 1680 ice_debug(hw, ICE_DBG_INIT, "package previously loaded - no work.\n"); 1681 status = ICE_SUCCESS; 1682 } 1683 1684 /* Get information on the package currently loaded in HW, then make sure 1685 * the driver is compatible with this version. 1686 */ 1687 if (!status) { 1688 status = ice_get_pkg_info(hw); 1689 if (!status) 1690 status = ice_chk_pkg_version(&hw->active_pkg_ver); 1691 } 1692 1693 if (!status) { 1694 hw->seg = seg; 1695 /* on successful package download update other required 1696 * registers to support the package and fill HW tables 1697 * with package content. 1698 */ 1699 ice_init_pkg_regs(hw); 1700 ice_fill_blk_tbls(hw); 1701 ice_fill_hw_ptype(hw); 1702 ice_get_prof_index_max(hw); 1703 } else { 1704 ice_debug(hw, ICE_DBG_INIT, "package load failed, %d\n", 1705 status); 1706 } 1707 1708 return status; 1709 } 1710 1711 /** 1712 * ice_copy_and_init_pkg - initialize/download a copy of the package 1713 * @hw: pointer to the hardware structure 1714 * @buf: pointer to the package buffer 1715 * @len: size of the package buffer 1716 * 1717 * This function copies the package buffer, and then calls ice_init_pkg() to 1718 * initialize the copied package contents. 1719 * 1720 * The copying is necessary if the package buffer supplied is constant, or if 1721 * the memory may disappear shortly after calling this function. 1722 * 1723 * If the package buffer resides in the data segment and can be modified, the 1724 * caller is free to use ice_init_pkg() instead of ice_copy_and_init_pkg(). 1725 * 1726 * However, if the package buffer needs to be copied first, such as when being 1727 * read from a file, the caller should use ice_copy_and_init_pkg(). 1728 * 1729 * This function will first copy the package buffer, before calling 1730 * ice_init_pkg(). The caller is free to immediately destroy the original 1731 * package buffer, as the new copy will be managed by this function and 1732 * related routines. 1733 */ 1734 enum ice_status ice_copy_and_init_pkg(struct ice_hw *hw, const u8 *buf, u32 len) 1735 { 1736 enum ice_status status; 1737 u8 *buf_copy; 1738 1739 if (!buf || !len) 1740 return ICE_ERR_PARAM; 1741 1742 buf_copy = (u8 *)ice_memdup(hw, buf, len, ICE_NONDMA_TO_NONDMA); 1743 1744 status = ice_init_pkg(hw, buf_copy, len); 1745 if (status) { 1746 /* Free the copy, since we failed to initialize the package */ 1747 ice_free(hw, buf_copy); 1748 } else { 1749 /* Track the copied pkg so we can free it later */ 1750 hw->pkg_copy = buf_copy; 1751 hw->pkg_size = len; 1752 } 1753 1754 return status; 1755 } 1756 1757 /** 1758 * ice_pkg_buf_alloc 1759 * @hw: pointer to the HW structure 1760 * 1761 * Allocates a package buffer and returns a pointer to the buffer header. 1762 * Note: all package contents must be in Little Endian form. 1763 */ 1764 static struct ice_buf_build *ice_pkg_buf_alloc(struct ice_hw *hw) 1765 { 1766 struct ice_buf_build *bld; 1767 struct ice_buf_hdr *buf; 1768 1769 bld = (struct ice_buf_build *)ice_malloc(hw, sizeof(*bld)); 1770 if (!bld) 1771 return NULL; 1772 1773 buf = (struct ice_buf_hdr *)bld; 1774 buf->data_end = CPU_TO_LE16(offsetof(struct ice_buf_hdr, 1775 section_entry)); 1776 return bld; 1777 } 1778 1779 /** 1780 * ice_get_sw_prof_type - determine switch profile type 1781 * @hw: pointer to the HW structure 1782 * @fv: pointer to the switch field vector 1783 */ 1784 static enum ice_prof_type 1785 ice_get_sw_prof_type(struct ice_hw *hw, struct ice_fv *fv) 1786 { 1787 u16 i; 1788 1789 for (i = 0; i < hw->blk[ICE_BLK_SW].es.fvw; i++) { 1790 /* UDP tunnel will have UDP_OF protocol ID and VNI offset */ 1791 if (fv->ew[i].prot_id == (u8)ICE_PROT_UDP_OF && 1792 fv->ew[i].off == ICE_VNI_OFFSET) 1793 return ICE_PROF_TUN_UDP; 1794 1795 /* GRE tunnel will have GRE protocol */ 1796 if (fv->ew[i].prot_id == (u8)ICE_PROT_GRE_OF) 1797 return ICE_PROF_TUN_GRE; 1798 1799 /* PPPOE tunnel will have PPPOE protocol */ 1800 if (fv->ew[i].prot_id == (u8)ICE_PROT_PPPOE) 1801 return ICE_PROF_TUN_PPPOE; 1802 } 1803 1804 return ICE_PROF_NON_TUN; 1805 } 1806 1807 /** 1808 * ice_get_sw_fv_bitmap - Get switch field vector bitmap based on profile type 1809 * @hw: pointer to hardware structure 1810 * @req_profs: type of profiles requested 1811 * @bm: pointer to memory for returning the bitmap of field vectors 1812 */ 1813 void 1814 ice_get_sw_fv_bitmap(struct ice_hw *hw, enum ice_prof_type req_profs, 1815 ice_bitmap_t *bm) 1816 { 1817 struct ice_pkg_enum state; 1818 struct ice_seg *ice_seg; 1819 struct ice_fv *fv; 1820 1821 if (req_profs == ICE_PROF_ALL) { 1822 ice_bitmap_set(bm, 0, ICE_MAX_NUM_PROFILES); 1823 return; 1824 } 1825 1826 ice_memset(&state, 0, sizeof(state), ICE_NONDMA_MEM); 1827 ice_zero_bitmap(bm, ICE_MAX_NUM_PROFILES); 1828 ice_seg = hw->seg; 1829 do { 1830 enum ice_prof_type prof_type; 1831 u32 offset; 1832 1833 fv = (struct ice_fv *) 1834 ice_pkg_enum_entry(ice_seg, &state, ICE_SID_FLD_VEC_SW, 1835 &offset, ice_sw_fv_handler); 1836 ice_seg = NULL; 1837 1838 if (fv) { 1839 /* Determine field vector type */ 1840 prof_type = ice_get_sw_prof_type(hw, fv); 1841 1842 if (req_profs & prof_type) 1843 ice_set_bit((u16)offset, bm); 1844 } 1845 } while (fv); 1846 } 1847 1848 /** 1849 * ice_get_sw_fv_list 1850 * @hw: pointer to the HW structure 1851 * @prot_ids: field vector to search for with a given protocol ID 1852 * @ids_cnt: lookup/protocol count 1853 * @bm: bitmap of field vectors to consider 1854 * @fv_list: Head of a list 1855 * 1856 * Finds all the field vector entries from switch block that contain 1857 * a given protocol ID and returns a list of structures of type 1858 * "ice_sw_fv_list_entry". Every structure in the list has a field vector 1859 * definition and profile ID information 1860 * NOTE: The caller of the function is responsible for freeing the memory 1861 * allocated for every list entry. 1862 */ 1863 enum ice_status 1864 ice_get_sw_fv_list(struct ice_hw *hw, u8 *prot_ids, u16 ids_cnt, 1865 ice_bitmap_t *bm, struct LIST_HEAD_TYPE *fv_list) 1866 { 1867 struct ice_sw_fv_list_entry *fvl; 1868 struct ice_sw_fv_list_entry *tmp; 1869 struct ice_pkg_enum state; 1870 struct ice_seg *ice_seg; 1871 struct ice_fv *fv; 1872 u32 offset; 1873 1874 ice_memset(&state, 0, sizeof(state), ICE_NONDMA_MEM); 1875 1876 if (!ids_cnt || !hw->seg) 1877 return ICE_ERR_PARAM; 1878 1879 ice_seg = hw->seg; 1880 do { 1881 u16 i; 1882 1883 fv = (struct ice_fv *) 1884 ice_pkg_enum_entry(ice_seg, &state, ICE_SID_FLD_VEC_SW, 1885 &offset, ice_sw_fv_handler); 1886 if (!fv) 1887 break; 1888 ice_seg = NULL; 1889 1890 /* If field vector is not in the bitmap list, then skip this 1891 * profile. 1892 */ 1893 if (!ice_is_bit_set(bm, (u16)offset)) 1894 continue; 1895 1896 for (i = 0; i < ids_cnt; i++) { 1897 int j; 1898 1899 /* This code assumes that if a switch field vector line 1900 * has a matching protocol, then this line will contain 1901 * the entries necessary to represent every field in 1902 * that protocol header. 1903 */ 1904 for (j = 0; j < hw->blk[ICE_BLK_SW].es.fvw; j++) 1905 if (fv->ew[j].prot_id == prot_ids[i]) 1906 break; 1907 if (j >= hw->blk[ICE_BLK_SW].es.fvw) 1908 break; 1909 if (i + 1 == ids_cnt) { 1910 fvl = (struct ice_sw_fv_list_entry *) 1911 ice_malloc(hw, sizeof(*fvl)); 1912 if (!fvl) 1913 goto err; 1914 fvl->fv_ptr = fv; 1915 fvl->profile_id = offset; 1916 LIST_ADD(&fvl->list_entry, fv_list); 1917 break; 1918 } 1919 } 1920 } while (fv); 1921 if (LIST_EMPTY(fv_list)) 1922 return ICE_ERR_CFG; 1923 return ICE_SUCCESS; 1924 1925 err: 1926 LIST_FOR_EACH_ENTRY_SAFE(fvl, tmp, fv_list, ice_sw_fv_list_entry, 1927 list_entry) { 1928 LIST_DEL(&fvl->list_entry); 1929 ice_free(hw, fvl); 1930 } 1931 1932 return ICE_ERR_NO_MEMORY; 1933 } 1934 1935 /** 1936 * ice_init_prof_result_bm - Initialize the profile result index bitmap 1937 * @hw: pointer to hardware structure 1938 */ 1939 void ice_init_prof_result_bm(struct ice_hw *hw) 1940 { 1941 struct ice_pkg_enum state; 1942 struct ice_seg *ice_seg; 1943 struct ice_fv *fv; 1944 1945 ice_memset(&state, 0, sizeof(state), ICE_NONDMA_MEM); 1946 1947 if (!hw->seg) 1948 return; 1949 1950 ice_seg = hw->seg; 1951 do { 1952 u32 off; 1953 u16 i; 1954 1955 fv = (struct ice_fv *) 1956 ice_pkg_enum_entry(ice_seg, &state, ICE_SID_FLD_VEC_SW, 1957 &off, ice_sw_fv_handler); 1958 ice_seg = NULL; 1959 if (!fv) 1960 break; 1961 1962 ice_zero_bitmap(hw->switch_info->prof_res_bm[off], 1963 ICE_MAX_FV_WORDS); 1964 1965 /* Determine empty field vector indices, these can be 1966 * used for recipe results. Skip index 0, since it is 1967 * always used for Switch ID. 1968 */ 1969 for (i = 1; i < ICE_MAX_FV_WORDS; i++) 1970 if (fv->ew[i].prot_id == ICE_PROT_INVALID && 1971 fv->ew[i].off == ICE_FV_OFFSET_INVAL) 1972 ice_set_bit(i, 1973 hw->switch_info->prof_res_bm[off]); 1974 } while (fv); 1975 } 1976 1977 /** 1978 * ice_pkg_buf_free 1979 * @hw: pointer to the HW structure 1980 * @bld: pointer to pkg build (allocated by ice_pkg_buf_alloc()) 1981 * 1982 * Frees a package buffer 1983 */ 1984 void ice_pkg_buf_free(struct ice_hw *hw, struct ice_buf_build *bld) 1985 { 1986 ice_free(hw, bld); 1987 } 1988 1989 /** 1990 * ice_pkg_buf_reserve_section 1991 * @bld: pointer to pkg build (allocated by ice_pkg_buf_alloc()) 1992 * @count: the number of sections to reserve 1993 * 1994 * Reserves one or more section table entries in a package buffer. This routine 1995 * can be called multiple times as long as they are made before calling 1996 * ice_pkg_buf_alloc_section(). Once ice_pkg_buf_alloc_section() 1997 * is called once, the number of sections that can be allocated will not be able 1998 * to be increased; not using all reserved sections is fine, but this will 1999 * result in some wasted space in the buffer. 2000 * Note: all package contents must be in Little Endian form. 2001 */ 2002 static enum ice_status 2003 ice_pkg_buf_reserve_section(struct ice_buf_build *bld, u16 count) 2004 { 2005 struct ice_buf_hdr *buf; 2006 u16 section_count; 2007 u16 data_end; 2008 2009 if (!bld) 2010 return ICE_ERR_PARAM; 2011 2012 buf = (struct ice_buf_hdr *)&bld->buf; 2013 2014 /* already an active section, can't increase table size */ 2015 section_count = LE16_TO_CPU(buf->section_count); 2016 if (section_count > 0) 2017 return ICE_ERR_CFG; 2018 2019 if (bld->reserved_section_table_entries + count > ICE_MAX_S_COUNT) 2020 return ICE_ERR_CFG; 2021 bld->reserved_section_table_entries += count; 2022 2023 data_end = LE16_TO_CPU(buf->data_end) + 2024 FLEX_ARRAY_SIZE(buf, section_entry, count); 2025 buf->data_end = CPU_TO_LE16(data_end); 2026 2027 return ICE_SUCCESS; 2028 } 2029 2030 /** 2031 * ice_pkg_buf_alloc_section 2032 * @bld: pointer to pkg build (allocated by ice_pkg_buf_alloc()) 2033 * @type: the section type value 2034 * @size: the size of the section to reserve (in bytes) 2035 * 2036 * Reserves memory in the buffer for a section's content and updates the 2037 * buffers' status accordingly. This routine returns a pointer to the first 2038 * byte of the section start within the buffer, which is used to fill in the 2039 * section contents. 2040 * Note: all package contents must be in Little Endian form. 2041 */ 2042 static void * 2043 ice_pkg_buf_alloc_section(struct ice_buf_build *bld, u32 type, u16 size) 2044 { 2045 struct ice_buf_hdr *buf; 2046 u16 sect_count; 2047 u16 data_end; 2048 2049 if (!bld || !type || !size) 2050 return NULL; 2051 2052 buf = (struct ice_buf_hdr *)&bld->buf; 2053 2054 /* check for enough space left in buffer */ 2055 data_end = LE16_TO_CPU(buf->data_end); 2056 2057 /* section start must align on 4 byte boundary */ 2058 data_end = ICE_ALIGN(data_end, 4); 2059 2060 if ((data_end + size) > ICE_MAX_S_DATA_END) 2061 return NULL; 2062 2063 /* check for more available section table entries */ 2064 sect_count = LE16_TO_CPU(buf->section_count); 2065 if (sect_count < bld->reserved_section_table_entries) { 2066 void *section_ptr = ((u8 *)buf) + data_end; 2067 2068 buf->section_entry[sect_count].offset = CPU_TO_LE16(data_end); 2069 buf->section_entry[sect_count].size = CPU_TO_LE16(size); 2070 buf->section_entry[sect_count].type = CPU_TO_LE32(type); 2071 2072 data_end += size; 2073 buf->data_end = CPU_TO_LE16(data_end); 2074 2075 buf->section_count = CPU_TO_LE16(sect_count + 1); 2076 return section_ptr; 2077 } 2078 2079 /* no free section table entries */ 2080 return NULL; 2081 } 2082 2083 /** 2084 * ice_pkg_buf_alloc_single_section 2085 * @hw: pointer to the HW structure 2086 * @type: the section type value 2087 * @size: the size of the section to reserve (in bytes) 2088 * @section: returns pointer to the section 2089 * 2090 * Allocates a package buffer with a single section. 2091 * Note: all package contents must be in Little Endian form. 2092 */ 2093 struct ice_buf_build * 2094 ice_pkg_buf_alloc_single_section(struct ice_hw *hw, u32 type, u16 size, 2095 void **section) 2096 { 2097 struct ice_buf_build *buf; 2098 2099 if (!section) 2100 return NULL; 2101 2102 buf = ice_pkg_buf_alloc(hw); 2103 if (!buf) 2104 return NULL; 2105 2106 if (ice_pkg_buf_reserve_section(buf, 1)) 2107 goto ice_pkg_buf_alloc_single_section_err; 2108 2109 *section = ice_pkg_buf_alloc_section(buf, type, size); 2110 if (!*section) 2111 goto ice_pkg_buf_alloc_single_section_err; 2112 2113 return buf; 2114 2115 ice_pkg_buf_alloc_single_section_err: 2116 ice_pkg_buf_free(hw, buf); 2117 return NULL; 2118 } 2119 2120 /** 2121 * ice_pkg_buf_get_active_sections 2122 * @bld: pointer to pkg build (allocated by ice_pkg_buf_alloc()) 2123 * 2124 * Returns the number of active sections. Before using the package buffer 2125 * in an update package command, the caller should make sure that there is at 2126 * least one active section - otherwise, the buffer is not legal and should 2127 * not be used. 2128 * Note: all package contents must be in Little Endian form. 2129 */ 2130 static u16 ice_pkg_buf_get_active_sections(struct ice_buf_build *bld) 2131 { 2132 struct ice_buf_hdr *buf; 2133 2134 if (!bld) 2135 return 0; 2136 2137 buf = (struct ice_buf_hdr *)&bld->buf; 2138 return LE16_TO_CPU(buf->section_count); 2139 } 2140 2141 /** 2142 * ice_pkg_buf 2143 * @bld: pointer to pkg build (allocated by ice_pkg_buf_alloc()) 2144 * 2145 * Return a pointer to the buffer's header 2146 */ 2147 struct ice_buf *ice_pkg_buf(struct ice_buf_build *bld) 2148 { 2149 if (!bld) 2150 return NULL; 2151 2152 return &bld->buf; 2153 } 2154 2155 /** 2156 * ice_tunnel_port_in_use_hlpr - helper function to determine tunnel usage 2157 * @hw: pointer to the HW structure 2158 * @port: port to search for 2159 * @index: optionally returns index 2160 * 2161 * Returns whether a port is already in use as a tunnel, and optionally its 2162 * index 2163 */ 2164 static bool ice_tunnel_port_in_use_hlpr(struct ice_hw *hw, u16 port, u16 *index) 2165 { 2166 u16 i; 2167 2168 for (i = 0; i < hw->tnl.count && i < ICE_TUNNEL_MAX_ENTRIES; i++) 2169 if (hw->tnl.tbl[i].in_use && hw->tnl.tbl[i].port == port) { 2170 if (index) 2171 *index = i; 2172 return true; 2173 } 2174 2175 return false; 2176 } 2177 2178 /** 2179 * ice_tunnel_port_in_use 2180 * @hw: pointer to the HW structure 2181 * @port: port to search for 2182 * @index: optionally returns index 2183 * 2184 * Returns whether a port is already in use as a tunnel, and optionally its 2185 * index 2186 */ 2187 bool ice_tunnel_port_in_use(struct ice_hw *hw, u16 port, u16 *index) 2188 { 2189 bool res; 2190 2191 ice_acquire_lock(&hw->tnl_lock); 2192 res = ice_tunnel_port_in_use_hlpr(hw, port, index); 2193 ice_release_lock(&hw->tnl_lock); 2194 2195 return res; 2196 } 2197 2198 /** 2199 * ice_tunnel_get_type 2200 * @hw: pointer to the HW structure 2201 * @port: port to search for 2202 * @type: returns tunnel index 2203 * 2204 * For a given port number, will return the type of tunnel. 2205 */ 2206 bool 2207 ice_tunnel_get_type(struct ice_hw *hw, u16 port, enum ice_tunnel_type *type) 2208 { 2209 bool res = false; 2210 u16 i; 2211 2212 ice_acquire_lock(&hw->tnl_lock); 2213 2214 for (i = 0; i < hw->tnl.count && i < ICE_TUNNEL_MAX_ENTRIES; i++) 2215 if (hw->tnl.tbl[i].in_use && hw->tnl.tbl[i].port == port) { 2216 *type = hw->tnl.tbl[i].type; 2217 res = true; 2218 break; 2219 } 2220 2221 ice_release_lock(&hw->tnl_lock); 2222 2223 return res; 2224 } 2225 2226 /** 2227 * ice_find_free_tunnel_entry 2228 * @hw: pointer to the HW structure 2229 * @type: tunnel type 2230 * @index: optionally returns index 2231 * 2232 * Returns whether there is a free tunnel entry, and optionally its index 2233 */ 2234 static bool 2235 ice_find_free_tunnel_entry(struct ice_hw *hw, enum ice_tunnel_type type, 2236 u16 *index) 2237 { 2238 u16 i; 2239 2240 for (i = 0; i < hw->tnl.count && i < ICE_TUNNEL_MAX_ENTRIES; i++) 2241 if (hw->tnl.tbl[i].valid && !hw->tnl.tbl[i].in_use && 2242 hw->tnl.tbl[i].type == type) { 2243 if (index) 2244 *index = i; 2245 return true; 2246 } 2247 2248 return false; 2249 } 2250 2251 /** 2252 * ice_get_open_tunnel_port - retrieve an open tunnel port 2253 * @hw: pointer to the HW structure 2254 * @type: tunnel type (TNL_ALL will return any open port) 2255 * @port: returns open port 2256 */ 2257 bool 2258 ice_get_open_tunnel_port(struct ice_hw *hw, enum ice_tunnel_type type, 2259 u16 *port) 2260 { 2261 bool res = false; 2262 u16 i; 2263 2264 ice_acquire_lock(&hw->tnl_lock); 2265 2266 for (i = 0; i < hw->tnl.count && i < ICE_TUNNEL_MAX_ENTRIES; i++) 2267 if (hw->tnl.tbl[i].valid && hw->tnl.tbl[i].in_use && 2268 (type == TNL_ALL || hw->tnl.tbl[i].type == type)) { 2269 *port = hw->tnl.tbl[i].port; 2270 res = true; 2271 break; 2272 } 2273 2274 ice_release_lock(&hw->tnl_lock); 2275 2276 return res; 2277 } 2278 2279 /** 2280 * ice_upd_dvm_boost_entry 2281 * @hw: pointer to the HW structure 2282 * @entry: pointer to double vlan boost entry info 2283 */ 2284 static enum ice_status 2285 ice_upd_dvm_boost_entry(struct ice_hw *hw, struct ice_dvm_entry *entry) 2286 { 2287 struct ice_boost_tcam_section *sect_rx, *sect_tx; 2288 enum ice_status status = ICE_ERR_MAX_LIMIT; 2289 struct ice_buf_build *bld; 2290 u8 val, dc, nm; 2291 2292 bld = ice_pkg_buf_alloc(hw); 2293 if (!bld) 2294 return ICE_ERR_NO_MEMORY; 2295 2296 /* allocate 2 sections, one for Rx parser, one for Tx parser */ 2297 if (ice_pkg_buf_reserve_section(bld, 2)) 2298 goto ice_upd_dvm_boost_entry_err; 2299 2300 sect_rx = (struct ice_boost_tcam_section *) 2301 ice_pkg_buf_alloc_section(bld, ICE_SID_RXPARSER_BOOST_TCAM, 2302 ice_struct_size(sect_rx, tcam, 1)); 2303 if (!sect_rx) 2304 goto ice_upd_dvm_boost_entry_err; 2305 sect_rx->count = CPU_TO_LE16(1); 2306 2307 sect_tx = (struct ice_boost_tcam_section *) 2308 ice_pkg_buf_alloc_section(bld, ICE_SID_TXPARSER_BOOST_TCAM, 2309 ice_struct_size(sect_tx, tcam, 1)); 2310 if (!sect_tx) 2311 goto ice_upd_dvm_boost_entry_err; 2312 sect_tx->count = CPU_TO_LE16(1); 2313 2314 /* copy original boost entry to update package buffer */ 2315 ice_memcpy(sect_rx->tcam, entry->boost_entry, sizeof(*sect_rx->tcam), 2316 ICE_NONDMA_TO_NONDMA); 2317 2318 /* re-write the don't care and never match bits accordingly */ 2319 if (entry->enable) { 2320 /* all bits are don't care */ 2321 val = 0x00; 2322 dc = 0xFF; 2323 nm = 0x00; 2324 } else { 2325 /* disable, one never match bit, the rest are don't care */ 2326 val = 0x00; 2327 dc = 0xF7; 2328 nm = 0x08; 2329 } 2330 2331 ice_set_key((u8 *)§_rx->tcam[0].key, sizeof(sect_rx->tcam[0].key), 2332 &val, NULL, &dc, &nm, 0, sizeof(u8)); 2333 2334 /* exact copy of entry to Tx section entry */ 2335 ice_memcpy(sect_tx->tcam, sect_rx->tcam, sizeof(*sect_tx->tcam), 2336 ICE_NONDMA_TO_NONDMA); 2337 2338 status = ice_update_pkg_no_lock(hw, ice_pkg_buf(bld), 1); 2339 2340 ice_upd_dvm_boost_entry_err: 2341 ice_pkg_buf_free(hw, bld); 2342 2343 return status; 2344 } 2345 2346 /** 2347 * ice_set_dvm_boost_entries 2348 * @hw: pointer to the HW structure 2349 * 2350 * Enable double vlan by updating the appropriate boost tcam entries. 2351 */ 2352 enum ice_status ice_set_dvm_boost_entries(struct ice_hw *hw) 2353 { 2354 enum ice_status status; 2355 u16 i; 2356 2357 for (i = 0; i < hw->dvm_upd.count; i++) { 2358 status = ice_upd_dvm_boost_entry(hw, &hw->dvm_upd.tbl[i]); 2359 if (status) 2360 return status; 2361 } 2362 2363 return ICE_SUCCESS; 2364 } 2365 2366 /** 2367 * ice_create_tunnel 2368 * @hw: pointer to the HW structure 2369 * @type: type of tunnel 2370 * @port: port of tunnel to create 2371 * 2372 * Create a tunnel by updating the parse graph in the parser. We do that by 2373 * creating a package buffer with the tunnel info and issuing an update package 2374 * command. 2375 */ 2376 enum ice_status 2377 ice_create_tunnel(struct ice_hw *hw, enum ice_tunnel_type type, u16 port) 2378 { 2379 struct ice_boost_tcam_section *sect_rx, *sect_tx; 2380 enum ice_status status = ICE_ERR_MAX_LIMIT; 2381 struct ice_buf_build *bld; 2382 u16 index; 2383 2384 ice_acquire_lock(&hw->tnl_lock); 2385 2386 if (ice_tunnel_port_in_use_hlpr(hw, port, &index)) { 2387 hw->tnl.tbl[index].ref++; 2388 status = ICE_SUCCESS; 2389 goto ice_create_tunnel_end; 2390 } 2391 2392 if (!ice_find_free_tunnel_entry(hw, type, &index)) { 2393 status = ICE_ERR_OUT_OF_RANGE; 2394 goto ice_create_tunnel_end; 2395 } 2396 2397 bld = ice_pkg_buf_alloc(hw); 2398 if (!bld) { 2399 status = ICE_ERR_NO_MEMORY; 2400 goto ice_create_tunnel_end; 2401 } 2402 2403 /* allocate 2 sections, one for Rx parser, one for Tx parser */ 2404 if (ice_pkg_buf_reserve_section(bld, 2)) 2405 goto ice_create_tunnel_err; 2406 2407 sect_rx = (struct ice_boost_tcam_section *) 2408 ice_pkg_buf_alloc_section(bld, ICE_SID_RXPARSER_BOOST_TCAM, 2409 ice_struct_size(sect_rx, tcam, 1)); 2410 if (!sect_rx) 2411 goto ice_create_tunnel_err; 2412 sect_rx->count = CPU_TO_LE16(1); 2413 2414 sect_tx = (struct ice_boost_tcam_section *) 2415 ice_pkg_buf_alloc_section(bld, ICE_SID_TXPARSER_BOOST_TCAM, 2416 ice_struct_size(sect_tx, tcam, 1)); 2417 if (!sect_tx) 2418 goto ice_create_tunnel_err; 2419 sect_tx->count = CPU_TO_LE16(1); 2420 2421 /* copy original boost entry to update package buffer */ 2422 ice_memcpy(sect_rx->tcam, hw->tnl.tbl[index].boost_entry, 2423 sizeof(*sect_rx->tcam), ICE_NONDMA_TO_NONDMA); 2424 2425 /* over-write the never-match dest port key bits with the encoded port 2426 * bits 2427 */ 2428 ice_set_key((u8 *)§_rx->tcam[0].key, sizeof(sect_rx->tcam[0].key), 2429 (u8 *)&port, NULL, NULL, NULL, 2430 (u16)offsetof(struct ice_boost_key_value, hv_dst_port_key), 2431 sizeof(sect_rx->tcam[0].key.key.hv_dst_port_key)); 2432 2433 /* exact copy of entry to Tx section entry */ 2434 ice_memcpy(sect_tx->tcam, sect_rx->tcam, sizeof(*sect_tx->tcam), 2435 ICE_NONDMA_TO_NONDMA); 2436 2437 status = ice_update_pkg(hw, ice_pkg_buf(bld), 1); 2438 if (!status) { 2439 hw->tnl.tbl[index].port = port; 2440 hw->tnl.tbl[index].in_use = true; 2441 hw->tnl.tbl[index].ref = 1; 2442 } 2443 2444 ice_create_tunnel_err: 2445 ice_pkg_buf_free(hw, bld); 2446 2447 ice_create_tunnel_end: 2448 ice_release_lock(&hw->tnl_lock); 2449 2450 return status; 2451 } 2452 2453 /** 2454 * ice_destroy_tunnel 2455 * @hw: pointer to the HW structure 2456 * @port: port of tunnel to destroy (ignored if the all parameter is true) 2457 * @all: flag that states to destroy all tunnels 2458 * 2459 * Destroys a tunnel or all tunnels by creating an update package buffer 2460 * targeting the specific updates requested and then performing an update 2461 * package. 2462 */ 2463 enum ice_status ice_destroy_tunnel(struct ice_hw *hw, u16 port, bool all) 2464 { 2465 struct ice_boost_tcam_section *sect_rx, *sect_tx; 2466 enum ice_status status = ICE_ERR_MAX_LIMIT; 2467 struct ice_buf_build *bld; 2468 u16 count = 0; 2469 u16 index; 2470 u16 size; 2471 u16 i, j; 2472 2473 ice_acquire_lock(&hw->tnl_lock); 2474 2475 if (!all && ice_tunnel_port_in_use_hlpr(hw, port, &index)) 2476 if (hw->tnl.tbl[index].ref > 1) { 2477 hw->tnl.tbl[index].ref--; 2478 status = ICE_SUCCESS; 2479 goto ice_destroy_tunnel_end; 2480 } 2481 2482 /* determine count */ 2483 for (i = 0; i < hw->tnl.count && i < ICE_TUNNEL_MAX_ENTRIES; i++) 2484 if (hw->tnl.tbl[i].valid && hw->tnl.tbl[i].in_use && 2485 (all || hw->tnl.tbl[i].port == port)) 2486 count++; 2487 2488 if (!count) { 2489 status = ICE_ERR_PARAM; 2490 goto ice_destroy_tunnel_end; 2491 } 2492 2493 /* size of section - there is at least one entry */ 2494 size = ice_struct_size(sect_rx, tcam, count); 2495 2496 bld = ice_pkg_buf_alloc(hw); 2497 if (!bld) { 2498 status = ICE_ERR_NO_MEMORY; 2499 goto ice_destroy_tunnel_end; 2500 } 2501 2502 /* allocate 2 sections, one for Rx parser, one for Tx parser */ 2503 if (ice_pkg_buf_reserve_section(bld, 2)) 2504 goto ice_destroy_tunnel_err; 2505 2506 sect_rx = (struct ice_boost_tcam_section *) 2507 ice_pkg_buf_alloc_section(bld, ICE_SID_RXPARSER_BOOST_TCAM, 2508 size); 2509 if (!sect_rx) 2510 goto ice_destroy_tunnel_err; 2511 sect_rx->count = CPU_TO_LE16(count); 2512 2513 sect_tx = (struct ice_boost_tcam_section *) 2514 ice_pkg_buf_alloc_section(bld, ICE_SID_TXPARSER_BOOST_TCAM, 2515 size); 2516 if (!sect_tx) 2517 goto ice_destroy_tunnel_err; 2518 sect_tx->count = CPU_TO_LE16(count); 2519 2520 /* copy original boost entry to update package buffer, one copy to Rx 2521 * section, another copy to the Tx section 2522 */ 2523 for (i = 0, j = 0; i < hw->tnl.count && i < ICE_TUNNEL_MAX_ENTRIES; i++) 2524 if (hw->tnl.tbl[i].valid && hw->tnl.tbl[i].in_use && 2525 (all || hw->tnl.tbl[i].port == port)) { 2526 ice_memcpy(sect_rx->tcam + j, 2527 hw->tnl.tbl[i].boost_entry, 2528 sizeof(*sect_rx->tcam), 2529 ICE_NONDMA_TO_NONDMA); 2530 ice_memcpy(sect_tx->tcam + j, 2531 hw->tnl.tbl[i].boost_entry, 2532 sizeof(*sect_tx->tcam), 2533 ICE_NONDMA_TO_NONDMA); 2534 hw->tnl.tbl[i].marked = true; 2535 j++; 2536 } 2537 2538 status = ice_update_pkg(hw, ice_pkg_buf(bld), 1); 2539 if (!status) 2540 for (i = 0; i < hw->tnl.count && 2541 i < ICE_TUNNEL_MAX_ENTRIES; i++) 2542 if (hw->tnl.tbl[i].marked) { 2543 hw->tnl.tbl[i].ref = 0; 2544 hw->tnl.tbl[i].port = 0; 2545 hw->tnl.tbl[i].in_use = false; 2546 hw->tnl.tbl[i].marked = false; 2547 } 2548 2549 ice_destroy_tunnel_err: 2550 ice_pkg_buf_free(hw, bld); 2551 2552 ice_destroy_tunnel_end: 2553 ice_release_lock(&hw->tnl_lock); 2554 2555 return status; 2556 } 2557 2558 /** 2559 * ice_find_prot_off - find prot ID and offset pair, based on prof and FV index 2560 * @hw: pointer to the hardware structure 2561 * @blk: hardware block 2562 * @prof: profile ID 2563 * @fv_idx: field vector word index 2564 * @prot: variable to receive the protocol ID 2565 * @off: variable to receive the protocol offset 2566 */ 2567 enum ice_status 2568 ice_find_prot_off(struct ice_hw *hw, enum ice_block blk, u8 prof, u16 fv_idx, 2569 u8 *prot, u16 *off) 2570 { 2571 struct ice_fv_word *fv_ext; 2572 2573 if (prof >= hw->blk[blk].es.count) 2574 return ICE_ERR_PARAM; 2575 2576 if (fv_idx >= hw->blk[blk].es.fvw) 2577 return ICE_ERR_PARAM; 2578 2579 fv_ext = hw->blk[blk].es.t + (prof * hw->blk[blk].es.fvw); 2580 2581 *prot = fv_ext[fv_idx].prot_id; 2582 *off = fv_ext[fv_idx].off; 2583 2584 return ICE_SUCCESS; 2585 } 2586 2587 /* PTG Management */ 2588 2589 /** 2590 * ice_ptg_find_ptype - Search for packet type group using packet type (ptype) 2591 * @hw: pointer to the hardware structure 2592 * @blk: HW block 2593 * @ptype: the ptype to search for 2594 * @ptg: pointer to variable that receives the PTG 2595 * 2596 * This function will search the PTGs for a particular ptype, returning the 2597 * PTG ID that contains it through the PTG parameter, with the value of 2598 * ICE_DEFAULT_PTG (0) meaning it is part the default PTG. 2599 */ 2600 static enum ice_status 2601 ice_ptg_find_ptype(struct ice_hw *hw, enum ice_block blk, u16 ptype, u8 *ptg) 2602 { 2603 if (ptype >= ICE_XLT1_CNT || !ptg) 2604 return ICE_ERR_PARAM; 2605 2606 *ptg = hw->blk[blk].xlt1.ptypes[ptype].ptg; 2607 return ICE_SUCCESS; 2608 } 2609 2610 /** 2611 * ice_ptg_alloc_val - Allocates a new packet type group ID by value 2612 * @hw: pointer to the hardware structure 2613 * @blk: HW block 2614 * @ptg: the PTG to allocate 2615 * 2616 * This function allocates a given packet type group ID specified by the PTG 2617 * parameter. 2618 */ 2619 static void ice_ptg_alloc_val(struct ice_hw *hw, enum ice_block blk, u8 ptg) 2620 { 2621 hw->blk[blk].xlt1.ptg_tbl[ptg].in_use = true; 2622 } 2623 2624 /** 2625 * ice_ptg_remove_ptype - Removes ptype from a particular packet type group 2626 * @hw: pointer to the hardware structure 2627 * @blk: HW block 2628 * @ptype: the ptype to remove 2629 * @ptg: the PTG to remove the ptype from 2630 * 2631 * This function will remove the ptype from the specific PTG, and move it to 2632 * the default PTG (ICE_DEFAULT_PTG). 2633 */ 2634 static enum ice_status 2635 ice_ptg_remove_ptype(struct ice_hw *hw, enum ice_block blk, u16 ptype, u8 ptg) 2636 { 2637 struct ice_ptg_ptype **ch; 2638 struct ice_ptg_ptype *p; 2639 2640 if (ptype > ICE_XLT1_CNT - 1) 2641 return ICE_ERR_PARAM; 2642 2643 if (!hw->blk[blk].xlt1.ptg_tbl[ptg].in_use) 2644 return ICE_ERR_DOES_NOT_EXIST; 2645 2646 /* Should not happen if .in_use is set, bad config */ 2647 if (!hw->blk[blk].xlt1.ptg_tbl[ptg].first_ptype) 2648 return ICE_ERR_CFG; 2649 2650 /* find the ptype within this PTG, and bypass the link over it */ 2651 p = hw->blk[blk].xlt1.ptg_tbl[ptg].first_ptype; 2652 ch = &hw->blk[blk].xlt1.ptg_tbl[ptg].first_ptype; 2653 while (p) { 2654 if (ptype == (p - hw->blk[blk].xlt1.ptypes)) { 2655 *ch = p->next_ptype; 2656 break; 2657 } 2658 2659 ch = &p->next_ptype; 2660 p = p->next_ptype; 2661 } 2662 2663 hw->blk[blk].xlt1.ptypes[ptype].ptg = ICE_DEFAULT_PTG; 2664 hw->blk[blk].xlt1.ptypes[ptype].next_ptype = NULL; 2665 2666 return ICE_SUCCESS; 2667 } 2668 2669 /** 2670 * ice_ptg_add_mv_ptype - Adds/moves ptype to a particular packet type group 2671 * @hw: pointer to the hardware structure 2672 * @blk: HW block 2673 * @ptype: the ptype to add or move 2674 * @ptg: the PTG to add or move the ptype to 2675 * 2676 * This function will either add or move a ptype to a particular PTG depending 2677 * on if the ptype is already part of another group. Note that using a 2678 * a destination PTG ID of ICE_DEFAULT_PTG (0) will move the ptype to the 2679 * default PTG. 2680 */ 2681 static enum ice_status 2682 ice_ptg_add_mv_ptype(struct ice_hw *hw, enum ice_block blk, u16 ptype, u8 ptg) 2683 { 2684 enum ice_status status; 2685 u8 original_ptg; 2686 2687 if (ptype > ICE_XLT1_CNT - 1) 2688 return ICE_ERR_PARAM; 2689 2690 if (!hw->blk[blk].xlt1.ptg_tbl[ptg].in_use && ptg != ICE_DEFAULT_PTG) 2691 return ICE_ERR_DOES_NOT_EXIST; 2692 2693 status = ice_ptg_find_ptype(hw, blk, ptype, &original_ptg); 2694 if (status) 2695 return status; 2696 2697 /* Is ptype already in the correct PTG? */ 2698 if (original_ptg == ptg) 2699 return ICE_SUCCESS; 2700 2701 /* Remove from original PTG and move back to the default PTG */ 2702 if (original_ptg != ICE_DEFAULT_PTG) 2703 ice_ptg_remove_ptype(hw, blk, ptype, original_ptg); 2704 2705 /* Moving to default PTG? Then we're done with this request */ 2706 if (ptg == ICE_DEFAULT_PTG) 2707 return ICE_SUCCESS; 2708 2709 /* Add ptype to PTG at beginning of list */ 2710 hw->blk[blk].xlt1.ptypes[ptype].next_ptype = 2711 hw->blk[blk].xlt1.ptg_tbl[ptg].first_ptype; 2712 hw->blk[blk].xlt1.ptg_tbl[ptg].first_ptype = 2713 &hw->blk[blk].xlt1.ptypes[ptype]; 2714 2715 hw->blk[blk].xlt1.ptypes[ptype].ptg = ptg; 2716 hw->blk[blk].xlt1.t[ptype] = ptg; 2717 2718 return ICE_SUCCESS; 2719 } 2720 2721 /* Block / table size info */ 2722 struct ice_blk_size_details { 2723 u16 xlt1; /* # XLT1 entries */ 2724 u16 xlt2; /* # XLT2 entries */ 2725 u16 prof_tcam; /* # profile ID TCAM entries */ 2726 u16 prof_id; /* # profile IDs */ 2727 u8 prof_cdid_bits; /* # CDID one-hot bits used in key */ 2728 u16 prof_redir; /* # profile redirection entries */ 2729 u16 es; /* # extraction sequence entries */ 2730 u16 fvw; /* # field vector words */ 2731 u8 overwrite; /* overwrite existing entries allowed */ 2732 u8 reverse; /* reverse FV order */ 2733 }; 2734 2735 static const struct ice_blk_size_details blk_sizes[ICE_BLK_COUNT] = { 2736 /** 2737 * Table Definitions 2738 * XLT1 - Number of entries in XLT1 table 2739 * XLT2 - Number of entries in XLT2 table 2740 * TCAM - Number of entries Profile ID TCAM table 2741 * CDID - Control Domain ID of the hardware block 2742 * PRED - Number of entries in the Profile Redirection Table 2743 * FV - Number of entries in the Field Vector 2744 * FVW - Width (in WORDs) of the Field Vector 2745 * OVR - Overwrite existing table entries 2746 * REV - Reverse FV 2747 */ 2748 /* XLT1 , XLT2 ,TCAM, PID,CDID,PRED, FV, FVW */ 2749 /* Overwrite , Reverse FV */ 2750 /* SW */ { ICE_XLT1_CNT, ICE_XLT2_CNT, 512, 256, 0, 256, 256, 48, 2751 false, false }, 2752 /* ACL */ { ICE_XLT1_CNT, ICE_XLT2_CNT, 512, 128, 0, 128, 128, 32, 2753 false, false }, 2754 /* FD */ { ICE_XLT1_CNT, ICE_XLT2_CNT, 512, 128, 0, 128, 128, 24, 2755 false, true }, 2756 /* RSS */ { ICE_XLT1_CNT, ICE_XLT2_CNT, 512, 128, 0, 128, 128, 24, 2757 true, true }, 2758 /* PE */ { ICE_XLT1_CNT, ICE_XLT2_CNT, 64, 32, 0, 32, 32, 24, 2759 false, false }, 2760 }; 2761 2762 enum ice_sid_all { 2763 ICE_SID_XLT1_OFF = 0, 2764 ICE_SID_XLT2_OFF, 2765 ICE_SID_PR_OFF, 2766 ICE_SID_PR_REDIR_OFF, 2767 ICE_SID_ES_OFF, 2768 ICE_SID_OFF_COUNT, 2769 }; 2770 2771 /* Characteristic handling */ 2772 2773 /** 2774 * ice_match_prop_lst - determine if properties of two lists match 2775 * @list1: first properties list 2776 * @list2: second properties list 2777 * 2778 * Count, cookies and the order must match in order to be considered equivalent. 2779 */ 2780 static bool 2781 ice_match_prop_lst(struct LIST_HEAD_TYPE *list1, struct LIST_HEAD_TYPE *list2) 2782 { 2783 struct ice_vsig_prof *tmp1; 2784 struct ice_vsig_prof *tmp2; 2785 u16 chk_count = 0; 2786 u16 count = 0; 2787 2788 /* compare counts */ 2789 LIST_FOR_EACH_ENTRY(tmp1, list1, ice_vsig_prof, list) 2790 count++; 2791 LIST_FOR_EACH_ENTRY(tmp2, list2, ice_vsig_prof, list) 2792 chk_count++; 2793 if (!count || count != chk_count) 2794 return false; 2795 2796 tmp1 = LIST_FIRST_ENTRY(list1, struct ice_vsig_prof, list); 2797 tmp2 = LIST_FIRST_ENTRY(list2, struct ice_vsig_prof, list); 2798 2799 /* profile cookies must compare, and in the exact same order to take 2800 * into account priority 2801 */ 2802 while (count--) { 2803 if (tmp2->profile_cookie != tmp1->profile_cookie) 2804 return false; 2805 2806 tmp1 = LIST_NEXT_ENTRY(tmp1, struct ice_vsig_prof, list); 2807 tmp2 = LIST_NEXT_ENTRY(tmp2, struct ice_vsig_prof, list); 2808 } 2809 2810 return true; 2811 } 2812 2813 /* VSIG Management */ 2814 2815 /** 2816 * ice_vsig_find_vsi - find a VSIG that contains a specified VSI 2817 * @hw: pointer to the hardware structure 2818 * @blk: HW block 2819 * @vsi: VSI of interest 2820 * @vsig: pointer to receive the VSI group 2821 * 2822 * This function will lookup the VSI entry in the XLT2 list and return 2823 * the VSI group its associated with. 2824 */ 2825 enum ice_status 2826 ice_vsig_find_vsi(struct ice_hw *hw, enum ice_block blk, u16 vsi, u16 *vsig) 2827 { 2828 if (!vsig || vsi >= ICE_MAX_VSI) 2829 return ICE_ERR_PARAM; 2830 2831 /* As long as there's a default or valid VSIG associated with the input 2832 * VSI, the functions returns a success. Any handling of VSIG will be 2833 * done by the following add, update or remove functions. 2834 */ 2835 *vsig = hw->blk[blk].xlt2.vsis[vsi].vsig; 2836 2837 return ICE_SUCCESS; 2838 } 2839 2840 /** 2841 * ice_vsig_alloc_val - allocate a new VSIG by value 2842 * @hw: pointer to the hardware structure 2843 * @blk: HW block 2844 * @vsig: the VSIG to allocate 2845 * 2846 * This function will allocate a given VSIG specified by the VSIG parameter. 2847 */ 2848 static u16 ice_vsig_alloc_val(struct ice_hw *hw, enum ice_block blk, u16 vsig) 2849 { 2850 u16 idx = vsig & ICE_VSIG_IDX_M; 2851 2852 if (!hw->blk[blk].xlt2.vsig_tbl[idx].in_use) { 2853 INIT_LIST_HEAD(&hw->blk[blk].xlt2.vsig_tbl[idx].prop_lst); 2854 hw->blk[blk].xlt2.vsig_tbl[idx].in_use = true; 2855 } 2856 2857 return ICE_VSIG_VALUE(idx, hw->pf_id); 2858 } 2859 2860 /** 2861 * ice_vsig_alloc - Finds a free entry and allocates a new VSIG 2862 * @hw: pointer to the hardware structure 2863 * @blk: HW block 2864 * 2865 * This function will iterate through the VSIG list and mark the first 2866 * unused entry for the new VSIG entry as used and return that value. 2867 */ 2868 static u16 ice_vsig_alloc(struct ice_hw *hw, enum ice_block blk) 2869 { 2870 u16 i; 2871 2872 for (i = 1; i < ICE_MAX_VSIGS; i++) 2873 if (!hw->blk[blk].xlt2.vsig_tbl[i].in_use) 2874 return ice_vsig_alloc_val(hw, blk, i); 2875 2876 return ICE_DEFAULT_VSIG; 2877 } 2878 2879 /** 2880 * ice_find_dup_props_vsig - find VSI group with a specified set of properties 2881 * @hw: pointer to the hardware structure 2882 * @blk: HW block 2883 * @chs: characteristic list 2884 * @vsig: returns the VSIG with the matching profiles, if found 2885 * 2886 * Each VSIG is associated with a characteristic set; i.e. all VSIs under 2887 * a group have the same characteristic set. To check if there exists a VSIG 2888 * which has the same characteristics as the input characteristics; this 2889 * function will iterate through the XLT2 list and return the VSIG that has a 2890 * matching configuration. In order to make sure that priorities are accounted 2891 * for, the list must match exactly, including the order in which the 2892 * characteristics are listed. 2893 */ 2894 static enum ice_status 2895 ice_find_dup_props_vsig(struct ice_hw *hw, enum ice_block blk, 2896 struct LIST_HEAD_TYPE *chs, u16 *vsig) 2897 { 2898 struct ice_xlt2 *xlt2 = &hw->blk[blk].xlt2; 2899 u16 i; 2900 2901 for (i = 0; i < xlt2->count; i++) 2902 if (xlt2->vsig_tbl[i].in_use && 2903 ice_match_prop_lst(chs, &xlt2->vsig_tbl[i].prop_lst)) { 2904 *vsig = ICE_VSIG_VALUE(i, hw->pf_id); 2905 return ICE_SUCCESS; 2906 } 2907 2908 return ICE_ERR_DOES_NOT_EXIST; 2909 } 2910 2911 /** 2912 * ice_vsig_free - free VSI group 2913 * @hw: pointer to the hardware structure 2914 * @blk: HW block 2915 * @vsig: VSIG to remove 2916 * 2917 * The function will remove all VSIs associated with the input VSIG and move 2918 * them to the DEFAULT_VSIG and mark the VSIG available. 2919 */ 2920 static enum ice_status 2921 ice_vsig_free(struct ice_hw *hw, enum ice_block blk, u16 vsig) 2922 { 2923 struct ice_vsig_prof *dtmp, *del; 2924 struct ice_vsig_vsi *vsi_cur; 2925 u16 idx; 2926 2927 idx = vsig & ICE_VSIG_IDX_M; 2928 if (idx >= ICE_MAX_VSIGS) 2929 return ICE_ERR_PARAM; 2930 2931 if (!hw->blk[blk].xlt2.vsig_tbl[idx].in_use) 2932 return ICE_ERR_DOES_NOT_EXIST; 2933 2934 hw->blk[blk].xlt2.vsig_tbl[idx].in_use = false; 2935 2936 vsi_cur = hw->blk[blk].xlt2.vsig_tbl[idx].first_vsi; 2937 /* If the VSIG has at least 1 VSI then iterate through the 2938 * list and remove the VSIs before deleting the group. 2939 */ 2940 if (vsi_cur) { 2941 /* remove all vsis associated with this VSIG XLT2 entry */ 2942 do { 2943 struct ice_vsig_vsi *tmp = vsi_cur->next_vsi; 2944 2945 vsi_cur->vsig = ICE_DEFAULT_VSIG; 2946 vsi_cur->changed = 1; 2947 vsi_cur->next_vsi = NULL; 2948 vsi_cur = tmp; 2949 } while (vsi_cur); 2950 2951 /* NULL terminate head of VSI list */ 2952 hw->blk[blk].xlt2.vsig_tbl[idx].first_vsi = NULL; 2953 } 2954 2955 /* free characteristic list */ 2956 LIST_FOR_EACH_ENTRY_SAFE(del, dtmp, 2957 &hw->blk[blk].xlt2.vsig_tbl[idx].prop_lst, 2958 ice_vsig_prof, list) { 2959 LIST_DEL(&del->list); 2960 ice_free(hw, del); 2961 } 2962 2963 /* if VSIG characteristic list was cleared for reset 2964 * re-initialize the list head 2965 */ 2966 INIT_LIST_HEAD(&hw->blk[blk].xlt2.vsig_tbl[idx].prop_lst); 2967 2968 return ICE_SUCCESS; 2969 } 2970 2971 /** 2972 * ice_vsig_remove_vsi - remove VSI from VSIG 2973 * @hw: pointer to the hardware structure 2974 * @blk: HW block 2975 * @vsi: VSI to remove 2976 * @vsig: VSI group to remove from 2977 * 2978 * The function will remove the input VSI from its VSI group and move it 2979 * to the DEFAULT_VSIG. 2980 */ 2981 static enum ice_status 2982 ice_vsig_remove_vsi(struct ice_hw *hw, enum ice_block blk, u16 vsi, u16 vsig) 2983 { 2984 struct ice_vsig_vsi **vsi_head, *vsi_cur, *vsi_tgt; 2985 u16 idx; 2986 2987 idx = vsig & ICE_VSIG_IDX_M; 2988 2989 if (vsi >= ICE_MAX_VSI || idx >= ICE_MAX_VSIGS) 2990 return ICE_ERR_PARAM; 2991 2992 if (!hw->blk[blk].xlt2.vsig_tbl[idx].in_use) 2993 return ICE_ERR_DOES_NOT_EXIST; 2994 2995 /* entry already in default VSIG, don't have to remove */ 2996 if (idx == ICE_DEFAULT_VSIG) 2997 return ICE_SUCCESS; 2998 2999 vsi_head = &hw->blk[blk].xlt2.vsig_tbl[idx].first_vsi; 3000 if (!(*vsi_head)) 3001 return ICE_ERR_CFG; 3002 3003 vsi_tgt = &hw->blk[blk].xlt2.vsis[vsi]; 3004 vsi_cur = (*vsi_head); 3005 3006 /* iterate the VSI list, skip over the entry to be removed */ 3007 while (vsi_cur) { 3008 if (vsi_tgt == vsi_cur) { 3009 (*vsi_head) = vsi_cur->next_vsi; 3010 break; 3011 } 3012 vsi_head = &vsi_cur->next_vsi; 3013 vsi_cur = vsi_cur->next_vsi; 3014 } 3015 3016 /* verify if VSI was removed from group list */ 3017 if (!vsi_cur) 3018 return ICE_ERR_DOES_NOT_EXIST; 3019 3020 vsi_cur->vsig = ICE_DEFAULT_VSIG; 3021 vsi_cur->changed = 1; 3022 vsi_cur->next_vsi = NULL; 3023 3024 return ICE_SUCCESS; 3025 } 3026 3027 /** 3028 * ice_vsig_add_mv_vsi - add or move a VSI to a VSI group 3029 * @hw: pointer to the hardware structure 3030 * @blk: HW block 3031 * @vsi: VSI to move 3032 * @vsig: destination VSI group 3033 * 3034 * This function will move or add the input VSI to the target VSIG. 3035 * The function will find the original VSIG the VSI belongs to and 3036 * move the entry to the DEFAULT_VSIG, update the original VSIG and 3037 * then move entry to the new VSIG. 3038 */ 3039 static enum ice_status 3040 ice_vsig_add_mv_vsi(struct ice_hw *hw, enum ice_block blk, u16 vsi, u16 vsig) 3041 { 3042 struct ice_vsig_vsi *tmp; 3043 enum ice_status status; 3044 u16 orig_vsig, idx; 3045 3046 idx = vsig & ICE_VSIG_IDX_M; 3047 3048 if (vsi >= ICE_MAX_VSI || idx >= ICE_MAX_VSIGS) 3049 return ICE_ERR_PARAM; 3050 3051 /* if VSIG not in use and VSIG is not default type this VSIG 3052 * doesn't exist. 3053 */ 3054 if (!hw->blk[blk].xlt2.vsig_tbl[idx].in_use && 3055 vsig != ICE_DEFAULT_VSIG) 3056 return ICE_ERR_DOES_NOT_EXIST; 3057 3058 status = ice_vsig_find_vsi(hw, blk, vsi, &orig_vsig); 3059 if (status) 3060 return status; 3061 3062 /* no update required if vsigs match */ 3063 if (orig_vsig == vsig) 3064 return ICE_SUCCESS; 3065 3066 if (orig_vsig != ICE_DEFAULT_VSIG) { 3067 /* remove entry from orig_vsig and add to default VSIG */ 3068 status = ice_vsig_remove_vsi(hw, blk, vsi, orig_vsig); 3069 if (status) 3070 return status; 3071 } 3072 3073 if (idx == ICE_DEFAULT_VSIG) 3074 return ICE_SUCCESS; 3075 3076 /* Create VSI entry and add VSIG and prop_mask values */ 3077 hw->blk[blk].xlt2.vsis[vsi].vsig = vsig; 3078 hw->blk[blk].xlt2.vsis[vsi].changed = 1; 3079 3080 /* Add new entry to the head of the VSIG list */ 3081 tmp = hw->blk[blk].xlt2.vsig_tbl[idx].first_vsi; 3082 hw->blk[blk].xlt2.vsig_tbl[idx].first_vsi = 3083 &hw->blk[blk].xlt2.vsis[vsi]; 3084 hw->blk[blk].xlt2.vsis[vsi].next_vsi = tmp; 3085 hw->blk[blk].xlt2.t[vsi] = vsig; 3086 3087 return ICE_SUCCESS; 3088 } 3089 3090 /** 3091 * ice_prof_has_mask_idx - determine if profile index masking is identical 3092 * @hw: pointer to the hardware structure 3093 * @blk: HW block 3094 * @prof: profile to check 3095 * @idx: profile index to check 3096 * @mask: mask to match 3097 */ 3098 static bool 3099 ice_prof_has_mask_idx(struct ice_hw *hw, enum ice_block blk, u8 prof, u16 idx, 3100 u16 mask) 3101 { 3102 bool expect_no_mask = false; 3103 bool found = false; 3104 bool match = false; 3105 u16 i; 3106 3107 /* If mask is 0x0000 or 0xffff, then there is no masking */ 3108 if (mask == 0 || mask == 0xffff) 3109 expect_no_mask = true; 3110 3111 /* Scan the enabled masks on this profile, for the specified idx */ 3112 for (i = hw->blk[blk].masks.first; i < hw->blk[blk].masks.first + 3113 hw->blk[blk].masks.count; i++) 3114 if (hw->blk[blk].es.mask_ena[prof] & BIT(i)) 3115 if (hw->blk[blk].masks.masks[i].in_use && 3116 hw->blk[blk].masks.masks[i].idx == idx) { 3117 found = true; 3118 if (hw->blk[blk].masks.masks[i].mask == mask) 3119 match = true; 3120 break; 3121 } 3122 3123 if (expect_no_mask) { 3124 if (found) 3125 return false; 3126 } else { 3127 if (!match) 3128 return false; 3129 } 3130 3131 return true; 3132 } 3133 3134 /** 3135 * ice_prof_has_mask - determine if profile masking is identical 3136 * @hw: pointer to the hardware structure 3137 * @blk: HW block 3138 * @prof: profile to check 3139 * @masks: masks to match 3140 */ 3141 static bool 3142 ice_prof_has_mask(struct ice_hw *hw, enum ice_block blk, u8 prof, u16 *masks) 3143 { 3144 u16 i; 3145 3146 /* es->mask_ena[prof] will have the mask */ 3147 for (i = 0; i < hw->blk[blk].es.fvw; i++) 3148 if (!ice_prof_has_mask_idx(hw, blk, prof, i, masks[i])) 3149 return false; 3150 3151 return true; 3152 } 3153 3154 /** 3155 * ice_find_prof_id_with_mask - find profile ID for a given field vector 3156 * @hw: pointer to the hardware structure 3157 * @blk: HW block 3158 * @fv: field vector to search for 3159 * @masks: masks for fv 3160 * @prof_id: receives the profile ID 3161 */ 3162 static enum ice_status 3163 ice_find_prof_id_with_mask(struct ice_hw *hw, enum ice_block blk, 3164 struct ice_fv_word *fv, u16 *masks, u8 *prof_id) 3165 { 3166 struct ice_es *es = &hw->blk[blk].es; 3167 u8 i; 3168 3169 /* For FD and RSS, we don't want to re-use an existed profile with the 3170 * same field vector and mask. This will cause rule interference. 3171 */ 3172 if (blk == ICE_BLK_FD || blk == ICE_BLK_RSS) 3173 return ICE_ERR_DOES_NOT_EXIST; 3174 3175 for (i = 0; i < (u8)es->count; i++) { 3176 u16 off = i * es->fvw; 3177 3178 if (memcmp(&es->t[off], fv, es->fvw * sizeof(*fv))) 3179 continue; 3180 3181 /* check if masks settings are the same for this profile */ 3182 if (masks && !ice_prof_has_mask(hw, blk, i, masks)) 3183 continue; 3184 3185 *prof_id = i; 3186 return ICE_SUCCESS; 3187 } 3188 3189 return ICE_ERR_DOES_NOT_EXIST; 3190 } 3191 3192 /** 3193 * ice_prof_id_rsrc_type - get profile ID resource type for a block type 3194 * @blk: the block type 3195 * @rsrc_type: pointer to variable to receive the resource type 3196 */ 3197 static bool ice_prof_id_rsrc_type(enum ice_block blk, u16 *rsrc_type) 3198 { 3199 switch (blk) { 3200 case ICE_BLK_SW: 3201 *rsrc_type = ICE_AQC_RES_TYPE_SWITCH_PROF_BLDR_PROFID; 3202 break; 3203 case ICE_BLK_ACL: 3204 *rsrc_type = ICE_AQC_RES_TYPE_ACL_PROF_BLDR_PROFID; 3205 break; 3206 case ICE_BLK_FD: 3207 *rsrc_type = ICE_AQC_RES_TYPE_FD_PROF_BLDR_PROFID; 3208 break; 3209 case ICE_BLK_RSS: 3210 *rsrc_type = ICE_AQC_RES_TYPE_HASH_PROF_BLDR_PROFID; 3211 break; 3212 case ICE_BLK_PE: 3213 *rsrc_type = ICE_AQC_RES_TYPE_QHASH_PROF_BLDR_PROFID; 3214 break; 3215 default: 3216 return false; 3217 } 3218 return true; 3219 } 3220 3221 /** 3222 * ice_tcam_ent_rsrc_type - get TCAM entry resource type for a block type 3223 * @blk: the block type 3224 * @rsrc_type: pointer to variable to receive the resource type 3225 */ 3226 static bool ice_tcam_ent_rsrc_type(enum ice_block blk, u16 *rsrc_type) 3227 { 3228 switch (blk) { 3229 case ICE_BLK_SW: 3230 *rsrc_type = ICE_AQC_RES_TYPE_SWITCH_PROF_BLDR_TCAM; 3231 break; 3232 case ICE_BLK_ACL: 3233 *rsrc_type = ICE_AQC_RES_TYPE_ACL_PROF_BLDR_TCAM; 3234 break; 3235 case ICE_BLK_FD: 3236 *rsrc_type = ICE_AQC_RES_TYPE_FD_PROF_BLDR_TCAM; 3237 break; 3238 case ICE_BLK_RSS: 3239 *rsrc_type = ICE_AQC_RES_TYPE_HASH_PROF_BLDR_TCAM; 3240 break; 3241 case ICE_BLK_PE: 3242 *rsrc_type = ICE_AQC_RES_TYPE_QHASH_PROF_BLDR_TCAM; 3243 break; 3244 default: 3245 return false; 3246 } 3247 return true; 3248 } 3249 3250 /** 3251 * ice_alloc_tcam_ent - allocate hardware TCAM entry 3252 * @hw: pointer to the HW struct 3253 * @blk: the block to allocate the TCAM for 3254 * @btm: true to allocate from bottom of table, false to allocate from top 3255 * @tcam_idx: pointer to variable to receive the TCAM entry 3256 * 3257 * This function allocates a new entry in a Profile ID TCAM for a specific 3258 * block. 3259 */ 3260 static enum ice_status 3261 ice_alloc_tcam_ent(struct ice_hw *hw, enum ice_block blk, bool btm, 3262 u16 *tcam_idx) 3263 { 3264 u16 res_type; 3265 3266 if (!ice_tcam_ent_rsrc_type(blk, &res_type)) 3267 return ICE_ERR_PARAM; 3268 3269 return ice_alloc_hw_res(hw, res_type, 1, btm, tcam_idx); 3270 } 3271 3272 /** 3273 * ice_free_tcam_ent - free hardware TCAM entry 3274 * @hw: pointer to the HW struct 3275 * @blk: the block from which to free the TCAM entry 3276 * @tcam_idx: the TCAM entry to free 3277 * 3278 * This function frees an entry in a Profile ID TCAM for a specific block. 3279 */ 3280 static enum ice_status 3281 ice_free_tcam_ent(struct ice_hw *hw, enum ice_block blk, u16 tcam_idx) 3282 { 3283 u16 res_type; 3284 3285 if (!ice_tcam_ent_rsrc_type(blk, &res_type)) 3286 return ICE_ERR_PARAM; 3287 3288 return ice_free_hw_res(hw, res_type, 1, &tcam_idx); 3289 } 3290 3291 /** 3292 * ice_alloc_prof_id - allocate profile ID 3293 * @hw: pointer to the HW struct 3294 * @blk: the block to allocate the profile ID for 3295 * @prof_id: pointer to variable to receive the profile ID 3296 * 3297 * This function allocates a new profile ID, which also corresponds to a Field 3298 * Vector (Extraction Sequence) entry. 3299 */ 3300 static enum ice_status 3301 ice_alloc_prof_id(struct ice_hw *hw, enum ice_block blk, u8 *prof_id) 3302 { 3303 enum ice_status status; 3304 u16 res_type; 3305 u16 get_prof; 3306 3307 if (!ice_prof_id_rsrc_type(blk, &res_type)) 3308 return ICE_ERR_PARAM; 3309 3310 status = ice_alloc_hw_res(hw, res_type, 1, false, &get_prof); 3311 if (!status) 3312 *prof_id = (u8)get_prof; 3313 3314 return status; 3315 } 3316 3317 /** 3318 * ice_free_prof_id - free profile ID 3319 * @hw: pointer to the HW struct 3320 * @blk: the block from which to free the profile ID 3321 * @prof_id: the profile ID to free 3322 * 3323 * This function frees a profile ID, which also corresponds to a Field Vector. 3324 */ 3325 static enum ice_status 3326 ice_free_prof_id(struct ice_hw *hw, enum ice_block blk, u8 prof_id) 3327 { 3328 u16 tmp_prof_id = (u16)prof_id; 3329 u16 res_type; 3330 3331 if (!ice_prof_id_rsrc_type(blk, &res_type)) 3332 return ICE_ERR_PARAM; 3333 3334 return ice_free_hw_res(hw, res_type, 1, &tmp_prof_id); 3335 } 3336 3337 /** 3338 * ice_prof_inc_ref - increment reference count for profile 3339 * @hw: pointer to the HW struct 3340 * @blk: the block from which to free the profile ID 3341 * @prof_id: the profile ID for which to increment the reference count 3342 */ 3343 static enum ice_status 3344 ice_prof_inc_ref(struct ice_hw *hw, enum ice_block blk, u8 prof_id) 3345 { 3346 if (prof_id > hw->blk[blk].es.count) 3347 return ICE_ERR_PARAM; 3348 3349 hw->blk[blk].es.ref_count[prof_id]++; 3350 3351 return ICE_SUCCESS; 3352 } 3353 3354 /** 3355 * ice_write_prof_mask_reg - write profile mask register 3356 * @hw: pointer to the HW struct 3357 * @blk: hardware block 3358 * @mask_idx: mask index 3359 * @idx: index of the FV which will use the mask 3360 * @mask: the 16-bit mask 3361 */ 3362 static void 3363 ice_write_prof_mask_reg(struct ice_hw *hw, enum ice_block blk, u16 mask_idx, 3364 u16 idx, u16 mask) 3365 { 3366 u32 offset; 3367 u32 val; 3368 3369 switch (blk) { 3370 case ICE_BLK_RSS: 3371 offset = GLQF_HMASK(mask_idx); 3372 val = (idx << GLQF_HMASK_MSK_INDEX_S) & 3373 GLQF_HMASK_MSK_INDEX_M; 3374 val |= (mask << GLQF_HMASK_MASK_S) & GLQF_HMASK_MASK_M; 3375 break; 3376 case ICE_BLK_FD: 3377 offset = GLQF_FDMASK(mask_idx); 3378 val = (idx << GLQF_FDMASK_MSK_INDEX_S) & 3379 GLQF_FDMASK_MSK_INDEX_M; 3380 val |= (mask << GLQF_FDMASK_MASK_S) & 3381 GLQF_FDMASK_MASK_M; 3382 break; 3383 default: 3384 ice_debug(hw, ICE_DBG_PKG, "No profile masks for block %d\n", 3385 blk); 3386 return; 3387 } 3388 3389 wr32(hw, offset, val); 3390 ice_debug(hw, ICE_DBG_PKG, "write mask, blk %d (%d): %x = %x\n", 3391 blk, idx, offset, val); 3392 } 3393 3394 /** 3395 * ice_write_prof_mask_enable_res - write profile mask enable register 3396 * @hw: pointer to the HW struct 3397 * @blk: hardware block 3398 * @prof_id: profile ID 3399 * @enable_mask: enable mask 3400 */ 3401 static void 3402 ice_write_prof_mask_enable_res(struct ice_hw *hw, enum ice_block blk, 3403 u16 prof_id, u32 enable_mask) 3404 { 3405 u32 offset; 3406 3407 switch (blk) { 3408 case ICE_BLK_RSS: 3409 offset = GLQF_HMASK_SEL(prof_id); 3410 break; 3411 case ICE_BLK_FD: 3412 offset = GLQF_FDMASK_SEL(prof_id); 3413 break; 3414 default: 3415 ice_debug(hw, ICE_DBG_PKG, "No profile masks for block %d\n", 3416 blk); 3417 return; 3418 } 3419 3420 wr32(hw, offset, enable_mask); 3421 ice_debug(hw, ICE_DBG_PKG, "write mask enable, blk %d (%d): %x = %x\n", 3422 blk, prof_id, offset, enable_mask); 3423 } 3424 3425 /** 3426 * ice_init_prof_masks - initial prof masks 3427 * @hw: pointer to the HW struct 3428 * @blk: hardware block 3429 */ 3430 static void ice_init_prof_masks(struct ice_hw *hw, enum ice_block blk) 3431 { 3432 u16 per_pf; 3433 u16 i; 3434 3435 ice_init_lock(&hw->blk[blk].masks.lock); 3436 3437 per_pf = ICE_PROF_MASK_COUNT / hw->dev_caps.num_funcs; 3438 3439 hw->blk[blk].masks.count = per_pf; 3440 hw->blk[blk].masks.first = hw->logical_pf_id * per_pf; 3441 3442 ice_memset(hw->blk[blk].masks.masks, 0, 3443 sizeof(hw->blk[blk].masks.masks), ICE_NONDMA_MEM); 3444 3445 for (i = hw->blk[blk].masks.first; 3446 i < hw->blk[blk].masks.first + hw->blk[blk].masks.count; i++) 3447 ice_write_prof_mask_reg(hw, blk, i, 0, 0); 3448 } 3449 3450 /** 3451 * ice_init_all_prof_masks - initial all prof masks 3452 * @hw: pointer to the HW struct 3453 */ 3454 void ice_init_all_prof_masks(struct ice_hw *hw) 3455 { 3456 ice_init_prof_masks(hw, ICE_BLK_RSS); 3457 ice_init_prof_masks(hw, ICE_BLK_FD); 3458 } 3459 3460 /** 3461 * ice_alloc_prof_mask - allocate profile mask 3462 * @hw: pointer to the HW struct 3463 * @blk: hardware block 3464 * @idx: index of FV which will use the mask 3465 * @mask: the 16-bit mask 3466 * @mask_idx: variable to receive the mask index 3467 */ 3468 static enum ice_status 3469 ice_alloc_prof_mask(struct ice_hw *hw, enum ice_block blk, u16 idx, u16 mask, 3470 u16 *mask_idx) 3471 { 3472 bool found_unused = false, found_copy = false; 3473 enum ice_status status = ICE_ERR_MAX_LIMIT; 3474 u16 unused_idx = 0, copy_idx = 0; 3475 u16 i; 3476 3477 if (blk != ICE_BLK_RSS && blk != ICE_BLK_FD) 3478 return ICE_ERR_PARAM; 3479 3480 ice_acquire_lock(&hw->blk[blk].masks.lock); 3481 3482 for (i = hw->blk[blk].masks.first; 3483 i < hw->blk[blk].masks.first + hw->blk[blk].masks.count; i++) 3484 if (hw->blk[blk].masks.masks[i].in_use) { 3485 /* if mask is in use and it exactly duplicates the 3486 * desired mask and index, then in can be reused 3487 */ 3488 if (hw->blk[blk].masks.masks[i].mask == mask && 3489 hw->blk[blk].masks.masks[i].idx == idx) { 3490 found_copy = true; 3491 copy_idx = i; 3492 break; 3493 } 3494 } else { 3495 /* save off unused index, but keep searching in case 3496 * there is an exact match later on 3497 */ 3498 if (!found_unused) { 3499 found_unused = true; 3500 unused_idx = i; 3501 } 3502 } 3503 3504 if (found_copy) 3505 i = copy_idx; 3506 else if (found_unused) 3507 i = unused_idx; 3508 else 3509 goto err_ice_alloc_prof_mask; 3510 3511 /* update mask for a new entry */ 3512 if (found_unused) { 3513 hw->blk[blk].masks.masks[i].in_use = true; 3514 hw->blk[blk].masks.masks[i].mask = mask; 3515 hw->blk[blk].masks.masks[i].idx = idx; 3516 hw->blk[blk].masks.masks[i].ref = 0; 3517 ice_write_prof_mask_reg(hw, blk, i, idx, mask); 3518 } 3519 3520 hw->blk[blk].masks.masks[i].ref++; 3521 *mask_idx = i; 3522 status = ICE_SUCCESS; 3523 3524 err_ice_alloc_prof_mask: 3525 ice_release_lock(&hw->blk[blk].masks.lock); 3526 3527 return status; 3528 } 3529 3530 /** 3531 * ice_free_prof_mask - free profile mask 3532 * @hw: pointer to the HW struct 3533 * @blk: hardware block 3534 * @mask_idx: index of mask 3535 */ 3536 static enum ice_status 3537 ice_free_prof_mask(struct ice_hw *hw, enum ice_block blk, u16 mask_idx) 3538 { 3539 if (blk != ICE_BLK_RSS && blk != ICE_BLK_FD) 3540 return ICE_ERR_PARAM; 3541 3542 if (!(mask_idx >= hw->blk[blk].masks.first && 3543 mask_idx < hw->blk[blk].masks.first + hw->blk[blk].masks.count)) 3544 return ICE_ERR_DOES_NOT_EXIST; 3545 3546 ice_acquire_lock(&hw->blk[blk].masks.lock); 3547 3548 if (!hw->blk[blk].masks.masks[mask_idx].in_use) 3549 goto exit_ice_free_prof_mask; 3550 3551 if (hw->blk[blk].masks.masks[mask_idx].ref > 1) { 3552 hw->blk[blk].masks.masks[mask_idx].ref--; 3553 goto exit_ice_free_prof_mask; 3554 } 3555 3556 /* remove mask */ 3557 hw->blk[blk].masks.masks[mask_idx].in_use = false; 3558 hw->blk[blk].masks.masks[mask_idx].mask = 0; 3559 hw->blk[blk].masks.masks[mask_idx].idx = 0; 3560 3561 /* update mask as unused entry */ 3562 ice_debug(hw, ICE_DBG_PKG, "Free mask, blk %d, mask %d\n", blk, 3563 mask_idx); 3564 ice_write_prof_mask_reg(hw, blk, mask_idx, 0, 0); 3565 3566 exit_ice_free_prof_mask: 3567 ice_release_lock(&hw->blk[blk].masks.lock); 3568 3569 return ICE_SUCCESS; 3570 } 3571 3572 /** 3573 * ice_free_prof_masks - free all profile masks for a profile 3574 * @hw: pointer to the HW struct 3575 * @blk: hardware block 3576 * @prof_id: profile ID 3577 */ 3578 static enum ice_status 3579 ice_free_prof_masks(struct ice_hw *hw, enum ice_block blk, u16 prof_id) 3580 { 3581 u32 mask_bm; 3582 u16 i; 3583 3584 if (blk != ICE_BLK_RSS && blk != ICE_BLK_FD) 3585 return ICE_ERR_PARAM; 3586 3587 mask_bm = hw->blk[blk].es.mask_ena[prof_id]; 3588 for (i = 0; i < BITS_PER_BYTE * sizeof(mask_bm); i++) 3589 if (mask_bm & BIT(i)) 3590 ice_free_prof_mask(hw, blk, i); 3591 3592 return ICE_SUCCESS; 3593 } 3594 3595 /** 3596 * ice_shutdown_prof_masks - releases lock for masking 3597 * @hw: pointer to the HW struct 3598 * @blk: hardware block 3599 * 3600 * This should be called before unloading the driver 3601 */ 3602 static void ice_shutdown_prof_masks(struct ice_hw *hw, enum ice_block blk) 3603 { 3604 u16 i; 3605 3606 ice_acquire_lock(&hw->blk[blk].masks.lock); 3607 3608 for (i = hw->blk[blk].masks.first; 3609 i < hw->blk[blk].masks.first + hw->blk[blk].masks.count; i++) { 3610 ice_write_prof_mask_reg(hw, blk, i, 0, 0); 3611 3612 hw->blk[blk].masks.masks[i].in_use = false; 3613 hw->blk[blk].masks.masks[i].idx = 0; 3614 hw->blk[blk].masks.masks[i].mask = 0; 3615 } 3616 3617 ice_release_lock(&hw->blk[blk].masks.lock); 3618 ice_destroy_lock(&hw->blk[blk].masks.lock); 3619 } 3620 3621 /** 3622 * ice_shutdown_all_prof_masks - releases all locks for masking 3623 * @hw: pointer to the HW struct 3624 * 3625 * This should be called before unloading the driver 3626 */ 3627 void ice_shutdown_all_prof_masks(struct ice_hw *hw) 3628 { 3629 ice_shutdown_prof_masks(hw, ICE_BLK_RSS); 3630 ice_shutdown_prof_masks(hw, ICE_BLK_FD); 3631 } 3632 3633 /** 3634 * ice_update_prof_masking - set registers according to masking 3635 * @hw: pointer to the HW struct 3636 * @blk: hardware block 3637 * @prof_id: profile ID 3638 * @masks: masks 3639 */ 3640 static enum ice_status 3641 ice_update_prof_masking(struct ice_hw *hw, enum ice_block blk, u16 prof_id, 3642 u16 *masks) 3643 { 3644 bool err = false; 3645 u32 ena_mask = 0; 3646 u16 idx; 3647 u16 i; 3648 3649 /* Only support FD and RSS masking, otherwise nothing to be done */ 3650 if (blk != ICE_BLK_RSS && blk != ICE_BLK_FD) 3651 return ICE_SUCCESS; 3652 3653 for (i = 0; i < hw->blk[blk].es.fvw; i++) 3654 if (masks[i] && masks[i] != 0xFFFF) { 3655 if (!ice_alloc_prof_mask(hw, blk, i, masks[i], &idx)) { 3656 ena_mask |= BIT(idx); 3657 } else { 3658 /* not enough bitmaps */ 3659 err = true; 3660 break; 3661 } 3662 } 3663 3664 if (err) { 3665 /* free any bitmaps we have allocated */ 3666 for (i = 0; i < BITS_PER_BYTE * sizeof(ena_mask); i++) 3667 if (ena_mask & BIT(i)) 3668 ice_free_prof_mask(hw, blk, i); 3669 3670 return ICE_ERR_OUT_OF_RANGE; 3671 } 3672 3673 /* enable the masks for this profile */ 3674 ice_write_prof_mask_enable_res(hw, blk, prof_id, ena_mask); 3675 3676 /* store enabled masks with profile so that they can be freed later */ 3677 hw->blk[blk].es.mask_ena[prof_id] = ena_mask; 3678 3679 return ICE_SUCCESS; 3680 } 3681 3682 /** 3683 * ice_write_es - write an extraction sequence to hardware 3684 * @hw: pointer to the HW struct 3685 * @blk: the block in which to write the extraction sequence 3686 * @prof_id: the profile ID to write 3687 * @fv: pointer to the extraction sequence to write - NULL to clear extraction 3688 */ 3689 static void 3690 ice_write_es(struct ice_hw *hw, enum ice_block blk, u8 prof_id, 3691 struct ice_fv_word *fv) 3692 { 3693 u16 off; 3694 3695 off = prof_id * hw->blk[blk].es.fvw; 3696 if (!fv) { 3697 ice_memset(&hw->blk[blk].es.t[off], 0, hw->blk[blk].es.fvw * 3698 sizeof(*fv), ICE_NONDMA_MEM); 3699 hw->blk[blk].es.written[prof_id] = false; 3700 } else { 3701 ice_memcpy(&hw->blk[blk].es.t[off], fv, hw->blk[blk].es.fvw * 3702 sizeof(*fv), ICE_NONDMA_TO_NONDMA); 3703 } 3704 } 3705 3706 /** 3707 * ice_prof_dec_ref - decrement reference count for profile 3708 * @hw: pointer to the HW struct 3709 * @blk: the block from which to free the profile ID 3710 * @prof_id: the profile ID for which to decrement the reference count 3711 */ 3712 static enum ice_status 3713 ice_prof_dec_ref(struct ice_hw *hw, enum ice_block blk, u8 prof_id) 3714 { 3715 if (prof_id > hw->blk[blk].es.count) 3716 return ICE_ERR_PARAM; 3717 3718 if (hw->blk[blk].es.ref_count[prof_id] > 0) { 3719 if (!--hw->blk[blk].es.ref_count[prof_id]) { 3720 ice_write_es(hw, blk, prof_id, NULL); 3721 ice_free_prof_masks(hw, blk, prof_id); 3722 return ice_free_prof_id(hw, blk, prof_id); 3723 } 3724 } 3725 3726 return ICE_SUCCESS; 3727 } 3728 3729 /* Block / table section IDs */ 3730 static const u32 ice_blk_sids[ICE_BLK_COUNT][ICE_SID_OFF_COUNT] = { 3731 /* SWITCH */ 3732 { ICE_SID_XLT1_SW, 3733 ICE_SID_XLT2_SW, 3734 ICE_SID_PROFID_TCAM_SW, 3735 ICE_SID_PROFID_REDIR_SW, 3736 ICE_SID_FLD_VEC_SW 3737 }, 3738 3739 /* ACL */ 3740 { ICE_SID_XLT1_ACL, 3741 ICE_SID_XLT2_ACL, 3742 ICE_SID_PROFID_TCAM_ACL, 3743 ICE_SID_PROFID_REDIR_ACL, 3744 ICE_SID_FLD_VEC_ACL 3745 }, 3746 3747 /* FD */ 3748 { ICE_SID_XLT1_FD, 3749 ICE_SID_XLT2_FD, 3750 ICE_SID_PROFID_TCAM_FD, 3751 ICE_SID_PROFID_REDIR_FD, 3752 ICE_SID_FLD_VEC_FD 3753 }, 3754 3755 /* RSS */ 3756 { ICE_SID_XLT1_RSS, 3757 ICE_SID_XLT2_RSS, 3758 ICE_SID_PROFID_TCAM_RSS, 3759 ICE_SID_PROFID_REDIR_RSS, 3760 ICE_SID_FLD_VEC_RSS 3761 }, 3762 3763 /* PE */ 3764 { ICE_SID_XLT1_PE, 3765 ICE_SID_XLT2_PE, 3766 ICE_SID_PROFID_TCAM_PE, 3767 ICE_SID_PROFID_REDIR_PE, 3768 ICE_SID_FLD_VEC_PE 3769 } 3770 }; 3771 3772 /** 3773 * ice_init_sw_xlt1_db - init software XLT1 database from HW tables 3774 * @hw: pointer to the hardware structure 3775 * @blk: the HW block to initialize 3776 */ 3777 static void ice_init_sw_xlt1_db(struct ice_hw *hw, enum ice_block blk) 3778 { 3779 u16 pt; 3780 3781 for (pt = 0; pt < hw->blk[blk].xlt1.count; pt++) { 3782 u8 ptg; 3783 3784 ptg = hw->blk[blk].xlt1.t[pt]; 3785 if (ptg != ICE_DEFAULT_PTG) { 3786 ice_ptg_alloc_val(hw, blk, ptg); 3787 ice_ptg_add_mv_ptype(hw, blk, pt, ptg); 3788 } 3789 } 3790 } 3791 3792 /** 3793 * ice_init_sw_xlt2_db - init software XLT2 database from HW tables 3794 * @hw: pointer to the hardware structure 3795 * @blk: the HW block to initialize 3796 */ 3797 static void ice_init_sw_xlt2_db(struct ice_hw *hw, enum ice_block blk) 3798 { 3799 u16 vsi; 3800 3801 for (vsi = 0; vsi < hw->blk[blk].xlt2.count; vsi++) { 3802 u16 vsig; 3803 3804 vsig = hw->blk[blk].xlt2.t[vsi]; 3805 if (vsig) { 3806 ice_vsig_alloc_val(hw, blk, vsig); 3807 ice_vsig_add_mv_vsi(hw, blk, vsi, vsig); 3808 /* no changes at this time, since this has been 3809 * initialized from the original package 3810 */ 3811 hw->blk[blk].xlt2.vsis[vsi].changed = 0; 3812 } 3813 } 3814 } 3815 3816 /** 3817 * ice_init_sw_db - init software database from HW tables 3818 * @hw: pointer to the hardware structure 3819 */ 3820 static void ice_init_sw_db(struct ice_hw *hw) 3821 { 3822 u16 i; 3823 3824 for (i = 0; i < ICE_BLK_COUNT; i++) { 3825 ice_init_sw_xlt1_db(hw, (enum ice_block)i); 3826 ice_init_sw_xlt2_db(hw, (enum ice_block)i); 3827 } 3828 } 3829 3830 /** 3831 * ice_fill_tbl - Reads content of a single table type into database 3832 * @hw: pointer to the hardware structure 3833 * @block_id: Block ID of the table to copy 3834 * @sid: Section ID of the table to copy 3835 * 3836 * Will attempt to read the entire content of a given table of a single block 3837 * into the driver database. We assume that the buffer will always 3838 * be as large or larger than the data contained in the package. If 3839 * this condition is not met, there is most likely an error in the package 3840 * contents. 3841 */ 3842 static void ice_fill_tbl(struct ice_hw *hw, enum ice_block block_id, u32 sid) 3843 { 3844 u32 dst_len, sect_len, offset = 0; 3845 struct ice_prof_redir_section *pr; 3846 struct ice_prof_id_section *pid; 3847 struct ice_xlt1_section *xlt1; 3848 struct ice_xlt2_section *xlt2; 3849 struct ice_sw_fv_section *es; 3850 struct ice_pkg_enum state; 3851 u8 *src, *dst; 3852 void *sect; 3853 3854 /* if the HW segment pointer is null then the first iteration of 3855 * ice_pkg_enum_section() will fail. In this case the HW tables will 3856 * not be filled and return success. 3857 */ 3858 if (!hw->seg) { 3859 ice_debug(hw, ICE_DBG_PKG, "hw->seg is NULL, tables are not filled\n"); 3860 return; 3861 } 3862 3863 ice_memset(&state, 0, sizeof(state), ICE_NONDMA_MEM); 3864 3865 sect = ice_pkg_enum_section(hw->seg, &state, sid); 3866 3867 while (sect) { 3868 switch (sid) { 3869 case ICE_SID_XLT1_SW: 3870 case ICE_SID_XLT1_FD: 3871 case ICE_SID_XLT1_RSS: 3872 case ICE_SID_XLT1_ACL: 3873 case ICE_SID_XLT1_PE: 3874 xlt1 = (struct ice_xlt1_section *)sect; 3875 src = xlt1->value; 3876 sect_len = LE16_TO_CPU(xlt1->count) * 3877 sizeof(*hw->blk[block_id].xlt1.t); 3878 dst = hw->blk[block_id].xlt1.t; 3879 dst_len = hw->blk[block_id].xlt1.count * 3880 sizeof(*hw->blk[block_id].xlt1.t); 3881 break; 3882 case ICE_SID_XLT2_SW: 3883 case ICE_SID_XLT2_FD: 3884 case ICE_SID_XLT2_RSS: 3885 case ICE_SID_XLT2_ACL: 3886 case ICE_SID_XLT2_PE: 3887 xlt2 = (struct ice_xlt2_section *)sect; 3888 src = (_FORCE_ u8 *)xlt2->value; 3889 sect_len = LE16_TO_CPU(xlt2->count) * 3890 sizeof(*hw->blk[block_id].xlt2.t); 3891 dst = (u8 *)hw->blk[block_id].xlt2.t; 3892 dst_len = hw->blk[block_id].xlt2.count * 3893 sizeof(*hw->blk[block_id].xlt2.t); 3894 break; 3895 case ICE_SID_PROFID_TCAM_SW: 3896 case ICE_SID_PROFID_TCAM_FD: 3897 case ICE_SID_PROFID_TCAM_RSS: 3898 case ICE_SID_PROFID_TCAM_ACL: 3899 case ICE_SID_PROFID_TCAM_PE: 3900 pid = (struct ice_prof_id_section *)sect; 3901 src = (u8 *)pid->entry; 3902 sect_len = LE16_TO_CPU(pid->count) * 3903 sizeof(*hw->blk[block_id].prof.t); 3904 dst = (u8 *)hw->blk[block_id].prof.t; 3905 dst_len = hw->blk[block_id].prof.count * 3906 sizeof(*hw->blk[block_id].prof.t); 3907 break; 3908 case ICE_SID_PROFID_REDIR_SW: 3909 case ICE_SID_PROFID_REDIR_FD: 3910 case ICE_SID_PROFID_REDIR_RSS: 3911 case ICE_SID_PROFID_REDIR_ACL: 3912 case ICE_SID_PROFID_REDIR_PE: 3913 pr = (struct ice_prof_redir_section *)sect; 3914 src = pr->redir_value; 3915 sect_len = LE16_TO_CPU(pr->count) * 3916 sizeof(*hw->blk[block_id].prof_redir.t); 3917 dst = hw->blk[block_id].prof_redir.t; 3918 dst_len = hw->blk[block_id].prof_redir.count * 3919 sizeof(*hw->blk[block_id].prof_redir.t); 3920 break; 3921 case ICE_SID_FLD_VEC_SW: 3922 case ICE_SID_FLD_VEC_FD: 3923 case ICE_SID_FLD_VEC_RSS: 3924 case ICE_SID_FLD_VEC_ACL: 3925 case ICE_SID_FLD_VEC_PE: 3926 es = (struct ice_sw_fv_section *)sect; 3927 src = (u8 *)es->fv; 3928 sect_len = (u32)(LE16_TO_CPU(es->count) * 3929 hw->blk[block_id].es.fvw) * 3930 sizeof(*hw->blk[block_id].es.t); 3931 dst = (u8 *)hw->blk[block_id].es.t; 3932 dst_len = (u32)(hw->blk[block_id].es.count * 3933 hw->blk[block_id].es.fvw) * 3934 sizeof(*hw->blk[block_id].es.t); 3935 break; 3936 default: 3937 return; 3938 } 3939 3940 /* if the section offset exceeds destination length, terminate 3941 * table fill. 3942 */ 3943 if (offset > dst_len) 3944 return; 3945 3946 /* if the sum of section size and offset exceed destination size 3947 * then we are out of bounds of the HW table size for that PF. 3948 * Changing section length to fill the remaining table space 3949 * of that PF. 3950 */ 3951 if ((offset + sect_len) > dst_len) 3952 sect_len = dst_len - offset; 3953 3954 ice_memcpy(dst + offset, src, sect_len, ICE_NONDMA_TO_NONDMA); 3955 offset += sect_len; 3956 sect = ice_pkg_enum_section(NULL, &state, sid); 3957 } 3958 } 3959 3960 /** 3961 * ice_fill_blk_tbls - Read package context for tables 3962 * @hw: pointer to the hardware structure 3963 * 3964 * Reads the current package contents and populates the driver 3965 * database with the data iteratively for all advanced feature 3966 * blocks. Assume that the HW tables have been allocated. 3967 */ 3968 void ice_fill_blk_tbls(struct ice_hw *hw) 3969 { 3970 u8 i; 3971 3972 for (i = 0; i < ICE_BLK_COUNT; i++) { 3973 enum ice_block blk_id = (enum ice_block)i; 3974 3975 ice_fill_tbl(hw, blk_id, hw->blk[blk_id].xlt1.sid); 3976 ice_fill_tbl(hw, blk_id, hw->blk[blk_id].xlt2.sid); 3977 ice_fill_tbl(hw, blk_id, hw->blk[blk_id].prof.sid); 3978 ice_fill_tbl(hw, blk_id, hw->blk[blk_id].prof_redir.sid); 3979 ice_fill_tbl(hw, blk_id, hw->blk[blk_id].es.sid); 3980 } 3981 3982 ice_init_sw_db(hw); 3983 } 3984 3985 /** 3986 * ice_free_prof_map - free profile map 3987 * @hw: pointer to the hardware structure 3988 * @blk_idx: HW block index 3989 */ 3990 static void ice_free_prof_map(struct ice_hw *hw, u8 blk_idx) 3991 { 3992 struct ice_es *es = &hw->blk[blk_idx].es; 3993 struct ice_prof_map *del, *tmp; 3994 3995 ice_acquire_lock(&es->prof_map_lock); 3996 LIST_FOR_EACH_ENTRY_SAFE(del, tmp, &es->prof_map, 3997 ice_prof_map, list) { 3998 LIST_DEL(&del->list); 3999 ice_free(hw, del); 4000 } 4001 INIT_LIST_HEAD(&es->prof_map); 4002 ice_release_lock(&es->prof_map_lock); 4003 } 4004 4005 /** 4006 * ice_free_flow_profs - free flow profile entries 4007 * @hw: pointer to the hardware structure 4008 * @blk_idx: HW block index 4009 */ 4010 static void ice_free_flow_profs(struct ice_hw *hw, u8 blk_idx) 4011 { 4012 struct ice_flow_prof *p, *tmp; 4013 4014 ice_acquire_lock(&hw->fl_profs_locks[blk_idx]); 4015 LIST_FOR_EACH_ENTRY_SAFE(p, tmp, &hw->fl_profs[blk_idx], 4016 ice_flow_prof, l_entry) { 4017 struct ice_flow_entry *e, *t; 4018 4019 LIST_FOR_EACH_ENTRY_SAFE(e, t, &p->entries, 4020 ice_flow_entry, l_entry) 4021 ice_flow_rem_entry(hw, (enum ice_block)blk_idx, 4022 ICE_FLOW_ENTRY_HNDL(e)); 4023 4024 LIST_DEL(&p->l_entry); 4025 if (p->acts) 4026 ice_free(hw, p->acts); 4027 4028 ice_destroy_lock(&p->entries_lock); 4029 ice_free(hw, p); 4030 } 4031 ice_release_lock(&hw->fl_profs_locks[blk_idx]); 4032 4033 /* if driver is in reset and tables are being cleared 4034 * re-initialize the flow profile list heads 4035 */ 4036 INIT_LIST_HEAD(&hw->fl_profs[blk_idx]); 4037 } 4038 4039 /** 4040 * ice_free_vsig_tbl - free complete VSIG table entries 4041 * @hw: pointer to the hardware structure 4042 * @blk: the HW block on which to free the VSIG table entries 4043 */ 4044 static void ice_free_vsig_tbl(struct ice_hw *hw, enum ice_block blk) 4045 { 4046 u16 i; 4047 4048 if (!hw->blk[blk].xlt2.vsig_tbl) 4049 return; 4050 4051 for (i = 1; i < ICE_MAX_VSIGS; i++) 4052 if (hw->blk[blk].xlt2.vsig_tbl[i].in_use) 4053 ice_vsig_free(hw, blk, i); 4054 } 4055 4056 /** 4057 * ice_free_hw_tbls - free hardware table memory 4058 * @hw: pointer to the hardware structure 4059 */ 4060 void ice_free_hw_tbls(struct ice_hw *hw) 4061 { 4062 struct ice_rss_cfg *r, *rt; 4063 u8 i; 4064 4065 for (i = 0; i < ICE_BLK_COUNT; i++) { 4066 if (hw->blk[i].is_list_init) { 4067 struct ice_es *es = &hw->blk[i].es; 4068 4069 ice_free_prof_map(hw, i); 4070 ice_destroy_lock(&es->prof_map_lock); 4071 ice_free_flow_profs(hw, i); 4072 ice_destroy_lock(&hw->fl_profs_locks[i]); 4073 4074 hw->blk[i].is_list_init = false; 4075 } 4076 ice_free_vsig_tbl(hw, (enum ice_block)i); 4077 ice_free(hw, hw->blk[i].xlt1.ptypes); 4078 ice_free(hw, hw->blk[i].xlt1.ptg_tbl); 4079 ice_free(hw, hw->blk[i].xlt1.t); 4080 ice_free(hw, hw->blk[i].xlt2.t); 4081 ice_free(hw, hw->blk[i].xlt2.vsig_tbl); 4082 ice_free(hw, hw->blk[i].xlt2.vsis); 4083 ice_free(hw, hw->blk[i].prof.t); 4084 ice_free(hw, hw->blk[i].prof_redir.t); 4085 ice_free(hw, hw->blk[i].es.t); 4086 ice_free(hw, hw->blk[i].es.ref_count); 4087 ice_free(hw, hw->blk[i].es.written); 4088 ice_free(hw, hw->blk[i].es.mask_ena); 4089 } 4090 4091 LIST_FOR_EACH_ENTRY_SAFE(r, rt, &hw->rss_list_head, 4092 ice_rss_cfg, l_entry) { 4093 LIST_DEL(&r->l_entry); 4094 ice_free(hw, r); 4095 } 4096 ice_destroy_lock(&hw->rss_locks); 4097 if (!hw->dcf_enabled) 4098 ice_shutdown_all_prof_masks(hw); 4099 ice_memset(hw->blk, 0, sizeof(hw->blk), ICE_NONDMA_MEM); 4100 } 4101 4102 /** 4103 * ice_init_flow_profs - init flow profile locks and list heads 4104 * @hw: pointer to the hardware structure 4105 * @blk_idx: HW block index 4106 */ 4107 static void ice_init_flow_profs(struct ice_hw *hw, u8 blk_idx) 4108 { 4109 ice_init_lock(&hw->fl_profs_locks[blk_idx]); 4110 INIT_LIST_HEAD(&hw->fl_profs[blk_idx]); 4111 } 4112 4113 /** 4114 * ice_clear_hw_tbls - clear HW tables and flow profiles 4115 * @hw: pointer to the hardware structure 4116 */ 4117 void ice_clear_hw_tbls(struct ice_hw *hw) 4118 { 4119 u8 i; 4120 4121 for (i = 0; i < ICE_BLK_COUNT; i++) { 4122 struct ice_prof_redir *prof_redir = &hw->blk[i].prof_redir; 4123 struct ice_prof_tcam *prof = &hw->blk[i].prof; 4124 struct ice_xlt1 *xlt1 = &hw->blk[i].xlt1; 4125 struct ice_xlt2 *xlt2 = &hw->blk[i].xlt2; 4126 struct ice_es *es = &hw->blk[i].es; 4127 4128 if (hw->blk[i].is_list_init) { 4129 ice_free_prof_map(hw, i); 4130 ice_free_flow_profs(hw, i); 4131 } 4132 4133 ice_free_vsig_tbl(hw, (enum ice_block)i); 4134 4135 ice_memset(xlt1->ptypes, 0, xlt1->count * sizeof(*xlt1->ptypes), 4136 ICE_NONDMA_MEM); 4137 ice_memset(xlt1->ptg_tbl, 0, 4138 ICE_MAX_PTGS * sizeof(*xlt1->ptg_tbl), 4139 ICE_NONDMA_MEM); 4140 ice_memset(xlt1->t, 0, xlt1->count * sizeof(*xlt1->t), 4141 ICE_NONDMA_MEM); 4142 4143 ice_memset(xlt2->vsis, 0, xlt2->count * sizeof(*xlt2->vsis), 4144 ICE_NONDMA_MEM); 4145 ice_memset(xlt2->vsig_tbl, 0, 4146 xlt2->count * sizeof(*xlt2->vsig_tbl), 4147 ICE_NONDMA_MEM); 4148 ice_memset(xlt2->t, 0, xlt2->count * sizeof(*xlt2->t), 4149 ICE_NONDMA_MEM); 4150 4151 ice_memset(prof->t, 0, prof->count * sizeof(*prof->t), 4152 ICE_NONDMA_MEM); 4153 ice_memset(prof_redir->t, 0, 4154 prof_redir->count * sizeof(*prof_redir->t), 4155 ICE_NONDMA_MEM); 4156 4157 ice_memset(es->t, 0, es->count * sizeof(*es->t) * es->fvw, 4158 ICE_NONDMA_MEM); 4159 ice_memset(es->ref_count, 0, es->count * sizeof(*es->ref_count), 4160 ICE_NONDMA_MEM); 4161 ice_memset(es->written, 0, es->count * sizeof(*es->written), 4162 ICE_NONDMA_MEM); 4163 ice_memset(es->mask_ena, 0, es->count * sizeof(*es->mask_ena), 4164 ICE_NONDMA_MEM); 4165 } 4166 } 4167 4168 /** 4169 * ice_init_hw_tbls - init hardware table memory 4170 * @hw: pointer to the hardware structure 4171 */ 4172 enum ice_status ice_init_hw_tbls(struct ice_hw *hw) 4173 { 4174 u8 i; 4175 4176 ice_init_lock(&hw->rss_locks); 4177 INIT_LIST_HEAD(&hw->rss_list_head); 4178 if (!hw->dcf_enabled) 4179 ice_init_all_prof_masks(hw); 4180 for (i = 0; i < ICE_BLK_COUNT; i++) { 4181 struct ice_prof_redir *prof_redir = &hw->blk[i].prof_redir; 4182 struct ice_prof_tcam *prof = &hw->blk[i].prof; 4183 struct ice_xlt1 *xlt1 = &hw->blk[i].xlt1; 4184 struct ice_xlt2 *xlt2 = &hw->blk[i].xlt2; 4185 struct ice_es *es = &hw->blk[i].es; 4186 u16 j; 4187 4188 if (hw->blk[i].is_list_init) 4189 continue; 4190 4191 ice_init_flow_profs(hw, i); 4192 ice_init_lock(&es->prof_map_lock); 4193 INIT_LIST_HEAD(&es->prof_map); 4194 hw->blk[i].is_list_init = true; 4195 4196 hw->blk[i].overwrite = blk_sizes[i].overwrite; 4197 es->reverse = blk_sizes[i].reverse; 4198 4199 xlt1->sid = ice_blk_sids[i][ICE_SID_XLT1_OFF]; 4200 xlt1->count = blk_sizes[i].xlt1; 4201 4202 xlt1->ptypes = (struct ice_ptg_ptype *) 4203 ice_calloc(hw, xlt1->count, sizeof(*xlt1->ptypes)); 4204 4205 if (!xlt1->ptypes) 4206 goto err; 4207 4208 xlt1->ptg_tbl = (struct ice_ptg_entry *) 4209 ice_calloc(hw, ICE_MAX_PTGS, sizeof(*xlt1->ptg_tbl)); 4210 4211 if (!xlt1->ptg_tbl) 4212 goto err; 4213 4214 xlt1->t = (u8 *)ice_calloc(hw, xlt1->count, sizeof(*xlt1->t)); 4215 if (!xlt1->t) 4216 goto err; 4217 4218 xlt2->sid = ice_blk_sids[i][ICE_SID_XLT2_OFF]; 4219 xlt2->count = blk_sizes[i].xlt2; 4220 4221 xlt2->vsis = (struct ice_vsig_vsi *) 4222 ice_calloc(hw, xlt2->count, sizeof(*xlt2->vsis)); 4223 4224 if (!xlt2->vsis) 4225 goto err; 4226 4227 xlt2->vsig_tbl = (struct ice_vsig_entry *) 4228 ice_calloc(hw, xlt2->count, sizeof(*xlt2->vsig_tbl)); 4229 if (!xlt2->vsig_tbl) 4230 goto err; 4231 4232 for (j = 0; j < xlt2->count; j++) 4233 INIT_LIST_HEAD(&xlt2->vsig_tbl[j].prop_lst); 4234 4235 xlt2->t = (u16 *)ice_calloc(hw, xlt2->count, sizeof(*xlt2->t)); 4236 if (!xlt2->t) 4237 goto err; 4238 4239 prof->sid = ice_blk_sids[i][ICE_SID_PR_OFF]; 4240 prof->count = blk_sizes[i].prof_tcam; 4241 prof->max_prof_id = blk_sizes[i].prof_id; 4242 prof->cdid_bits = blk_sizes[i].prof_cdid_bits; 4243 prof->t = (struct ice_prof_tcam_entry *) 4244 ice_calloc(hw, prof->count, sizeof(*prof->t)); 4245 4246 if (!prof->t) 4247 goto err; 4248 4249 prof_redir->sid = ice_blk_sids[i][ICE_SID_PR_REDIR_OFF]; 4250 prof_redir->count = blk_sizes[i].prof_redir; 4251 prof_redir->t = (u8 *)ice_calloc(hw, prof_redir->count, 4252 sizeof(*prof_redir->t)); 4253 4254 if (!prof_redir->t) 4255 goto err; 4256 4257 es->sid = ice_blk_sids[i][ICE_SID_ES_OFF]; 4258 es->count = blk_sizes[i].es; 4259 es->fvw = blk_sizes[i].fvw; 4260 es->t = (struct ice_fv_word *) 4261 ice_calloc(hw, (u32)(es->count * es->fvw), 4262 sizeof(*es->t)); 4263 if (!es->t) 4264 goto err; 4265 4266 es->ref_count = (u16 *) 4267 ice_calloc(hw, es->count, sizeof(*es->ref_count)); 4268 4269 if (!es->ref_count) 4270 goto err; 4271 4272 es->written = (u8 *) 4273 ice_calloc(hw, es->count, sizeof(*es->written)); 4274 4275 if (!es->written) 4276 goto err; 4277 4278 es->mask_ena = (u32 *) 4279 ice_calloc(hw, es->count, sizeof(*es->mask_ena)); 4280 4281 if (!es->mask_ena) 4282 goto err; 4283 } 4284 return ICE_SUCCESS; 4285 4286 err: 4287 ice_free_hw_tbls(hw); 4288 return ICE_ERR_NO_MEMORY; 4289 } 4290 4291 /** 4292 * ice_prof_gen_key - generate profile ID key 4293 * @hw: pointer to the HW struct 4294 * @blk: the block in which to write profile ID to 4295 * @ptg: packet type group (PTG) portion of key 4296 * @vsig: VSIG portion of key 4297 * @cdid: CDID portion of key 4298 * @flags: flag portion of key 4299 * @vl_msk: valid mask 4300 * @dc_msk: don't care mask 4301 * @nm_msk: never match mask 4302 * @key: output of profile ID key 4303 */ 4304 static enum ice_status 4305 ice_prof_gen_key(struct ice_hw *hw, enum ice_block blk, u8 ptg, u16 vsig, 4306 u8 cdid, u16 flags, u8 vl_msk[ICE_TCAM_KEY_VAL_SZ], 4307 u8 dc_msk[ICE_TCAM_KEY_VAL_SZ], u8 nm_msk[ICE_TCAM_KEY_VAL_SZ], 4308 u8 key[ICE_TCAM_KEY_SZ]) 4309 { 4310 struct ice_prof_id_key inkey; 4311 4312 inkey.xlt1 = ptg; 4313 inkey.xlt2_cdid = CPU_TO_LE16(vsig); 4314 inkey.flags = CPU_TO_LE16(flags); 4315 4316 switch (hw->blk[blk].prof.cdid_bits) { 4317 case 0: 4318 break; 4319 case 2: 4320 #define ICE_CD_2_M 0xC000U 4321 #define ICE_CD_2_S 14 4322 inkey.xlt2_cdid &= ~CPU_TO_LE16(ICE_CD_2_M); 4323 inkey.xlt2_cdid |= CPU_TO_LE16(BIT(cdid) << ICE_CD_2_S); 4324 break; 4325 case 4: 4326 #define ICE_CD_4_M 0xF000U 4327 #define ICE_CD_4_S 12 4328 inkey.xlt2_cdid &= ~CPU_TO_LE16(ICE_CD_4_M); 4329 inkey.xlt2_cdid |= CPU_TO_LE16(BIT(cdid) << ICE_CD_4_S); 4330 break; 4331 case 8: 4332 #define ICE_CD_8_M 0xFF00U 4333 #define ICE_CD_8_S 16 4334 inkey.xlt2_cdid &= ~CPU_TO_LE16(ICE_CD_8_M); 4335 inkey.xlt2_cdid |= CPU_TO_LE16(BIT(cdid) << ICE_CD_8_S); 4336 break; 4337 default: 4338 ice_debug(hw, ICE_DBG_PKG, "Error in profile config\n"); 4339 break; 4340 } 4341 4342 return ice_set_key(key, ICE_TCAM_KEY_SZ, (u8 *)&inkey, vl_msk, dc_msk, 4343 nm_msk, 0, ICE_TCAM_KEY_SZ / 2); 4344 } 4345 4346 /** 4347 * ice_tcam_write_entry - write TCAM entry 4348 * @hw: pointer to the HW struct 4349 * @blk: the block in which to write profile ID to 4350 * @idx: the entry index to write to 4351 * @prof_id: profile ID 4352 * @ptg: packet type group (PTG) portion of key 4353 * @vsig: VSIG portion of key 4354 * @cdid: CDID portion of key 4355 * @flags: flag portion of key 4356 * @vl_msk: valid mask 4357 * @dc_msk: don't care mask 4358 * @nm_msk: never match mask 4359 */ 4360 static enum ice_status 4361 ice_tcam_write_entry(struct ice_hw *hw, enum ice_block blk, u16 idx, 4362 u8 prof_id, u8 ptg, u16 vsig, u8 cdid, u16 flags, 4363 u8 vl_msk[ICE_TCAM_KEY_VAL_SZ], 4364 u8 dc_msk[ICE_TCAM_KEY_VAL_SZ], 4365 u8 nm_msk[ICE_TCAM_KEY_VAL_SZ]) 4366 { 4367 struct ice_prof_tcam_entry; 4368 enum ice_status status; 4369 4370 status = ice_prof_gen_key(hw, blk, ptg, vsig, cdid, flags, vl_msk, 4371 dc_msk, nm_msk, hw->blk[blk].prof.t[idx].key); 4372 if (!status) { 4373 hw->blk[blk].prof.t[idx].addr = CPU_TO_LE16(idx); 4374 hw->blk[blk].prof.t[idx].prof_id = prof_id; 4375 } 4376 4377 return status; 4378 } 4379 4380 /** 4381 * ice_vsig_get_ref - returns number of VSIs belong to a VSIG 4382 * @hw: pointer to the hardware structure 4383 * @blk: HW block 4384 * @vsig: VSIG to query 4385 * @refs: pointer to variable to receive the reference count 4386 */ 4387 static enum ice_status 4388 ice_vsig_get_ref(struct ice_hw *hw, enum ice_block blk, u16 vsig, u16 *refs) 4389 { 4390 u16 idx = vsig & ICE_VSIG_IDX_M; 4391 struct ice_vsig_vsi *ptr; 4392 4393 *refs = 0; 4394 4395 if (!hw->blk[blk].xlt2.vsig_tbl[idx].in_use) 4396 return ICE_ERR_DOES_NOT_EXIST; 4397 4398 ptr = hw->blk[blk].xlt2.vsig_tbl[idx].first_vsi; 4399 while (ptr) { 4400 (*refs)++; 4401 ptr = ptr->next_vsi; 4402 } 4403 4404 return ICE_SUCCESS; 4405 } 4406 4407 /** 4408 * ice_has_prof_vsig - check to see if VSIG has a specific profile 4409 * @hw: pointer to the hardware structure 4410 * @blk: HW block 4411 * @vsig: VSIG to check against 4412 * @hdl: profile handle 4413 */ 4414 static bool 4415 ice_has_prof_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsig, u64 hdl) 4416 { 4417 u16 idx = vsig & ICE_VSIG_IDX_M; 4418 struct ice_vsig_prof *ent; 4419 4420 LIST_FOR_EACH_ENTRY(ent, &hw->blk[blk].xlt2.vsig_tbl[idx].prop_lst, 4421 ice_vsig_prof, list) 4422 if (ent->profile_cookie == hdl) 4423 return true; 4424 4425 ice_debug(hw, ICE_DBG_INIT, "Characteristic list for VSI group %d not found.\n", 4426 vsig); 4427 return false; 4428 } 4429 4430 /** 4431 * ice_prof_bld_es - build profile ID extraction sequence changes 4432 * @hw: pointer to the HW struct 4433 * @blk: hardware block 4434 * @bld: the update package buffer build to add to 4435 * @chgs: the list of changes to make in hardware 4436 */ 4437 static enum ice_status 4438 ice_prof_bld_es(struct ice_hw *hw, enum ice_block blk, 4439 struct ice_buf_build *bld, struct LIST_HEAD_TYPE *chgs) 4440 { 4441 u16 vec_size = hw->blk[blk].es.fvw * sizeof(struct ice_fv_word); 4442 struct ice_chs_chg *tmp; 4443 4444 LIST_FOR_EACH_ENTRY(tmp, chgs, ice_chs_chg, list_entry) 4445 if (tmp->type == ICE_PTG_ES_ADD && tmp->add_prof) { 4446 u16 off = tmp->prof_id * hw->blk[blk].es.fvw; 4447 struct ice_pkg_es *p; 4448 u32 id; 4449 4450 id = ice_sect_id(blk, ICE_VEC_TBL); 4451 p = (struct ice_pkg_es *) 4452 ice_pkg_buf_alloc_section(bld, id, 4453 ice_struct_size(p, es, 4454 1) + 4455 vec_size - 4456 sizeof(p->es[0])); 4457 4458 if (!p) 4459 return ICE_ERR_MAX_LIMIT; 4460 4461 p->count = CPU_TO_LE16(1); 4462 p->offset = CPU_TO_LE16(tmp->prof_id); 4463 4464 ice_memcpy(p->es, &hw->blk[blk].es.t[off], vec_size, 4465 ICE_NONDMA_TO_NONDMA); 4466 } 4467 4468 return ICE_SUCCESS; 4469 } 4470 4471 /** 4472 * ice_prof_bld_tcam - build profile ID TCAM changes 4473 * @hw: pointer to the HW struct 4474 * @blk: hardware block 4475 * @bld: the update package buffer build to add to 4476 * @chgs: the list of changes to make in hardware 4477 */ 4478 static enum ice_status 4479 ice_prof_bld_tcam(struct ice_hw *hw, enum ice_block blk, 4480 struct ice_buf_build *bld, struct LIST_HEAD_TYPE *chgs) 4481 { 4482 struct ice_chs_chg *tmp; 4483 4484 LIST_FOR_EACH_ENTRY(tmp, chgs, ice_chs_chg, list_entry) 4485 if (tmp->type == ICE_TCAM_ADD && tmp->add_tcam_idx) { 4486 struct ice_prof_id_section *p; 4487 u32 id; 4488 4489 id = ice_sect_id(blk, ICE_PROF_TCAM); 4490 p = (struct ice_prof_id_section *) 4491 ice_pkg_buf_alloc_section(bld, id, 4492 ice_struct_size(p, 4493 entry, 4494 1)); 4495 4496 if (!p) 4497 return ICE_ERR_MAX_LIMIT; 4498 4499 p->count = CPU_TO_LE16(1); 4500 p->entry[0].addr = CPU_TO_LE16(tmp->tcam_idx); 4501 p->entry[0].prof_id = tmp->prof_id; 4502 4503 ice_memcpy(p->entry[0].key, 4504 &hw->blk[blk].prof.t[tmp->tcam_idx].key, 4505 sizeof(hw->blk[blk].prof.t->key), 4506 ICE_NONDMA_TO_NONDMA); 4507 } 4508 4509 return ICE_SUCCESS; 4510 } 4511 4512 /** 4513 * ice_prof_bld_xlt1 - build XLT1 changes 4514 * @blk: hardware block 4515 * @bld: the update package buffer build to add to 4516 * @chgs: the list of changes to make in hardware 4517 */ 4518 static enum ice_status 4519 ice_prof_bld_xlt1(enum ice_block blk, struct ice_buf_build *bld, 4520 struct LIST_HEAD_TYPE *chgs) 4521 { 4522 struct ice_chs_chg *tmp; 4523 4524 LIST_FOR_EACH_ENTRY(tmp, chgs, ice_chs_chg, list_entry) 4525 if (tmp->type == ICE_PTG_ES_ADD && tmp->add_ptg) { 4526 struct ice_xlt1_section *p; 4527 u32 id; 4528 4529 id = ice_sect_id(blk, ICE_XLT1); 4530 p = (struct ice_xlt1_section *) 4531 ice_pkg_buf_alloc_section(bld, id, 4532 ice_struct_size(p, 4533 value, 4534 1)); 4535 4536 if (!p) 4537 return ICE_ERR_MAX_LIMIT; 4538 4539 p->count = CPU_TO_LE16(1); 4540 p->offset = CPU_TO_LE16(tmp->ptype); 4541 p->value[0] = tmp->ptg; 4542 } 4543 4544 return ICE_SUCCESS; 4545 } 4546 4547 /** 4548 * ice_prof_bld_xlt2 - build XLT2 changes 4549 * @blk: hardware block 4550 * @bld: the update package buffer build to add to 4551 * @chgs: the list of changes to make in hardware 4552 */ 4553 static enum ice_status 4554 ice_prof_bld_xlt2(enum ice_block blk, struct ice_buf_build *bld, 4555 struct LIST_HEAD_TYPE *chgs) 4556 { 4557 struct ice_chs_chg *tmp; 4558 4559 LIST_FOR_EACH_ENTRY(tmp, chgs, ice_chs_chg, list_entry) { 4560 struct ice_xlt2_section *p; 4561 u32 id; 4562 4563 switch (tmp->type) { 4564 case ICE_VSIG_ADD: 4565 case ICE_VSI_MOVE: 4566 case ICE_VSIG_REM: 4567 id = ice_sect_id(blk, ICE_XLT2); 4568 p = (struct ice_xlt2_section *) 4569 ice_pkg_buf_alloc_section(bld, id, 4570 ice_struct_size(p, 4571 value, 4572 1)); 4573 4574 if (!p) 4575 return ICE_ERR_MAX_LIMIT; 4576 4577 p->count = CPU_TO_LE16(1); 4578 p->offset = CPU_TO_LE16(tmp->vsi); 4579 p->value[0] = CPU_TO_LE16(tmp->vsig); 4580 break; 4581 default: 4582 break; 4583 } 4584 } 4585 4586 return ICE_SUCCESS; 4587 } 4588 4589 /** 4590 * ice_upd_prof_hw - update hardware using the change list 4591 * @hw: pointer to the HW struct 4592 * @blk: hardware block 4593 * @chgs: the list of changes to make in hardware 4594 */ 4595 static enum ice_status 4596 ice_upd_prof_hw(struct ice_hw *hw, enum ice_block blk, 4597 struct LIST_HEAD_TYPE *chgs) 4598 { 4599 struct ice_buf_build *b; 4600 struct ice_chs_chg *tmp; 4601 enum ice_status status; 4602 u16 pkg_sects; 4603 u16 xlt1 = 0; 4604 u16 xlt2 = 0; 4605 u16 tcam = 0; 4606 u16 es = 0; 4607 u16 sects; 4608 4609 /* count number of sections we need */ 4610 LIST_FOR_EACH_ENTRY(tmp, chgs, ice_chs_chg, list_entry) { 4611 switch (tmp->type) { 4612 case ICE_PTG_ES_ADD: 4613 if (tmp->add_ptg) 4614 xlt1++; 4615 if (tmp->add_prof) 4616 es++; 4617 break; 4618 case ICE_TCAM_ADD: 4619 tcam++; 4620 break; 4621 case ICE_VSIG_ADD: 4622 case ICE_VSI_MOVE: 4623 case ICE_VSIG_REM: 4624 xlt2++; 4625 break; 4626 default: 4627 break; 4628 } 4629 } 4630 sects = xlt1 + xlt2 + tcam + es; 4631 4632 if (!sects) 4633 return ICE_SUCCESS; 4634 4635 /* Build update package buffer */ 4636 b = ice_pkg_buf_alloc(hw); 4637 if (!b) 4638 return ICE_ERR_NO_MEMORY; 4639 4640 status = ice_pkg_buf_reserve_section(b, sects); 4641 if (status) 4642 goto error_tmp; 4643 4644 /* Preserve order of table update: ES, TCAM, PTG, VSIG */ 4645 if (es) { 4646 status = ice_prof_bld_es(hw, blk, b, chgs); 4647 if (status) 4648 goto error_tmp; 4649 } 4650 4651 if (tcam) { 4652 status = ice_prof_bld_tcam(hw, blk, b, chgs); 4653 if (status) 4654 goto error_tmp; 4655 } 4656 4657 if (xlt1) { 4658 status = ice_prof_bld_xlt1(blk, b, chgs); 4659 if (status) 4660 goto error_tmp; 4661 } 4662 4663 if (xlt2) { 4664 status = ice_prof_bld_xlt2(blk, b, chgs); 4665 if (status) 4666 goto error_tmp; 4667 } 4668 4669 /* After package buffer build check if the section count in buffer is 4670 * non-zero and matches the number of sections detected for package 4671 * update. 4672 */ 4673 pkg_sects = ice_pkg_buf_get_active_sections(b); 4674 if (!pkg_sects || pkg_sects != sects) { 4675 status = ICE_ERR_INVAL_SIZE; 4676 goto error_tmp; 4677 } 4678 4679 /* update package */ 4680 status = ice_update_pkg(hw, ice_pkg_buf(b), 1); 4681 if (status == ICE_ERR_AQ_ERROR) 4682 ice_debug(hw, ICE_DBG_INIT, "Unable to update HW profile\n"); 4683 4684 error_tmp: 4685 ice_pkg_buf_free(hw, b); 4686 return status; 4687 } 4688 4689 /** 4690 * ice_update_fd_mask - set Flow Director Field Vector mask for a profile 4691 * @hw: pointer to the HW struct 4692 * @prof_id: profile ID 4693 * @mask_sel: mask select 4694 * 4695 * This function enable any of the masks selected by the mask select parameter 4696 * for the profile specified. 4697 */ 4698 static void ice_update_fd_mask(struct ice_hw *hw, u16 prof_id, u32 mask_sel) 4699 { 4700 wr32(hw, GLQF_FDMASK_SEL(prof_id), mask_sel); 4701 4702 ice_debug(hw, ICE_DBG_INIT, "fd mask(%d): %x = %x\n", prof_id, 4703 GLQF_FDMASK_SEL(prof_id), mask_sel); 4704 } 4705 4706 struct ice_fd_src_dst_pair { 4707 u8 prot_id; 4708 u8 count; 4709 u16 off; 4710 }; 4711 4712 static const struct ice_fd_src_dst_pair ice_fd_pairs[] = { 4713 /* These are defined in pairs */ 4714 { ICE_PROT_IPV4_OF_OR_S, 2, 12 }, 4715 { ICE_PROT_IPV4_OF_OR_S, 2, 16 }, 4716 4717 { ICE_PROT_IPV4_IL, 2, 12 }, 4718 { ICE_PROT_IPV4_IL, 2, 16 }, 4719 4720 { ICE_PROT_IPV4_IL_IL, 2, 12 }, 4721 { ICE_PROT_IPV4_IL_IL, 2, 16 }, 4722 4723 { ICE_PROT_IPV6_OF_OR_S, 8, 8 }, 4724 { ICE_PROT_IPV6_OF_OR_S, 8, 24 }, 4725 4726 { ICE_PROT_IPV6_IL, 8, 8 }, 4727 { ICE_PROT_IPV6_IL, 8, 24 }, 4728 4729 { ICE_PROT_IPV6_IL_IL, 8, 8 }, 4730 { ICE_PROT_IPV6_IL_IL, 8, 24 }, 4731 4732 { ICE_PROT_TCP_IL, 1, 0 }, 4733 { ICE_PROT_TCP_IL, 1, 2 }, 4734 4735 { ICE_PROT_UDP_OF, 1, 0 }, 4736 { ICE_PROT_UDP_OF, 1, 2 }, 4737 4738 { ICE_PROT_UDP_IL_OR_S, 1, 0 }, 4739 { ICE_PROT_UDP_IL_OR_S, 1, 2 }, 4740 4741 { ICE_PROT_SCTP_IL, 1, 0 }, 4742 { ICE_PROT_SCTP_IL, 1, 2 } 4743 }; 4744 4745 #define ICE_FD_SRC_DST_PAIR_COUNT ARRAY_SIZE(ice_fd_pairs) 4746 4747 /** 4748 * ice_update_fd_swap - set register appropriately for a FD FV extraction 4749 * @hw: pointer to the HW struct 4750 * @prof_id: profile ID 4751 * @es: extraction sequence (length of array is determined by the block) 4752 */ 4753 static enum ice_status 4754 ice_update_fd_swap(struct ice_hw *hw, u16 prof_id, struct ice_fv_word *es) 4755 { 4756 ice_declare_bitmap(pair_list, ICE_FD_SRC_DST_PAIR_COUNT); 4757 u8 pair_start[ICE_FD_SRC_DST_PAIR_COUNT] = { 0 }; 4758 #define ICE_FD_FV_NOT_FOUND (-2) 4759 s8 first_free = ICE_FD_FV_NOT_FOUND; 4760 u8 used[ICE_MAX_FV_WORDS] = { 0 }; 4761 s8 orig_free, si; 4762 u32 mask_sel = 0; 4763 u8 i, j, k; 4764 4765 ice_zero_bitmap(pair_list, ICE_FD_SRC_DST_PAIR_COUNT); 4766 4767 /* This code assumes that the Flow Director field vectors are assigned 4768 * from the end of the FV indexes working towards the zero index, that 4769 * only complete fields will be included and will be consecutive, and 4770 * that there are no gaps between valid indexes. 4771 */ 4772 4773 /* Determine swap fields present */ 4774 for (i = 0; i < hw->blk[ICE_BLK_FD].es.fvw; i++) { 4775 /* Find the first free entry, assuming right to left population. 4776 * This is where we can start adding additional pairs if needed. 4777 */ 4778 if (first_free == ICE_FD_FV_NOT_FOUND && es[i].prot_id != 4779 ICE_PROT_INVALID) 4780 first_free = i - 1; 4781 4782 for (j = 0; j < ICE_FD_SRC_DST_PAIR_COUNT; j++) 4783 if (es[i].prot_id == ice_fd_pairs[j].prot_id && 4784 es[i].off == ice_fd_pairs[j].off) { 4785 ice_set_bit(j, pair_list); 4786 pair_start[j] = i; 4787 } 4788 } 4789 4790 orig_free = first_free; 4791 4792 /* determine missing swap fields that need to be added */ 4793 for (i = 0; i < ICE_FD_SRC_DST_PAIR_COUNT; i += 2) { 4794 u8 bit1 = ice_is_bit_set(pair_list, i + 1); 4795 u8 bit0 = ice_is_bit_set(pair_list, i); 4796 4797 if (bit0 ^ bit1) { 4798 u8 index; 4799 4800 /* add the appropriate 'paired' entry */ 4801 if (!bit0) 4802 index = i; 4803 else 4804 index = i + 1; 4805 4806 /* check for room */ 4807 if (first_free + 1 < (s8)ice_fd_pairs[index].count) 4808 return ICE_ERR_MAX_LIMIT; 4809 4810 /* place in extraction sequence */ 4811 for (k = 0; k < ice_fd_pairs[index].count; k++) { 4812 es[first_free - k].prot_id = 4813 ice_fd_pairs[index].prot_id; 4814 es[first_free - k].off = 4815 ice_fd_pairs[index].off + (k * 2); 4816 4817 if (k > first_free) 4818 return ICE_ERR_OUT_OF_RANGE; 4819 4820 /* keep track of non-relevant fields */ 4821 mask_sel |= BIT(first_free - k); 4822 } 4823 4824 pair_start[index] = first_free; 4825 first_free -= ice_fd_pairs[index].count; 4826 } 4827 } 4828 4829 /* fill in the swap array */ 4830 si = hw->blk[ICE_BLK_FD].es.fvw - 1; 4831 while (si >= 0) { 4832 u8 indexes_used = 1; 4833 4834 /* assume flat at this index */ 4835 #define ICE_SWAP_VALID 0x80 4836 used[si] = si | ICE_SWAP_VALID; 4837 4838 if (orig_free == ICE_FD_FV_NOT_FOUND || si <= orig_free) { 4839 si -= indexes_used; 4840 continue; 4841 } 4842 4843 /* check for a swap location */ 4844 for (j = 0; j < ICE_FD_SRC_DST_PAIR_COUNT; j++) 4845 if (es[si].prot_id == ice_fd_pairs[j].prot_id && 4846 es[si].off == ice_fd_pairs[j].off) { 4847 u8 idx; 4848 4849 /* determine the appropriate matching field */ 4850 idx = j + ((j % 2) ? -1 : 1); 4851 4852 indexes_used = ice_fd_pairs[idx].count; 4853 for (k = 0; k < indexes_used; k++) { 4854 used[si - k] = (pair_start[idx] - k) | 4855 ICE_SWAP_VALID; 4856 } 4857 4858 break; 4859 } 4860 4861 si -= indexes_used; 4862 } 4863 4864 /* for each set of 4 swap and 4 inset indexes, write the appropriate 4865 * register 4866 */ 4867 for (j = 0; j < hw->blk[ICE_BLK_FD].es.fvw / 4; j++) { 4868 u32 raw_swap = 0; 4869 u32 raw_in = 0; 4870 4871 for (k = 0; k < 4; k++) { 4872 u8 idx; 4873 4874 idx = (j * 4) + k; 4875 if (used[idx] && !(mask_sel & BIT(idx))) { 4876 raw_swap |= used[idx] << (k * BITS_PER_BYTE); 4877 #define ICE_INSET_DFLT 0x9f 4878 raw_in |= ICE_INSET_DFLT << (k * BITS_PER_BYTE); 4879 } 4880 } 4881 4882 /* write the appropriate swap register set */ 4883 wr32(hw, GLQF_FDSWAP(prof_id, j), raw_swap); 4884 4885 ice_debug(hw, ICE_DBG_INIT, "swap wr(%d, %d): %x = %08x\n", 4886 prof_id, j, GLQF_FDSWAP(prof_id, j), raw_swap); 4887 4888 /* write the appropriate inset register set */ 4889 wr32(hw, GLQF_FDINSET(prof_id, j), raw_in); 4890 4891 ice_debug(hw, ICE_DBG_INIT, "inset wr(%d, %d): %x = %08x\n", 4892 prof_id, j, GLQF_FDINSET(prof_id, j), raw_in); 4893 } 4894 4895 /* initially clear the mask select for this profile */ 4896 ice_update_fd_mask(hw, prof_id, 0); 4897 4898 return ICE_SUCCESS; 4899 } 4900 4901 /* The entries here needs to match the order of enum ice_ptype_attrib */ 4902 static const struct ice_ptype_attrib_info ice_ptype_attributes[] = { 4903 { ICE_GTP_PDU_EH, ICE_GTP_PDU_FLAG_MASK }, 4904 { ICE_GTP_SESSION, ICE_GTP_FLAGS_MASK }, 4905 { ICE_GTP_DOWNLINK, ICE_GTP_FLAGS_MASK }, 4906 { ICE_GTP_UPLINK, ICE_GTP_FLAGS_MASK }, 4907 }; 4908 4909 /** 4910 * ice_get_ptype_attrib_info - get ptype attribute information 4911 * @type: attribute type 4912 * @info: pointer to variable to the attribute information 4913 */ 4914 static void 4915 ice_get_ptype_attrib_info(enum ice_ptype_attrib_type type, 4916 struct ice_ptype_attrib_info *info) 4917 { 4918 *info = ice_ptype_attributes[type]; 4919 } 4920 4921 /** 4922 * ice_add_prof_attrib - add any PTG with attributes to profile 4923 * @prof: pointer to the profile to which PTG entries will be added 4924 * @ptg: PTG to be added 4925 * @ptype: PTYPE that needs to be looked up 4926 * @attr: array of attributes that will be considered 4927 * @attr_cnt: number of elements in the attribute array 4928 */ 4929 static enum ice_status 4930 ice_add_prof_attrib(struct ice_prof_map *prof, u8 ptg, u16 ptype, 4931 const struct ice_ptype_attributes *attr, u16 attr_cnt) 4932 { 4933 bool found = false; 4934 u16 i; 4935 4936 for (i = 0; i < attr_cnt; i++) { 4937 if (attr[i].ptype == ptype) { 4938 found = true; 4939 4940 prof->ptg[prof->ptg_cnt] = ptg; 4941 ice_get_ptype_attrib_info(attr[i].attrib, 4942 &prof->attr[prof->ptg_cnt]); 4943 4944 if (++prof->ptg_cnt >= ICE_MAX_PTG_PER_PROFILE) 4945 return ICE_ERR_MAX_LIMIT; 4946 } 4947 } 4948 4949 if (!found) 4950 return ICE_ERR_DOES_NOT_EXIST; 4951 4952 return ICE_SUCCESS; 4953 } 4954 4955 /** 4956 * ice_disable_fd_swap - set register appropriately to disable FD swap 4957 * @hw: pointer to the HW struct 4958 * @prof_id: profile ID 4959 */ 4960 void ice_disable_fd_swap(struct ice_hw *hw, u16 prof_id) 4961 { 4962 u8 swap_val = ICE_SWAP_VALID; 4963 u8 i; 4964 /* Since the SWAP Flag in the Programming Desc doesn't work, 4965 * here add method to disable the SWAP Option via setting 4966 * certain SWAP and INSET register set. 4967 */ 4968 for (i = 0; i < hw->blk[ICE_BLK_FD].es.fvw / 4; i++) { 4969 u32 raw_swap = 0; 4970 u32 raw_in = 0; 4971 u8 j; 4972 4973 for (j = 0; j < 4; j++) { 4974 raw_swap |= (swap_val++) << (j * BITS_PER_BYTE); 4975 raw_in |= ICE_INSET_DFLT << (j * BITS_PER_BYTE); 4976 } 4977 4978 /* write the FDIR swap register set */ 4979 wr32(hw, GLQF_FDSWAP(prof_id, i), raw_swap); 4980 4981 ice_debug(hw, ICE_DBG_INIT, "swap wr(%d, %d): %x = %08x\n", 4982 prof_id, i, GLQF_FDSWAP(prof_id, i), raw_swap); 4983 4984 /* write the FDIR inset register set */ 4985 wr32(hw, GLQF_FDINSET(prof_id, i), raw_in); 4986 4987 ice_debug(hw, ICE_DBG_INIT, "inset wr(%d, %d): %x = %08x\n", 4988 prof_id, i, GLQF_FDINSET(prof_id, i), raw_in); 4989 } 4990 } 4991 4992 /** 4993 * ice_add_prof - add profile 4994 * @hw: pointer to the HW struct 4995 * @blk: hardware block 4996 * @id: profile tracking ID 4997 * @ptypes: array of bitmaps indicating ptypes (ICE_FLOW_PTYPE_MAX bits) 4998 * @attr: array of attributes 4999 * @attr_cnt: number of elements in attrib array 5000 * @es: extraction sequence (length of array is determined by the block) 5001 * @masks: mask for extraction sequence 5002 * @fd_swap: enable/disable FDIR paired src/dst fields swap option 5003 * 5004 * This function registers a profile, which matches a set of PTYPES with a 5005 * particular extraction sequence. While the hardware profile is allocated 5006 * it will not be written until the first call to ice_add_flow that specifies 5007 * the ID value used here. 5008 */ 5009 enum ice_status 5010 ice_add_prof(struct ice_hw *hw, enum ice_block blk, u64 id, u8 ptypes[], 5011 const struct ice_ptype_attributes *attr, u16 attr_cnt, 5012 struct ice_fv_word *es, u16 *masks, bool fd_swap) 5013 { 5014 u32 bytes = DIVIDE_AND_ROUND_UP(ICE_FLOW_PTYPE_MAX, BITS_PER_BYTE); 5015 ice_declare_bitmap(ptgs_used, ICE_XLT1_CNT); 5016 struct ice_prof_map *prof; 5017 enum ice_status status; 5018 u8 byte = 0; 5019 u8 prof_id; 5020 5021 ice_zero_bitmap(ptgs_used, ICE_XLT1_CNT); 5022 5023 ice_acquire_lock(&hw->blk[blk].es.prof_map_lock); 5024 5025 /* search for existing profile */ 5026 status = ice_find_prof_id_with_mask(hw, blk, es, masks, &prof_id); 5027 if (status) { 5028 /* allocate profile ID */ 5029 status = ice_alloc_prof_id(hw, blk, &prof_id); 5030 if (status) 5031 goto err_ice_add_prof; 5032 if (blk == ICE_BLK_FD && fd_swap) { 5033 /* For Flow Director block, the extraction sequence may 5034 * need to be altered in the case where there are paired 5035 * fields that have no match. This is necessary because 5036 * for Flow Director, src and dest fields need to paired 5037 * for filter programming and these values are swapped 5038 * during Tx. 5039 */ 5040 status = ice_update_fd_swap(hw, prof_id, es); 5041 if (status) 5042 goto err_ice_add_prof; 5043 } else if (blk == ICE_BLK_FD) { 5044 ice_disable_fd_swap(hw, prof_id); 5045 } 5046 status = ice_update_prof_masking(hw, blk, prof_id, masks); 5047 if (status) 5048 goto err_ice_add_prof; 5049 5050 /* and write new es */ 5051 ice_write_es(hw, blk, prof_id, es); 5052 } 5053 5054 ice_prof_inc_ref(hw, blk, prof_id); 5055 5056 /* add profile info */ 5057 5058 prof = (struct ice_prof_map *)ice_malloc(hw, sizeof(*prof)); 5059 if (!prof) 5060 goto err_ice_add_prof; 5061 5062 prof->profile_cookie = id; 5063 prof->prof_id = prof_id; 5064 prof->ptg_cnt = 0; 5065 prof->context = 0; 5066 5067 /* build list of ptgs */ 5068 while (bytes && prof->ptg_cnt < ICE_MAX_PTG_PER_PROFILE) { 5069 u8 bit; 5070 5071 if (!ptypes[byte]) { 5072 bytes--; 5073 byte++; 5074 continue; 5075 } 5076 5077 /* Examine 8 bits per byte */ 5078 ice_for_each_set_bit(bit, (ice_bitmap_t *)&ptypes[byte], 5079 BITS_PER_BYTE) { 5080 u16 ptype; 5081 u8 ptg; 5082 5083 ptype = byte * BITS_PER_BYTE + bit; 5084 5085 /* The package should place all ptypes in a non-zero 5086 * PTG, so the following call should never fail. 5087 */ 5088 if (ice_ptg_find_ptype(hw, blk, ptype, &ptg)) 5089 continue; 5090 5091 /* If PTG is already added, skip and continue */ 5092 if (ice_is_bit_set(ptgs_used, ptg)) 5093 continue; 5094 5095 ice_set_bit(ptg, ptgs_used); 5096 /* Check to see there are any attributes for this 5097 * ptype, and add them if found. 5098 */ 5099 status = ice_add_prof_attrib(prof, ptg, ptype, attr, 5100 attr_cnt); 5101 if (status == ICE_ERR_MAX_LIMIT) 5102 break; 5103 if (status) { 5104 /* This is simple a ptype/PTG with no 5105 * attribute 5106 */ 5107 prof->ptg[prof->ptg_cnt] = ptg; 5108 prof->attr[prof->ptg_cnt].flags = 0; 5109 prof->attr[prof->ptg_cnt].mask = 0; 5110 5111 if (++prof->ptg_cnt >= ICE_MAX_PTG_PER_PROFILE) 5112 break; 5113 } 5114 } 5115 5116 bytes--; 5117 byte++; 5118 } 5119 5120 LIST_ADD(&prof->list, &hw->blk[blk].es.prof_map); 5121 status = ICE_SUCCESS; 5122 5123 err_ice_add_prof: 5124 ice_release_lock(&hw->blk[blk].es.prof_map_lock); 5125 return status; 5126 } 5127 5128 /** 5129 * ice_search_prof_id - Search for a profile tracking ID 5130 * @hw: pointer to the HW struct 5131 * @blk: hardware block 5132 * @id: profile tracking ID 5133 * 5134 * This will search for a profile tracking ID which was previously added. 5135 * The profile map lock should be held before calling this function. 5136 */ 5137 struct ice_prof_map * 5138 ice_search_prof_id(struct ice_hw *hw, enum ice_block blk, u64 id) 5139 { 5140 struct ice_prof_map *entry = NULL; 5141 struct ice_prof_map *map; 5142 5143 LIST_FOR_EACH_ENTRY(map, &hw->blk[blk].es.prof_map, ice_prof_map, list) 5144 if (map->profile_cookie == id) { 5145 entry = map; 5146 break; 5147 } 5148 5149 return entry; 5150 } 5151 5152 /** 5153 * ice_vsig_prof_id_count - count profiles in a VSIG 5154 * @hw: pointer to the HW struct 5155 * @blk: hardware block 5156 * @vsig: VSIG to remove the profile from 5157 */ 5158 static u16 5159 ice_vsig_prof_id_count(struct ice_hw *hw, enum ice_block blk, u16 vsig) 5160 { 5161 u16 idx = vsig & ICE_VSIG_IDX_M, count = 0; 5162 struct ice_vsig_prof *p; 5163 5164 LIST_FOR_EACH_ENTRY(p, &hw->blk[blk].xlt2.vsig_tbl[idx].prop_lst, 5165 ice_vsig_prof, list) 5166 count++; 5167 5168 return count; 5169 } 5170 5171 /** 5172 * ice_rel_tcam_idx - release a TCAM index 5173 * @hw: pointer to the HW struct 5174 * @blk: hardware block 5175 * @idx: the index to release 5176 */ 5177 static enum ice_status 5178 ice_rel_tcam_idx(struct ice_hw *hw, enum ice_block blk, u16 idx) 5179 { 5180 /* Masks to invoke a never match entry */ 5181 u8 vl_msk[ICE_TCAM_KEY_VAL_SZ] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; 5182 u8 dc_msk[ICE_TCAM_KEY_VAL_SZ] = { 0xFE, 0xFF, 0xFF, 0xFF, 0xFF }; 5183 u8 nm_msk[ICE_TCAM_KEY_VAL_SZ] = { 0x01, 0x00, 0x00, 0x00, 0x00 }; 5184 enum ice_status status; 5185 5186 /* write the TCAM entry */ 5187 status = ice_tcam_write_entry(hw, blk, idx, 0, 0, 0, 0, 0, vl_msk, 5188 dc_msk, nm_msk); 5189 if (status) 5190 return status; 5191 5192 /* release the TCAM entry */ 5193 status = ice_free_tcam_ent(hw, blk, idx); 5194 5195 return status; 5196 } 5197 5198 /** 5199 * ice_rem_prof_id - remove one profile from a VSIG 5200 * @hw: pointer to the HW struct 5201 * @blk: hardware block 5202 * @prof: pointer to profile structure to remove 5203 */ 5204 static enum ice_status 5205 ice_rem_prof_id(struct ice_hw *hw, enum ice_block blk, 5206 struct ice_vsig_prof *prof) 5207 { 5208 enum ice_status status; 5209 u16 i; 5210 5211 for (i = 0; i < prof->tcam_count; i++) 5212 if (prof->tcam[i].in_use) { 5213 prof->tcam[i].in_use = false; 5214 status = ice_rel_tcam_idx(hw, blk, 5215 prof->tcam[i].tcam_idx); 5216 if (status) 5217 return ICE_ERR_HW_TABLE; 5218 } 5219 5220 return ICE_SUCCESS; 5221 } 5222 5223 /** 5224 * ice_rem_vsig - remove VSIG 5225 * @hw: pointer to the HW struct 5226 * @blk: hardware block 5227 * @vsig: the VSIG to remove 5228 * @chg: the change list 5229 */ 5230 static enum ice_status 5231 ice_rem_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsig, 5232 struct LIST_HEAD_TYPE *chg) 5233 { 5234 u16 idx = vsig & ICE_VSIG_IDX_M; 5235 struct ice_vsig_vsi *vsi_cur; 5236 struct ice_vsig_prof *d, *t; 5237 enum ice_status status; 5238 5239 /* remove TCAM entries */ 5240 LIST_FOR_EACH_ENTRY_SAFE(d, t, 5241 &hw->blk[blk].xlt2.vsig_tbl[idx].prop_lst, 5242 ice_vsig_prof, list) { 5243 status = ice_rem_prof_id(hw, blk, d); 5244 if (status) 5245 return status; 5246 5247 LIST_DEL(&d->list); 5248 ice_free(hw, d); 5249 } 5250 5251 /* Move all VSIS associated with this VSIG to the default VSIG */ 5252 vsi_cur = hw->blk[blk].xlt2.vsig_tbl[idx].first_vsi; 5253 /* If the VSIG has at least 1 VSI then iterate through the list 5254 * and remove the VSIs before deleting the group. 5255 */ 5256 if (vsi_cur) 5257 do { 5258 struct ice_vsig_vsi *tmp = vsi_cur->next_vsi; 5259 struct ice_chs_chg *p; 5260 5261 p = (struct ice_chs_chg *)ice_malloc(hw, sizeof(*p)); 5262 if (!p) 5263 return ICE_ERR_NO_MEMORY; 5264 5265 p->type = ICE_VSIG_REM; 5266 p->orig_vsig = vsig; 5267 p->vsig = ICE_DEFAULT_VSIG; 5268 p->vsi = vsi_cur - hw->blk[blk].xlt2.vsis; 5269 5270 LIST_ADD(&p->list_entry, chg); 5271 5272 vsi_cur = tmp; 5273 } while (vsi_cur); 5274 5275 return ice_vsig_free(hw, blk, vsig); 5276 } 5277 5278 /** 5279 * ice_rem_prof_id_vsig - remove a specific profile from a VSIG 5280 * @hw: pointer to the HW struct 5281 * @blk: hardware block 5282 * @vsig: VSIG to remove the profile from 5283 * @hdl: profile handle indicating which profile to remove 5284 * @chg: list to receive a record of changes 5285 */ 5286 static enum ice_status 5287 ice_rem_prof_id_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsig, u64 hdl, 5288 struct LIST_HEAD_TYPE *chg) 5289 { 5290 u16 idx = vsig & ICE_VSIG_IDX_M; 5291 struct ice_vsig_prof *p, *t; 5292 enum ice_status status; 5293 5294 LIST_FOR_EACH_ENTRY_SAFE(p, t, 5295 &hw->blk[blk].xlt2.vsig_tbl[idx].prop_lst, 5296 ice_vsig_prof, list) 5297 if (p->profile_cookie == hdl) { 5298 if (ice_vsig_prof_id_count(hw, blk, vsig) == 1) 5299 /* this is the last profile, remove the VSIG */ 5300 return ice_rem_vsig(hw, blk, vsig, chg); 5301 5302 status = ice_rem_prof_id(hw, blk, p); 5303 if (!status) { 5304 LIST_DEL(&p->list); 5305 ice_free(hw, p); 5306 } 5307 return status; 5308 } 5309 5310 return ICE_ERR_DOES_NOT_EXIST; 5311 } 5312 5313 /** 5314 * ice_rem_flow_all - remove all flows with a particular profile 5315 * @hw: pointer to the HW struct 5316 * @blk: hardware block 5317 * @id: profile tracking ID 5318 */ 5319 static enum ice_status 5320 ice_rem_flow_all(struct ice_hw *hw, enum ice_block blk, u64 id) 5321 { 5322 struct ice_chs_chg *del, *tmp; 5323 struct LIST_HEAD_TYPE chg; 5324 enum ice_status status; 5325 u16 i; 5326 5327 INIT_LIST_HEAD(&chg); 5328 5329 for (i = 1; i < ICE_MAX_VSIGS; i++) 5330 if (hw->blk[blk].xlt2.vsig_tbl[i].in_use) { 5331 if (ice_has_prof_vsig(hw, blk, i, id)) { 5332 status = ice_rem_prof_id_vsig(hw, blk, i, id, 5333 &chg); 5334 if (status) 5335 goto err_ice_rem_flow_all; 5336 } 5337 } 5338 5339 status = ice_upd_prof_hw(hw, blk, &chg); 5340 5341 err_ice_rem_flow_all: 5342 LIST_FOR_EACH_ENTRY_SAFE(del, tmp, &chg, ice_chs_chg, list_entry) { 5343 LIST_DEL(&del->list_entry); 5344 ice_free(hw, del); 5345 } 5346 5347 return status; 5348 } 5349 5350 /** 5351 * ice_rem_prof - remove profile 5352 * @hw: pointer to the HW struct 5353 * @blk: hardware block 5354 * @id: profile tracking ID 5355 * 5356 * This will remove the profile specified by the ID parameter, which was 5357 * previously created through ice_add_prof. If any existing entries 5358 * are associated with this profile, they will be removed as well. 5359 */ 5360 enum ice_status ice_rem_prof(struct ice_hw *hw, enum ice_block blk, u64 id) 5361 { 5362 struct ice_prof_map *pmap; 5363 enum ice_status status; 5364 5365 ice_acquire_lock(&hw->blk[blk].es.prof_map_lock); 5366 5367 pmap = ice_search_prof_id(hw, blk, id); 5368 if (!pmap) { 5369 status = ICE_ERR_DOES_NOT_EXIST; 5370 goto err_ice_rem_prof; 5371 } 5372 5373 /* remove all flows with this profile */ 5374 status = ice_rem_flow_all(hw, blk, pmap->profile_cookie); 5375 if (status) 5376 goto err_ice_rem_prof; 5377 5378 /* dereference profile, and possibly remove */ 5379 ice_prof_dec_ref(hw, blk, pmap->prof_id); 5380 5381 LIST_DEL(&pmap->list); 5382 ice_free(hw, pmap); 5383 5384 err_ice_rem_prof: 5385 ice_release_lock(&hw->blk[blk].es.prof_map_lock); 5386 return status; 5387 } 5388 5389 /** 5390 * ice_get_prof - get profile 5391 * @hw: pointer to the HW struct 5392 * @blk: hardware block 5393 * @hdl: profile handle 5394 * @chg: change list 5395 */ 5396 static enum ice_status 5397 ice_get_prof(struct ice_hw *hw, enum ice_block blk, u64 hdl, 5398 struct LIST_HEAD_TYPE *chg) 5399 { 5400 enum ice_status status = ICE_SUCCESS; 5401 struct ice_prof_map *map; 5402 struct ice_chs_chg *p; 5403 u16 i; 5404 5405 ice_acquire_lock(&hw->blk[blk].es.prof_map_lock); 5406 /* Get the details on the profile specified by the handle ID */ 5407 map = ice_search_prof_id(hw, blk, hdl); 5408 if (!map) { 5409 status = ICE_ERR_DOES_NOT_EXIST; 5410 goto err_ice_get_prof; 5411 } 5412 5413 for (i = 0; i < map->ptg_cnt; i++) 5414 if (!hw->blk[blk].es.written[map->prof_id]) { 5415 /* add ES to change list */ 5416 p = (struct ice_chs_chg *)ice_malloc(hw, sizeof(*p)); 5417 if (!p) { 5418 status = ICE_ERR_NO_MEMORY; 5419 goto err_ice_get_prof; 5420 } 5421 5422 p->type = ICE_PTG_ES_ADD; 5423 p->ptype = 0; 5424 p->ptg = map->ptg[i]; 5425 p->attr = map->attr[i]; 5426 p->add_ptg = 0; 5427 5428 p->add_prof = 1; 5429 p->prof_id = map->prof_id; 5430 5431 hw->blk[blk].es.written[map->prof_id] = true; 5432 5433 LIST_ADD(&p->list_entry, chg); 5434 } 5435 5436 err_ice_get_prof: 5437 ice_release_lock(&hw->blk[blk].es.prof_map_lock); 5438 /* let caller clean up the change list */ 5439 return status; 5440 } 5441 5442 /** 5443 * ice_get_profs_vsig - get a copy of the list of profiles from a VSIG 5444 * @hw: pointer to the HW struct 5445 * @blk: hardware block 5446 * @vsig: VSIG from which to copy the list 5447 * @lst: output list 5448 * 5449 * This routine makes a copy of the list of profiles in the specified VSIG. 5450 */ 5451 static enum ice_status 5452 ice_get_profs_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsig, 5453 struct LIST_HEAD_TYPE *lst) 5454 { 5455 struct ice_vsig_prof *ent1, *ent2; 5456 u16 idx = vsig & ICE_VSIG_IDX_M; 5457 5458 LIST_FOR_EACH_ENTRY(ent1, &hw->blk[blk].xlt2.vsig_tbl[idx].prop_lst, 5459 ice_vsig_prof, list) { 5460 struct ice_vsig_prof *p; 5461 5462 /* copy to the input list */ 5463 p = (struct ice_vsig_prof *)ice_memdup(hw, ent1, sizeof(*p), 5464 ICE_NONDMA_TO_NONDMA); 5465 if (!p) 5466 goto err_ice_get_profs_vsig; 5467 5468 LIST_ADD_TAIL(&p->list, lst); 5469 } 5470 5471 return ICE_SUCCESS; 5472 5473 err_ice_get_profs_vsig: 5474 LIST_FOR_EACH_ENTRY_SAFE(ent1, ent2, lst, ice_vsig_prof, list) { 5475 LIST_DEL(&ent1->list); 5476 ice_free(hw, ent1); 5477 } 5478 5479 return ICE_ERR_NO_MEMORY; 5480 } 5481 5482 /** 5483 * ice_add_prof_to_lst - add profile entry to a list 5484 * @hw: pointer to the HW struct 5485 * @blk: hardware block 5486 * @lst: the list to be added to 5487 * @hdl: profile handle of entry to add 5488 */ 5489 static enum ice_status 5490 ice_add_prof_to_lst(struct ice_hw *hw, enum ice_block blk, 5491 struct LIST_HEAD_TYPE *lst, u64 hdl) 5492 { 5493 enum ice_status status = ICE_SUCCESS; 5494 struct ice_prof_map *map; 5495 struct ice_vsig_prof *p; 5496 u16 i; 5497 5498 ice_acquire_lock(&hw->blk[blk].es.prof_map_lock); 5499 map = ice_search_prof_id(hw, blk, hdl); 5500 if (!map) { 5501 status = ICE_ERR_DOES_NOT_EXIST; 5502 goto err_ice_add_prof_to_lst; 5503 } 5504 5505 p = (struct ice_vsig_prof *)ice_malloc(hw, sizeof(*p)); 5506 if (!p) { 5507 status = ICE_ERR_NO_MEMORY; 5508 goto err_ice_add_prof_to_lst; 5509 } 5510 5511 p->profile_cookie = map->profile_cookie; 5512 p->prof_id = map->prof_id; 5513 p->tcam_count = map->ptg_cnt; 5514 5515 for (i = 0; i < map->ptg_cnt; i++) { 5516 p->tcam[i].prof_id = map->prof_id; 5517 p->tcam[i].tcam_idx = ICE_INVALID_TCAM; 5518 p->tcam[i].ptg = map->ptg[i]; 5519 p->tcam[i].attr = map->attr[i]; 5520 } 5521 5522 LIST_ADD(&p->list, lst); 5523 5524 err_ice_add_prof_to_lst: 5525 ice_release_lock(&hw->blk[blk].es.prof_map_lock); 5526 return status; 5527 } 5528 5529 /** 5530 * ice_move_vsi - move VSI to another VSIG 5531 * @hw: pointer to the HW struct 5532 * @blk: hardware block 5533 * @vsi: the VSI to move 5534 * @vsig: the VSIG to move the VSI to 5535 * @chg: the change list 5536 */ 5537 static enum ice_status 5538 ice_move_vsi(struct ice_hw *hw, enum ice_block blk, u16 vsi, u16 vsig, 5539 struct LIST_HEAD_TYPE *chg) 5540 { 5541 enum ice_status status; 5542 struct ice_chs_chg *p; 5543 u16 orig_vsig; 5544 5545 p = (struct ice_chs_chg *)ice_malloc(hw, sizeof(*p)); 5546 if (!p) 5547 return ICE_ERR_NO_MEMORY; 5548 5549 status = ice_vsig_find_vsi(hw, blk, vsi, &orig_vsig); 5550 if (!status) 5551 status = ice_vsig_add_mv_vsi(hw, blk, vsi, vsig); 5552 5553 if (status) { 5554 ice_free(hw, p); 5555 return status; 5556 } 5557 5558 p->type = ICE_VSI_MOVE; 5559 p->vsi = vsi; 5560 p->orig_vsig = orig_vsig; 5561 p->vsig = vsig; 5562 5563 LIST_ADD(&p->list_entry, chg); 5564 5565 return ICE_SUCCESS; 5566 } 5567 5568 /** 5569 * ice_set_tcam_flags - set TCAM flag don't care mask 5570 * @mask: mask for flags 5571 * @dc_mask: pointer to the don't care mask 5572 */ 5573 static void ice_set_tcam_flags(u16 mask, u8 dc_mask[ICE_TCAM_KEY_VAL_SZ]) 5574 { 5575 u16 *flag_word; 5576 5577 /* flags are lowest u16 */ 5578 flag_word = (u16 *)dc_mask; 5579 *flag_word = ~mask; 5580 } 5581 5582 /** 5583 * ice_rem_chg_tcam_ent - remove a specific TCAM entry from change list 5584 * @hw: pointer to the HW struct 5585 * @idx: the index of the TCAM entry to remove 5586 * @chg: the list of change structures to search 5587 */ 5588 static void 5589 ice_rem_chg_tcam_ent(struct ice_hw *hw, u16 idx, struct LIST_HEAD_TYPE *chg) 5590 { 5591 struct ice_chs_chg *pos, *tmp; 5592 5593 LIST_FOR_EACH_ENTRY_SAFE(tmp, pos, chg, ice_chs_chg, list_entry) 5594 if (tmp->type == ICE_TCAM_ADD && tmp->tcam_idx == idx) { 5595 LIST_DEL(&tmp->list_entry); 5596 ice_free(hw, tmp); 5597 } 5598 } 5599 5600 /** 5601 * ice_prof_tcam_ena_dis - add enable or disable TCAM change 5602 * @hw: pointer to the HW struct 5603 * @blk: hardware block 5604 * @enable: true to enable, false to disable 5605 * @vsig: the VSIG of the TCAM entry 5606 * @tcam: pointer the TCAM info structure of the TCAM to disable 5607 * @chg: the change list 5608 * 5609 * This function appends an enable or disable TCAM entry in the change log 5610 */ 5611 static enum ice_status 5612 ice_prof_tcam_ena_dis(struct ice_hw *hw, enum ice_block blk, bool enable, 5613 u16 vsig, struct ice_tcam_inf *tcam, 5614 struct LIST_HEAD_TYPE *chg) 5615 { 5616 enum ice_status status; 5617 struct ice_chs_chg *p; 5618 5619 u8 vl_msk[ICE_TCAM_KEY_VAL_SZ] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; 5620 u8 dc_msk[ICE_TCAM_KEY_VAL_SZ] = { 0xFF, 0xFF, 0x00, 0x00, 0x00 }; 5621 u8 nm_msk[ICE_TCAM_KEY_VAL_SZ] = { 0x00, 0x00, 0x00, 0x00, 0x00 }; 5622 5623 /* if disabling, free the TCAM */ 5624 if (!enable) { 5625 status = ice_rel_tcam_idx(hw, blk, tcam->tcam_idx); 5626 5627 /* if we have already created a change for this TCAM entry, then 5628 * we need to remove that entry, in order to prevent writing to 5629 * a TCAM entry we no longer will have ownership of. 5630 */ 5631 ice_rem_chg_tcam_ent(hw, tcam->tcam_idx, chg); 5632 tcam->tcam_idx = 0; 5633 tcam->in_use = 0; 5634 return status; 5635 } 5636 5637 /* for re-enabling, reallocate a TCAM */ 5638 /* for entries with empty attribute masks, allocate entry from 5639 * the bottom of the TCAM table; otherwise, allocate from the 5640 * top of the table in order to give it higher priority 5641 */ 5642 status = ice_alloc_tcam_ent(hw, blk, tcam->attr.mask == 0, 5643 &tcam->tcam_idx); 5644 if (status) 5645 return status; 5646 5647 /* add TCAM to change list */ 5648 p = (struct ice_chs_chg *)ice_malloc(hw, sizeof(*p)); 5649 if (!p) 5650 return ICE_ERR_NO_MEMORY; 5651 5652 /* set don't care masks for TCAM flags */ 5653 ice_set_tcam_flags(tcam->attr.mask, dc_msk); 5654 5655 status = ice_tcam_write_entry(hw, blk, tcam->tcam_idx, tcam->prof_id, 5656 tcam->ptg, vsig, 0, tcam->attr.flags, 5657 vl_msk, dc_msk, nm_msk); 5658 if (status) 5659 goto err_ice_prof_tcam_ena_dis; 5660 5661 tcam->in_use = 1; 5662 5663 p->type = ICE_TCAM_ADD; 5664 p->add_tcam_idx = true; 5665 p->prof_id = tcam->prof_id; 5666 p->ptg = tcam->ptg; 5667 p->vsig = 0; 5668 p->tcam_idx = tcam->tcam_idx; 5669 5670 /* log change */ 5671 LIST_ADD(&p->list_entry, chg); 5672 5673 return ICE_SUCCESS; 5674 5675 err_ice_prof_tcam_ena_dis: 5676 ice_free(hw, p); 5677 return status; 5678 } 5679 5680 /** 5681 * ice_ptg_attr_in_use - determine if PTG and attribute pair is in use 5682 * @ptg_attr: pointer to the PTG and attribute pair to check 5683 * @ptgs_used: bitmap that denotes which PTGs are in use 5684 * @attr_used: array of PTG and attributes pairs already used 5685 * @attr_cnt: count of entries in the attr_used array 5686 */ 5687 static bool 5688 ice_ptg_attr_in_use(struct ice_tcam_inf *ptg_attr, ice_bitmap_t *ptgs_used, 5689 struct ice_tcam_inf *attr_used[], u16 attr_cnt) 5690 { 5691 u16 i; 5692 5693 if (!ice_is_bit_set(ptgs_used, ptg_attr->ptg)) 5694 return false; 5695 5696 /* the PTG is used, so now look for correct attributes */ 5697 for (i = 0; i < attr_cnt; i++) 5698 if (attr_used[i]->ptg == ptg_attr->ptg && 5699 attr_used[i]->attr.flags == ptg_attr->attr.flags && 5700 attr_used[i]->attr.mask == ptg_attr->attr.mask) 5701 return true; 5702 5703 return false; 5704 } 5705 5706 /** 5707 * ice_adj_prof_priorities - adjust profile based on priorities 5708 * @hw: pointer to the HW struct 5709 * @blk: hardware block 5710 * @vsig: the VSIG for which to adjust profile priorities 5711 * @chg: the change list 5712 */ 5713 static enum ice_status 5714 ice_adj_prof_priorities(struct ice_hw *hw, enum ice_block blk, u16 vsig, 5715 struct LIST_HEAD_TYPE *chg) 5716 { 5717 ice_declare_bitmap(ptgs_used, ICE_XLT1_CNT); 5718 struct ice_tcam_inf **attr_used; 5719 enum ice_status status = ICE_SUCCESS; 5720 struct ice_vsig_prof *t; 5721 u16 attr_used_cnt = 0; 5722 u16 idx; 5723 5724 #define ICE_MAX_PTG_ATTRS 1024 5725 attr_used = (struct ice_tcam_inf **)ice_calloc(hw, ICE_MAX_PTG_ATTRS, 5726 sizeof(*attr_used)); 5727 if (!attr_used) 5728 return ICE_ERR_NO_MEMORY; 5729 5730 ice_zero_bitmap(ptgs_used, ICE_XLT1_CNT); 5731 idx = vsig & ICE_VSIG_IDX_M; 5732 5733 /* Priority is based on the order in which the profiles are added. The 5734 * newest added profile has highest priority and the oldest added 5735 * profile has the lowest priority. Since the profile property list for 5736 * a VSIG is sorted from newest to oldest, this code traverses the list 5737 * in order and enables the first of each PTG that it finds (that is not 5738 * already enabled); it also disables any duplicate PTGs that it finds 5739 * in the older profiles (that are currently enabled). 5740 */ 5741 5742 LIST_FOR_EACH_ENTRY(t, &hw->blk[blk].xlt2.vsig_tbl[idx].prop_lst, 5743 ice_vsig_prof, list) { 5744 u16 i; 5745 5746 for (i = 0; i < t->tcam_count; i++) { 5747 bool used; 5748 5749 /* Scan the priorities from newest to oldest. 5750 * Make sure that the newest profiles take priority. 5751 */ 5752 used = ice_ptg_attr_in_use(&t->tcam[i], ptgs_used, 5753 attr_used, attr_used_cnt); 5754 5755 if (used && t->tcam[i].in_use) { 5756 /* need to mark this PTG as never match, as it 5757 * was already in use and therefore duplicate 5758 * (and lower priority) 5759 */ 5760 status = ice_prof_tcam_ena_dis(hw, blk, false, 5761 vsig, 5762 &t->tcam[i], 5763 chg); 5764 if (status) 5765 goto err_ice_adj_prof_priorities; 5766 } else if (!used && !t->tcam[i].in_use) { 5767 /* need to enable this PTG, as it in not in use 5768 * and not enabled (highest priority) 5769 */ 5770 status = ice_prof_tcam_ena_dis(hw, blk, true, 5771 vsig, 5772 &t->tcam[i], 5773 chg); 5774 if (status) 5775 goto err_ice_adj_prof_priorities; 5776 } 5777 5778 /* keep track of used ptgs */ 5779 ice_set_bit(t->tcam[i].ptg, ptgs_used); 5780 if (attr_used_cnt < ICE_MAX_PTG_ATTRS) 5781 attr_used[attr_used_cnt++] = &t->tcam[i]; 5782 else 5783 ice_debug(hw, ICE_DBG_INIT, "Warn: ICE_MAX_PTG_ATTRS exceeded\n"); 5784 } 5785 } 5786 5787 err_ice_adj_prof_priorities: 5788 ice_free(hw, attr_used); 5789 return status; 5790 } 5791 5792 /** 5793 * ice_add_prof_id_vsig - add profile to VSIG 5794 * @hw: pointer to the HW struct 5795 * @blk: hardware block 5796 * @vsig: the VSIG to which this profile is to be added 5797 * @hdl: the profile handle indicating the profile to add 5798 * @rev: true to add entries to the end of the list 5799 * @chg: the change list 5800 */ 5801 static enum ice_status 5802 ice_add_prof_id_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsig, u64 hdl, 5803 bool rev, struct LIST_HEAD_TYPE *chg) 5804 { 5805 /* Masks that ignore flags */ 5806 u8 vl_msk[ICE_TCAM_KEY_VAL_SZ] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; 5807 u8 dc_msk[ICE_TCAM_KEY_VAL_SZ] = { 0xFF, 0xFF, 0x00, 0x00, 0x00 }; 5808 u8 nm_msk[ICE_TCAM_KEY_VAL_SZ] = { 0x00, 0x00, 0x00, 0x00, 0x00 }; 5809 enum ice_status status = ICE_SUCCESS; 5810 struct ice_prof_map *map; 5811 struct ice_vsig_prof *t; 5812 struct ice_chs_chg *p; 5813 u16 vsig_idx, i; 5814 5815 /* Error, if this VSIG already has this profile */ 5816 if (ice_has_prof_vsig(hw, blk, vsig, hdl)) 5817 return ICE_ERR_ALREADY_EXISTS; 5818 5819 /* new VSIG profile structure */ 5820 t = (struct ice_vsig_prof *)ice_malloc(hw, sizeof(*t)); 5821 if (!t) 5822 return ICE_ERR_NO_MEMORY; 5823 5824 ice_acquire_lock(&hw->blk[blk].es.prof_map_lock); 5825 /* Get the details on the profile specified by the handle ID */ 5826 map = ice_search_prof_id(hw, blk, hdl); 5827 if (!map) { 5828 status = ICE_ERR_DOES_NOT_EXIST; 5829 goto err_ice_add_prof_id_vsig; 5830 } 5831 5832 t->profile_cookie = map->profile_cookie; 5833 t->prof_id = map->prof_id; 5834 t->tcam_count = map->ptg_cnt; 5835 5836 /* create TCAM entries */ 5837 for (i = 0; i < map->ptg_cnt; i++) { 5838 u16 tcam_idx; 5839 5840 /* add TCAM to change list */ 5841 p = (struct ice_chs_chg *)ice_malloc(hw, sizeof(*p)); 5842 if (!p) { 5843 status = ICE_ERR_NO_MEMORY; 5844 goto err_ice_add_prof_id_vsig; 5845 } 5846 5847 /* allocate the TCAM entry index */ 5848 /* for entries with empty attribute masks, allocate entry from 5849 * the bottom of the TCAM table; otherwise, allocate from the 5850 * top of the table in order to give it higher priority 5851 */ 5852 status = ice_alloc_tcam_ent(hw, blk, map->attr[i].mask == 0, 5853 &tcam_idx); 5854 if (status) { 5855 ice_free(hw, p); 5856 goto err_ice_add_prof_id_vsig; 5857 } 5858 5859 t->tcam[i].ptg = map->ptg[i]; 5860 t->tcam[i].prof_id = map->prof_id; 5861 t->tcam[i].tcam_idx = tcam_idx; 5862 t->tcam[i].attr = map->attr[i]; 5863 t->tcam[i].in_use = true; 5864 5865 p->type = ICE_TCAM_ADD; 5866 p->add_tcam_idx = true; 5867 p->prof_id = t->tcam[i].prof_id; 5868 p->ptg = t->tcam[i].ptg; 5869 p->vsig = vsig; 5870 p->tcam_idx = t->tcam[i].tcam_idx; 5871 5872 /* set don't care masks for TCAM flags */ 5873 ice_set_tcam_flags(t->tcam[i].attr.mask, dc_msk); 5874 5875 /* write the TCAM entry */ 5876 status = ice_tcam_write_entry(hw, blk, t->tcam[i].tcam_idx, 5877 t->tcam[i].prof_id, 5878 t->tcam[i].ptg, vsig, 0, 5879 t->tcam[i].attr.flags, vl_msk, 5880 dc_msk, nm_msk); 5881 if (status) { 5882 ice_free(hw, p); 5883 goto err_ice_add_prof_id_vsig; 5884 } 5885 5886 /* log change */ 5887 LIST_ADD(&p->list_entry, chg); 5888 } 5889 5890 /* add profile to VSIG */ 5891 vsig_idx = vsig & ICE_VSIG_IDX_M; 5892 if (rev) 5893 LIST_ADD_TAIL(&t->list, 5894 &hw->blk[blk].xlt2.vsig_tbl[vsig_idx].prop_lst); 5895 else 5896 LIST_ADD(&t->list, 5897 &hw->blk[blk].xlt2.vsig_tbl[vsig_idx].prop_lst); 5898 5899 ice_release_lock(&hw->blk[blk].es.prof_map_lock); 5900 return status; 5901 5902 err_ice_add_prof_id_vsig: 5903 ice_release_lock(&hw->blk[blk].es.prof_map_lock); 5904 /* let caller clean up the change list */ 5905 ice_free(hw, t); 5906 return status; 5907 } 5908 5909 /** 5910 * ice_create_prof_id_vsig - add a new VSIG with a single profile 5911 * @hw: pointer to the HW struct 5912 * @blk: hardware block 5913 * @vsi: the initial VSI that will be in VSIG 5914 * @hdl: the profile handle of the profile that will be added to the VSIG 5915 * @chg: the change list 5916 */ 5917 static enum ice_status 5918 ice_create_prof_id_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl, 5919 struct LIST_HEAD_TYPE *chg) 5920 { 5921 enum ice_status status; 5922 struct ice_chs_chg *p; 5923 u16 new_vsig; 5924 5925 p = (struct ice_chs_chg *)ice_malloc(hw, sizeof(*p)); 5926 if (!p) 5927 return ICE_ERR_NO_MEMORY; 5928 5929 new_vsig = ice_vsig_alloc(hw, blk); 5930 if (!new_vsig) { 5931 status = ICE_ERR_HW_TABLE; 5932 goto err_ice_create_prof_id_vsig; 5933 } 5934 5935 status = ice_move_vsi(hw, blk, vsi, new_vsig, chg); 5936 if (status) 5937 goto err_ice_create_prof_id_vsig; 5938 5939 status = ice_add_prof_id_vsig(hw, blk, new_vsig, hdl, false, chg); 5940 if (status) 5941 goto err_ice_create_prof_id_vsig; 5942 5943 p->type = ICE_VSIG_ADD; 5944 p->vsi = vsi; 5945 p->orig_vsig = ICE_DEFAULT_VSIG; 5946 p->vsig = new_vsig; 5947 5948 LIST_ADD(&p->list_entry, chg); 5949 5950 return ICE_SUCCESS; 5951 5952 err_ice_create_prof_id_vsig: 5953 /* let caller clean up the change list */ 5954 ice_free(hw, p); 5955 return status; 5956 } 5957 5958 /** 5959 * ice_create_vsig_from_lst - create a new VSIG with a list of profiles 5960 * @hw: pointer to the HW struct 5961 * @blk: hardware block 5962 * @vsi: the initial VSI that will be in VSIG 5963 * @lst: the list of profile that will be added to the VSIG 5964 * @new_vsig: return of new VSIG 5965 * @chg: the change list 5966 */ 5967 static enum ice_status 5968 ice_create_vsig_from_lst(struct ice_hw *hw, enum ice_block blk, u16 vsi, 5969 struct LIST_HEAD_TYPE *lst, u16 *new_vsig, 5970 struct LIST_HEAD_TYPE *chg) 5971 { 5972 struct ice_vsig_prof *t; 5973 enum ice_status status; 5974 u16 vsig; 5975 5976 vsig = ice_vsig_alloc(hw, blk); 5977 if (!vsig) 5978 return ICE_ERR_HW_TABLE; 5979 5980 status = ice_move_vsi(hw, blk, vsi, vsig, chg); 5981 if (status) 5982 return status; 5983 5984 LIST_FOR_EACH_ENTRY(t, lst, ice_vsig_prof, list) { 5985 /* Reverse the order here since we are copying the list */ 5986 status = ice_add_prof_id_vsig(hw, blk, vsig, t->profile_cookie, 5987 true, chg); 5988 if (status) 5989 return status; 5990 } 5991 5992 *new_vsig = vsig; 5993 5994 return ICE_SUCCESS; 5995 } 5996 5997 /** 5998 * ice_find_prof_vsig - find a VSIG with a specific profile handle 5999 * @hw: pointer to the HW struct 6000 * @blk: hardware block 6001 * @hdl: the profile handle of the profile to search for 6002 * @vsig: returns the VSIG with the matching profile 6003 */ 6004 static bool 6005 ice_find_prof_vsig(struct ice_hw *hw, enum ice_block blk, u64 hdl, u16 *vsig) 6006 { 6007 struct ice_vsig_prof *t; 6008 struct LIST_HEAD_TYPE lst; 6009 enum ice_status status; 6010 6011 INIT_LIST_HEAD(&lst); 6012 6013 t = (struct ice_vsig_prof *)ice_malloc(hw, sizeof(*t)); 6014 if (!t) 6015 return false; 6016 6017 t->profile_cookie = hdl; 6018 LIST_ADD(&t->list, &lst); 6019 6020 status = ice_find_dup_props_vsig(hw, blk, &lst, vsig); 6021 6022 LIST_DEL(&t->list); 6023 ice_free(hw, t); 6024 6025 return status == ICE_SUCCESS; 6026 } 6027 6028 /** 6029 * ice_add_vsi_flow - add VSI flow 6030 * @hw: pointer to the HW struct 6031 * @blk: hardware block 6032 * @vsi: input VSI 6033 * @vsig: target VSIG to include the input VSI 6034 * 6035 * Calling this function will add the VSI to a given VSIG and 6036 * update the HW tables accordingly. This call can be used to 6037 * add multiple VSIs to a VSIG if we know beforehand that those 6038 * VSIs have the same characteristics of the VSIG. This will 6039 * save time in generating a new VSIG and TCAMs till a match is 6040 * found and subsequent rollback when a matching VSIG is found. 6041 */ 6042 enum ice_status 6043 ice_add_vsi_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u16 vsig) 6044 { 6045 struct ice_chs_chg *tmp, *del; 6046 struct LIST_HEAD_TYPE chg; 6047 enum ice_status status; 6048 6049 /* if target VSIG is default the move is invalid */ 6050 if ((vsig & ICE_VSIG_IDX_M) == ICE_DEFAULT_VSIG) 6051 return ICE_ERR_PARAM; 6052 6053 INIT_LIST_HEAD(&chg); 6054 6055 /* move VSI to the VSIG that matches */ 6056 status = ice_move_vsi(hw, blk, vsi, vsig, &chg); 6057 /* update hardware if success */ 6058 if (!status) 6059 status = ice_upd_prof_hw(hw, blk, &chg); 6060 6061 LIST_FOR_EACH_ENTRY_SAFE(del, tmp, &chg, ice_chs_chg, list_entry) { 6062 LIST_DEL(&del->list_entry); 6063 ice_free(hw, del); 6064 } 6065 6066 return status; 6067 } 6068 6069 /** 6070 * ice_add_prof_id_flow - add profile flow 6071 * @hw: pointer to the HW struct 6072 * @blk: hardware block 6073 * @vsi: the VSI to enable with the profile specified by ID 6074 * @hdl: profile handle 6075 * 6076 * Calling this function will update the hardware tables to enable the 6077 * profile indicated by the ID parameter for the VSIs specified in the VSI 6078 * array. Once successfully called, the flow will be enabled. 6079 */ 6080 enum ice_status 6081 ice_add_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl) 6082 { 6083 struct ice_vsig_prof *tmp1, *del1; 6084 struct LIST_HEAD_TYPE union_lst; 6085 struct ice_chs_chg *tmp, *del; 6086 struct LIST_HEAD_TYPE chg; 6087 enum ice_status status; 6088 u16 vsig; 6089 6090 INIT_LIST_HEAD(&union_lst); 6091 INIT_LIST_HEAD(&chg); 6092 6093 /* Get profile */ 6094 status = ice_get_prof(hw, blk, hdl, &chg); 6095 if (status) 6096 return status; 6097 6098 /* determine if VSI is already part of a VSIG */ 6099 status = ice_vsig_find_vsi(hw, blk, vsi, &vsig); 6100 if (!status && vsig) { 6101 bool only_vsi; 6102 u16 or_vsig; 6103 u16 ref; 6104 6105 /* found in VSIG */ 6106 or_vsig = vsig; 6107 6108 /* make sure that there is no overlap/conflict between the new 6109 * characteristics and the existing ones; we don't support that 6110 * scenario 6111 */ 6112 if (ice_has_prof_vsig(hw, blk, vsig, hdl)) { 6113 status = ICE_ERR_ALREADY_EXISTS; 6114 goto err_ice_add_prof_id_flow; 6115 } 6116 6117 /* last VSI in the VSIG? */ 6118 status = ice_vsig_get_ref(hw, blk, vsig, &ref); 6119 if (status) 6120 goto err_ice_add_prof_id_flow; 6121 only_vsi = (ref == 1); 6122 6123 /* create a union of the current profiles and the one being 6124 * added 6125 */ 6126 status = ice_get_profs_vsig(hw, blk, vsig, &union_lst); 6127 if (status) 6128 goto err_ice_add_prof_id_flow; 6129 6130 status = ice_add_prof_to_lst(hw, blk, &union_lst, hdl); 6131 if (status) 6132 goto err_ice_add_prof_id_flow; 6133 6134 /* search for an existing VSIG with an exact charc match */ 6135 status = ice_find_dup_props_vsig(hw, blk, &union_lst, &vsig); 6136 if (!status) { 6137 /* move VSI to the VSIG that matches */ 6138 status = ice_move_vsi(hw, blk, vsi, vsig, &chg); 6139 if (status) 6140 goto err_ice_add_prof_id_flow; 6141 6142 /* VSI has been moved out of or_vsig. If the or_vsig had 6143 * only that VSI it is now empty and can be removed. 6144 */ 6145 if (only_vsi) { 6146 status = ice_rem_vsig(hw, blk, or_vsig, &chg); 6147 if (status) 6148 goto err_ice_add_prof_id_flow; 6149 } 6150 } else if (only_vsi) { 6151 /* If the original VSIG only contains one VSI, then it 6152 * will be the requesting VSI. In this case the VSI is 6153 * not sharing entries and we can simply add the new 6154 * profile to the VSIG. 6155 */ 6156 status = ice_add_prof_id_vsig(hw, blk, vsig, hdl, false, 6157 &chg); 6158 if (status) 6159 goto err_ice_add_prof_id_flow; 6160 6161 /* Adjust priorities */ 6162 status = ice_adj_prof_priorities(hw, blk, vsig, &chg); 6163 if (status) 6164 goto err_ice_add_prof_id_flow; 6165 } else { 6166 /* No match, so we need a new VSIG */ 6167 status = ice_create_vsig_from_lst(hw, blk, vsi, 6168 &union_lst, &vsig, 6169 &chg); 6170 if (status) 6171 goto err_ice_add_prof_id_flow; 6172 6173 /* Adjust priorities */ 6174 status = ice_adj_prof_priorities(hw, blk, vsig, &chg); 6175 if (status) 6176 goto err_ice_add_prof_id_flow; 6177 } 6178 } else { 6179 /* need to find or add a VSIG */ 6180 /* search for an existing VSIG with an exact charc match */ 6181 if (ice_find_prof_vsig(hw, blk, hdl, &vsig)) { 6182 /* found an exact match */ 6183 /* add or move VSI to the VSIG that matches */ 6184 status = ice_move_vsi(hw, blk, vsi, vsig, &chg); 6185 if (status) 6186 goto err_ice_add_prof_id_flow; 6187 } else { 6188 /* we did not find an exact match */ 6189 /* we need to add a VSIG */ 6190 status = ice_create_prof_id_vsig(hw, blk, vsi, hdl, 6191 &chg); 6192 if (status) 6193 goto err_ice_add_prof_id_flow; 6194 } 6195 } 6196 6197 /* update hardware */ 6198 if (!status) 6199 status = ice_upd_prof_hw(hw, blk, &chg); 6200 6201 err_ice_add_prof_id_flow: 6202 LIST_FOR_EACH_ENTRY_SAFE(del, tmp, &chg, ice_chs_chg, list_entry) { 6203 LIST_DEL(&del->list_entry); 6204 ice_free(hw, del); 6205 } 6206 6207 LIST_FOR_EACH_ENTRY_SAFE(del1, tmp1, &union_lst, ice_vsig_prof, list) { 6208 LIST_DEL(&del1->list); 6209 ice_free(hw, del1); 6210 } 6211 6212 return status; 6213 } 6214 6215 /** 6216 * ice_rem_prof_from_list - remove a profile from list 6217 * @hw: pointer to the HW struct 6218 * @lst: list to remove the profile from 6219 * @hdl: the profile handle indicating the profile to remove 6220 */ 6221 static enum ice_status 6222 ice_rem_prof_from_list(struct ice_hw *hw, struct LIST_HEAD_TYPE *lst, u64 hdl) 6223 { 6224 struct ice_vsig_prof *ent, *tmp; 6225 6226 LIST_FOR_EACH_ENTRY_SAFE(ent, tmp, lst, ice_vsig_prof, list) 6227 if (ent->profile_cookie == hdl) { 6228 LIST_DEL(&ent->list); 6229 ice_free(hw, ent); 6230 return ICE_SUCCESS; 6231 } 6232 6233 return ICE_ERR_DOES_NOT_EXIST; 6234 } 6235 6236 /** 6237 * ice_rem_prof_id_flow - remove flow 6238 * @hw: pointer to the HW struct 6239 * @blk: hardware block 6240 * @vsi: the VSI from which to remove the profile specified by ID 6241 * @hdl: profile tracking handle 6242 * 6243 * Calling this function will update the hardware tables to remove the 6244 * profile indicated by the ID parameter for the VSIs specified in the VSI 6245 * array. Once successfully called, the flow will be disabled. 6246 */ 6247 enum ice_status 6248 ice_rem_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl) 6249 { 6250 struct ice_vsig_prof *tmp1, *del1; 6251 struct LIST_HEAD_TYPE chg, copy; 6252 struct ice_chs_chg *tmp, *del; 6253 enum ice_status status; 6254 u16 vsig; 6255 6256 INIT_LIST_HEAD(©); 6257 INIT_LIST_HEAD(&chg); 6258 6259 /* determine if VSI is already part of a VSIG */ 6260 status = ice_vsig_find_vsi(hw, blk, vsi, &vsig); 6261 if (!status && vsig) { 6262 bool last_profile; 6263 bool only_vsi; 6264 u16 ref; 6265 6266 /* found in VSIG */ 6267 last_profile = ice_vsig_prof_id_count(hw, blk, vsig) == 1; 6268 status = ice_vsig_get_ref(hw, blk, vsig, &ref); 6269 if (status) 6270 goto err_ice_rem_prof_id_flow; 6271 only_vsi = (ref == 1); 6272 6273 if (only_vsi) { 6274 /* If the original VSIG only contains one reference, 6275 * which will be the requesting VSI, then the VSI is not 6276 * sharing entries and we can simply remove the specific 6277 * characteristics from the VSIG. 6278 */ 6279 6280 if (last_profile) { 6281 /* If there are no profiles left for this VSIG, 6282 * then simply remove the VSIG. 6283 */ 6284 status = ice_rem_vsig(hw, blk, vsig, &chg); 6285 if (status) 6286 goto err_ice_rem_prof_id_flow; 6287 } else { 6288 status = ice_rem_prof_id_vsig(hw, blk, vsig, 6289 hdl, &chg); 6290 if (status) 6291 goto err_ice_rem_prof_id_flow; 6292 6293 /* Adjust priorities */ 6294 status = ice_adj_prof_priorities(hw, blk, vsig, 6295 &chg); 6296 if (status) 6297 goto err_ice_rem_prof_id_flow; 6298 } 6299 6300 } else { 6301 /* Make a copy of the VSIG's list of Profiles */ 6302 status = ice_get_profs_vsig(hw, blk, vsig, ©); 6303 if (status) 6304 goto err_ice_rem_prof_id_flow; 6305 6306 /* Remove specified profile entry from the list */ 6307 status = ice_rem_prof_from_list(hw, ©, hdl); 6308 if (status) 6309 goto err_ice_rem_prof_id_flow; 6310 6311 if (LIST_EMPTY(©)) { 6312 status = ice_move_vsi(hw, blk, vsi, 6313 ICE_DEFAULT_VSIG, &chg); 6314 if (status) 6315 goto err_ice_rem_prof_id_flow; 6316 6317 } else if (!ice_find_dup_props_vsig(hw, blk, ©, 6318 &vsig)) { 6319 /* found an exact match */ 6320 /* add or move VSI to the VSIG that matches */ 6321 /* Search for a VSIG with a matching profile 6322 * list 6323 */ 6324 6325 /* Found match, move VSI to the matching VSIG */ 6326 status = ice_move_vsi(hw, blk, vsi, vsig, &chg); 6327 if (status) 6328 goto err_ice_rem_prof_id_flow; 6329 } else { 6330 /* since no existing VSIG supports this 6331 * characteristic pattern, we need to create a 6332 * new VSIG and TCAM entries 6333 */ 6334 status = ice_create_vsig_from_lst(hw, blk, vsi, 6335 ©, &vsig, 6336 &chg); 6337 if (status) 6338 goto err_ice_rem_prof_id_flow; 6339 6340 /* Adjust priorities */ 6341 status = ice_adj_prof_priorities(hw, blk, vsig, 6342 &chg); 6343 if (status) 6344 goto err_ice_rem_prof_id_flow; 6345 } 6346 } 6347 } else { 6348 status = ICE_ERR_DOES_NOT_EXIST; 6349 } 6350 6351 /* update hardware tables */ 6352 if (!status) 6353 status = ice_upd_prof_hw(hw, blk, &chg); 6354 6355 err_ice_rem_prof_id_flow: 6356 LIST_FOR_EACH_ENTRY_SAFE(del, tmp, &chg, ice_chs_chg, list_entry) { 6357 LIST_DEL(&del->list_entry); 6358 ice_free(hw, del); 6359 } 6360 6361 LIST_FOR_EACH_ENTRY_SAFE(del1, tmp1, ©, ice_vsig_prof, list) { 6362 LIST_DEL(&del1->list); 6363 ice_free(hw, del1); 6364 } 6365 6366 return status; 6367 } 6368 6369 /** 6370 * ice_flow_assoc_hw_prof - add profile id flow for main/ctrl VSI flow entry 6371 * @hw: pointer to the HW struct 6372 * @blk: HW block 6373 * @dest_vsi_handle: dest VSI handle 6374 * @fdir_vsi_handle: fdir programming VSI handle 6375 * @id: profile id (handle) 6376 * 6377 * Calling this function will update the hardware tables to enable the 6378 * profile indicated by the ID parameter for the VSIs specified in the VSI 6379 * array. Once successfully called, the flow will be enabled. 6380 */ 6381 enum ice_status 6382 ice_flow_assoc_hw_prof(struct ice_hw *hw, enum ice_block blk, 6383 u16 dest_vsi_handle, u16 fdir_vsi_handle, int id) 6384 { 6385 enum ice_status status = ICE_SUCCESS; 6386 u16 vsi_num; 6387 6388 vsi_num = ice_get_hw_vsi_num(hw, dest_vsi_handle); 6389 status = ice_add_prof_id_flow(hw, blk, vsi_num, id); 6390 if (status) { 6391 ice_debug(hw, ICE_DBG_FLOW, "HW profile add failed for main VSI flow entry, %d\n", 6392 status); 6393 goto err_add_prof; 6394 } 6395 6396 if (blk != ICE_BLK_FD) 6397 return status; 6398 6399 vsi_num = ice_get_hw_vsi_num(hw, fdir_vsi_handle); 6400 status = ice_add_prof_id_flow(hw, blk, vsi_num, id); 6401 if (status) { 6402 ice_debug(hw, ICE_DBG_FLOW, "HW profile add failed for ctrl VSI flow entry, %d\n", 6403 status); 6404 goto err_add_entry; 6405 } 6406 6407 return status; 6408 6409 err_add_entry: 6410 vsi_num = ice_get_hw_vsi_num(hw, dest_vsi_handle); 6411 ice_rem_prof_id_flow(hw, blk, vsi_num, id); 6412 err_add_prof: 6413 ice_flow_rem_prof(hw, blk, id); 6414 6415 return status; 6416 } 6417