1 // SPDX-License-Identifier: GPL-2.0-only 2 /* Atlantic Network Driver 3 * Copyright (C) 2020 Marvell International Ltd. 4 */ 5 6 #include "macsec_api.h" 7 #include <linux/mdio.h> 8 #include "MSS_Ingress_registers.h" 9 #include "MSS_Egress_registers.h" 10 #include "aq_phy.h" 11 12 #define AQ_API_CALL_SAFE(func, ...) \ 13 ({ \ 14 int ret; \ 15 do { \ 16 ret = aq_mss_mdio_sem_get(hw); \ 17 if (unlikely(ret)) \ 18 break; \ 19 \ 20 ret = func(__VA_ARGS__); \ 21 \ 22 aq_mss_mdio_sem_put(hw); \ 23 } while (0); \ 24 ret; \ 25 }) 26 27 /******************************************************************************* 28 * MDIO wrappers 29 ******************************************************************************/ 30 static int aq_mss_mdio_sem_get(struct aq_hw_s *hw) 31 { 32 u32 val; 33 34 return readx_poll_timeout_atomic(hw_atl_sem_mdio_get, hw, val, 35 val == 1U, 10U, 100000U); 36 } 37 38 static void aq_mss_mdio_sem_put(struct aq_hw_s *hw) 39 { 40 hw_atl_reg_glb_cpu_sem_set(hw, 1U, HW_ATL_FW_SM_MDIO); 41 } 42 43 static int aq_mss_mdio_read(struct aq_hw_s *hw, u16 mmd, u16 addr, u16 *data) 44 { 45 *data = aq_mdio_read_word(hw, mmd, addr); 46 return (*data != 0xffff) ? 0 : -ETIME; 47 } 48 49 static int aq_mss_mdio_write(struct aq_hw_s *hw, u16 mmd, u16 addr, u16 data) 50 { 51 aq_mdio_write_word(hw, mmd, addr, data); 52 return 0; 53 } 54 55 /******************************************************************************* 56 * MACSEC config and status 57 ******************************************************************************/ 58 59 static int set_raw_ingress_record(struct aq_hw_s *hw, u16 *packed_record, 60 u8 num_words, u8 table_id, 61 u16 table_index) 62 { 63 struct mss_ingress_lut_addr_ctl_register lut_sel_reg; 64 struct mss_ingress_lut_ctl_register lut_op_reg; 65 66 unsigned int i; 67 68 /* NOTE: MSS registers must always be read/written as adjacent pairs. 69 * For instance, to write either or both 1E.80A0 and 80A1, we have to: 70 * 1. Write 1E.80A0 first 71 * 2. Then write 1E.80A1 72 * 73 * For HHD devices: These writes need to be performed consecutively, and 74 * to ensure this we use the PIF mailbox to delegate the reads/writes to 75 * the FW. 76 * 77 * For EUR devices: Not need to use the PIF mailbox; it is safe to 78 * write to the registers directly. 79 */ 80 81 /* Write the packed record words to the data buffer registers. */ 82 for (i = 0; i < num_words; i += 2) { 83 aq_mss_mdio_write(hw, MDIO_MMD_VEND1, 84 MSS_INGRESS_LUT_DATA_CTL_REGISTER_ADDR + i, 85 packed_record[i]); 86 aq_mss_mdio_write(hw, MDIO_MMD_VEND1, 87 MSS_INGRESS_LUT_DATA_CTL_REGISTER_ADDR + i + 88 1, 89 packed_record[i + 1]); 90 } 91 92 /* Clear out the unused data buffer registers. */ 93 for (i = num_words; i < 24; i += 2) { 94 aq_mss_mdio_write(hw, MDIO_MMD_VEND1, 95 MSS_INGRESS_LUT_DATA_CTL_REGISTER_ADDR + i, 96 0); 97 aq_mss_mdio_write(hw, MDIO_MMD_VEND1, 98 MSS_INGRESS_LUT_DATA_CTL_REGISTER_ADDR + i + 1, 0); 99 } 100 101 /* Select the table and row index to write to */ 102 lut_sel_reg.bits_0.lut_select = table_id; 103 lut_sel_reg.bits_0.lut_addr = table_index; 104 105 lut_op_reg.bits_0.lut_read = 0; 106 lut_op_reg.bits_0.lut_write = 1; 107 108 aq_mss_mdio_write(hw, MDIO_MMD_VEND1, 109 MSS_INGRESS_LUT_ADDR_CTL_REGISTER_ADDR, 110 lut_sel_reg.word_0); 111 aq_mss_mdio_write(hw, MDIO_MMD_VEND1, MSS_INGRESS_LUT_CTL_REGISTER_ADDR, 112 lut_op_reg.word_0); 113 114 return 0; 115 } 116 117 /*! Read the specified Ingress LUT table row. 118 * packed_record - [OUT] The table row data (raw). 119 */ 120 static int get_raw_ingress_record(struct aq_hw_s *hw, u16 *packed_record, 121 u8 num_words, u8 table_id, 122 u16 table_index) 123 { 124 struct mss_ingress_lut_addr_ctl_register lut_sel_reg; 125 struct mss_ingress_lut_ctl_register lut_op_reg; 126 int ret; 127 128 unsigned int i; 129 130 /* Select the table and row index to read */ 131 lut_sel_reg.bits_0.lut_select = table_id; 132 lut_sel_reg.bits_0.lut_addr = table_index; 133 134 lut_op_reg.bits_0.lut_read = 1; 135 lut_op_reg.bits_0.lut_write = 0; 136 137 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1, 138 MSS_INGRESS_LUT_ADDR_CTL_REGISTER_ADDR, 139 lut_sel_reg.word_0); 140 if (unlikely(ret)) 141 return ret; 142 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1, 143 MSS_INGRESS_LUT_CTL_REGISTER_ADDR, 144 lut_op_reg.word_0); 145 if (unlikely(ret)) 146 return ret; 147 148 memset(packed_record, 0, sizeof(u16) * num_words); 149 150 for (i = 0; i < num_words; i += 2) { 151 ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1, 152 MSS_INGRESS_LUT_DATA_CTL_REGISTER_ADDR + 153 i, 154 &packed_record[i]); 155 if (unlikely(ret)) 156 return ret; 157 ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1, 158 MSS_INGRESS_LUT_DATA_CTL_REGISTER_ADDR + 159 i + 1, 160 &packed_record[i + 1]); 161 if (unlikely(ret)) 162 return ret; 163 } 164 165 return 0; 166 } 167 168 /*! Write packed_record to the specified Egress LUT table row. */ 169 static int set_raw_egress_record(struct aq_hw_s *hw, u16 *packed_record, 170 u8 num_words, u8 table_id, 171 u16 table_index) 172 { 173 struct mss_egress_lut_addr_ctl_register lut_sel_reg; 174 struct mss_egress_lut_ctl_register lut_op_reg; 175 176 unsigned int i; 177 178 /* Write the packed record words to the data buffer registers. */ 179 for (i = 0; i < num_words; i += 2) { 180 aq_mss_mdio_write(hw, MDIO_MMD_VEND1, 181 MSS_EGRESS_LUT_DATA_CTL_REGISTER_ADDR + i, 182 packed_record[i]); 183 aq_mss_mdio_write(hw, MDIO_MMD_VEND1, 184 MSS_EGRESS_LUT_DATA_CTL_REGISTER_ADDR + i + 1, 185 packed_record[i + 1]); 186 } 187 188 /* Clear out the unused data buffer registers. */ 189 for (i = num_words; i < 28; i += 2) { 190 aq_mss_mdio_write(hw, MDIO_MMD_VEND1, 191 MSS_EGRESS_LUT_DATA_CTL_REGISTER_ADDR + i, 0); 192 aq_mss_mdio_write(hw, MDIO_MMD_VEND1, 193 MSS_EGRESS_LUT_DATA_CTL_REGISTER_ADDR + i + 1, 194 0); 195 } 196 197 /* Select the table and row index to write to */ 198 lut_sel_reg.bits_0.lut_select = table_id; 199 lut_sel_reg.bits_0.lut_addr = table_index; 200 201 lut_op_reg.bits_0.lut_read = 0; 202 lut_op_reg.bits_0.lut_write = 1; 203 204 aq_mss_mdio_write(hw, MDIO_MMD_VEND1, 205 MSS_EGRESS_LUT_ADDR_CTL_REGISTER_ADDR, 206 lut_sel_reg.word_0); 207 aq_mss_mdio_write(hw, MDIO_MMD_VEND1, MSS_EGRESS_LUT_CTL_REGISTER_ADDR, 208 lut_op_reg.word_0); 209 210 return 0; 211 } 212 213 static int get_raw_egress_record(struct aq_hw_s *hw, u16 *packed_record, 214 u8 num_words, u8 table_id, 215 u16 table_index) 216 { 217 struct mss_egress_lut_addr_ctl_register lut_sel_reg; 218 struct mss_egress_lut_ctl_register lut_op_reg; 219 int ret; 220 221 unsigned int i; 222 223 /* Select the table and row index to read */ 224 lut_sel_reg.bits_0.lut_select = table_id; 225 lut_sel_reg.bits_0.lut_addr = table_index; 226 227 lut_op_reg.bits_0.lut_read = 1; 228 lut_op_reg.bits_0.lut_write = 0; 229 230 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1, 231 MSS_EGRESS_LUT_ADDR_CTL_REGISTER_ADDR, 232 lut_sel_reg.word_0); 233 if (unlikely(ret)) 234 return ret; 235 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1, 236 MSS_EGRESS_LUT_CTL_REGISTER_ADDR, 237 lut_op_reg.word_0); 238 if (unlikely(ret)) 239 return ret; 240 241 memset(packed_record, 0, sizeof(u16) * num_words); 242 243 for (i = 0; i < num_words; i += 2) { 244 ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1, 245 MSS_EGRESS_LUT_DATA_CTL_REGISTER_ADDR + 246 i, 247 &packed_record[i]); 248 if (unlikely(ret)) 249 return ret; 250 ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1, 251 MSS_EGRESS_LUT_DATA_CTL_REGISTER_ADDR + 252 i + 1, 253 &packed_record[i + 1]); 254 if (unlikely(ret)) 255 return ret; 256 } 257 258 return 0; 259 } 260 261 static int 262 set_ingress_prectlf_record(struct aq_hw_s *hw, 263 const struct aq_mss_ingress_prectlf_record *rec, 264 u16 table_index) 265 { 266 u16 packed_record[6]; 267 268 if (table_index >= NUMROWS_INGRESSPRECTLFRECORD) 269 return -EINVAL; 270 271 memset(packed_record, 0, sizeof(u16) * 6); 272 273 packed_record[0] = rec->sa_da[0] & 0xFFFF; 274 packed_record[1] = (rec->sa_da[0] >> 16) & 0xFFFF; 275 packed_record[2] = rec->sa_da[1] & 0xFFFF; 276 packed_record[3] = rec->eth_type & 0xFFFF; 277 packed_record[4] = rec->match_mask & 0xFFFF; 278 packed_record[5] = rec->match_type & 0xF; 279 packed_record[5] |= (rec->action & 0x1) << 4; 280 281 return set_raw_ingress_record(hw, packed_record, 6, 0, 282 ROWOFFSET_INGRESSPRECTLFRECORD + 283 table_index); 284 } 285 286 int aq_mss_set_ingress_prectlf_record(struct aq_hw_s *hw, 287 const struct aq_mss_ingress_prectlf_record *rec, 288 u16 table_index) 289 { 290 return AQ_API_CALL_SAFE(set_ingress_prectlf_record, hw, rec, 291 table_index); 292 } 293 294 static int get_ingress_prectlf_record(struct aq_hw_s *hw, 295 struct aq_mss_ingress_prectlf_record *rec, 296 u16 table_index) 297 { 298 u16 packed_record[6]; 299 int ret; 300 301 if (table_index >= NUMROWS_INGRESSPRECTLFRECORD) 302 return -EINVAL; 303 304 /* If the row that we want to read is odd, first read the previous even 305 * row, throw that value away, and finally read the desired row. 306 * This is a workaround for EUR devices that allows us to read 307 * odd-numbered rows. For HHD devices: this workaround will not work, 308 * so don't bother; odd-numbered rows are not readable. 309 */ 310 if ((table_index % 2) > 0) { 311 ret = get_raw_ingress_record(hw, packed_record, 6, 0, 312 ROWOFFSET_INGRESSPRECTLFRECORD + 313 table_index - 1); 314 if (unlikely(ret)) 315 return ret; 316 } 317 318 ret = get_raw_ingress_record(hw, packed_record, 6, 0, 319 ROWOFFSET_INGRESSPRECTLFRECORD + 320 table_index); 321 if (unlikely(ret)) 322 return ret; 323 324 rec->sa_da[0] = packed_record[0]; 325 rec->sa_da[0] |= packed_record[1] << 16; 326 327 rec->sa_da[1] = packed_record[2]; 328 329 rec->eth_type = packed_record[3]; 330 331 rec->match_mask = packed_record[4]; 332 333 rec->match_type = packed_record[5] & 0xF; 334 335 rec->action = (packed_record[5] >> 4) & 0x1; 336 337 return 0; 338 } 339 340 int aq_mss_get_ingress_prectlf_record(struct aq_hw_s *hw, 341 struct aq_mss_ingress_prectlf_record *rec, 342 u16 table_index) 343 { 344 memset(rec, 0, sizeof(*rec)); 345 346 return AQ_API_CALL_SAFE(get_ingress_prectlf_record, hw, rec, 347 table_index); 348 } 349 350 static int 351 set_ingress_preclass_record(struct aq_hw_s *hw, 352 const struct aq_mss_ingress_preclass_record *rec, 353 u16 table_index) 354 { 355 u16 packed_record[20]; 356 357 if (table_index >= NUMROWS_INGRESSPRECLASSRECORD) 358 return -EINVAL; 359 360 memset(packed_record, 0, sizeof(u16) * 20); 361 362 packed_record[0] = rec->sci[0] & 0xFFFF; 363 packed_record[1] = (rec->sci[0] >> 16) & 0xFFFF; 364 365 packed_record[2] = rec->sci[1] & 0xFFFF; 366 packed_record[3] = (rec->sci[1] >> 16) & 0xFFFF; 367 368 packed_record[4] = rec->tci & 0xFF; 369 370 packed_record[4] |= (rec->encr_offset & 0xFF) << 8; 371 372 packed_record[5] = rec->eth_type & 0xFFFF; 373 374 packed_record[6] = rec->snap[0] & 0xFFFF; 375 packed_record[7] = (rec->snap[0] >> 16) & 0xFFFF; 376 377 packed_record[8] = rec->snap[1] & 0xFF; 378 379 packed_record[8] |= (rec->llc & 0xFF) << 8; 380 packed_record[9] = (rec->llc >> 8) & 0xFFFF; 381 382 packed_record[10] = rec->mac_sa[0] & 0xFFFF; 383 packed_record[11] = (rec->mac_sa[0] >> 16) & 0xFFFF; 384 385 packed_record[12] = rec->mac_sa[1] & 0xFFFF; 386 387 packed_record[13] = rec->mac_da[0] & 0xFFFF; 388 packed_record[14] = (rec->mac_da[0] >> 16) & 0xFFFF; 389 390 packed_record[15] = rec->mac_da[1] & 0xFFFF; 391 392 packed_record[16] = rec->lpbk_packet & 0x1; 393 394 packed_record[16] |= (rec->an_mask & 0x3) << 1; 395 396 packed_record[16] |= (rec->tci_mask & 0x3F) << 3; 397 398 packed_record[16] |= (rec->sci_mask & 0x7F) << 9; 399 packed_record[17] = (rec->sci_mask >> 7) & 0x1; 400 401 packed_record[17] |= (rec->eth_type_mask & 0x3) << 1; 402 403 packed_record[17] |= (rec->snap_mask & 0x1F) << 3; 404 405 packed_record[17] |= (rec->llc_mask & 0x7) << 8; 406 407 packed_record[17] |= (rec->_802_2_encapsulate & 0x1) << 11; 408 409 packed_record[17] |= (rec->sa_mask & 0xF) << 12; 410 packed_record[18] = (rec->sa_mask >> 4) & 0x3; 411 412 packed_record[18] |= (rec->da_mask & 0x3F) << 2; 413 414 packed_record[18] |= (rec->lpbk_mask & 0x1) << 8; 415 416 packed_record[18] |= (rec->sc_idx & 0x1F) << 9; 417 418 packed_record[18] |= (rec->proc_dest & 0x1) << 14; 419 420 packed_record[18] |= (rec->action & 0x1) << 15; 421 packed_record[19] = (rec->action >> 1) & 0x1; 422 423 packed_record[19] |= (rec->ctrl_unctrl & 0x1) << 1; 424 425 packed_record[19] |= (rec->sci_from_table & 0x1) << 2; 426 427 packed_record[19] |= (rec->reserved & 0xF) << 3; 428 429 packed_record[19] |= (rec->valid & 0x1) << 7; 430 431 return set_raw_ingress_record(hw, packed_record, 20, 1, 432 ROWOFFSET_INGRESSPRECLASSRECORD + 433 table_index); 434 } 435 436 int aq_mss_set_ingress_preclass_record(struct aq_hw_s *hw, 437 const struct aq_mss_ingress_preclass_record *rec, 438 u16 table_index) 439 { 440 int err = AQ_API_CALL_SAFE(set_ingress_preclass_record, hw, rec, 441 table_index); 442 443 WARN_ONCE(err, "%s failed with %d\n", __func__, err); 444 445 return err; 446 } 447 448 static int 449 get_ingress_preclass_record(struct aq_hw_s *hw, 450 struct aq_mss_ingress_preclass_record *rec, 451 u16 table_index) 452 { 453 u16 packed_record[20]; 454 int ret; 455 456 if (table_index >= NUMROWS_INGRESSPRECLASSRECORD) 457 return -EINVAL; 458 459 /* If the row that we want to read is odd, first read the previous even 460 * row, throw that value away, and finally read the desired row. 461 */ 462 if ((table_index % 2) > 0) { 463 ret = get_raw_ingress_record(hw, packed_record, 20, 1, 464 ROWOFFSET_INGRESSPRECLASSRECORD + 465 table_index - 1); 466 if (unlikely(ret)) 467 return ret; 468 } 469 470 ret = get_raw_ingress_record(hw, packed_record, 20, 1, 471 ROWOFFSET_INGRESSPRECLASSRECORD + 472 table_index); 473 if (unlikely(ret)) 474 return ret; 475 476 rec->sci[0] = packed_record[0]; 477 rec->sci[0] |= packed_record[1] << 16; 478 479 rec->sci[1] = packed_record[2]; 480 rec->sci[1] |= packed_record[3] << 16; 481 482 rec->tci = packed_record[4] & 0xFF; 483 484 rec->encr_offset = (packed_record[4] >> 8) & 0xFF; 485 486 rec->eth_type = packed_record[5]; 487 488 rec->snap[0] = packed_record[6]; 489 rec->snap[0] |= packed_record[7] << 16; 490 491 rec->snap[1] = packed_record[8] & 0xFF; 492 493 rec->llc = (packed_record[8] >> 8) & 0xFF; 494 rec->llc |= packed_record[9] << 8; 495 496 rec->mac_sa[0] = packed_record[10]; 497 rec->mac_sa[0] |= packed_record[11] << 16; 498 499 rec->mac_sa[1] = packed_record[12]; 500 501 rec->mac_da[0] = packed_record[13]; 502 rec->mac_da[0] |= packed_record[14] << 16; 503 504 rec->mac_da[1] = packed_record[15]; 505 506 rec->lpbk_packet = packed_record[16] & 0x1; 507 508 rec->an_mask = (packed_record[16] >> 1) & 0x3; 509 510 rec->tci_mask = (packed_record[16] >> 3) & 0x3F; 511 512 rec->sci_mask = (packed_record[16] >> 9) & 0x7F; 513 rec->sci_mask |= (packed_record[17] & 0x1) << 7; 514 515 rec->eth_type_mask = (packed_record[17] >> 1) & 0x3; 516 517 rec->snap_mask = (packed_record[17] >> 3) & 0x1F; 518 519 rec->llc_mask = (packed_record[17] >> 8) & 0x7; 520 521 rec->_802_2_encapsulate = (packed_record[17] >> 11) & 0x1; 522 523 rec->sa_mask = (packed_record[17] >> 12) & 0xF; 524 rec->sa_mask |= (packed_record[18] & 0x3) << 4; 525 526 rec->da_mask = (packed_record[18] >> 2) & 0x3F; 527 528 rec->lpbk_mask = (packed_record[18] >> 8) & 0x1; 529 530 rec->sc_idx = (packed_record[18] >> 9) & 0x1F; 531 532 rec->proc_dest = (packed_record[18] >> 14) & 0x1; 533 534 rec->action = (packed_record[18] >> 15) & 0x1; 535 rec->action |= (packed_record[19] & 0x1) << 1; 536 537 rec->ctrl_unctrl = (packed_record[19] >> 1) & 0x1; 538 539 rec->sci_from_table = (packed_record[19] >> 2) & 0x1; 540 541 rec->reserved = (packed_record[19] >> 3) & 0xF; 542 543 rec->valid = (packed_record[19] >> 7) & 0x1; 544 545 return 0; 546 } 547 548 int aq_mss_get_ingress_preclass_record(struct aq_hw_s *hw, 549 struct aq_mss_ingress_preclass_record *rec, 550 u16 table_index) 551 { 552 memset(rec, 0, sizeof(*rec)); 553 554 return AQ_API_CALL_SAFE(get_ingress_preclass_record, hw, rec, 555 table_index); 556 } 557 558 static int set_ingress_sc_record(struct aq_hw_s *hw, 559 const struct aq_mss_ingress_sc_record *rec, 560 u16 table_index) 561 { 562 u16 packed_record[8]; 563 564 if (table_index >= NUMROWS_INGRESSSCRECORD) 565 return -EINVAL; 566 567 memset(packed_record, 0, sizeof(u16) * 8); 568 569 packed_record[0] = rec->stop_time & 0xFFFF; 570 packed_record[1] = (rec->stop_time >> 16) & 0xFFFF; 571 572 packed_record[2] = rec->start_time & 0xFFFF; 573 packed_record[3] = (rec->start_time >> 16) & 0xFFFF; 574 575 packed_record[4] = rec->validate_frames & 0x3; 576 577 packed_record[4] |= (rec->replay_protect & 0x1) << 2; 578 579 packed_record[4] |= (rec->anti_replay_window & 0x1FFF) << 3; 580 packed_record[5] = (rec->anti_replay_window >> 13) & 0xFFFF; 581 packed_record[6] = (rec->anti_replay_window >> 29) & 0x7; 582 583 packed_record[6] |= (rec->receiving & 0x1) << 3; 584 585 packed_record[6] |= (rec->fresh & 0x1) << 4; 586 587 packed_record[6] |= (rec->an_rol & 0x1) << 5; 588 589 packed_record[6] |= (rec->reserved & 0x3FF) << 6; 590 packed_record[7] = (rec->reserved >> 10) & 0x7FFF; 591 592 packed_record[7] |= (rec->valid & 0x1) << 15; 593 594 return set_raw_ingress_record(hw, packed_record, 8, 3, 595 ROWOFFSET_INGRESSSCRECORD + table_index); 596 } 597 598 int aq_mss_set_ingress_sc_record(struct aq_hw_s *hw, 599 const struct aq_mss_ingress_sc_record *rec, 600 u16 table_index) 601 { 602 int err = AQ_API_CALL_SAFE(set_ingress_sc_record, hw, rec, table_index); 603 604 WARN_ONCE(err, "%s failed with %d\n", __func__, err); 605 606 return err; 607 } 608 609 static int get_ingress_sc_record(struct aq_hw_s *hw, 610 struct aq_mss_ingress_sc_record *rec, 611 u16 table_index) 612 { 613 u16 packed_record[8]; 614 int ret; 615 616 if (table_index >= NUMROWS_INGRESSSCRECORD) 617 return -EINVAL; 618 619 ret = get_raw_ingress_record(hw, packed_record, 8, 3, 620 ROWOFFSET_INGRESSSCRECORD + table_index); 621 if (unlikely(ret)) 622 return ret; 623 624 rec->stop_time = packed_record[0]; 625 rec->stop_time |= packed_record[1] << 16; 626 627 rec->start_time = packed_record[2]; 628 rec->start_time |= packed_record[3] << 16; 629 630 rec->validate_frames = packed_record[4] & 0x3; 631 632 rec->replay_protect = (packed_record[4] >> 2) & 0x1; 633 634 rec->anti_replay_window = (packed_record[4] >> 3) & 0x1FFF; 635 rec->anti_replay_window |= packed_record[5] << 13; 636 rec->anti_replay_window |= (packed_record[6] & 0x7) << 29; 637 638 rec->receiving = (packed_record[6] >> 3) & 0x1; 639 640 rec->fresh = (packed_record[6] >> 4) & 0x1; 641 642 rec->an_rol = (packed_record[6] >> 5) & 0x1; 643 644 rec->reserved = (packed_record[6] >> 6) & 0x3FF; 645 rec->reserved |= (packed_record[7] & 0x7FFF) << 10; 646 647 rec->valid = (packed_record[7] >> 15) & 0x1; 648 649 return 0; 650 } 651 652 int aq_mss_get_ingress_sc_record(struct aq_hw_s *hw, 653 struct aq_mss_ingress_sc_record *rec, 654 u16 table_index) 655 { 656 memset(rec, 0, sizeof(*rec)); 657 658 return AQ_API_CALL_SAFE(get_ingress_sc_record, hw, rec, table_index); 659 } 660 661 static int set_ingress_sa_record(struct aq_hw_s *hw, 662 const struct aq_mss_ingress_sa_record *rec, 663 u16 table_index) 664 { 665 u16 packed_record[8]; 666 667 if (table_index >= NUMROWS_INGRESSSARECORD) 668 return -EINVAL; 669 670 memset(packed_record, 0, sizeof(u16) * 8); 671 672 packed_record[0] = rec->stop_time & 0xFFFF; 673 packed_record[1] = (rec->stop_time >> 16) & 0xFFFF; 674 675 packed_record[2] = rec->start_time & 0xFFFF; 676 packed_record[3] = (rec->start_time >> 16) & 0xFFFF; 677 678 packed_record[4] = rec->next_pn & 0xFFFF; 679 packed_record[5] = (rec->next_pn >> 16) & 0xFFFF; 680 681 packed_record[6] = rec->sat_nextpn & 0x1; 682 683 packed_record[6] |= (rec->in_use & 0x1) << 1; 684 685 packed_record[6] |= (rec->fresh & 0x1) << 2; 686 687 packed_record[6] |= (rec->reserved & 0x1FFF) << 3; 688 packed_record[7] = (rec->reserved >> 13) & 0x7FFF; 689 690 packed_record[7] |= (rec->valid & 0x1) << 15; 691 692 return set_raw_ingress_record(hw, packed_record, 8, 3, 693 ROWOFFSET_INGRESSSARECORD + table_index); 694 } 695 696 int aq_mss_set_ingress_sa_record(struct aq_hw_s *hw, 697 const struct aq_mss_ingress_sa_record *rec, 698 u16 table_index) 699 { 700 int err = AQ_API_CALL_SAFE(set_ingress_sa_record, hw, rec, table_index); 701 702 WARN_ONCE(err, "%s failed with %d\n", __func__, err); 703 704 return err; 705 } 706 707 static int get_ingress_sa_record(struct aq_hw_s *hw, 708 struct aq_mss_ingress_sa_record *rec, 709 u16 table_index) 710 { 711 u16 packed_record[8]; 712 int ret; 713 714 if (table_index >= NUMROWS_INGRESSSARECORD) 715 return -EINVAL; 716 717 ret = get_raw_ingress_record(hw, packed_record, 8, 3, 718 ROWOFFSET_INGRESSSARECORD + table_index); 719 if (unlikely(ret)) 720 return ret; 721 722 rec->stop_time = packed_record[0]; 723 rec->stop_time |= packed_record[1] << 16; 724 725 rec->start_time = packed_record[2]; 726 rec->start_time |= packed_record[3] << 16; 727 728 rec->next_pn = packed_record[4]; 729 rec->next_pn |= packed_record[5] << 16; 730 731 rec->sat_nextpn = packed_record[6] & 0x1; 732 733 rec->in_use = (packed_record[6] >> 1) & 0x1; 734 735 rec->fresh = (packed_record[6] >> 2) & 0x1; 736 737 rec->reserved = (packed_record[6] >> 3) & 0x1FFF; 738 rec->reserved |= (packed_record[7] & 0x7FFF) << 13; 739 740 rec->valid = (packed_record[7] >> 15) & 0x1; 741 742 return 0; 743 } 744 745 int aq_mss_get_ingress_sa_record(struct aq_hw_s *hw, 746 struct aq_mss_ingress_sa_record *rec, 747 u16 table_index) 748 { 749 memset(rec, 0, sizeof(*rec)); 750 751 return AQ_API_CALL_SAFE(get_ingress_sa_record, hw, rec, table_index); 752 } 753 754 static int 755 set_ingress_sakey_record(struct aq_hw_s *hw, 756 const struct aq_mss_ingress_sakey_record *rec, 757 u16 table_index) 758 { 759 u16 packed_record[18]; 760 int ret; 761 762 if (table_index >= NUMROWS_INGRESSSAKEYRECORD) 763 return -EINVAL; 764 765 memset(packed_record, 0, sizeof(u16) * 18); 766 767 packed_record[0] = rec->key[0] & 0xFFFF; 768 packed_record[1] = (rec->key[0] >> 16) & 0xFFFF; 769 770 packed_record[2] = rec->key[1] & 0xFFFF; 771 packed_record[3] = (rec->key[1] >> 16) & 0xFFFF; 772 773 packed_record[4] = rec->key[2] & 0xFFFF; 774 packed_record[5] = (rec->key[2] >> 16) & 0xFFFF; 775 776 packed_record[6] = rec->key[3] & 0xFFFF; 777 packed_record[7] = (rec->key[3] >> 16) & 0xFFFF; 778 779 packed_record[8] = rec->key[4] & 0xFFFF; 780 packed_record[9] = (rec->key[4] >> 16) & 0xFFFF; 781 782 packed_record[10] = rec->key[5] & 0xFFFF; 783 packed_record[11] = (rec->key[5] >> 16) & 0xFFFF; 784 785 packed_record[12] = rec->key[6] & 0xFFFF; 786 packed_record[13] = (rec->key[6] >> 16) & 0xFFFF; 787 788 packed_record[14] = rec->key[7] & 0xFFFF; 789 packed_record[15] = (rec->key[7] >> 16) & 0xFFFF; 790 791 packed_record[16] = rec->key_len & 0x3; 792 793 ret = set_raw_ingress_record(hw, packed_record, 18, 2, 794 ROWOFFSET_INGRESSSAKEYRECORD + 795 table_index); 796 797 memzero_explicit(packed_record, sizeof(packed_record)); 798 return ret; 799 } 800 801 int aq_mss_set_ingress_sakey_record(struct aq_hw_s *hw, 802 const struct aq_mss_ingress_sakey_record *rec, 803 u16 table_index) 804 { 805 int err = AQ_API_CALL_SAFE(set_ingress_sakey_record, hw, rec, 806 table_index); 807 808 WARN_ONCE(err, "%s failed with %d\n", __func__, err); 809 810 return err; 811 } 812 813 static int get_ingress_sakey_record(struct aq_hw_s *hw, 814 struct aq_mss_ingress_sakey_record *rec, 815 u16 table_index) 816 { 817 u16 packed_record[18]; 818 int ret; 819 820 if (table_index >= NUMROWS_INGRESSSAKEYRECORD) 821 return -EINVAL; 822 823 ret = get_raw_ingress_record(hw, packed_record, 18, 2, 824 ROWOFFSET_INGRESSSAKEYRECORD + 825 table_index); 826 if (unlikely(ret)) 827 return ret; 828 829 rec->key[0] = packed_record[0]; 830 rec->key[0] |= packed_record[1] << 16; 831 832 rec->key[1] = packed_record[2]; 833 rec->key[1] |= packed_record[3] << 16; 834 835 rec->key[2] = packed_record[4]; 836 rec->key[2] |= packed_record[5] << 16; 837 838 rec->key[3] = packed_record[6]; 839 rec->key[3] |= packed_record[7] << 16; 840 841 rec->key[4] = packed_record[8]; 842 rec->key[4] |= packed_record[9] << 16; 843 844 rec->key[5] = packed_record[10]; 845 rec->key[5] |= packed_record[11] << 16; 846 847 rec->key[6] = packed_record[12]; 848 rec->key[6] |= packed_record[13] << 16; 849 850 rec->key[7] = packed_record[14]; 851 rec->key[7] |= packed_record[15] << 16; 852 853 rec->key_len = packed_record[16] & 0x3; 854 855 return 0; 856 } 857 858 int aq_mss_get_ingress_sakey_record(struct aq_hw_s *hw, 859 struct aq_mss_ingress_sakey_record *rec, 860 u16 table_index) 861 { 862 memset(rec, 0, sizeof(*rec)); 863 864 return AQ_API_CALL_SAFE(get_ingress_sakey_record, hw, rec, table_index); 865 } 866 867 static int 868 set_ingress_postclass_record(struct aq_hw_s *hw, 869 const struct aq_mss_ingress_postclass_record *rec, 870 u16 table_index) 871 { 872 u16 packed_record[8]; 873 874 if (table_index >= NUMROWS_INGRESSPOSTCLASSRECORD) 875 return -EINVAL; 876 877 memset(packed_record, 0, sizeof(u16) * 8); 878 879 packed_record[0] = rec->byte0 & 0xFF; 880 881 packed_record[0] |= (rec->byte1 & 0xFF) << 8; 882 883 packed_record[1] = rec->byte2 & 0xFF; 884 885 packed_record[1] |= (rec->byte3 & 0xFF) << 8; 886 887 packed_record[2] = rec->eth_type & 0xFFFF; 888 889 packed_record[3] = rec->eth_type_valid & 0x1; 890 891 packed_record[3] |= (rec->vlan_id & 0xFFF) << 1; 892 893 packed_record[3] |= (rec->vlan_up & 0x7) << 13; 894 895 packed_record[4] = rec->vlan_valid & 0x1; 896 897 packed_record[4] |= (rec->sai & 0x1F) << 1; 898 899 packed_record[4] |= (rec->sai_hit & 0x1) << 6; 900 901 packed_record[4] |= (rec->eth_type_mask & 0xF) << 7; 902 903 packed_record[4] |= (rec->byte3_location & 0x1F) << 11; 904 packed_record[5] = (rec->byte3_location >> 5) & 0x1; 905 906 packed_record[5] |= (rec->byte3_mask & 0x3) << 1; 907 908 packed_record[5] |= (rec->byte2_location & 0x3F) << 3; 909 910 packed_record[5] |= (rec->byte2_mask & 0x3) << 9; 911 912 packed_record[5] |= (rec->byte1_location & 0x1F) << 11; 913 packed_record[6] = (rec->byte1_location >> 5) & 0x1; 914 915 packed_record[6] |= (rec->byte1_mask & 0x3) << 1; 916 917 packed_record[6] |= (rec->byte0_location & 0x3F) << 3; 918 919 packed_record[6] |= (rec->byte0_mask & 0x3) << 9; 920 921 packed_record[6] |= (rec->eth_type_valid_mask & 0x3) << 11; 922 923 packed_record[6] |= (rec->vlan_id_mask & 0x7) << 13; 924 packed_record[7] = (rec->vlan_id_mask >> 3) & 0x1; 925 926 packed_record[7] |= (rec->vlan_up_mask & 0x3) << 1; 927 928 packed_record[7] |= (rec->vlan_valid_mask & 0x3) << 3; 929 930 packed_record[7] |= (rec->sai_mask & 0x3) << 5; 931 932 packed_record[7] |= (rec->sai_hit_mask & 0x3) << 7; 933 934 packed_record[7] |= (rec->firstlevel_actions & 0x1) << 9; 935 936 packed_record[7] |= (rec->secondlevel_actions & 0x1) << 10; 937 938 packed_record[7] |= (rec->reserved & 0xF) << 11; 939 940 packed_record[7] |= (rec->valid & 0x1) << 15; 941 942 return set_raw_ingress_record(hw, packed_record, 8, 4, 943 ROWOFFSET_INGRESSPOSTCLASSRECORD + 944 table_index); 945 } 946 947 int aq_mss_set_ingress_postclass_record(struct aq_hw_s *hw, 948 const struct aq_mss_ingress_postclass_record *rec, 949 u16 table_index) 950 { 951 return AQ_API_CALL_SAFE(set_ingress_postclass_record, hw, rec, 952 table_index); 953 } 954 955 static int 956 get_ingress_postclass_record(struct aq_hw_s *hw, 957 struct aq_mss_ingress_postclass_record *rec, 958 u16 table_index) 959 { 960 u16 packed_record[8]; 961 int ret; 962 963 if (table_index >= NUMROWS_INGRESSPOSTCLASSRECORD) 964 return -EINVAL; 965 966 /* If the row that we want to read is odd, first read the previous even 967 * row, throw that value away, and finally read the desired row. 968 */ 969 if ((table_index % 2) > 0) { 970 ret = get_raw_ingress_record(hw, packed_record, 8, 4, 971 ROWOFFSET_INGRESSPOSTCLASSRECORD + 972 table_index - 1); 973 if (unlikely(ret)) 974 return ret; 975 } 976 977 ret = get_raw_ingress_record(hw, packed_record, 8, 4, 978 ROWOFFSET_INGRESSPOSTCLASSRECORD + 979 table_index); 980 if (unlikely(ret)) 981 return ret; 982 983 rec->byte0 = packed_record[0] & 0xFF; 984 985 rec->byte1 = (packed_record[0] >> 8) & 0xFF; 986 987 rec->byte2 = packed_record[1] & 0xFF; 988 989 rec->byte3 = (packed_record[1] >> 8) & 0xFF; 990 991 rec->eth_type = packed_record[2]; 992 993 rec->eth_type_valid = packed_record[3] & 0x1; 994 995 rec->vlan_id = (packed_record[3] >> 1) & 0xFFF; 996 997 rec->vlan_up = (packed_record[3] >> 13) & 0x7; 998 999 rec->vlan_valid = packed_record[4] & 0x1; 1000 1001 rec->sai = (packed_record[4] >> 1) & 0x1F; 1002 1003 rec->sai_hit = (packed_record[4] >> 6) & 0x1; 1004 1005 rec->eth_type_mask = (packed_record[4] >> 7) & 0xF; 1006 1007 rec->byte3_location = (packed_record[4] >> 11) & 0x1F; 1008 rec->byte3_location |= (packed_record[5] & 0x1) << 5; 1009 1010 rec->byte3_mask = (packed_record[5] >> 1) & 0x3; 1011 1012 rec->byte2_location = (packed_record[5] >> 3) & 0x3F; 1013 1014 rec->byte2_mask = (packed_record[5] >> 9) & 0x3; 1015 1016 rec->byte1_location = (packed_record[5] >> 11) & 0x1F; 1017 rec->byte1_location |= (packed_record[6] & 0x1) << 5; 1018 1019 rec->byte1_mask = (packed_record[6] >> 1) & 0x3; 1020 1021 rec->byte0_location = (packed_record[6] >> 3) & 0x3F; 1022 1023 rec->byte0_mask = (packed_record[6] >> 9) & 0x3; 1024 1025 rec->eth_type_valid_mask = (packed_record[6] >> 11) & 0x3; 1026 1027 rec->vlan_id_mask = (packed_record[6] >> 13) & 0x7; 1028 rec->vlan_id_mask |= (packed_record[7] & 0x1) << 3; 1029 1030 rec->vlan_up_mask = (packed_record[7] >> 1) & 0x3; 1031 1032 rec->vlan_valid_mask = (packed_record[7] >> 3) & 0x3; 1033 1034 rec->sai_mask = (packed_record[7] >> 5) & 0x3; 1035 1036 rec->sai_hit_mask = (packed_record[7] >> 7) & 0x3; 1037 1038 rec->firstlevel_actions = (packed_record[7] >> 9) & 0x1; 1039 1040 rec->secondlevel_actions = (packed_record[7] >> 10) & 0x1; 1041 1042 rec->reserved = (packed_record[7] >> 11) & 0xF; 1043 1044 rec->valid = (packed_record[7] >> 15) & 0x1; 1045 1046 return 0; 1047 } 1048 1049 int aq_mss_get_ingress_postclass_record(struct aq_hw_s *hw, 1050 struct aq_mss_ingress_postclass_record *rec, 1051 u16 table_index) 1052 { 1053 memset(rec, 0, sizeof(*rec)); 1054 1055 return AQ_API_CALL_SAFE(get_ingress_postclass_record, hw, rec, 1056 table_index); 1057 } 1058 1059 static int 1060 set_ingress_postctlf_record(struct aq_hw_s *hw, 1061 const struct aq_mss_ingress_postctlf_record *rec, 1062 u16 table_index) 1063 { 1064 u16 packed_record[6]; 1065 1066 if (table_index >= NUMROWS_INGRESSPOSTCTLFRECORD) 1067 return -EINVAL; 1068 1069 memset(packed_record, 0, sizeof(u16) * 6); 1070 1071 packed_record[0] = rec->sa_da[0] & 0xFFFF; 1072 packed_record[1] = (rec->sa_da[0] >> 16) & 0xFFFF; 1073 1074 packed_record[2] = rec->sa_da[1] & 0xFFFF; 1075 1076 packed_record[3] = rec->eth_type & 0xFFFF; 1077 1078 packed_record[4] = rec->match_mask & 0xFFFF; 1079 1080 packed_record[5] = rec->match_type & 0xF; 1081 1082 packed_record[5] |= (rec->action & 0x1) << 4; 1083 1084 return set_raw_ingress_record(hw, packed_record, 6, 5, 1085 ROWOFFSET_INGRESSPOSTCTLFRECORD + 1086 table_index); 1087 } 1088 1089 int aq_mss_set_ingress_postctlf_record(struct aq_hw_s *hw, 1090 const struct aq_mss_ingress_postctlf_record *rec, 1091 u16 table_index) 1092 { 1093 return AQ_API_CALL_SAFE(set_ingress_postctlf_record, hw, rec, 1094 table_index); 1095 } 1096 1097 static int 1098 get_ingress_postctlf_record(struct aq_hw_s *hw, 1099 struct aq_mss_ingress_postctlf_record *rec, 1100 u16 table_index) 1101 { 1102 u16 packed_record[6]; 1103 int ret; 1104 1105 if (table_index >= NUMROWS_INGRESSPOSTCTLFRECORD) 1106 return -EINVAL; 1107 1108 /* If the row that we want to read is odd, first read the previous even 1109 * row, throw that value away, and finally read the desired row. 1110 */ 1111 if ((table_index % 2) > 0) { 1112 ret = get_raw_ingress_record(hw, packed_record, 6, 5, 1113 ROWOFFSET_INGRESSPOSTCTLFRECORD + 1114 table_index - 1); 1115 if (unlikely(ret)) 1116 return ret; 1117 } 1118 1119 ret = get_raw_ingress_record(hw, packed_record, 6, 5, 1120 ROWOFFSET_INGRESSPOSTCTLFRECORD + 1121 table_index); 1122 if (unlikely(ret)) 1123 return ret; 1124 1125 rec->sa_da[0] = packed_record[0]; 1126 rec->sa_da[0] |= packed_record[1] << 16; 1127 1128 rec->sa_da[1] = packed_record[2]; 1129 1130 rec->eth_type = packed_record[3]; 1131 1132 rec->match_mask = packed_record[4]; 1133 1134 rec->match_type = packed_record[5] & 0xF; 1135 1136 rec->action = (packed_record[5] >> 4) & 0x1; 1137 1138 return 0; 1139 } 1140 1141 int aq_mss_get_ingress_postctlf_record(struct aq_hw_s *hw, 1142 struct aq_mss_ingress_postctlf_record *rec, 1143 u16 table_index) 1144 { 1145 memset(rec, 0, sizeof(*rec)); 1146 1147 return AQ_API_CALL_SAFE(get_ingress_postctlf_record, hw, rec, 1148 table_index); 1149 } 1150 1151 static int set_egress_ctlf_record(struct aq_hw_s *hw, 1152 const struct aq_mss_egress_ctlf_record *rec, 1153 u16 table_index) 1154 { 1155 u16 packed_record[6]; 1156 1157 if (table_index >= NUMROWS_EGRESSCTLFRECORD) 1158 return -EINVAL; 1159 1160 memset(packed_record, 0, sizeof(u16) * 6); 1161 1162 packed_record[0] = rec->sa_da[0] & 0xFFFF; 1163 packed_record[1] = (rec->sa_da[0] >> 16) & 0xFFFF; 1164 1165 packed_record[2] = rec->sa_da[1] & 0xFFFF; 1166 1167 packed_record[3] = rec->eth_type & 0xFFFF; 1168 1169 packed_record[4] = rec->match_mask & 0xFFFF; 1170 1171 packed_record[5] = rec->match_type & 0xF; 1172 1173 packed_record[5] |= (rec->action & 0x1) << 4; 1174 1175 return set_raw_egress_record(hw, packed_record, 6, 0, 1176 ROWOFFSET_EGRESSCTLFRECORD + table_index); 1177 } 1178 1179 int aq_mss_set_egress_ctlf_record(struct aq_hw_s *hw, 1180 const struct aq_mss_egress_ctlf_record *rec, 1181 u16 table_index) 1182 { 1183 return AQ_API_CALL_SAFE(set_egress_ctlf_record, hw, rec, table_index); 1184 } 1185 1186 static int get_egress_ctlf_record(struct aq_hw_s *hw, 1187 struct aq_mss_egress_ctlf_record *rec, 1188 u16 table_index) 1189 { 1190 u16 packed_record[6]; 1191 int ret; 1192 1193 if (table_index >= NUMROWS_EGRESSCTLFRECORD) 1194 return -EINVAL; 1195 1196 /* If the row that we want to read is odd, first read the previous even 1197 * row, throw that value away, and finally read the desired row. 1198 */ 1199 if ((table_index % 2) > 0) { 1200 ret = get_raw_egress_record(hw, packed_record, 6, 0, 1201 ROWOFFSET_EGRESSCTLFRECORD + 1202 table_index - 1); 1203 if (unlikely(ret)) 1204 return ret; 1205 } 1206 1207 ret = get_raw_egress_record(hw, packed_record, 6, 0, 1208 ROWOFFSET_EGRESSCTLFRECORD + table_index); 1209 if (unlikely(ret)) 1210 return ret; 1211 1212 rec->sa_da[0] = packed_record[0]; 1213 rec->sa_da[0] |= packed_record[1] << 16; 1214 1215 rec->sa_da[1] = packed_record[2]; 1216 1217 rec->eth_type = packed_record[3]; 1218 1219 rec->match_mask = packed_record[4]; 1220 1221 rec->match_type = packed_record[5] & 0xF; 1222 1223 rec->action = (packed_record[5] >> 4) & 0x1; 1224 1225 return 0; 1226 } 1227 1228 int aq_mss_get_egress_ctlf_record(struct aq_hw_s *hw, 1229 struct aq_mss_egress_ctlf_record *rec, 1230 u16 table_index) 1231 { 1232 memset(rec, 0, sizeof(*rec)); 1233 1234 return AQ_API_CALL_SAFE(get_egress_ctlf_record, hw, rec, table_index); 1235 } 1236 1237 static int set_egress_class_record(struct aq_hw_s *hw, 1238 const struct aq_mss_egress_class_record *rec, 1239 u16 table_index) 1240 { 1241 u16 packed_record[28]; 1242 1243 if (table_index >= NUMROWS_EGRESSCLASSRECORD) 1244 return -EINVAL; 1245 1246 memset(packed_record, 0, sizeof(u16) * 28); 1247 1248 packed_record[0] = rec->vlan_id & 0xFFF; 1249 1250 packed_record[0] |= (rec->vlan_up & 0x7) << 12; 1251 1252 packed_record[0] |= (rec->vlan_valid & 0x1) << 15; 1253 1254 packed_record[1] = rec->byte3 & 0xFF; 1255 1256 packed_record[1] |= (rec->byte2 & 0xFF) << 8; 1257 1258 packed_record[2] = rec->byte1 & 0xFF; 1259 1260 packed_record[2] |= (rec->byte0 & 0xFF) << 8; 1261 1262 packed_record[3] = rec->tci & 0xFF; 1263 1264 packed_record[3] |= (rec->sci[0] & 0xFF) << 8; 1265 packed_record[4] = (rec->sci[0] >> 8) & 0xFFFF; 1266 packed_record[5] = (rec->sci[0] >> 24) & 0xFF; 1267 1268 packed_record[5] |= (rec->sci[1] & 0xFF) << 8; 1269 packed_record[6] = (rec->sci[1] >> 8) & 0xFFFF; 1270 packed_record[7] = (rec->sci[1] >> 24) & 0xFF; 1271 1272 packed_record[7] |= (rec->eth_type & 0xFF) << 8; 1273 packed_record[8] = (rec->eth_type >> 8) & 0xFF; 1274 1275 packed_record[8] |= (rec->snap[0] & 0xFF) << 8; 1276 packed_record[9] = (rec->snap[0] >> 8) & 0xFFFF; 1277 packed_record[10] = (rec->snap[0] >> 24) & 0xFF; 1278 1279 packed_record[10] |= (rec->snap[1] & 0xFF) << 8; 1280 1281 packed_record[11] = rec->llc & 0xFFFF; 1282 packed_record[12] = (rec->llc >> 16) & 0xFF; 1283 1284 packed_record[12] |= (rec->mac_sa[0] & 0xFF) << 8; 1285 packed_record[13] = (rec->mac_sa[0] >> 8) & 0xFFFF; 1286 packed_record[14] = (rec->mac_sa[0] >> 24) & 0xFF; 1287 1288 packed_record[14] |= (rec->mac_sa[1] & 0xFF) << 8; 1289 packed_record[15] = (rec->mac_sa[1] >> 8) & 0xFF; 1290 1291 packed_record[15] |= (rec->mac_da[0] & 0xFF) << 8; 1292 packed_record[16] = (rec->mac_da[0] >> 8) & 0xFFFF; 1293 packed_record[17] = (rec->mac_da[0] >> 24) & 0xFF; 1294 1295 packed_record[17] |= (rec->mac_da[1] & 0xFF) << 8; 1296 packed_record[18] = (rec->mac_da[1] >> 8) & 0xFF; 1297 1298 packed_record[18] |= (rec->pn & 0xFF) << 8; 1299 packed_record[19] = (rec->pn >> 8) & 0xFFFF; 1300 packed_record[20] = (rec->pn >> 24) & 0xFF; 1301 1302 packed_record[20] |= (rec->byte3_location & 0x3F) << 8; 1303 1304 packed_record[20] |= (rec->byte3_mask & 0x1) << 14; 1305 1306 packed_record[20] |= (rec->byte2_location & 0x1) << 15; 1307 packed_record[21] = (rec->byte2_location >> 1) & 0x1F; 1308 1309 packed_record[21] |= (rec->byte2_mask & 0x1) << 5; 1310 1311 packed_record[21] |= (rec->byte1_location & 0x3F) << 6; 1312 1313 packed_record[21] |= (rec->byte1_mask & 0x1) << 12; 1314 1315 packed_record[21] |= (rec->byte0_location & 0x7) << 13; 1316 packed_record[22] = (rec->byte0_location >> 3) & 0x7; 1317 1318 packed_record[22] |= (rec->byte0_mask & 0x1) << 3; 1319 1320 packed_record[22] |= (rec->vlan_id_mask & 0x3) << 4; 1321 1322 packed_record[22] |= (rec->vlan_up_mask & 0x1) << 6; 1323 1324 packed_record[22] |= (rec->vlan_valid_mask & 0x1) << 7; 1325 1326 packed_record[22] |= (rec->tci_mask & 0xFF) << 8; 1327 1328 packed_record[23] = rec->sci_mask & 0xFF; 1329 1330 packed_record[23] |= (rec->eth_type_mask & 0x3) << 8; 1331 1332 packed_record[23] |= (rec->snap_mask & 0x1F) << 10; 1333 1334 packed_record[23] |= (rec->llc_mask & 0x1) << 15; 1335 packed_record[24] = (rec->llc_mask >> 1) & 0x3; 1336 1337 packed_record[24] |= (rec->sa_mask & 0x3F) << 2; 1338 1339 packed_record[24] |= (rec->da_mask & 0x3F) << 8; 1340 1341 packed_record[24] |= (rec->pn_mask & 0x3) << 14; 1342 packed_record[25] = (rec->pn_mask >> 2) & 0x3; 1343 1344 packed_record[25] |= (rec->eight02dot2 & 0x1) << 2; 1345 1346 packed_record[25] |= (rec->tci_sc & 0x1) << 3; 1347 1348 packed_record[25] |= (rec->tci_87543 & 0x1) << 4; 1349 1350 packed_record[25] |= (rec->exp_sectag_en & 0x1) << 5; 1351 1352 packed_record[25] |= (rec->sc_idx & 0x1F) << 6; 1353 1354 packed_record[25] |= (rec->sc_sa & 0x3) << 11; 1355 1356 packed_record[25] |= (rec->debug & 0x1) << 13; 1357 1358 packed_record[25] |= (rec->action & 0x3) << 14; 1359 1360 packed_record[26] = (rec->valid & 0x1) << 3; 1361 1362 return set_raw_egress_record(hw, packed_record, 28, 1, 1363 ROWOFFSET_EGRESSCLASSRECORD + table_index); 1364 } 1365 1366 int aq_mss_set_egress_class_record(struct aq_hw_s *hw, 1367 const struct aq_mss_egress_class_record *rec, 1368 u16 table_index) 1369 { 1370 return AQ_API_CALL_SAFE(set_egress_class_record, hw, rec, table_index); 1371 } 1372 1373 static int get_egress_class_record(struct aq_hw_s *hw, 1374 struct aq_mss_egress_class_record *rec, 1375 u16 table_index) 1376 { 1377 u16 packed_record[28]; 1378 int ret; 1379 1380 if (table_index >= NUMROWS_EGRESSCLASSRECORD) 1381 return -EINVAL; 1382 1383 /* If the row that we want to read is odd, first read the previous even 1384 * row, throw that value away, and finally read the desired row. 1385 */ 1386 if ((table_index % 2) > 0) { 1387 ret = get_raw_egress_record(hw, packed_record, 28, 1, 1388 ROWOFFSET_EGRESSCLASSRECORD + 1389 table_index - 1); 1390 if (unlikely(ret)) 1391 return ret; 1392 } 1393 1394 ret = get_raw_egress_record(hw, packed_record, 28, 1, 1395 ROWOFFSET_EGRESSCLASSRECORD + table_index); 1396 if (unlikely(ret)) 1397 return ret; 1398 1399 rec->vlan_id = packed_record[0] & 0xFFF; 1400 1401 rec->vlan_up = (packed_record[0] >> 12) & 0x7; 1402 1403 rec->vlan_valid = (packed_record[0] >> 15) & 0x1; 1404 1405 rec->byte3 = packed_record[1] & 0xFF; 1406 1407 rec->byte2 = (packed_record[1] >> 8) & 0xFF; 1408 1409 rec->byte1 = packed_record[2] & 0xFF; 1410 1411 rec->byte0 = (packed_record[2] >> 8) & 0xFF; 1412 1413 rec->tci = packed_record[3] & 0xFF; 1414 1415 rec->sci[0] = (packed_record[3] >> 8) & 0xFF; 1416 rec->sci[0] |= packed_record[4] << 8; 1417 rec->sci[0] |= (packed_record[5] & 0xFF) << 24; 1418 1419 rec->sci[1] = (packed_record[5] >> 8) & 0xFF; 1420 rec->sci[1] |= packed_record[6] << 8; 1421 rec->sci[1] |= (packed_record[7] & 0xFF) << 24; 1422 1423 rec->eth_type = (packed_record[7] >> 8) & 0xFF; 1424 rec->eth_type |= (packed_record[8] & 0xFF) << 8; 1425 1426 rec->snap[0] = (packed_record[8] >> 8) & 0xFF; 1427 rec->snap[0] |= packed_record[9] << 8; 1428 rec->snap[0] |= (packed_record[10] & 0xFF) << 24; 1429 1430 rec->snap[1] = (packed_record[10] >> 8) & 0xFF; 1431 1432 rec->llc = packed_record[11]; 1433 rec->llc |= (packed_record[12] & 0xFF) << 16; 1434 1435 rec->mac_sa[0] = (packed_record[12] >> 8) & 0xFF; 1436 rec->mac_sa[0] |= packed_record[13] << 8; 1437 rec->mac_sa[0] |= (packed_record[14] & 0xFF) << 24; 1438 1439 rec->mac_sa[1] = (packed_record[14] >> 8) & 0xFF; 1440 rec->mac_sa[1] |= (packed_record[15] & 0xFF) << 8; 1441 1442 rec->mac_da[0] = (packed_record[15] >> 8) & 0xFF; 1443 rec->mac_da[0] |= packed_record[16] << 8; 1444 rec->mac_da[0] |= (packed_record[17] & 0xFF) << 24; 1445 1446 rec->mac_da[1] = (packed_record[17] >> 8) & 0xFF; 1447 rec->mac_da[1] |= (packed_record[18] & 0xFF) << 8; 1448 1449 rec->pn = (packed_record[18] >> 8) & 0xFF; 1450 rec->pn |= packed_record[19] << 8; 1451 rec->pn |= (packed_record[20] & 0xFF) << 24; 1452 1453 rec->byte3_location = (packed_record[20] >> 8) & 0x3F; 1454 1455 rec->byte3_mask = (packed_record[20] >> 14) & 0x1; 1456 1457 rec->byte2_location = (packed_record[20] >> 15) & 0x1; 1458 rec->byte2_location |= (packed_record[21] & 0x1F) << 1; 1459 1460 rec->byte2_mask = (packed_record[21] >> 5) & 0x1; 1461 1462 rec->byte1_location = (packed_record[21] >> 6) & 0x3F; 1463 1464 rec->byte1_mask = (packed_record[21] >> 12) & 0x1; 1465 1466 rec->byte0_location = (packed_record[21] >> 13) & 0x7; 1467 rec->byte0_location |= (packed_record[22] & 0x7) << 3; 1468 1469 rec->byte0_mask = (packed_record[22] >> 3) & 0x1; 1470 1471 rec->vlan_id_mask = (packed_record[22] >> 4) & 0x3; 1472 1473 rec->vlan_up_mask = (packed_record[22] >> 6) & 0x1; 1474 1475 rec->vlan_valid_mask = (packed_record[22] >> 7) & 0x1; 1476 1477 rec->tci_mask = (packed_record[22] >> 8) & 0xFF; 1478 1479 rec->sci_mask = packed_record[23] & 0xFF; 1480 1481 rec->eth_type_mask = (packed_record[23] >> 8) & 0x3; 1482 1483 rec->snap_mask = (packed_record[23] >> 10) & 0x1F; 1484 1485 rec->llc_mask = (packed_record[23] >> 15) & 0x1; 1486 rec->llc_mask |= (packed_record[24] & 0x3) << 1; 1487 1488 rec->sa_mask = (packed_record[24] >> 2) & 0x3F; 1489 1490 rec->da_mask = (packed_record[24] >> 8) & 0x3F; 1491 1492 rec->pn_mask = (packed_record[24] >> 14) & 0x3; 1493 rec->pn_mask |= (packed_record[25] & 0x3) << 2; 1494 1495 rec->eight02dot2 = (packed_record[25] >> 2) & 0x1; 1496 1497 rec->tci_sc = (packed_record[25] >> 3) & 0x1; 1498 1499 rec->tci_87543 = (packed_record[25] >> 4) & 0x1; 1500 1501 rec->exp_sectag_en = (packed_record[25] >> 5) & 0x1; 1502 1503 rec->sc_idx = (packed_record[25] >> 6) & 0x1F; 1504 1505 rec->sc_sa = (packed_record[25] >> 11) & 0x3; 1506 1507 rec->debug = (packed_record[25] >> 13) & 0x1; 1508 1509 rec->action = (packed_record[25] >> 14) & 0x3; 1510 1511 rec->valid = (packed_record[26] >> 3) & 0x1; 1512 1513 return 0; 1514 } 1515 1516 int aq_mss_get_egress_class_record(struct aq_hw_s *hw, 1517 struct aq_mss_egress_class_record *rec, 1518 u16 table_index) 1519 { 1520 memset(rec, 0, sizeof(*rec)); 1521 1522 return AQ_API_CALL_SAFE(get_egress_class_record, hw, rec, table_index); 1523 } 1524 1525 static int set_egress_sc_record(struct aq_hw_s *hw, 1526 const struct aq_mss_egress_sc_record *rec, 1527 u16 table_index) 1528 { 1529 u16 packed_record[8]; 1530 1531 if (table_index >= NUMROWS_EGRESSSCRECORD) 1532 return -EINVAL; 1533 1534 memset(packed_record, 0, sizeof(u16) * 8); 1535 1536 packed_record[0] = rec->start_time & 0xFFFF; 1537 packed_record[1] = (rec->start_time >> 16) & 0xFFFF; 1538 1539 packed_record[2] = rec->stop_time & 0xFFFF; 1540 packed_record[3] = (rec->stop_time >> 16) & 0xFFFF; 1541 1542 packed_record[4] = rec->curr_an & 0x3; 1543 1544 packed_record[4] |= (rec->an_roll & 0x1) << 2; 1545 1546 packed_record[4] |= (rec->tci & 0x3F) << 3; 1547 1548 packed_record[4] |= (rec->enc_off & 0x7F) << 9; 1549 packed_record[5] = (rec->enc_off >> 7) & 0x1; 1550 1551 packed_record[5] |= (rec->protect & 0x1) << 1; 1552 1553 packed_record[5] |= (rec->recv & 0x1) << 2; 1554 1555 packed_record[5] |= (rec->fresh & 0x1) << 3; 1556 1557 packed_record[5] |= (rec->sak_len & 0x3) << 4; 1558 1559 packed_record[7] = (rec->valid & 0x1) << 15; 1560 1561 return set_raw_egress_record(hw, packed_record, 8, 2, 1562 ROWOFFSET_EGRESSSCRECORD + table_index); 1563 } 1564 1565 int aq_mss_set_egress_sc_record(struct aq_hw_s *hw, 1566 const struct aq_mss_egress_sc_record *rec, 1567 u16 table_index) 1568 { 1569 return AQ_API_CALL_SAFE(set_egress_sc_record, hw, rec, table_index); 1570 } 1571 1572 static int get_egress_sc_record(struct aq_hw_s *hw, 1573 struct aq_mss_egress_sc_record *rec, 1574 u16 table_index) 1575 { 1576 u16 packed_record[8]; 1577 int ret; 1578 1579 if (table_index >= NUMROWS_EGRESSSCRECORD) 1580 return -EINVAL; 1581 1582 ret = get_raw_egress_record(hw, packed_record, 8, 2, 1583 ROWOFFSET_EGRESSSCRECORD + table_index); 1584 if (unlikely(ret)) 1585 return ret; 1586 1587 rec->start_time = packed_record[0]; 1588 rec->start_time |= packed_record[1] << 16; 1589 1590 rec->stop_time = packed_record[2]; 1591 rec->stop_time |= packed_record[3] << 16; 1592 1593 rec->curr_an = packed_record[4] & 0x3; 1594 1595 rec->an_roll = (packed_record[4] >> 2) & 0x1; 1596 1597 rec->tci = (packed_record[4] >> 3) & 0x3F; 1598 1599 rec->enc_off = (packed_record[4] >> 9) & 0x7F; 1600 rec->enc_off |= (packed_record[5] & 0x1) << 7; 1601 1602 rec->protect = (packed_record[5] >> 1) & 0x1; 1603 1604 rec->recv = (packed_record[5] >> 2) & 0x1; 1605 1606 rec->fresh = (packed_record[5] >> 3) & 0x1; 1607 1608 rec->sak_len = (packed_record[5] >> 4) & 0x3; 1609 1610 rec->valid = (packed_record[7] >> 15) & 0x1; 1611 1612 return 0; 1613 } 1614 1615 int aq_mss_get_egress_sc_record(struct aq_hw_s *hw, 1616 struct aq_mss_egress_sc_record *rec, 1617 u16 table_index) 1618 { 1619 memset(rec, 0, sizeof(*rec)); 1620 1621 return AQ_API_CALL_SAFE(get_egress_sc_record, hw, rec, table_index); 1622 } 1623 1624 static int set_egress_sa_record(struct aq_hw_s *hw, 1625 const struct aq_mss_egress_sa_record *rec, 1626 u16 table_index) 1627 { 1628 u16 packed_record[8]; 1629 1630 if (table_index >= NUMROWS_EGRESSSARECORD) 1631 return -EINVAL; 1632 1633 memset(packed_record, 0, sizeof(u16) * 8); 1634 1635 packed_record[0] = rec->start_time & 0xFFFF; 1636 packed_record[1] = (rec->start_time >> 16) & 0xFFFF; 1637 1638 packed_record[2] = rec->stop_time & 0xFFFF; 1639 packed_record[3] = (rec->stop_time >> 16) & 0xFFFF; 1640 1641 packed_record[4] = rec->next_pn & 0xFFFF; 1642 packed_record[5] = (rec->next_pn >> 16) & 0xFFFF; 1643 1644 packed_record[6] = rec->sat_pn & 0x1; 1645 1646 packed_record[6] |= (rec->fresh & 0x1) << 1; 1647 1648 packed_record[7] = (rec->valid & 0x1) << 15; 1649 1650 return set_raw_egress_record(hw, packed_record, 8, 2, 1651 ROWOFFSET_EGRESSSARECORD + table_index); 1652 } 1653 1654 int aq_mss_set_egress_sa_record(struct aq_hw_s *hw, 1655 const struct aq_mss_egress_sa_record *rec, 1656 u16 table_index) 1657 { 1658 int err = AQ_API_CALL_SAFE(set_egress_sa_record, hw, rec, table_index); 1659 1660 WARN_ONCE(err, "%s failed with %d\n", __func__, err); 1661 1662 return err; 1663 } 1664 1665 static int get_egress_sa_record(struct aq_hw_s *hw, 1666 struct aq_mss_egress_sa_record *rec, 1667 u16 table_index) 1668 { 1669 u16 packed_record[8]; 1670 int ret; 1671 1672 if (table_index >= NUMROWS_EGRESSSARECORD) 1673 return -EINVAL; 1674 1675 ret = get_raw_egress_record(hw, packed_record, 8, 2, 1676 ROWOFFSET_EGRESSSARECORD + table_index); 1677 if (unlikely(ret)) 1678 return ret; 1679 1680 rec->start_time = packed_record[0]; 1681 rec->start_time |= packed_record[1] << 16; 1682 1683 rec->stop_time = packed_record[2]; 1684 rec->stop_time |= packed_record[3] << 16; 1685 1686 rec->next_pn = packed_record[4]; 1687 rec->next_pn |= packed_record[5] << 16; 1688 1689 rec->sat_pn = packed_record[6] & 0x1; 1690 1691 rec->fresh = (packed_record[6] >> 1) & 0x1; 1692 1693 rec->valid = (packed_record[7] >> 15) & 0x1; 1694 1695 return 0; 1696 } 1697 1698 int aq_mss_get_egress_sa_record(struct aq_hw_s *hw, 1699 struct aq_mss_egress_sa_record *rec, 1700 u16 table_index) 1701 { 1702 memset(rec, 0, sizeof(*rec)); 1703 1704 return AQ_API_CALL_SAFE(get_egress_sa_record, hw, rec, table_index); 1705 } 1706 1707 static int set_egress_sakey_record(struct aq_hw_s *hw, 1708 const struct aq_mss_egress_sakey_record *rec, 1709 u16 table_index) 1710 { 1711 u16 packed_record[16]; 1712 int ret; 1713 1714 if (table_index >= NUMROWS_EGRESSSAKEYRECORD) 1715 return -EINVAL; 1716 1717 memset(packed_record, 0, sizeof(u16) * 16); 1718 1719 packed_record[0] = rec->key[0] & 0xFFFF; 1720 packed_record[1] = (rec->key[0] >> 16) & 0xFFFF; 1721 1722 packed_record[2] = rec->key[1] & 0xFFFF; 1723 packed_record[3] = (rec->key[1] >> 16) & 0xFFFF; 1724 1725 packed_record[4] = rec->key[2] & 0xFFFF; 1726 packed_record[5] = (rec->key[2] >> 16) & 0xFFFF; 1727 1728 packed_record[6] = rec->key[3] & 0xFFFF; 1729 packed_record[7] = (rec->key[3] >> 16) & 0xFFFF; 1730 1731 packed_record[8] = rec->key[4] & 0xFFFF; 1732 packed_record[9] = (rec->key[4] >> 16) & 0xFFFF; 1733 1734 packed_record[10] = rec->key[5] & 0xFFFF; 1735 packed_record[11] = (rec->key[5] >> 16) & 0xFFFF; 1736 1737 packed_record[12] = rec->key[6] & 0xFFFF; 1738 packed_record[13] = (rec->key[6] >> 16) & 0xFFFF; 1739 1740 packed_record[14] = rec->key[7] & 0xFFFF; 1741 packed_record[15] = (rec->key[7] >> 16) & 0xFFFF; 1742 1743 ret = set_raw_egress_record(hw, packed_record, 8, 2, 1744 ROWOFFSET_EGRESSSAKEYRECORD + table_index); 1745 if (unlikely(ret)) 1746 goto clear_key; 1747 ret = set_raw_egress_record(hw, packed_record + 8, 8, 2, 1748 ROWOFFSET_EGRESSSAKEYRECORD + table_index - 1749 32); 1750 1751 clear_key: 1752 memzero_explicit(packed_record, sizeof(packed_record)); 1753 return ret; 1754 } 1755 1756 int aq_mss_set_egress_sakey_record(struct aq_hw_s *hw, 1757 const struct aq_mss_egress_sakey_record *rec, 1758 u16 table_index) 1759 { 1760 int err = AQ_API_CALL_SAFE(set_egress_sakey_record, hw, rec, 1761 table_index); 1762 1763 WARN_ONCE(err, "%s failed with %d\n", __func__, err); 1764 1765 return err; 1766 } 1767 1768 static int get_egress_sakey_record(struct aq_hw_s *hw, 1769 struct aq_mss_egress_sakey_record *rec, 1770 u16 table_index) 1771 { 1772 u16 packed_record[16]; 1773 int ret; 1774 1775 if (table_index >= NUMROWS_EGRESSSAKEYRECORD) 1776 return -EINVAL; 1777 1778 ret = get_raw_egress_record(hw, packed_record, 8, 2, 1779 ROWOFFSET_EGRESSSAKEYRECORD + table_index); 1780 if (unlikely(ret)) 1781 return ret; 1782 ret = get_raw_egress_record(hw, packed_record + 8, 8, 2, 1783 ROWOFFSET_EGRESSSAKEYRECORD + table_index - 1784 32); 1785 if (unlikely(ret)) 1786 return ret; 1787 1788 rec->key[0] = packed_record[0]; 1789 rec->key[0] |= packed_record[1] << 16; 1790 1791 rec->key[1] = packed_record[2]; 1792 rec->key[1] |= packed_record[3] << 16; 1793 1794 rec->key[2] = packed_record[4]; 1795 rec->key[2] |= packed_record[5] << 16; 1796 1797 rec->key[3] = packed_record[6]; 1798 rec->key[3] |= packed_record[7] << 16; 1799 1800 rec->key[4] = packed_record[8]; 1801 rec->key[4] |= packed_record[9] << 16; 1802 1803 rec->key[5] = packed_record[10]; 1804 rec->key[5] |= packed_record[11] << 16; 1805 1806 rec->key[6] = packed_record[12]; 1807 rec->key[6] |= packed_record[13] << 16; 1808 1809 rec->key[7] = packed_record[14]; 1810 rec->key[7] |= packed_record[15] << 16; 1811 1812 return 0; 1813 } 1814 1815 int aq_mss_get_egress_sakey_record(struct aq_hw_s *hw, 1816 struct aq_mss_egress_sakey_record *rec, 1817 u16 table_index) 1818 { 1819 memset(rec, 0, sizeof(*rec)); 1820 1821 return AQ_API_CALL_SAFE(get_egress_sakey_record, hw, rec, table_index); 1822 } 1823 1824 static int get_egress_sc_counters(struct aq_hw_s *hw, 1825 struct aq_mss_egress_sc_counters *counters, 1826 u16 sc_index) 1827 { 1828 u16 packed_record[4]; 1829 int ret; 1830 1831 if (sc_index >= NUMROWS_EGRESSSCRECORD) 1832 return -EINVAL; 1833 1834 ret = get_raw_egress_record(hw, packed_record, 4, 3, sc_index * 8 + 4); 1835 if (unlikely(ret)) 1836 return ret; 1837 counters->sc_protected_pkts[0] = 1838 packed_record[0] | (packed_record[1] << 16); 1839 counters->sc_protected_pkts[1] = 1840 packed_record[2] | (packed_record[3] << 16); 1841 1842 ret = get_raw_egress_record(hw, packed_record, 4, 3, sc_index * 8 + 5); 1843 if (unlikely(ret)) 1844 return ret; 1845 counters->sc_encrypted_pkts[0] = 1846 packed_record[0] | (packed_record[1] << 16); 1847 counters->sc_encrypted_pkts[1] = 1848 packed_record[2] | (packed_record[3] << 16); 1849 1850 ret = get_raw_egress_record(hw, packed_record, 4, 3, sc_index * 8 + 6); 1851 if (unlikely(ret)) 1852 return ret; 1853 counters->sc_protected_octets[0] = 1854 packed_record[0] | (packed_record[1] << 16); 1855 counters->sc_protected_octets[1] = 1856 packed_record[2] | (packed_record[3] << 16); 1857 1858 ret = get_raw_egress_record(hw, packed_record, 4, 3, sc_index * 8 + 7); 1859 if (unlikely(ret)) 1860 return ret; 1861 counters->sc_encrypted_octets[0] = 1862 packed_record[0] | (packed_record[1] << 16); 1863 counters->sc_encrypted_octets[1] = 1864 packed_record[2] | (packed_record[3] << 16); 1865 1866 return 0; 1867 } 1868 1869 int aq_mss_get_egress_sc_counters(struct aq_hw_s *hw, 1870 struct aq_mss_egress_sc_counters *counters, 1871 u16 sc_index) 1872 { 1873 memset(counters, 0, sizeof(*counters)); 1874 1875 return AQ_API_CALL_SAFE(get_egress_sc_counters, hw, counters, sc_index); 1876 } 1877 1878 static int get_egress_sa_counters(struct aq_hw_s *hw, 1879 struct aq_mss_egress_sa_counters *counters, 1880 u16 sa_index) 1881 { 1882 u16 packed_record[4]; 1883 int ret; 1884 1885 if (sa_index >= NUMROWS_EGRESSSARECORD) 1886 return -EINVAL; 1887 1888 ret = get_raw_egress_record(hw, packed_record, 4, 3, sa_index * 8 + 0); 1889 if (unlikely(ret)) 1890 return ret; 1891 counters->sa_hit_drop_redirect[0] = 1892 packed_record[0] | (packed_record[1] << 16); 1893 counters->sa_hit_drop_redirect[1] = 1894 packed_record[2] | (packed_record[3] << 16); 1895 1896 ret = get_raw_egress_record(hw, packed_record, 4, 3, sa_index * 8 + 1); 1897 if (unlikely(ret)) 1898 return ret; 1899 counters->sa_protected2_pkts[0] = 1900 packed_record[0] | (packed_record[1] << 16); 1901 counters->sa_protected2_pkts[1] = 1902 packed_record[2] | (packed_record[3] << 16); 1903 1904 ret = get_raw_egress_record(hw, packed_record, 4, 3, sa_index * 8 + 2); 1905 if (unlikely(ret)) 1906 return ret; 1907 counters->sa_protected_pkts[0] = 1908 packed_record[0] | (packed_record[1] << 16); 1909 counters->sa_protected_pkts[1] = 1910 packed_record[2] | (packed_record[3] << 16); 1911 1912 ret = get_raw_egress_record(hw, packed_record, 4, 3, sa_index * 8 + 3); 1913 if (unlikely(ret)) 1914 return ret; 1915 counters->sa_encrypted_pkts[0] = 1916 packed_record[0] | (packed_record[1] << 16); 1917 counters->sa_encrypted_pkts[1] = 1918 packed_record[2] | (packed_record[3] << 16); 1919 1920 return 0; 1921 } 1922 1923 int aq_mss_get_egress_sa_counters(struct aq_hw_s *hw, 1924 struct aq_mss_egress_sa_counters *counters, 1925 u16 sa_index) 1926 { 1927 memset(counters, 0, sizeof(*counters)); 1928 1929 return AQ_API_CALL_SAFE(get_egress_sa_counters, hw, counters, sa_index); 1930 } 1931 1932 static int 1933 get_egress_common_counters(struct aq_hw_s *hw, 1934 struct aq_mss_egress_common_counters *counters) 1935 { 1936 u16 packed_record[4]; 1937 int ret; 1938 1939 ret = get_raw_egress_record(hw, packed_record, 4, 3, 256 + 0); 1940 if (unlikely(ret)) 1941 return ret; 1942 counters->ctl_pkt[0] = packed_record[0] | (packed_record[1] << 16); 1943 counters->ctl_pkt[1] = packed_record[2] | (packed_record[3] << 16); 1944 1945 ret = get_raw_egress_record(hw, packed_record, 4, 3, 256 + 1); 1946 if (unlikely(ret)) 1947 return ret; 1948 counters->unknown_sa_pkts[0] = 1949 packed_record[0] | (packed_record[1] << 16); 1950 counters->unknown_sa_pkts[1] = 1951 packed_record[2] | (packed_record[3] << 16); 1952 1953 ret = get_raw_egress_record(hw, packed_record, 4, 3, 256 + 2); 1954 if (unlikely(ret)) 1955 return ret; 1956 counters->untagged_pkts[0] = 1957 packed_record[0] | (packed_record[1] << 16); 1958 counters->untagged_pkts[1] = 1959 packed_record[2] | (packed_record[3] << 16); 1960 1961 ret = get_raw_egress_record(hw, packed_record, 4, 3, 256 + 3); 1962 if (unlikely(ret)) 1963 return ret; 1964 counters->too_long[0] = packed_record[0] | (packed_record[1] << 16); 1965 counters->too_long[1] = packed_record[2] | (packed_record[3] << 16); 1966 1967 ret = get_raw_egress_record(hw, packed_record, 4, 3, 256 + 4); 1968 if (unlikely(ret)) 1969 return ret; 1970 counters->ecc_error_pkts[0] = 1971 packed_record[0] | (packed_record[1] << 16); 1972 counters->ecc_error_pkts[1] = 1973 packed_record[2] | (packed_record[3] << 16); 1974 1975 ret = get_raw_egress_record(hw, packed_record, 4, 3, 256 + 5); 1976 if (unlikely(ret)) 1977 return ret; 1978 counters->unctrl_hit_drop_redir[0] = 1979 packed_record[0] | (packed_record[1] << 16); 1980 counters->unctrl_hit_drop_redir[1] = 1981 packed_record[2] | (packed_record[3] << 16); 1982 1983 return 0; 1984 } 1985 1986 int aq_mss_get_egress_common_counters(struct aq_hw_s *hw, 1987 struct aq_mss_egress_common_counters *counters) 1988 { 1989 memset(counters, 0, sizeof(*counters)); 1990 1991 return AQ_API_CALL_SAFE(get_egress_common_counters, hw, counters); 1992 } 1993 1994 static int clear_egress_counters(struct aq_hw_s *hw) 1995 { 1996 struct mss_egress_ctl_register ctl_reg; 1997 int ret; 1998 1999 memset(&ctl_reg, 0, sizeof(ctl_reg)); 2000 2001 ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1, MSS_EGRESS_CTL_REGISTER_ADDR, 2002 &ctl_reg.word_0); 2003 if (unlikely(ret)) 2004 return ret; 2005 ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1, 2006 MSS_EGRESS_CTL_REGISTER_ADDR + 4, 2007 &ctl_reg.word_1); 2008 if (unlikely(ret)) 2009 return ret; 2010 2011 /* Toggle the Egress MIB clear bit 0->1->0 */ 2012 ctl_reg.bits_0.clear_counter = 0; 2013 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1, 2014 MSS_EGRESS_CTL_REGISTER_ADDR, ctl_reg.word_0); 2015 if (unlikely(ret)) 2016 return ret; 2017 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1, 2018 MSS_EGRESS_CTL_REGISTER_ADDR + 4, 2019 ctl_reg.word_1); 2020 if (unlikely(ret)) 2021 return ret; 2022 2023 ctl_reg.bits_0.clear_counter = 1; 2024 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1, 2025 MSS_EGRESS_CTL_REGISTER_ADDR, ctl_reg.word_0); 2026 if (unlikely(ret)) 2027 return ret; 2028 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1, 2029 MSS_EGRESS_CTL_REGISTER_ADDR + 4, 2030 ctl_reg.word_1); 2031 if (unlikely(ret)) 2032 return ret; 2033 2034 ctl_reg.bits_0.clear_counter = 0; 2035 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1, 2036 MSS_EGRESS_CTL_REGISTER_ADDR, ctl_reg.word_0); 2037 if (unlikely(ret)) 2038 return ret; 2039 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1, 2040 MSS_EGRESS_CTL_REGISTER_ADDR + 4, 2041 ctl_reg.word_1); 2042 if (unlikely(ret)) 2043 return ret; 2044 2045 return 0; 2046 } 2047 2048 int aq_mss_clear_egress_counters(struct aq_hw_s *hw) 2049 { 2050 return AQ_API_CALL_SAFE(clear_egress_counters, hw); 2051 } 2052 2053 static int get_ingress_sa_counters(struct aq_hw_s *hw, 2054 struct aq_mss_ingress_sa_counters *counters, 2055 u16 sa_index) 2056 { 2057 u16 packed_record[4]; 2058 int ret; 2059 2060 if (sa_index >= NUMROWS_INGRESSSARECORD) 2061 return -EINVAL; 2062 2063 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 2064 sa_index * 12 + 0); 2065 if (unlikely(ret)) 2066 return ret; 2067 counters->untagged_hit_pkts[0] = 2068 packed_record[0] | (packed_record[1] << 16); 2069 counters->untagged_hit_pkts[1] = 2070 packed_record[2] | (packed_record[3] << 16); 2071 2072 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 2073 sa_index * 12 + 1); 2074 if (unlikely(ret)) 2075 return ret; 2076 counters->ctrl_hit_drop_redir_pkts[0] = 2077 packed_record[0] | (packed_record[1] << 16); 2078 counters->ctrl_hit_drop_redir_pkts[1] = 2079 packed_record[2] | (packed_record[3] << 16); 2080 2081 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 2082 sa_index * 12 + 2); 2083 if (unlikely(ret)) 2084 return ret; 2085 counters->not_using_sa[0] = packed_record[0] | (packed_record[1] << 16); 2086 counters->not_using_sa[1] = packed_record[2] | (packed_record[3] << 16); 2087 2088 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 2089 sa_index * 12 + 3); 2090 if (unlikely(ret)) 2091 return ret; 2092 counters->unused_sa[0] = packed_record[0] | (packed_record[1] << 16); 2093 counters->unused_sa[1] = packed_record[2] | (packed_record[3] << 16); 2094 2095 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 2096 sa_index * 12 + 4); 2097 if (unlikely(ret)) 2098 return ret; 2099 counters->not_valid_pkts[0] = 2100 packed_record[0] | (packed_record[1] << 16); 2101 counters->not_valid_pkts[1] = 2102 packed_record[2] | (packed_record[3] << 16); 2103 2104 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 2105 sa_index * 12 + 5); 2106 if (unlikely(ret)) 2107 return ret; 2108 counters->invalid_pkts[0] = packed_record[0] | (packed_record[1] << 16); 2109 counters->invalid_pkts[1] = packed_record[2] | (packed_record[3] << 16); 2110 2111 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 2112 sa_index * 12 + 6); 2113 if (unlikely(ret)) 2114 return ret; 2115 counters->ok_pkts[0] = packed_record[0] | (packed_record[1] << 16); 2116 counters->ok_pkts[1] = packed_record[2] | (packed_record[3] << 16); 2117 2118 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 2119 sa_index * 12 + 7); 2120 if (unlikely(ret)) 2121 return ret; 2122 counters->late_pkts[0] = packed_record[0] | (packed_record[1] << 16); 2123 counters->late_pkts[1] = packed_record[2] | (packed_record[3] << 16); 2124 2125 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 2126 sa_index * 12 + 8); 2127 if (unlikely(ret)) 2128 return ret; 2129 counters->delayed_pkts[0] = packed_record[0] | (packed_record[1] << 16); 2130 counters->delayed_pkts[1] = packed_record[2] | (packed_record[3] << 16); 2131 2132 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 2133 sa_index * 12 + 9); 2134 if (unlikely(ret)) 2135 return ret; 2136 counters->unchecked_pkts[0] = 2137 packed_record[0] | (packed_record[1] << 16); 2138 counters->unchecked_pkts[1] = 2139 packed_record[2] | (packed_record[3] << 16); 2140 2141 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 2142 sa_index * 12 + 10); 2143 if (unlikely(ret)) 2144 return ret; 2145 counters->validated_octets[0] = 2146 packed_record[0] | (packed_record[1] << 16); 2147 counters->validated_octets[1] = 2148 packed_record[2] | (packed_record[3] << 16); 2149 2150 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 2151 sa_index * 12 + 11); 2152 if (unlikely(ret)) 2153 return ret; 2154 counters->decrypted_octets[0] = 2155 packed_record[0] | (packed_record[1] << 16); 2156 counters->decrypted_octets[1] = 2157 packed_record[2] | (packed_record[3] << 16); 2158 2159 return 0; 2160 } 2161 2162 int aq_mss_get_ingress_sa_counters(struct aq_hw_s *hw, 2163 struct aq_mss_ingress_sa_counters *counters, 2164 u16 sa_index) 2165 { 2166 memset(counters, 0, sizeof(*counters)); 2167 2168 return AQ_API_CALL_SAFE(get_ingress_sa_counters, hw, counters, 2169 sa_index); 2170 } 2171 2172 static int 2173 get_ingress_common_counters(struct aq_hw_s *hw, 2174 struct aq_mss_ingress_common_counters *counters) 2175 { 2176 u16 packed_record[4]; 2177 int ret; 2178 2179 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 0); 2180 if (unlikely(ret)) 2181 return ret; 2182 counters->ctl_pkts[0] = packed_record[0] | (packed_record[1] << 16); 2183 counters->ctl_pkts[1] = packed_record[2] | (packed_record[3] << 16); 2184 2185 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 1); 2186 if (unlikely(ret)) 2187 return ret; 2188 counters->tagged_miss_pkts[0] = 2189 packed_record[0] | (packed_record[1] << 16); 2190 counters->tagged_miss_pkts[1] = 2191 packed_record[2] | (packed_record[3] << 16); 2192 2193 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 2); 2194 if (unlikely(ret)) 2195 return ret; 2196 counters->untagged_miss_pkts[0] = 2197 packed_record[0] | (packed_record[1] << 16); 2198 counters->untagged_miss_pkts[1] = 2199 packed_record[2] | (packed_record[3] << 16); 2200 2201 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 3); 2202 if (unlikely(ret)) 2203 return ret; 2204 counters->notag_pkts[0] = packed_record[0] | (packed_record[1] << 16); 2205 counters->notag_pkts[1] = packed_record[2] | (packed_record[3] << 16); 2206 2207 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 4); 2208 if (unlikely(ret)) 2209 return ret; 2210 counters->untagged_pkts[0] = 2211 packed_record[0] | (packed_record[1] << 16); 2212 counters->untagged_pkts[1] = 2213 packed_record[2] | (packed_record[3] << 16); 2214 2215 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 5); 2216 if (unlikely(ret)) 2217 return ret; 2218 counters->bad_tag_pkts[0] = packed_record[0] | (packed_record[1] << 16); 2219 counters->bad_tag_pkts[1] = packed_record[2] | (packed_record[3] << 16); 2220 2221 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 6); 2222 if (unlikely(ret)) 2223 return ret; 2224 counters->no_sci_pkts[0] = packed_record[0] | (packed_record[1] << 16); 2225 counters->no_sci_pkts[1] = packed_record[2] | (packed_record[3] << 16); 2226 2227 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 7); 2228 if (unlikely(ret)) 2229 return ret; 2230 counters->unknown_sci_pkts[0] = 2231 packed_record[0] | (packed_record[1] << 16); 2232 counters->unknown_sci_pkts[1] = 2233 packed_record[2] | (packed_record[3] << 16); 2234 2235 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 8); 2236 if (unlikely(ret)) 2237 return ret; 2238 counters->ctrl_prt_pass_pkts[0] = 2239 packed_record[0] | (packed_record[1] << 16); 2240 counters->ctrl_prt_pass_pkts[1] = 2241 packed_record[2] | (packed_record[3] << 16); 2242 2243 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 9); 2244 if (unlikely(ret)) 2245 return ret; 2246 counters->unctrl_prt_pass_pkts[0] = 2247 packed_record[0] | (packed_record[1] << 16); 2248 counters->unctrl_prt_pass_pkts[1] = 2249 packed_record[2] | (packed_record[3] << 16); 2250 2251 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 10); 2252 if (unlikely(ret)) 2253 return ret; 2254 counters->ctrl_prt_fail_pkts[0] = 2255 packed_record[0] | (packed_record[1] << 16); 2256 counters->ctrl_prt_fail_pkts[1] = 2257 packed_record[2] | (packed_record[3] << 16); 2258 2259 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 11); 2260 if (unlikely(ret)) 2261 return ret; 2262 counters->unctrl_prt_fail_pkts[0] = 2263 packed_record[0] | (packed_record[1] << 16); 2264 counters->unctrl_prt_fail_pkts[1] = 2265 packed_record[2] | (packed_record[3] << 16); 2266 2267 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 12); 2268 if (unlikely(ret)) 2269 return ret; 2270 counters->too_long_pkts[0] = 2271 packed_record[0] | (packed_record[1] << 16); 2272 counters->too_long_pkts[1] = 2273 packed_record[2] | (packed_record[3] << 16); 2274 2275 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 13); 2276 if (unlikely(ret)) 2277 return ret; 2278 counters->igpoc_ctl_pkts[0] = 2279 packed_record[0] | (packed_record[1] << 16); 2280 counters->igpoc_ctl_pkts[1] = 2281 packed_record[2] | (packed_record[3] << 16); 2282 2283 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 14); 2284 if (unlikely(ret)) 2285 return ret; 2286 counters->ecc_error_pkts[0] = 2287 packed_record[0] | (packed_record[1] << 16); 2288 counters->ecc_error_pkts[1] = 2289 packed_record[2] | (packed_record[3] << 16); 2290 2291 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 15); 2292 if (unlikely(ret)) 2293 return ret; 2294 counters->unctrl_hit_drop_redir[0] = 2295 packed_record[0] | (packed_record[1] << 16); 2296 counters->unctrl_hit_drop_redir[1] = 2297 packed_record[2] | (packed_record[3] << 16); 2298 2299 return 0; 2300 } 2301 2302 int aq_mss_get_ingress_common_counters(struct aq_hw_s *hw, 2303 struct aq_mss_ingress_common_counters *counters) 2304 { 2305 memset(counters, 0, sizeof(*counters)); 2306 2307 return AQ_API_CALL_SAFE(get_ingress_common_counters, hw, counters); 2308 } 2309 2310 static int clear_ingress_counters(struct aq_hw_s *hw) 2311 { 2312 struct mss_ingress_ctl_register ctl_reg; 2313 int ret; 2314 2315 memset(&ctl_reg, 0, sizeof(ctl_reg)); 2316 2317 ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1, 2318 MSS_INGRESS_CTL_REGISTER_ADDR, &ctl_reg.word_0); 2319 if (unlikely(ret)) 2320 return ret; 2321 ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1, 2322 MSS_INGRESS_CTL_REGISTER_ADDR + 4, 2323 &ctl_reg.word_1); 2324 if (unlikely(ret)) 2325 return ret; 2326 2327 /* Toggle the Ingress MIB clear bit 0->1->0 */ 2328 ctl_reg.bits_0.clear_count = 0; 2329 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1, 2330 MSS_INGRESS_CTL_REGISTER_ADDR, ctl_reg.word_0); 2331 if (unlikely(ret)) 2332 return ret; 2333 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1, 2334 MSS_INGRESS_CTL_REGISTER_ADDR + 4, 2335 ctl_reg.word_1); 2336 if (unlikely(ret)) 2337 return ret; 2338 2339 ctl_reg.bits_0.clear_count = 1; 2340 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1, 2341 MSS_INGRESS_CTL_REGISTER_ADDR, ctl_reg.word_0); 2342 if (unlikely(ret)) 2343 return ret; 2344 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1, 2345 MSS_INGRESS_CTL_REGISTER_ADDR + 4, 2346 ctl_reg.word_1); 2347 if (unlikely(ret)) 2348 return ret; 2349 2350 ctl_reg.bits_0.clear_count = 0; 2351 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1, 2352 MSS_INGRESS_CTL_REGISTER_ADDR, ctl_reg.word_0); 2353 if (unlikely(ret)) 2354 return ret; 2355 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1, 2356 MSS_INGRESS_CTL_REGISTER_ADDR + 4, 2357 ctl_reg.word_1); 2358 if (unlikely(ret)) 2359 return ret; 2360 2361 return 0; 2362 } 2363 2364 int aq_mss_clear_ingress_counters(struct aq_hw_s *hw) 2365 { 2366 return AQ_API_CALL_SAFE(clear_ingress_counters, hw); 2367 } 2368 2369 static int get_egress_sa_expired(struct aq_hw_s *hw, u32 *expired) 2370 { 2371 u16 val; 2372 int ret; 2373 2374 ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1, 2375 MSS_EGRESS_SA_EXPIRED_STATUS_REGISTER_ADDR, 2376 &val); 2377 if (unlikely(ret)) 2378 return ret; 2379 2380 *expired = val; 2381 2382 ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1, 2383 MSS_EGRESS_SA_EXPIRED_STATUS_REGISTER_ADDR + 1, 2384 &val); 2385 if (unlikely(ret)) 2386 return ret; 2387 2388 *expired |= val << 16; 2389 2390 return 0; 2391 } 2392 2393 int aq_mss_get_egress_sa_expired(struct aq_hw_s *hw, u32 *expired) 2394 { 2395 *expired = 0; 2396 2397 return AQ_API_CALL_SAFE(get_egress_sa_expired, hw, expired); 2398 } 2399 2400 static int get_egress_sa_threshold_expired(struct aq_hw_s *hw, 2401 u32 *expired) 2402 { 2403 u16 val; 2404 int ret; 2405 2406 ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1, 2407 MSS_EGRESS_SA_THRESHOLD_EXPIRED_STATUS_REGISTER_ADDR, &val); 2408 if (unlikely(ret)) 2409 return ret; 2410 2411 *expired = val; 2412 2413 ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1, 2414 MSS_EGRESS_SA_THRESHOLD_EXPIRED_STATUS_REGISTER_ADDR + 1, &val); 2415 if (unlikely(ret)) 2416 return ret; 2417 2418 *expired |= val << 16; 2419 2420 return 0; 2421 } 2422 2423 int aq_mss_get_egress_sa_threshold_expired(struct aq_hw_s *hw, 2424 u32 *expired) 2425 { 2426 *expired = 0; 2427 2428 return AQ_API_CALL_SAFE(get_egress_sa_threshold_expired, hw, expired); 2429 } 2430 2431 static int set_egress_sa_expired(struct aq_hw_s *hw, u32 expired) 2432 { 2433 int ret; 2434 2435 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1, 2436 MSS_EGRESS_SA_EXPIRED_STATUS_REGISTER_ADDR, 2437 expired & 0xFFFF); 2438 if (unlikely(ret)) 2439 return ret; 2440 2441 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1, 2442 MSS_EGRESS_SA_EXPIRED_STATUS_REGISTER_ADDR + 1, 2443 expired >> 16); 2444 if (unlikely(ret)) 2445 return ret; 2446 2447 return 0; 2448 } 2449 2450 int aq_mss_set_egress_sa_expired(struct aq_hw_s *hw, u32 expired) 2451 { 2452 return AQ_API_CALL_SAFE(set_egress_sa_expired, hw, expired); 2453 } 2454 2455 static int set_egress_sa_threshold_expired(struct aq_hw_s *hw, u32 expired) 2456 { 2457 int ret; 2458 2459 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1, 2460 MSS_EGRESS_SA_THRESHOLD_EXPIRED_STATUS_REGISTER_ADDR, 2461 expired & 0xFFFF); 2462 if (unlikely(ret)) 2463 return ret; 2464 2465 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1, 2466 MSS_EGRESS_SA_THRESHOLD_EXPIRED_STATUS_REGISTER_ADDR + 1, 2467 expired >> 16); 2468 if (unlikely(ret)) 2469 return ret; 2470 2471 return 0; 2472 } 2473 2474 int aq_mss_set_egress_sa_threshold_expired(struct aq_hw_s *hw, u32 expired) 2475 { 2476 return AQ_API_CALL_SAFE(set_egress_sa_threshold_expired, hw, expired); 2477 } 2478