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 761 if (table_index >= NUMROWS_INGRESSSAKEYRECORD) 762 return -EINVAL; 763 764 memset(packed_record, 0, sizeof(u16) * 18); 765 766 packed_record[0] = rec->key[0] & 0xFFFF; 767 packed_record[1] = (rec->key[0] >> 16) & 0xFFFF; 768 769 packed_record[2] = rec->key[1] & 0xFFFF; 770 packed_record[3] = (rec->key[1] >> 16) & 0xFFFF; 771 772 packed_record[4] = rec->key[2] & 0xFFFF; 773 packed_record[5] = (rec->key[2] >> 16) & 0xFFFF; 774 775 packed_record[6] = rec->key[3] & 0xFFFF; 776 packed_record[7] = (rec->key[3] >> 16) & 0xFFFF; 777 778 packed_record[8] = rec->key[4] & 0xFFFF; 779 packed_record[9] = (rec->key[4] >> 16) & 0xFFFF; 780 781 packed_record[10] = rec->key[5] & 0xFFFF; 782 packed_record[11] = (rec->key[5] >> 16) & 0xFFFF; 783 784 packed_record[12] = rec->key[6] & 0xFFFF; 785 packed_record[13] = (rec->key[6] >> 16) & 0xFFFF; 786 787 packed_record[14] = rec->key[7] & 0xFFFF; 788 packed_record[15] = (rec->key[7] >> 16) & 0xFFFF; 789 790 packed_record[16] = rec->key_len & 0x3; 791 792 return set_raw_ingress_record(hw, packed_record, 18, 2, 793 ROWOFFSET_INGRESSSAKEYRECORD + 794 table_index); 795 } 796 797 int aq_mss_set_ingress_sakey_record(struct aq_hw_s *hw, 798 const struct aq_mss_ingress_sakey_record *rec, 799 u16 table_index) 800 { 801 int err = AQ_API_CALL_SAFE(set_ingress_sakey_record, hw, rec, 802 table_index); 803 804 WARN_ONCE(err, "%s failed with %d\n", __func__, err); 805 806 return err; 807 } 808 809 static int get_ingress_sakey_record(struct aq_hw_s *hw, 810 struct aq_mss_ingress_sakey_record *rec, 811 u16 table_index) 812 { 813 u16 packed_record[18]; 814 int ret; 815 816 if (table_index >= NUMROWS_INGRESSSAKEYRECORD) 817 return -EINVAL; 818 819 ret = get_raw_ingress_record(hw, packed_record, 18, 2, 820 ROWOFFSET_INGRESSSAKEYRECORD + 821 table_index); 822 if (unlikely(ret)) 823 return ret; 824 825 rec->key[0] = packed_record[0]; 826 rec->key[0] |= packed_record[1] << 16; 827 828 rec->key[1] = packed_record[2]; 829 rec->key[1] |= packed_record[3] << 16; 830 831 rec->key[2] = packed_record[4]; 832 rec->key[2] |= packed_record[5] << 16; 833 834 rec->key[3] = packed_record[6]; 835 rec->key[3] |= packed_record[7] << 16; 836 837 rec->key[4] = packed_record[8]; 838 rec->key[4] |= packed_record[9] << 16; 839 840 rec->key[5] = packed_record[10]; 841 rec->key[5] |= packed_record[11] << 16; 842 843 rec->key[6] = packed_record[12]; 844 rec->key[6] |= packed_record[13] << 16; 845 846 rec->key[7] = packed_record[14]; 847 rec->key[7] |= packed_record[15] << 16; 848 849 rec->key_len = packed_record[16] & 0x3; 850 851 return 0; 852 } 853 854 int aq_mss_get_ingress_sakey_record(struct aq_hw_s *hw, 855 struct aq_mss_ingress_sakey_record *rec, 856 u16 table_index) 857 { 858 memset(rec, 0, sizeof(*rec)); 859 860 return AQ_API_CALL_SAFE(get_ingress_sakey_record, hw, rec, table_index); 861 } 862 863 static int 864 set_ingress_postclass_record(struct aq_hw_s *hw, 865 const struct aq_mss_ingress_postclass_record *rec, 866 u16 table_index) 867 { 868 u16 packed_record[8]; 869 870 if (table_index >= NUMROWS_INGRESSPOSTCLASSRECORD) 871 return -EINVAL; 872 873 memset(packed_record, 0, sizeof(u16) * 8); 874 875 packed_record[0] = rec->byte0 & 0xFF; 876 877 packed_record[0] |= (rec->byte1 & 0xFF) << 8; 878 879 packed_record[1] = rec->byte2 & 0xFF; 880 881 packed_record[1] |= (rec->byte3 & 0xFF) << 8; 882 883 packed_record[2] = rec->eth_type & 0xFFFF; 884 885 packed_record[3] = rec->eth_type_valid & 0x1; 886 887 packed_record[3] |= (rec->vlan_id & 0xFFF) << 1; 888 889 packed_record[3] |= (rec->vlan_up & 0x7) << 13; 890 891 packed_record[4] = rec->vlan_valid & 0x1; 892 893 packed_record[4] |= (rec->sai & 0x1F) << 1; 894 895 packed_record[4] |= (rec->sai_hit & 0x1) << 6; 896 897 packed_record[4] |= (rec->eth_type_mask & 0xF) << 7; 898 899 packed_record[4] |= (rec->byte3_location & 0x1F) << 11; 900 packed_record[5] = (rec->byte3_location >> 5) & 0x1; 901 902 packed_record[5] |= (rec->byte3_mask & 0x3) << 1; 903 904 packed_record[5] |= (rec->byte2_location & 0x3F) << 3; 905 906 packed_record[5] |= (rec->byte2_mask & 0x3) << 9; 907 908 packed_record[5] |= (rec->byte1_location & 0x1F) << 11; 909 packed_record[6] = (rec->byte1_location >> 5) & 0x1; 910 911 packed_record[6] |= (rec->byte1_mask & 0x3) << 1; 912 913 packed_record[6] |= (rec->byte0_location & 0x3F) << 3; 914 915 packed_record[6] |= (rec->byte0_mask & 0x3) << 9; 916 917 packed_record[6] |= (rec->eth_type_valid_mask & 0x3) << 11; 918 919 packed_record[6] |= (rec->vlan_id_mask & 0x7) << 13; 920 packed_record[7] = (rec->vlan_id_mask >> 3) & 0x1; 921 922 packed_record[7] |= (rec->vlan_up_mask & 0x3) << 1; 923 924 packed_record[7] |= (rec->vlan_valid_mask & 0x3) << 3; 925 926 packed_record[7] |= (rec->sai_mask & 0x3) << 5; 927 928 packed_record[7] |= (rec->sai_hit_mask & 0x3) << 7; 929 930 packed_record[7] |= (rec->firstlevel_actions & 0x1) << 9; 931 932 packed_record[7] |= (rec->secondlevel_actions & 0x1) << 10; 933 934 packed_record[7] |= (rec->reserved & 0xF) << 11; 935 936 packed_record[7] |= (rec->valid & 0x1) << 15; 937 938 return set_raw_ingress_record(hw, packed_record, 8, 4, 939 ROWOFFSET_INGRESSPOSTCLASSRECORD + 940 table_index); 941 } 942 943 int aq_mss_set_ingress_postclass_record(struct aq_hw_s *hw, 944 const struct aq_mss_ingress_postclass_record *rec, 945 u16 table_index) 946 { 947 return AQ_API_CALL_SAFE(set_ingress_postclass_record, hw, rec, 948 table_index); 949 } 950 951 static int 952 get_ingress_postclass_record(struct aq_hw_s *hw, 953 struct aq_mss_ingress_postclass_record *rec, 954 u16 table_index) 955 { 956 u16 packed_record[8]; 957 int ret; 958 959 if (table_index >= NUMROWS_INGRESSPOSTCLASSRECORD) 960 return -EINVAL; 961 962 /* If the row that we want to read is odd, first read the previous even 963 * row, throw that value away, and finally read the desired row. 964 */ 965 if ((table_index % 2) > 0) { 966 ret = get_raw_ingress_record(hw, packed_record, 8, 4, 967 ROWOFFSET_INGRESSPOSTCLASSRECORD + 968 table_index - 1); 969 if (unlikely(ret)) 970 return ret; 971 } 972 973 ret = get_raw_ingress_record(hw, packed_record, 8, 4, 974 ROWOFFSET_INGRESSPOSTCLASSRECORD + 975 table_index); 976 if (unlikely(ret)) 977 return ret; 978 979 rec->byte0 = packed_record[0] & 0xFF; 980 981 rec->byte1 = (packed_record[0] >> 8) & 0xFF; 982 983 rec->byte2 = packed_record[1] & 0xFF; 984 985 rec->byte3 = (packed_record[1] >> 8) & 0xFF; 986 987 rec->eth_type = packed_record[2]; 988 989 rec->eth_type_valid = packed_record[3] & 0x1; 990 991 rec->vlan_id = (packed_record[3] >> 1) & 0xFFF; 992 993 rec->vlan_up = (packed_record[3] >> 13) & 0x7; 994 995 rec->vlan_valid = packed_record[4] & 0x1; 996 997 rec->sai = (packed_record[4] >> 1) & 0x1F; 998 999 rec->sai_hit = (packed_record[4] >> 6) & 0x1; 1000 1001 rec->eth_type_mask = (packed_record[4] >> 7) & 0xF; 1002 1003 rec->byte3_location = (packed_record[4] >> 11) & 0x1F; 1004 rec->byte3_location |= (packed_record[5] & 0x1) << 5; 1005 1006 rec->byte3_mask = (packed_record[5] >> 1) & 0x3; 1007 1008 rec->byte2_location = (packed_record[5] >> 3) & 0x3F; 1009 1010 rec->byte2_mask = (packed_record[5] >> 9) & 0x3; 1011 1012 rec->byte1_location = (packed_record[5] >> 11) & 0x1F; 1013 rec->byte1_location |= (packed_record[6] & 0x1) << 5; 1014 1015 rec->byte1_mask = (packed_record[6] >> 1) & 0x3; 1016 1017 rec->byte0_location = (packed_record[6] >> 3) & 0x3F; 1018 1019 rec->byte0_mask = (packed_record[6] >> 9) & 0x3; 1020 1021 rec->eth_type_valid_mask = (packed_record[6] >> 11) & 0x3; 1022 1023 rec->vlan_id_mask = (packed_record[6] >> 13) & 0x7; 1024 rec->vlan_id_mask |= (packed_record[7] & 0x1) << 3; 1025 1026 rec->vlan_up_mask = (packed_record[7] >> 1) & 0x3; 1027 1028 rec->vlan_valid_mask = (packed_record[7] >> 3) & 0x3; 1029 1030 rec->sai_mask = (packed_record[7] >> 5) & 0x3; 1031 1032 rec->sai_hit_mask = (packed_record[7] >> 7) & 0x3; 1033 1034 rec->firstlevel_actions = (packed_record[7] >> 9) & 0x1; 1035 1036 rec->secondlevel_actions = (packed_record[7] >> 10) & 0x1; 1037 1038 rec->reserved = (packed_record[7] >> 11) & 0xF; 1039 1040 rec->valid = (packed_record[7] >> 15) & 0x1; 1041 1042 return 0; 1043 } 1044 1045 int aq_mss_get_ingress_postclass_record(struct aq_hw_s *hw, 1046 struct aq_mss_ingress_postclass_record *rec, 1047 u16 table_index) 1048 { 1049 memset(rec, 0, sizeof(*rec)); 1050 1051 return AQ_API_CALL_SAFE(get_ingress_postclass_record, hw, rec, 1052 table_index); 1053 } 1054 1055 static int 1056 set_ingress_postctlf_record(struct aq_hw_s *hw, 1057 const struct aq_mss_ingress_postctlf_record *rec, 1058 u16 table_index) 1059 { 1060 u16 packed_record[6]; 1061 1062 if (table_index >= NUMROWS_INGRESSPOSTCTLFRECORD) 1063 return -EINVAL; 1064 1065 memset(packed_record, 0, sizeof(u16) * 6); 1066 1067 packed_record[0] = rec->sa_da[0] & 0xFFFF; 1068 packed_record[1] = (rec->sa_da[0] >> 16) & 0xFFFF; 1069 1070 packed_record[2] = rec->sa_da[1] & 0xFFFF; 1071 1072 packed_record[3] = rec->eth_type & 0xFFFF; 1073 1074 packed_record[4] = rec->match_mask & 0xFFFF; 1075 1076 packed_record[5] = rec->match_type & 0xF; 1077 1078 packed_record[5] |= (rec->action & 0x1) << 4; 1079 1080 return set_raw_ingress_record(hw, packed_record, 6, 5, 1081 ROWOFFSET_INGRESSPOSTCTLFRECORD + 1082 table_index); 1083 } 1084 1085 int aq_mss_set_ingress_postctlf_record(struct aq_hw_s *hw, 1086 const struct aq_mss_ingress_postctlf_record *rec, 1087 u16 table_index) 1088 { 1089 return AQ_API_CALL_SAFE(set_ingress_postctlf_record, hw, rec, 1090 table_index); 1091 } 1092 1093 static int 1094 get_ingress_postctlf_record(struct aq_hw_s *hw, 1095 struct aq_mss_ingress_postctlf_record *rec, 1096 u16 table_index) 1097 { 1098 u16 packed_record[6]; 1099 int ret; 1100 1101 if (table_index >= NUMROWS_INGRESSPOSTCTLFRECORD) 1102 return -EINVAL; 1103 1104 /* If the row that we want to read is odd, first read the previous even 1105 * row, throw that value away, and finally read the desired row. 1106 */ 1107 if ((table_index % 2) > 0) { 1108 ret = get_raw_ingress_record(hw, packed_record, 6, 5, 1109 ROWOFFSET_INGRESSPOSTCTLFRECORD + 1110 table_index - 1); 1111 if (unlikely(ret)) 1112 return ret; 1113 } 1114 1115 ret = get_raw_ingress_record(hw, packed_record, 6, 5, 1116 ROWOFFSET_INGRESSPOSTCTLFRECORD + 1117 table_index); 1118 if (unlikely(ret)) 1119 return ret; 1120 1121 rec->sa_da[0] = packed_record[0]; 1122 rec->sa_da[0] |= packed_record[1] << 16; 1123 1124 rec->sa_da[1] = packed_record[2]; 1125 1126 rec->eth_type = packed_record[3]; 1127 1128 rec->match_mask = packed_record[4]; 1129 1130 rec->match_type = packed_record[5] & 0xF; 1131 1132 rec->action = (packed_record[5] >> 4) & 0x1; 1133 1134 return 0; 1135 } 1136 1137 int aq_mss_get_ingress_postctlf_record(struct aq_hw_s *hw, 1138 struct aq_mss_ingress_postctlf_record *rec, 1139 u16 table_index) 1140 { 1141 memset(rec, 0, sizeof(*rec)); 1142 1143 return AQ_API_CALL_SAFE(get_ingress_postctlf_record, hw, rec, 1144 table_index); 1145 } 1146 1147 static int set_egress_ctlf_record(struct aq_hw_s *hw, 1148 const struct aq_mss_egress_ctlf_record *rec, 1149 u16 table_index) 1150 { 1151 u16 packed_record[6]; 1152 1153 if (table_index >= NUMROWS_EGRESSCTLFRECORD) 1154 return -EINVAL; 1155 1156 memset(packed_record, 0, sizeof(u16) * 6); 1157 1158 packed_record[0] = rec->sa_da[0] & 0xFFFF; 1159 packed_record[1] = (rec->sa_da[0] >> 16) & 0xFFFF; 1160 1161 packed_record[2] = rec->sa_da[1] & 0xFFFF; 1162 1163 packed_record[3] = rec->eth_type & 0xFFFF; 1164 1165 packed_record[4] = rec->match_mask & 0xFFFF; 1166 1167 packed_record[5] = rec->match_type & 0xF; 1168 1169 packed_record[5] |= (rec->action & 0x1) << 4; 1170 1171 return set_raw_egress_record(hw, packed_record, 6, 0, 1172 ROWOFFSET_EGRESSCTLFRECORD + table_index); 1173 } 1174 1175 int aq_mss_set_egress_ctlf_record(struct aq_hw_s *hw, 1176 const struct aq_mss_egress_ctlf_record *rec, 1177 u16 table_index) 1178 { 1179 return AQ_API_CALL_SAFE(set_egress_ctlf_record, hw, rec, table_index); 1180 } 1181 1182 static int get_egress_ctlf_record(struct aq_hw_s *hw, 1183 struct aq_mss_egress_ctlf_record *rec, 1184 u16 table_index) 1185 { 1186 u16 packed_record[6]; 1187 int ret; 1188 1189 if (table_index >= NUMROWS_EGRESSCTLFRECORD) 1190 return -EINVAL; 1191 1192 /* If the row that we want to read is odd, first read the previous even 1193 * row, throw that value away, and finally read the desired row. 1194 */ 1195 if ((table_index % 2) > 0) { 1196 ret = get_raw_egress_record(hw, packed_record, 6, 0, 1197 ROWOFFSET_EGRESSCTLFRECORD + 1198 table_index - 1); 1199 if (unlikely(ret)) 1200 return ret; 1201 } 1202 1203 ret = get_raw_egress_record(hw, packed_record, 6, 0, 1204 ROWOFFSET_EGRESSCTLFRECORD + table_index); 1205 if (unlikely(ret)) 1206 return ret; 1207 1208 rec->sa_da[0] = packed_record[0]; 1209 rec->sa_da[0] |= packed_record[1] << 16; 1210 1211 rec->sa_da[1] = packed_record[2]; 1212 1213 rec->eth_type = packed_record[3]; 1214 1215 rec->match_mask = packed_record[4]; 1216 1217 rec->match_type = packed_record[5] & 0xF; 1218 1219 rec->action = (packed_record[5] >> 4) & 0x1; 1220 1221 return 0; 1222 } 1223 1224 int aq_mss_get_egress_ctlf_record(struct aq_hw_s *hw, 1225 struct aq_mss_egress_ctlf_record *rec, 1226 u16 table_index) 1227 { 1228 memset(rec, 0, sizeof(*rec)); 1229 1230 return AQ_API_CALL_SAFE(get_egress_ctlf_record, hw, rec, table_index); 1231 } 1232 1233 static int set_egress_class_record(struct aq_hw_s *hw, 1234 const struct aq_mss_egress_class_record *rec, 1235 u16 table_index) 1236 { 1237 u16 packed_record[28]; 1238 1239 if (table_index >= NUMROWS_EGRESSCLASSRECORD) 1240 return -EINVAL; 1241 1242 memset(packed_record, 0, sizeof(u16) * 28); 1243 1244 packed_record[0] = rec->vlan_id & 0xFFF; 1245 1246 packed_record[0] |= (rec->vlan_up & 0x7) << 12; 1247 1248 packed_record[0] |= (rec->vlan_valid & 0x1) << 15; 1249 1250 packed_record[1] = rec->byte3 & 0xFF; 1251 1252 packed_record[1] |= (rec->byte2 & 0xFF) << 8; 1253 1254 packed_record[2] = rec->byte1 & 0xFF; 1255 1256 packed_record[2] |= (rec->byte0 & 0xFF) << 8; 1257 1258 packed_record[3] = rec->tci & 0xFF; 1259 1260 packed_record[3] |= (rec->sci[0] & 0xFF) << 8; 1261 packed_record[4] = (rec->sci[0] >> 8) & 0xFFFF; 1262 packed_record[5] = (rec->sci[0] >> 24) & 0xFF; 1263 1264 packed_record[5] |= (rec->sci[1] & 0xFF) << 8; 1265 packed_record[6] = (rec->sci[1] >> 8) & 0xFFFF; 1266 packed_record[7] = (rec->sci[1] >> 24) & 0xFF; 1267 1268 packed_record[7] |= (rec->eth_type & 0xFF) << 8; 1269 packed_record[8] = (rec->eth_type >> 8) & 0xFF; 1270 1271 packed_record[8] |= (rec->snap[0] & 0xFF) << 8; 1272 packed_record[9] = (rec->snap[0] >> 8) & 0xFFFF; 1273 packed_record[10] = (rec->snap[0] >> 24) & 0xFF; 1274 1275 packed_record[10] |= (rec->snap[1] & 0xFF) << 8; 1276 1277 packed_record[11] = rec->llc & 0xFFFF; 1278 packed_record[12] = (rec->llc >> 16) & 0xFF; 1279 1280 packed_record[12] |= (rec->mac_sa[0] & 0xFF) << 8; 1281 packed_record[13] = (rec->mac_sa[0] >> 8) & 0xFFFF; 1282 packed_record[14] = (rec->mac_sa[0] >> 24) & 0xFF; 1283 1284 packed_record[14] |= (rec->mac_sa[1] & 0xFF) << 8; 1285 packed_record[15] = (rec->mac_sa[1] >> 8) & 0xFF; 1286 1287 packed_record[15] |= (rec->mac_da[0] & 0xFF) << 8; 1288 packed_record[16] = (rec->mac_da[0] >> 8) & 0xFFFF; 1289 packed_record[17] = (rec->mac_da[0] >> 24) & 0xFF; 1290 1291 packed_record[17] |= (rec->mac_da[1] & 0xFF) << 8; 1292 packed_record[18] = (rec->mac_da[1] >> 8) & 0xFF; 1293 1294 packed_record[18] |= (rec->pn & 0xFF) << 8; 1295 packed_record[19] = (rec->pn >> 8) & 0xFFFF; 1296 packed_record[20] = (rec->pn >> 24) & 0xFF; 1297 1298 packed_record[20] |= (rec->byte3_location & 0x3F) << 8; 1299 1300 packed_record[20] |= (rec->byte3_mask & 0x1) << 14; 1301 1302 packed_record[20] |= (rec->byte2_location & 0x1) << 15; 1303 packed_record[21] = (rec->byte2_location >> 1) & 0x1F; 1304 1305 packed_record[21] |= (rec->byte2_mask & 0x1) << 5; 1306 1307 packed_record[21] |= (rec->byte1_location & 0x3F) << 6; 1308 1309 packed_record[21] |= (rec->byte1_mask & 0x1) << 12; 1310 1311 packed_record[21] |= (rec->byte0_location & 0x7) << 13; 1312 packed_record[22] = (rec->byte0_location >> 3) & 0x7; 1313 1314 packed_record[22] |= (rec->byte0_mask & 0x1) << 3; 1315 1316 packed_record[22] |= (rec->vlan_id_mask & 0x3) << 4; 1317 1318 packed_record[22] |= (rec->vlan_up_mask & 0x1) << 6; 1319 1320 packed_record[22] |= (rec->vlan_valid_mask & 0x1) << 7; 1321 1322 packed_record[22] |= (rec->tci_mask & 0xFF) << 8; 1323 1324 packed_record[23] = rec->sci_mask & 0xFF; 1325 1326 packed_record[23] |= (rec->eth_type_mask & 0x3) << 8; 1327 1328 packed_record[23] |= (rec->snap_mask & 0x1F) << 10; 1329 1330 packed_record[23] |= (rec->llc_mask & 0x1) << 15; 1331 packed_record[24] = (rec->llc_mask >> 1) & 0x3; 1332 1333 packed_record[24] |= (rec->sa_mask & 0x3F) << 2; 1334 1335 packed_record[24] |= (rec->da_mask & 0x3F) << 8; 1336 1337 packed_record[24] |= (rec->pn_mask & 0x3) << 14; 1338 packed_record[25] = (rec->pn_mask >> 2) & 0x3; 1339 1340 packed_record[25] |= (rec->eight02dot2 & 0x1) << 2; 1341 1342 packed_record[25] |= (rec->tci_sc & 0x1) << 3; 1343 1344 packed_record[25] |= (rec->tci_87543 & 0x1) << 4; 1345 1346 packed_record[25] |= (rec->exp_sectag_en & 0x1) << 5; 1347 1348 packed_record[25] |= (rec->sc_idx & 0x1F) << 6; 1349 1350 packed_record[25] |= (rec->sc_sa & 0x3) << 11; 1351 1352 packed_record[25] |= (rec->debug & 0x1) << 13; 1353 1354 packed_record[25] |= (rec->action & 0x3) << 14; 1355 1356 packed_record[26] = (rec->valid & 0x1) << 3; 1357 1358 return set_raw_egress_record(hw, packed_record, 28, 1, 1359 ROWOFFSET_EGRESSCLASSRECORD + table_index); 1360 } 1361 1362 int aq_mss_set_egress_class_record(struct aq_hw_s *hw, 1363 const struct aq_mss_egress_class_record *rec, 1364 u16 table_index) 1365 { 1366 return AQ_API_CALL_SAFE(set_egress_class_record, hw, rec, table_index); 1367 } 1368 1369 static int get_egress_class_record(struct aq_hw_s *hw, 1370 struct aq_mss_egress_class_record *rec, 1371 u16 table_index) 1372 { 1373 u16 packed_record[28]; 1374 int ret; 1375 1376 if (table_index >= NUMROWS_EGRESSCLASSRECORD) 1377 return -EINVAL; 1378 1379 /* If the row that we want to read is odd, first read the previous even 1380 * row, throw that value away, and finally read the desired row. 1381 */ 1382 if ((table_index % 2) > 0) { 1383 ret = get_raw_egress_record(hw, packed_record, 28, 1, 1384 ROWOFFSET_EGRESSCLASSRECORD + 1385 table_index - 1); 1386 if (unlikely(ret)) 1387 return ret; 1388 } 1389 1390 ret = get_raw_egress_record(hw, packed_record, 28, 1, 1391 ROWOFFSET_EGRESSCLASSRECORD + table_index); 1392 if (unlikely(ret)) 1393 return ret; 1394 1395 rec->vlan_id = packed_record[0] & 0xFFF; 1396 1397 rec->vlan_up = (packed_record[0] >> 12) & 0x7; 1398 1399 rec->vlan_valid = (packed_record[0] >> 15) & 0x1; 1400 1401 rec->byte3 = packed_record[1] & 0xFF; 1402 1403 rec->byte2 = (packed_record[1] >> 8) & 0xFF; 1404 1405 rec->byte1 = packed_record[2] & 0xFF; 1406 1407 rec->byte0 = (packed_record[2] >> 8) & 0xFF; 1408 1409 rec->tci = packed_record[3] & 0xFF; 1410 1411 rec->sci[0] = (packed_record[3] >> 8) & 0xFF; 1412 rec->sci[0] |= packed_record[4] << 8; 1413 rec->sci[0] |= (packed_record[5] & 0xFF) << 24; 1414 1415 rec->sci[1] = (packed_record[5] >> 8) & 0xFF; 1416 rec->sci[1] |= packed_record[6] << 8; 1417 rec->sci[1] |= (packed_record[7] & 0xFF) << 24; 1418 1419 rec->eth_type = (packed_record[7] >> 8) & 0xFF; 1420 rec->eth_type |= (packed_record[8] & 0xFF) << 8; 1421 1422 rec->snap[0] = (packed_record[8] >> 8) & 0xFF; 1423 rec->snap[0] |= packed_record[9] << 8; 1424 rec->snap[0] |= (packed_record[10] & 0xFF) << 24; 1425 1426 rec->snap[1] = (packed_record[10] >> 8) & 0xFF; 1427 1428 rec->llc = packed_record[11]; 1429 rec->llc |= (packed_record[12] & 0xFF) << 16; 1430 1431 rec->mac_sa[0] = (packed_record[12] >> 8) & 0xFF; 1432 rec->mac_sa[0] |= packed_record[13] << 8; 1433 rec->mac_sa[0] |= (packed_record[14] & 0xFF) << 24; 1434 1435 rec->mac_sa[1] = (packed_record[14] >> 8) & 0xFF; 1436 rec->mac_sa[1] |= (packed_record[15] & 0xFF) << 8; 1437 1438 rec->mac_da[0] = (packed_record[15] >> 8) & 0xFF; 1439 rec->mac_da[0] |= packed_record[16] << 8; 1440 rec->mac_da[0] |= (packed_record[17] & 0xFF) << 24; 1441 1442 rec->mac_da[1] = (packed_record[17] >> 8) & 0xFF; 1443 rec->mac_da[1] |= (packed_record[18] & 0xFF) << 8; 1444 1445 rec->pn = (packed_record[18] >> 8) & 0xFF; 1446 rec->pn |= packed_record[19] << 8; 1447 rec->pn |= (packed_record[20] & 0xFF) << 24; 1448 1449 rec->byte3_location = (packed_record[20] >> 8) & 0x3F; 1450 1451 rec->byte3_mask = (packed_record[20] >> 14) & 0x1; 1452 1453 rec->byte2_location = (packed_record[20] >> 15) & 0x1; 1454 rec->byte2_location |= (packed_record[21] & 0x1F) << 1; 1455 1456 rec->byte2_mask = (packed_record[21] >> 5) & 0x1; 1457 1458 rec->byte1_location = (packed_record[21] >> 6) & 0x3F; 1459 1460 rec->byte1_mask = (packed_record[21] >> 12) & 0x1; 1461 1462 rec->byte0_location = (packed_record[21] >> 13) & 0x7; 1463 rec->byte0_location |= (packed_record[22] & 0x7) << 3; 1464 1465 rec->byte0_mask = (packed_record[22] >> 3) & 0x1; 1466 1467 rec->vlan_id_mask = (packed_record[22] >> 4) & 0x3; 1468 1469 rec->vlan_up_mask = (packed_record[22] >> 6) & 0x1; 1470 1471 rec->vlan_valid_mask = (packed_record[22] >> 7) & 0x1; 1472 1473 rec->tci_mask = (packed_record[22] >> 8) & 0xFF; 1474 1475 rec->sci_mask = packed_record[23] & 0xFF; 1476 1477 rec->eth_type_mask = (packed_record[23] >> 8) & 0x3; 1478 1479 rec->snap_mask = (packed_record[23] >> 10) & 0x1F; 1480 1481 rec->llc_mask = (packed_record[23] >> 15) & 0x1; 1482 rec->llc_mask |= (packed_record[24] & 0x3) << 1; 1483 1484 rec->sa_mask = (packed_record[24] >> 2) & 0x3F; 1485 1486 rec->da_mask = (packed_record[24] >> 8) & 0x3F; 1487 1488 rec->pn_mask = (packed_record[24] >> 14) & 0x3; 1489 rec->pn_mask |= (packed_record[25] & 0x3) << 2; 1490 1491 rec->eight02dot2 = (packed_record[25] >> 2) & 0x1; 1492 1493 rec->tci_sc = (packed_record[25] >> 3) & 0x1; 1494 1495 rec->tci_87543 = (packed_record[25] >> 4) & 0x1; 1496 1497 rec->exp_sectag_en = (packed_record[25] >> 5) & 0x1; 1498 1499 rec->sc_idx = (packed_record[25] >> 6) & 0x1F; 1500 1501 rec->sc_sa = (packed_record[25] >> 11) & 0x3; 1502 1503 rec->debug = (packed_record[25] >> 13) & 0x1; 1504 1505 rec->action = (packed_record[25] >> 14) & 0x3; 1506 1507 rec->valid = (packed_record[26] >> 3) & 0x1; 1508 1509 return 0; 1510 } 1511 1512 int aq_mss_get_egress_class_record(struct aq_hw_s *hw, 1513 struct aq_mss_egress_class_record *rec, 1514 u16 table_index) 1515 { 1516 memset(rec, 0, sizeof(*rec)); 1517 1518 return AQ_API_CALL_SAFE(get_egress_class_record, hw, rec, table_index); 1519 } 1520 1521 static int set_egress_sc_record(struct aq_hw_s *hw, 1522 const struct aq_mss_egress_sc_record *rec, 1523 u16 table_index) 1524 { 1525 u16 packed_record[8]; 1526 1527 if (table_index >= NUMROWS_EGRESSSCRECORD) 1528 return -EINVAL; 1529 1530 memset(packed_record, 0, sizeof(u16) * 8); 1531 1532 packed_record[0] = rec->start_time & 0xFFFF; 1533 packed_record[1] = (rec->start_time >> 16) & 0xFFFF; 1534 1535 packed_record[2] = rec->stop_time & 0xFFFF; 1536 packed_record[3] = (rec->stop_time >> 16) & 0xFFFF; 1537 1538 packed_record[4] = rec->curr_an & 0x3; 1539 1540 packed_record[4] |= (rec->an_roll & 0x1) << 2; 1541 1542 packed_record[4] |= (rec->tci & 0x3F) << 3; 1543 1544 packed_record[4] |= (rec->enc_off & 0x7F) << 9; 1545 packed_record[5] = (rec->enc_off >> 7) & 0x1; 1546 1547 packed_record[5] |= (rec->protect & 0x1) << 1; 1548 1549 packed_record[5] |= (rec->recv & 0x1) << 2; 1550 1551 packed_record[5] |= (rec->fresh & 0x1) << 3; 1552 1553 packed_record[5] |= (rec->sak_len & 0x3) << 4; 1554 1555 packed_record[7] = (rec->valid & 0x1) << 15; 1556 1557 return set_raw_egress_record(hw, packed_record, 8, 2, 1558 ROWOFFSET_EGRESSSCRECORD + table_index); 1559 } 1560 1561 int aq_mss_set_egress_sc_record(struct aq_hw_s *hw, 1562 const struct aq_mss_egress_sc_record *rec, 1563 u16 table_index) 1564 { 1565 return AQ_API_CALL_SAFE(set_egress_sc_record, hw, rec, table_index); 1566 } 1567 1568 static int get_egress_sc_record(struct aq_hw_s *hw, 1569 struct aq_mss_egress_sc_record *rec, 1570 u16 table_index) 1571 { 1572 u16 packed_record[8]; 1573 int ret; 1574 1575 if (table_index >= NUMROWS_EGRESSSCRECORD) 1576 return -EINVAL; 1577 1578 ret = get_raw_egress_record(hw, packed_record, 8, 2, 1579 ROWOFFSET_EGRESSSCRECORD + table_index); 1580 if (unlikely(ret)) 1581 return ret; 1582 1583 rec->start_time = packed_record[0]; 1584 rec->start_time |= packed_record[1] << 16; 1585 1586 rec->stop_time = packed_record[2]; 1587 rec->stop_time |= packed_record[3] << 16; 1588 1589 rec->curr_an = packed_record[4] & 0x3; 1590 1591 rec->an_roll = (packed_record[4] >> 2) & 0x1; 1592 1593 rec->tci = (packed_record[4] >> 3) & 0x3F; 1594 1595 rec->enc_off = (packed_record[4] >> 9) & 0x7F; 1596 rec->enc_off |= (packed_record[5] & 0x1) << 7; 1597 1598 rec->protect = (packed_record[5] >> 1) & 0x1; 1599 1600 rec->recv = (packed_record[5] >> 2) & 0x1; 1601 1602 rec->fresh = (packed_record[5] >> 3) & 0x1; 1603 1604 rec->sak_len = (packed_record[5] >> 4) & 0x3; 1605 1606 rec->valid = (packed_record[7] >> 15) & 0x1; 1607 1608 return 0; 1609 } 1610 1611 int aq_mss_get_egress_sc_record(struct aq_hw_s *hw, 1612 struct aq_mss_egress_sc_record *rec, 1613 u16 table_index) 1614 { 1615 memset(rec, 0, sizeof(*rec)); 1616 1617 return AQ_API_CALL_SAFE(get_egress_sc_record, hw, rec, table_index); 1618 } 1619 1620 static int set_egress_sa_record(struct aq_hw_s *hw, 1621 const struct aq_mss_egress_sa_record *rec, 1622 u16 table_index) 1623 { 1624 u16 packed_record[8]; 1625 1626 if (table_index >= NUMROWS_EGRESSSARECORD) 1627 return -EINVAL; 1628 1629 memset(packed_record, 0, sizeof(u16) * 8); 1630 1631 packed_record[0] = rec->start_time & 0xFFFF; 1632 packed_record[1] = (rec->start_time >> 16) & 0xFFFF; 1633 1634 packed_record[2] = rec->stop_time & 0xFFFF; 1635 packed_record[3] = (rec->stop_time >> 16) & 0xFFFF; 1636 1637 packed_record[4] = rec->next_pn & 0xFFFF; 1638 packed_record[5] = (rec->next_pn >> 16) & 0xFFFF; 1639 1640 packed_record[6] = rec->sat_pn & 0x1; 1641 1642 packed_record[6] |= (rec->fresh & 0x1) << 1; 1643 1644 packed_record[7] = (rec->valid & 0x1) << 15; 1645 1646 return set_raw_egress_record(hw, packed_record, 8, 2, 1647 ROWOFFSET_EGRESSSARECORD + table_index); 1648 } 1649 1650 int aq_mss_set_egress_sa_record(struct aq_hw_s *hw, 1651 const struct aq_mss_egress_sa_record *rec, 1652 u16 table_index) 1653 { 1654 int err = AQ_API_CALL_SAFE(set_egress_sa_record, hw, rec, table_index); 1655 1656 WARN_ONCE(err, "%s failed with %d\n", __func__, err); 1657 1658 return err; 1659 } 1660 1661 static int get_egress_sa_record(struct aq_hw_s *hw, 1662 struct aq_mss_egress_sa_record *rec, 1663 u16 table_index) 1664 { 1665 u16 packed_record[8]; 1666 int ret; 1667 1668 if (table_index >= NUMROWS_EGRESSSARECORD) 1669 return -EINVAL; 1670 1671 ret = get_raw_egress_record(hw, packed_record, 8, 2, 1672 ROWOFFSET_EGRESSSARECORD + table_index); 1673 if (unlikely(ret)) 1674 return ret; 1675 1676 rec->start_time = packed_record[0]; 1677 rec->start_time |= packed_record[1] << 16; 1678 1679 rec->stop_time = packed_record[2]; 1680 rec->stop_time |= packed_record[3] << 16; 1681 1682 rec->next_pn = packed_record[4]; 1683 rec->next_pn |= packed_record[5] << 16; 1684 1685 rec->sat_pn = packed_record[6] & 0x1; 1686 1687 rec->fresh = (packed_record[6] >> 1) & 0x1; 1688 1689 rec->valid = (packed_record[7] >> 15) & 0x1; 1690 1691 return 0; 1692 } 1693 1694 int aq_mss_get_egress_sa_record(struct aq_hw_s *hw, 1695 struct aq_mss_egress_sa_record *rec, 1696 u16 table_index) 1697 { 1698 memset(rec, 0, sizeof(*rec)); 1699 1700 return AQ_API_CALL_SAFE(get_egress_sa_record, hw, rec, table_index); 1701 } 1702 1703 static int set_egress_sakey_record(struct aq_hw_s *hw, 1704 const struct aq_mss_egress_sakey_record *rec, 1705 u16 table_index) 1706 { 1707 u16 packed_record[16]; 1708 int ret; 1709 1710 if (table_index >= NUMROWS_EGRESSSAKEYRECORD) 1711 return -EINVAL; 1712 1713 memset(packed_record, 0, sizeof(u16) * 16); 1714 1715 packed_record[0] = rec->key[0] & 0xFFFF; 1716 packed_record[1] = (rec->key[0] >> 16) & 0xFFFF; 1717 1718 packed_record[2] = rec->key[1] & 0xFFFF; 1719 packed_record[3] = (rec->key[1] >> 16) & 0xFFFF; 1720 1721 packed_record[4] = rec->key[2] & 0xFFFF; 1722 packed_record[5] = (rec->key[2] >> 16) & 0xFFFF; 1723 1724 packed_record[6] = rec->key[3] & 0xFFFF; 1725 packed_record[7] = (rec->key[3] >> 16) & 0xFFFF; 1726 1727 packed_record[8] = rec->key[4] & 0xFFFF; 1728 packed_record[9] = (rec->key[4] >> 16) & 0xFFFF; 1729 1730 packed_record[10] = rec->key[5] & 0xFFFF; 1731 packed_record[11] = (rec->key[5] >> 16) & 0xFFFF; 1732 1733 packed_record[12] = rec->key[6] & 0xFFFF; 1734 packed_record[13] = (rec->key[6] >> 16) & 0xFFFF; 1735 1736 packed_record[14] = rec->key[7] & 0xFFFF; 1737 packed_record[15] = (rec->key[7] >> 16) & 0xFFFF; 1738 1739 ret = set_raw_egress_record(hw, packed_record, 8, 2, 1740 ROWOFFSET_EGRESSSAKEYRECORD + table_index); 1741 if (unlikely(ret)) 1742 return ret; 1743 ret = set_raw_egress_record(hw, packed_record + 8, 8, 2, 1744 ROWOFFSET_EGRESSSAKEYRECORD + table_index - 1745 32); 1746 if (unlikely(ret)) 1747 return ret; 1748 1749 return 0; 1750 } 1751 1752 int aq_mss_set_egress_sakey_record(struct aq_hw_s *hw, 1753 const struct aq_mss_egress_sakey_record *rec, 1754 u16 table_index) 1755 { 1756 int err = AQ_API_CALL_SAFE(set_egress_sakey_record, hw, rec, 1757 table_index); 1758 1759 WARN_ONCE(err, "%s failed with %d\n", __func__, err); 1760 1761 return err; 1762 } 1763 1764 static int get_egress_sakey_record(struct aq_hw_s *hw, 1765 struct aq_mss_egress_sakey_record *rec, 1766 u16 table_index) 1767 { 1768 u16 packed_record[16]; 1769 int ret; 1770 1771 if (table_index >= NUMROWS_EGRESSSAKEYRECORD) 1772 return -EINVAL; 1773 1774 ret = get_raw_egress_record(hw, packed_record, 8, 2, 1775 ROWOFFSET_EGRESSSAKEYRECORD + table_index); 1776 if (unlikely(ret)) 1777 return ret; 1778 ret = get_raw_egress_record(hw, packed_record + 8, 8, 2, 1779 ROWOFFSET_EGRESSSAKEYRECORD + table_index - 1780 32); 1781 if (unlikely(ret)) 1782 return ret; 1783 1784 rec->key[0] = packed_record[0]; 1785 rec->key[0] |= packed_record[1] << 16; 1786 1787 rec->key[1] = packed_record[2]; 1788 rec->key[1] |= packed_record[3] << 16; 1789 1790 rec->key[2] = packed_record[4]; 1791 rec->key[2] |= packed_record[5] << 16; 1792 1793 rec->key[3] = packed_record[6]; 1794 rec->key[3] |= packed_record[7] << 16; 1795 1796 rec->key[4] = packed_record[8]; 1797 rec->key[4] |= packed_record[9] << 16; 1798 1799 rec->key[5] = packed_record[10]; 1800 rec->key[5] |= packed_record[11] << 16; 1801 1802 rec->key[6] = packed_record[12]; 1803 rec->key[6] |= packed_record[13] << 16; 1804 1805 rec->key[7] = packed_record[14]; 1806 rec->key[7] |= packed_record[15] << 16; 1807 1808 return 0; 1809 } 1810 1811 int aq_mss_get_egress_sakey_record(struct aq_hw_s *hw, 1812 struct aq_mss_egress_sakey_record *rec, 1813 u16 table_index) 1814 { 1815 memset(rec, 0, sizeof(*rec)); 1816 1817 return AQ_API_CALL_SAFE(get_egress_sakey_record, hw, rec, table_index); 1818 } 1819 1820 static int get_egress_sc_counters(struct aq_hw_s *hw, 1821 struct aq_mss_egress_sc_counters *counters, 1822 u16 sc_index) 1823 { 1824 u16 packed_record[4]; 1825 int ret; 1826 1827 if (sc_index >= NUMROWS_EGRESSSCRECORD) 1828 return -EINVAL; 1829 1830 ret = get_raw_egress_record(hw, packed_record, 4, 3, sc_index * 8 + 4); 1831 if (unlikely(ret)) 1832 return ret; 1833 counters->sc_protected_pkts[0] = 1834 packed_record[0] | (packed_record[1] << 16); 1835 counters->sc_protected_pkts[1] = 1836 packed_record[2] | (packed_record[3] << 16); 1837 1838 ret = get_raw_egress_record(hw, packed_record, 4, 3, sc_index * 8 + 5); 1839 if (unlikely(ret)) 1840 return ret; 1841 counters->sc_encrypted_pkts[0] = 1842 packed_record[0] | (packed_record[1] << 16); 1843 counters->sc_encrypted_pkts[1] = 1844 packed_record[2] | (packed_record[3] << 16); 1845 1846 ret = get_raw_egress_record(hw, packed_record, 4, 3, sc_index * 8 + 6); 1847 if (unlikely(ret)) 1848 return ret; 1849 counters->sc_protected_octets[0] = 1850 packed_record[0] | (packed_record[1] << 16); 1851 counters->sc_protected_octets[1] = 1852 packed_record[2] | (packed_record[3] << 16); 1853 1854 ret = get_raw_egress_record(hw, packed_record, 4, 3, sc_index * 8 + 7); 1855 if (unlikely(ret)) 1856 return ret; 1857 counters->sc_encrypted_octets[0] = 1858 packed_record[0] | (packed_record[1] << 16); 1859 counters->sc_encrypted_octets[1] = 1860 packed_record[2] | (packed_record[3] << 16); 1861 1862 return 0; 1863 } 1864 1865 int aq_mss_get_egress_sc_counters(struct aq_hw_s *hw, 1866 struct aq_mss_egress_sc_counters *counters, 1867 u16 sc_index) 1868 { 1869 memset(counters, 0, sizeof(*counters)); 1870 1871 return AQ_API_CALL_SAFE(get_egress_sc_counters, hw, counters, sc_index); 1872 } 1873 1874 static int get_egress_sa_counters(struct aq_hw_s *hw, 1875 struct aq_mss_egress_sa_counters *counters, 1876 u16 sa_index) 1877 { 1878 u16 packed_record[4]; 1879 int ret; 1880 1881 if (sa_index >= NUMROWS_EGRESSSARECORD) 1882 return -EINVAL; 1883 1884 ret = get_raw_egress_record(hw, packed_record, 4, 3, sa_index * 8 + 0); 1885 if (unlikely(ret)) 1886 return ret; 1887 counters->sa_hit_drop_redirect[0] = 1888 packed_record[0] | (packed_record[1] << 16); 1889 counters->sa_hit_drop_redirect[1] = 1890 packed_record[2] | (packed_record[3] << 16); 1891 1892 ret = get_raw_egress_record(hw, packed_record, 4, 3, sa_index * 8 + 1); 1893 if (unlikely(ret)) 1894 return ret; 1895 counters->sa_protected2_pkts[0] = 1896 packed_record[0] | (packed_record[1] << 16); 1897 counters->sa_protected2_pkts[1] = 1898 packed_record[2] | (packed_record[3] << 16); 1899 1900 ret = get_raw_egress_record(hw, packed_record, 4, 3, sa_index * 8 + 2); 1901 if (unlikely(ret)) 1902 return ret; 1903 counters->sa_protected_pkts[0] = 1904 packed_record[0] | (packed_record[1] << 16); 1905 counters->sa_protected_pkts[1] = 1906 packed_record[2] | (packed_record[3] << 16); 1907 1908 ret = get_raw_egress_record(hw, packed_record, 4, 3, sa_index * 8 + 3); 1909 if (unlikely(ret)) 1910 return ret; 1911 counters->sa_encrypted_pkts[0] = 1912 packed_record[0] | (packed_record[1] << 16); 1913 counters->sa_encrypted_pkts[1] = 1914 packed_record[2] | (packed_record[3] << 16); 1915 1916 return 0; 1917 } 1918 1919 int aq_mss_get_egress_sa_counters(struct aq_hw_s *hw, 1920 struct aq_mss_egress_sa_counters *counters, 1921 u16 sa_index) 1922 { 1923 memset(counters, 0, sizeof(*counters)); 1924 1925 return AQ_API_CALL_SAFE(get_egress_sa_counters, hw, counters, sa_index); 1926 } 1927 1928 static int 1929 get_egress_common_counters(struct aq_hw_s *hw, 1930 struct aq_mss_egress_common_counters *counters) 1931 { 1932 u16 packed_record[4]; 1933 int ret; 1934 1935 ret = get_raw_egress_record(hw, packed_record, 4, 3, 256 + 0); 1936 if (unlikely(ret)) 1937 return ret; 1938 counters->ctl_pkt[0] = packed_record[0] | (packed_record[1] << 16); 1939 counters->ctl_pkt[1] = packed_record[2] | (packed_record[3] << 16); 1940 1941 ret = get_raw_egress_record(hw, packed_record, 4, 3, 256 + 1); 1942 if (unlikely(ret)) 1943 return ret; 1944 counters->unknown_sa_pkts[0] = 1945 packed_record[0] | (packed_record[1] << 16); 1946 counters->unknown_sa_pkts[1] = 1947 packed_record[2] | (packed_record[3] << 16); 1948 1949 ret = get_raw_egress_record(hw, packed_record, 4, 3, 256 + 2); 1950 if (unlikely(ret)) 1951 return ret; 1952 counters->untagged_pkts[0] = 1953 packed_record[0] | (packed_record[1] << 16); 1954 counters->untagged_pkts[1] = 1955 packed_record[2] | (packed_record[3] << 16); 1956 1957 ret = get_raw_egress_record(hw, packed_record, 4, 3, 256 + 3); 1958 if (unlikely(ret)) 1959 return ret; 1960 counters->too_long[0] = packed_record[0] | (packed_record[1] << 16); 1961 counters->too_long[1] = packed_record[2] | (packed_record[3] << 16); 1962 1963 ret = get_raw_egress_record(hw, packed_record, 4, 3, 256 + 4); 1964 if (unlikely(ret)) 1965 return ret; 1966 counters->ecc_error_pkts[0] = 1967 packed_record[0] | (packed_record[1] << 16); 1968 counters->ecc_error_pkts[1] = 1969 packed_record[2] | (packed_record[3] << 16); 1970 1971 ret = get_raw_egress_record(hw, packed_record, 4, 3, 256 + 5); 1972 if (unlikely(ret)) 1973 return ret; 1974 counters->unctrl_hit_drop_redir[0] = 1975 packed_record[0] | (packed_record[1] << 16); 1976 counters->unctrl_hit_drop_redir[1] = 1977 packed_record[2] | (packed_record[3] << 16); 1978 1979 return 0; 1980 } 1981 1982 int aq_mss_get_egress_common_counters(struct aq_hw_s *hw, 1983 struct aq_mss_egress_common_counters *counters) 1984 { 1985 memset(counters, 0, sizeof(*counters)); 1986 1987 return AQ_API_CALL_SAFE(get_egress_common_counters, hw, counters); 1988 } 1989 1990 static int clear_egress_counters(struct aq_hw_s *hw) 1991 { 1992 struct mss_egress_ctl_register ctl_reg; 1993 int ret; 1994 1995 memset(&ctl_reg, 0, sizeof(ctl_reg)); 1996 1997 ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1, MSS_EGRESS_CTL_REGISTER_ADDR, 1998 &ctl_reg.word_0); 1999 if (unlikely(ret)) 2000 return ret; 2001 ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1, 2002 MSS_EGRESS_CTL_REGISTER_ADDR + 4, 2003 &ctl_reg.word_1); 2004 if (unlikely(ret)) 2005 return ret; 2006 2007 /* Toggle the Egress MIB clear bit 0->1->0 */ 2008 ctl_reg.bits_0.clear_counter = 0; 2009 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1, 2010 MSS_EGRESS_CTL_REGISTER_ADDR, ctl_reg.word_0); 2011 if (unlikely(ret)) 2012 return ret; 2013 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1, 2014 MSS_EGRESS_CTL_REGISTER_ADDR + 4, 2015 ctl_reg.word_1); 2016 if (unlikely(ret)) 2017 return ret; 2018 2019 ctl_reg.bits_0.clear_counter = 1; 2020 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1, 2021 MSS_EGRESS_CTL_REGISTER_ADDR, ctl_reg.word_0); 2022 if (unlikely(ret)) 2023 return ret; 2024 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1, 2025 MSS_EGRESS_CTL_REGISTER_ADDR + 4, 2026 ctl_reg.word_1); 2027 if (unlikely(ret)) 2028 return ret; 2029 2030 ctl_reg.bits_0.clear_counter = 0; 2031 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1, 2032 MSS_EGRESS_CTL_REGISTER_ADDR, ctl_reg.word_0); 2033 if (unlikely(ret)) 2034 return ret; 2035 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1, 2036 MSS_EGRESS_CTL_REGISTER_ADDR + 4, 2037 ctl_reg.word_1); 2038 if (unlikely(ret)) 2039 return ret; 2040 2041 return 0; 2042 } 2043 2044 int aq_mss_clear_egress_counters(struct aq_hw_s *hw) 2045 { 2046 return AQ_API_CALL_SAFE(clear_egress_counters, hw); 2047 } 2048 2049 static int get_ingress_sa_counters(struct aq_hw_s *hw, 2050 struct aq_mss_ingress_sa_counters *counters, 2051 u16 sa_index) 2052 { 2053 u16 packed_record[4]; 2054 int ret; 2055 2056 if (sa_index >= NUMROWS_INGRESSSARECORD) 2057 return -EINVAL; 2058 2059 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 2060 sa_index * 12 + 0); 2061 if (unlikely(ret)) 2062 return ret; 2063 counters->untagged_hit_pkts[0] = 2064 packed_record[0] | (packed_record[1] << 16); 2065 counters->untagged_hit_pkts[1] = 2066 packed_record[2] | (packed_record[3] << 16); 2067 2068 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 2069 sa_index * 12 + 1); 2070 if (unlikely(ret)) 2071 return ret; 2072 counters->ctrl_hit_drop_redir_pkts[0] = 2073 packed_record[0] | (packed_record[1] << 16); 2074 counters->ctrl_hit_drop_redir_pkts[1] = 2075 packed_record[2] | (packed_record[3] << 16); 2076 2077 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 2078 sa_index * 12 + 2); 2079 if (unlikely(ret)) 2080 return ret; 2081 counters->not_using_sa[0] = packed_record[0] | (packed_record[1] << 16); 2082 counters->not_using_sa[1] = packed_record[2] | (packed_record[3] << 16); 2083 2084 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 2085 sa_index * 12 + 3); 2086 if (unlikely(ret)) 2087 return ret; 2088 counters->unused_sa[0] = packed_record[0] | (packed_record[1] << 16); 2089 counters->unused_sa[1] = packed_record[2] | (packed_record[3] << 16); 2090 2091 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 2092 sa_index * 12 + 4); 2093 if (unlikely(ret)) 2094 return ret; 2095 counters->not_valid_pkts[0] = 2096 packed_record[0] | (packed_record[1] << 16); 2097 counters->not_valid_pkts[1] = 2098 packed_record[2] | (packed_record[3] << 16); 2099 2100 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 2101 sa_index * 12 + 5); 2102 if (unlikely(ret)) 2103 return ret; 2104 counters->invalid_pkts[0] = packed_record[0] | (packed_record[1] << 16); 2105 counters->invalid_pkts[1] = packed_record[2] | (packed_record[3] << 16); 2106 2107 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 2108 sa_index * 12 + 6); 2109 if (unlikely(ret)) 2110 return ret; 2111 counters->ok_pkts[0] = packed_record[0] | (packed_record[1] << 16); 2112 counters->ok_pkts[1] = packed_record[2] | (packed_record[3] << 16); 2113 2114 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 2115 sa_index * 12 + 7); 2116 if (unlikely(ret)) 2117 return ret; 2118 counters->late_pkts[0] = packed_record[0] | (packed_record[1] << 16); 2119 counters->late_pkts[1] = packed_record[2] | (packed_record[3] << 16); 2120 2121 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 2122 sa_index * 12 + 8); 2123 if (unlikely(ret)) 2124 return ret; 2125 counters->delayed_pkts[0] = packed_record[0] | (packed_record[1] << 16); 2126 counters->delayed_pkts[1] = packed_record[2] | (packed_record[3] << 16); 2127 2128 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 2129 sa_index * 12 + 9); 2130 if (unlikely(ret)) 2131 return ret; 2132 counters->unchecked_pkts[0] = 2133 packed_record[0] | (packed_record[1] << 16); 2134 counters->unchecked_pkts[1] = 2135 packed_record[2] | (packed_record[3] << 16); 2136 2137 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 2138 sa_index * 12 + 10); 2139 if (unlikely(ret)) 2140 return ret; 2141 counters->validated_octets[0] = 2142 packed_record[0] | (packed_record[1] << 16); 2143 counters->validated_octets[1] = 2144 packed_record[2] | (packed_record[3] << 16); 2145 2146 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 2147 sa_index * 12 + 11); 2148 if (unlikely(ret)) 2149 return ret; 2150 counters->decrypted_octets[0] = 2151 packed_record[0] | (packed_record[1] << 16); 2152 counters->decrypted_octets[1] = 2153 packed_record[2] | (packed_record[3] << 16); 2154 2155 return 0; 2156 } 2157 2158 int aq_mss_get_ingress_sa_counters(struct aq_hw_s *hw, 2159 struct aq_mss_ingress_sa_counters *counters, 2160 u16 sa_index) 2161 { 2162 memset(counters, 0, sizeof(*counters)); 2163 2164 return AQ_API_CALL_SAFE(get_ingress_sa_counters, hw, counters, 2165 sa_index); 2166 } 2167 2168 static int 2169 get_ingress_common_counters(struct aq_hw_s *hw, 2170 struct aq_mss_ingress_common_counters *counters) 2171 { 2172 u16 packed_record[4]; 2173 int ret; 2174 2175 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 0); 2176 if (unlikely(ret)) 2177 return ret; 2178 counters->ctl_pkts[0] = packed_record[0] | (packed_record[1] << 16); 2179 counters->ctl_pkts[1] = packed_record[2] | (packed_record[3] << 16); 2180 2181 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 1); 2182 if (unlikely(ret)) 2183 return ret; 2184 counters->tagged_miss_pkts[0] = 2185 packed_record[0] | (packed_record[1] << 16); 2186 counters->tagged_miss_pkts[1] = 2187 packed_record[2] | (packed_record[3] << 16); 2188 2189 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 2); 2190 if (unlikely(ret)) 2191 return ret; 2192 counters->untagged_miss_pkts[0] = 2193 packed_record[0] | (packed_record[1] << 16); 2194 counters->untagged_miss_pkts[1] = 2195 packed_record[2] | (packed_record[3] << 16); 2196 2197 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 3); 2198 if (unlikely(ret)) 2199 return ret; 2200 counters->notag_pkts[0] = packed_record[0] | (packed_record[1] << 16); 2201 counters->notag_pkts[1] = packed_record[2] | (packed_record[3] << 16); 2202 2203 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 4); 2204 if (unlikely(ret)) 2205 return ret; 2206 counters->untagged_pkts[0] = 2207 packed_record[0] | (packed_record[1] << 16); 2208 counters->untagged_pkts[1] = 2209 packed_record[2] | (packed_record[3] << 16); 2210 2211 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 5); 2212 if (unlikely(ret)) 2213 return ret; 2214 counters->bad_tag_pkts[0] = packed_record[0] | (packed_record[1] << 16); 2215 counters->bad_tag_pkts[1] = packed_record[2] | (packed_record[3] << 16); 2216 2217 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 6); 2218 if (unlikely(ret)) 2219 return ret; 2220 counters->no_sci_pkts[0] = packed_record[0] | (packed_record[1] << 16); 2221 counters->no_sci_pkts[1] = packed_record[2] | (packed_record[3] << 16); 2222 2223 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 7); 2224 if (unlikely(ret)) 2225 return ret; 2226 counters->unknown_sci_pkts[0] = 2227 packed_record[0] | (packed_record[1] << 16); 2228 counters->unknown_sci_pkts[1] = 2229 packed_record[2] | (packed_record[3] << 16); 2230 2231 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 8); 2232 if (unlikely(ret)) 2233 return ret; 2234 counters->ctrl_prt_pass_pkts[0] = 2235 packed_record[0] | (packed_record[1] << 16); 2236 counters->ctrl_prt_pass_pkts[1] = 2237 packed_record[2] | (packed_record[3] << 16); 2238 2239 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 9); 2240 if (unlikely(ret)) 2241 return ret; 2242 counters->unctrl_prt_pass_pkts[0] = 2243 packed_record[0] | (packed_record[1] << 16); 2244 counters->unctrl_prt_pass_pkts[1] = 2245 packed_record[2] | (packed_record[3] << 16); 2246 2247 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 10); 2248 if (unlikely(ret)) 2249 return ret; 2250 counters->ctrl_prt_fail_pkts[0] = 2251 packed_record[0] | (packed_record[1] << 16); 2252 counters->ctrl_prt_fail_pkts[1] = 2253 packed_record[2] | (packed_record[3] << 16); 2254 2255 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 11); 2256 if (unlikely(ret)) 2257 return ret; 2258 counters->unctrl_prt_fail_pkts[0] = 2259 packed_record[0] | (packed_record[1] << 16); 2260 counters->unctrl_prt_fail_pkts[1] = 2261 packed_record[2] | (packed_record[3] << 16); 2262 2263 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 12); 2264 if (unlikely(ret)) 2265 return ret; 2266 counters->too_long_pkts[0] = 2267 packed_record[0] | (packed_record[1] << 16); 2268 counters->too_long_pkts[1] = 2269 packed_record[2] | (packed_record[3] << 16); 2270 2271 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 13); 2272 if (unlikely(ret)) 2273 return ret; 2274 counters->igpoc_ctl_pkts[0] = 2275 packed_record[0] | (packed_record[1] << 16); 2276 counters->igpoc_ctl_pkts[1] = 2277 packed_record[2] | (packed_record[3] << 16); 2278 2279 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 14); 2280 if (unlikely(ret)) 2281 return ret; 2282 counters->ecc_error_pkts[0] = 2283 packed_record[0] | (packed_record[1] << 16); 2284 counters->ecc_error_pkts[1] = 2285 packed_record[2] | (packed_record[3] << 16); 2286 2287 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 15); 2288 if (unlikely(ret)) 2289 return ret; 2290 counters->unctrl_hit_drop_redir[0] = 2291 packed_record[0] | (packed_record[1] << 16); 2292 counters->unctrl_hit_drop_redir[1] = 2293 packed_record[2] | (packed_record[3] << 16); 2294 2295 return 0; 2296 } 2297 2298 int aq_mss_get_ingress_common_counters(struct aq_hw_s *hw, 2299 struct aq_mss_ingress_common_counters *counters) 2300 { 2301 memset(counters, 0, sizeof(*counters)); 2302 2303 return AQ_API_CALL_SAFE(get_ingress_common_counters, hw, counters); 2304 } 2305 2306 static int clear_ingress_counters(struct aq_hw_s *hw) 2307 { 2308 struct mss_ingress_ctl_register ctl_reg; 2309 int ret; 2310 2311 memset(&ctl_reg, 0, sizeof(ctl_reg)); 2312 2313 ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1, 2314 MSS_INGRESS_CTL_REGISTER_ADDR, &ctl_reg.word_0); 2315 if (unlikely(ret)) 2316 return ret; 2317 ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1, 2318 MSS_INGRESS_CTL_REGISTER_ADDR + 4, 2319 &ctl_reg.word_1); 2320 if (unlikely(ret)) 2321 return ret; 2322 2323 /* Toggle the Ingress MIB clear bit 0->1->0 */ 2324 ctl_reg.bits_0.clear_count = 0; 2325 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1, 2326 MSS_INGRESS_CTL_REGISTER_ADDR, ctl_reg.word_0); 2327 if (unlikely(ret)) 2328 return ret; 2329 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1, 2330 MSS_INGRESS_CTL_REGISTER_ADDR + 4, 2331 ctl_reg.word_1); 2332 if (unlikely(ret)) 2333 return ret; 2334 2335 ctl_reg.bits_0.clear_count = 1; 2336 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1, 2337 MSS_INGRESS_CTL_REGISTER_ADDR, ctl_reg.word_0); 2338 if (unlikely(ret)) 2339 return ret; 2340 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1, 2341 MSS_INGRESS_CTL_REGISTER_ADDR + 4, 2342 ctl_reg.word_1); 2343 if (unlikely(ret)) 2344 return ret; 2345 2346 ctl_reg.bits_0.clear_count = 0; 2347 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1, 2348 MSS_INGRESS_CTL_REGISTER_ADDR, ctl_reg.word_0); 2349 if (unlikely(ret)) 2350 return ret; 2351 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1, 2352 MSS_INGRESS_CTL_REGISTER_ADDR + 4, 2353 ctl_reg.word_1); 2354 if (unlikely(ret)) 2355 return ret; 2356 2357 return 0; 2358 } 2359 2360 int aq_mss_clear_ingress_counters(struct aq_hw_s *hw) 2361 { 2362 return AQ_API_CALL_SAFE(clear_ingress_counters, hw); 2363 } 2364 2365 static int get_egress_sa_expired(struct aq_hw_s *hw, u32 *expired) 2366 { 2367 u16 val; 2368 int ret; 2369 2370 ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1, 2371 MSS_EGRESS_SA_EXPIRED_STATUS_REGISTER_ADDR, 2372 &val); 2373 if (unlikely(ret)) 2374 return ret; 2375 2376 *expired = val; 2377 2378 ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1, 2379 MSS_EGRESS_SA_EXPIRED_STATUS_REGISTER_ADDR + 1, 2380 &val); 2381 if (unlikely(ret)) 2382 return ret; 2383 2384 *expired |= val << 16; 2385 2386 return 0; 2387 } 2388 2389 int aq_mss_get_egress_sa_expired(struct aq_hw_s *hw, u32 *expired) 2390 { 2391 *expired = 0; 2392 2393 return AQ_API_CALL_SAFE(get_egress_sa_expired, hw, expired); 2394 } 2395 2396 static int get_egress_sa_threshold_expired(struct aq_hw_s *hw, 2397 u32 *expired) 2398 { 2399 u16 val; 2400 int ret; 2401 2402 ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1, 2403 MSS_EGRESS_SA_THRESHOLD_EXPIRED_STATUS_REGISTER_ADDR, &val); 2404 if (unlikely(ret)) 2405 return ret; 2406 2407 *expired = val; 2408 2409 ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1, 2410 MSS_EGRESS_SA_THRESHOLD_EXPIRED_STATUS_REGISTER_ADDR + 1, &val); 2411 if (unlikely(ret)) 2412 return ret; 2413 2414 *expired |= val << 16; 2415 2416 return 0; 2417 } 2418 2419 int aq_mss_get_egress_sa_threshold_expired(struct aq_hw_s *hw, 2420 u32 *expired) 2421 { 2422 *expired = 0; 2423 2424 return AQ_API_CALL_SAFE(get_egress_sa_threshold_expired, hw, expired); 2425 } 2426 2427 static int set_egress_sa_expired(struct aq_hw_s *hw, u32 expired) 2428 { 2429 int ret; 2430 2431 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1, 2432 MSS_EGRESS_SA_EXPIRED_STATUS_REGISTER_ADDR, 2433 expired & 0xFFFF); 2434 if (unlikely(ret)) 2435 return ret; 2436 2437 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1, 2438 MSS_EGRESS_SA_EXPIRED_STATUS_REGISTER_ADDR + 1, 2439 expired >> 16); 2440 if (unlikely(ret)) 2441 return ret; 2442 2443 return 0; 2444 } 2445 2446 int aq_mss_set_egress_sa_expired(struct aq_hw_s *hw, u32 expired) 2447 { 2448 return AQ_API_CALL_SAFE(set_egress_sa_expired, hw, expired); 2449 } 2450 2451 static int set_egress_sa_threshold_expired(struct aq_hw_s *hw, u32 expired) 2452 { 2453 int ret; 2454 2455 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1, 2456 MSS_EGRESS_SA_THRESHOLD_EXPIRED_STATUS_REGISTER_ADDR, 2457 expired & 0xFFFF); 2458 if (unlikely(ret)) 2459 return ret; 2460 2461 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1, 2462 MSS_EGRESS_SA_THRESHOLD_EXPIRED_STATUS_REGISTER_ADDR + 1, 2463 expired >> 16); 2464 if (unlikely(ret)) 2465 return ret; 2466 2467 return 0; 2468 } 2469 2470 int aq_mss_set_egress_sa_threshold_expired(struct aq_hw_s *hw, u32 expired) 2471 { 2472 return AQ_API_CALL_SAFE(set_egress_sa_threshold_expired, hw, expired); 2473 } 2474