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