1 // SPDX-License-Identifier: GPL-2.0 2 /* Marvell MCS driver 3 * 4 * Copyright (C) 2022 Marvell. 5 */ 6 7 #include <linux/bitfield.h> 8 #include <linux/delay.h> 9 #include <linux/device.h> 10 #include <linux/module.h> 11 #include <linux/pci.h> 12 13 #include "mcs.h" 14 #include "mcs_reg.h" 15 16 #define DRV_NAME "Marvell MCS Driver" 17 18 #define PCI_CFG_REG_BAR_NUM 0 19 20 static const struct pci_device_id mcs_id_table[] = { 21 { PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_CN10K_MCS) }, 22 { 0, } /* end of table */ 23 }; 24 25 static LIST_HEAD(mcs_list); 26 27 void mcs_get_tx_secy_stats(struct mcs *mcs, struct mcs_secy_stats *stats, int id) 28 { 29 u64 reg; 30 31 reg = MCSX_CSE_TX_MEM_SLAVE_IFOUTCTLBCPKTSX(id); 32 stats->ctl_pkt_bcast_cnt = mcs_reg_read(mcs, reg); 33 34 reg = MCSX_CSE_TX_MEM_SLAVE_IFOUTCTLMCPKTSX(id); 35 stats->ctl_pkt_mcast_cnt = mcs_reg_read(mcs, reg); 36 37 reg = MCSX_CSE_TX_MEM_SLAVE_IFOUTCTLOCTETSX(id); 38 stats->ctl_octet_cnt = mcs_reg_read(mcs, reg); 39 40 reg = MCSX_CSE_TX_MEM_SLAVE_IFOUTCTLUCPKTSX(id); 41 stats->ctl_pkt_ucast_cnt = mcs_reg_read(mcs, reg); 42 43 reg = MCSX_CSE_TX_MEM_SLAVE_IFOUTUNCTLBCPKTSX(id); 44 stats->unctl_pkt_bcast_cnt = mcs_reg_read(mcs, reg); 45 46 reg = MCSX_CSE_TX_MEM_SLAVE_IFOUTUNCTLMCPKTSX(id); 47 stats->unctl_pkt_mcast_cnt = mcs_reg_read(mcs, reg); 48 49 reg = MCSX_CSE_TX_MEM_SLAVE_IFOUTUNCTLOCTETSX(id); 50 stats->unctl_octet_cnt = mcs_reg_read(mcs, reg); 51 52 reg = MCSX_CSE_TX_MEM_SLAVE_IFOUTUNCTLUCPKTSX(id); 53 stats->unctl_pkt_ucast_cnt = mcs_reg_read(mcs, reg); 54 55 reg = MCSX_CSE_TX_MEM_SLAVE_OUTOCTETSSECYENCRYPTEDX(id); 56 stats->octet_encrypted_cnt = mcs_reg_read(mcs, reg); 57 58 reg = MCSX_CSE_TX_MEM_SLAVE_OUTOCTETSSECYPROTECTEDX(id); 59 stats->octet_protected_cnt = mcs_reg_read(mcs, reg); 60 61 reg = MCSX_CSE_TX_MEM_SLAVE_OUTPKTSSECYNOACTIVESAX(id); 62 stats->pkt_noactivesa_cnt = mcs_reg_read(mcs, reg); 63 64 reg = MCSX_CSE_TX_MEM_SLAVE_OUTPKTSSECYTOOLONGX(id); 65 stats->pkt_toolong_cnt = mcs_reg_read(mcs, reg); 66 67 reg = MCSX_CSE_TX_MEM_SLAVE_OUTPKTSSECYUNTAGGEDX(id); 68 stats->pkt_untagged_cnt = mcs_reg_read(mcs, reg); 69 } 70 71 void mcs_get_rx_secy_stats(struct mcs *mcs, struct mcs_secy_stats *stats, int id) 72 { 73 u64 reg; 74 75 reg = MCSX_CSE_RX_MEM_SLAVE_IFINCTLBCPKTSX(id); 76 stats->ctl_pkt_bcast_cnt = mcs_reg_read(mcs, reg); 77 78 reg = MCSX_CSE_RX_MEM_SLAVE_IFINCTLMCPKTSX(id); 79 stats->ctl_pkt_mcast_cnt = mcs_reg_read(mcs, reg); 80 81 reg = MCSX_CSE_RX_MEM_SLAVE_IFINCTLOCTETSX(id); 82 stats->ctl_octet_cnt = mcs_reg_read(mcs, reg); 83 84 reg = MCSX_CSE_RX_MEM_SLAVE_IFINCTLUCPKTSX(id); 85 stats->ctl_pkt_ucast_cnt = mcs_reg_read(mcs, reg); 86 87 reg = MCSX_CSE_RX_MEM_SLAVE_IFINUNCTLBCPKTSX(id); 88 stats->unctl_pkt_bcast_cnt = mcs_reg_read(mcs, reg); 89 90 reg = MCSX_CSE_RX_MEM_SLAVE_IFINUNCTLMCPKTSX(id); 91 stats->unctl_pkt_mcast_cnt = mcs_reg_read(mcs, reg); 92 93 reg = MCSX_CSE_RX_MEM_SLAVE_IFINUNCTLOCTETSX(id); 94 stats->unctl_octet_cnt = mcs_reg_read(mcs, reg); 95 96 reg = MCSX_CSE_RX_MEM_SLAVE_IFINUNCTLUCPKTSX(id); 97 stats->unctl_pkt_ucast_cnt = mcs_reg_read(mcs, reg); 98 99 reg = MCSX_CSE_RX_MEM_SLAVE_INOCTETSSECYDECRYPTEDX(id); 100 stats->octet_decrypted_cnt = mcs_reg_read(mcs, reg); 101 102 reg = MCSX_CSE_RX_MEM_SLAVE_INOCTETSSECYVALIDATEX(id); 103 stats->octet_validated_cnt = mcs_reg_read(mcs, reg); 104 105 reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSCTRLPORTDISABLEDX(id); 106 stats->pkt_port_disabled_cnt = mcs_reg_read(mcs, reg); 107 108 reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYBADTAGX(id); 109 stats->pkt_badtag_cnt = mcs_reg_read(mcs, reg); 110 111 reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYNOSAX(id); 112 stats->pkt_nosa_cnt = mcs_reg_read(mcs, reg); 113 114 reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYNOSAERRORX(id); 115 stats->pkt_nosaerror_cnt = mcs_reg_read(mcs, reg); 116 117 reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYTAGGEDCTLX(id); 118 stats->pkt_tagged_ctl_cnt = mcs_reg_read(mcs, reg); 119 120 reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYUNTAGGEDORNOTAGX(id); 121 stats->pkt_untaged_cnt = mcs_reg_read(mcs, reg); 122 123 reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYCTLX(id); 124 stats->pkt_ctl_cnt = mcs_reg_read(mcs, reg); 125 126 if (mcs->hw->mcs_blks > 1) { 127 reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYNOTAGX(id); 128 stats->pkt_notag_cnt = mcs_reg_read(mcs, reg); 129 } 130 } 131 132 void mcs_get_flowid_stats(struct mcs *mcs, struct mcs_flowid_stats *stats, 133 int id, int dir) 134 { 135 u64 reg; 136 137 if (dir == MCS_RX) 138 reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSFLOWIDTCAMHITX(id); 139 else 140 reg = MCSX_CSE_TX_MEM_SLAVE_OUTPKTSFLOWIDTCAMHITX(id); 141 142 stats->tcam_hit_cnt = mcs_reg_read(mcs, reg); 143 } 144 145 void mcs_get_port_stats(struct mcs *mcs, struct mcs_port_stats *stats, 146 int id, int dir) 147 { 148 u64 reg; 149 150 if (dir == MCS_RX) { 151 reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSFLOWIDTCAMMISSX(id); 152 stats->tcam_miss_cnt = mcs_reg_read(mcs, reg); 153 154 reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSPARSEERRX(id); 155 stats->parser_err_cnt = mcs_reg_read(mcs, reg); 156 if (mcs->hw->mcs_blks > 1) { 157 reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSEARLYPREEMPTERRX(id); 158 stats->preempt_err_cnt = mcs_reg_read(mcs, reg); 159 } 160 } else { 161 reg = MCSX_CSE_TX_MEM_SLAVE_OUTPKTSFLOWIDTCAMMISSX(id); 162 stats->tcam_miss_cnt = mcs_reg_read(mcs, reg); 163 164 reg = MCSX_CSE_TX_MEM_SLAVE_OUTPKTSPARSEERRX(id); 165 stats->parser_err_cnt = mcs_reg_read(mcs, reg); 166 167 reg = MCSX_CSE_TX_MEM_SLAVE_OUTPKTSSECTAGINSERTIONERRX(id); 168 stats->sectag_insert_err_cnt = mcs_reg_read(mcs, reg); 169 } 170 } 171 172 void mcs_get_sa_stats(struct mcs *mcs, struct mcs_sa_stats *stats, int id, int dir) 173 { 174 u64 reg; 175 176 if (dir == MCS_RX) { 177 reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSAINVALIDX(id); 178 stats->pkt_invalid_cnt = mcs_reg_read(mcs, reg); 179 180 reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSANOTUSINGSAERRORX(id); 181 stats->pkt_nosaerror_cnt = mcs_reg_read(mcs, reg); 182 183 reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSANOTVALIDX(id); 184 stats->pkt_notvalid_cnt = mcs_reg_read(mcs, reg); 185 186 reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSAOKX(id); 187 stats->pkt_ok_cnt = mcs_reg_read(mcs, reg); 188 189 reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSAUNUSEDSAX(id); 190 stats->pkt_nosa_cnt = mcs_reg_read(mcs, reg); 191 } else { 192 reg = MCSX_CSE_TX_MEM_SLAVE_OUTPKTSSAENCRYPTEDX(id); 193 stats->pkt_encrypt_cnt = mcs_reg_read(mcs, reg); 194 195 reg = MCSX_CSE_TX_MEM_SLAVE_OUTPKTSSAPROTECTEDX(id); 196 stats->pkt_protected_cnt = mcs_reg_read(mcs, reg); 197 } 198 } 199 200 void mcs_get_sc_stats(struct mcs *mcs, struct mcs_sc_stats *stats, 201 int id, int dir) 202 { 203 u64 reg; 204 205 if (dir == MCS_RX) { 206 reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSCCAMHITX(id); 207 stats->hit_cnt = mcs_reg_read(mcs, reg); 208 209 reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSCINVALIDX(id); 210 stats->pkt_invalid_cnt = mcs_reg_read(mcs, reg); 211 212 reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSCLATEORDELAYEDX(id); 213 stats->pkt_late_cnt = mcs_reg_read(mcs, reg); 214 215 reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSCNOTVALIDX(id); 216 stats->pkt_notvalid_cnt = mcs_reg_read(mcs, reg); 217 218 reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSCUNCHECKEDOROKX(id); 219 stats->pkt_unchecked_cnt = mcs_reg_read(mcs, reg); 220 221 if (mcs->hw->mcs_blks > 1) { 222 reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSCDELAYEDX(id); 223 stats->pkt_delay_cnt = mcs_reg_read(mcs, reg); 224 225 reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSCOKX(id); 226 stats->pkt_ok_cnt = mcs_reg_read(mcs, reg); 227 } 228 if (mcs->hw->mcs_blks == 1) { 229 reg = MCSX_CSE_RX_MEM_SLAVE_INOCTETSSCDECRYPTEDX(id); 230 stats->octet_decrypt_cnt = mcs_reg_read(mcs, reg); 231 232 reg = MCSX_CSE_RX_MEM_SLAVE_INOCTETSSCVALIDATEX(id); 233 stats->octet_validate_cnt = mcs_reg_read(mcs, reg); 234 } 235 } else { 236 reg = MCSX_CSE_TX_MEM_SLAVE_OUTPKTSSCENCRYPTEDX(id); 237 stats->pkt_encrypt_cnt = mcs_reg_read(mcs, reg); 238 239 reg = MCSX_CSE_TX_MEM_SLAVE_OUTPKTSSCPROTECTEDX(id); 240 stats->pkt_protected_cnt = mcs_reg_read(mcs, reg); 241 242 if (mcs->hw->mcs_blks == 1) { 243 reg = MCSX_CSE_TX_MEM_SLAVE_OUTOCTETSSCENCRYPTEDX(id); 244 stats->octet_encrypt_cnt = mcs_reg_read(mcs, reg); 245 246 reg = MCSX_CSE_TX_MEM_SLAVE_OUTOCTETSSCPROTECTEDX(id); 247 stats->octet_protected_cnt = mcs_reg_read(mcs, reg); 248 } 249 } 250 } 251 252 void mcs_clear_stats(struct mcs *mcs, u8 type, u8 id, int dir) 253 { 254 struct mcs_flowid_stats flowid_st; 255 struct mcs_port_stats port_st; 256 struct mcs_secy_stats secy_st; 257 struct mcs_sc_stats sc_st; 258 struct mcs_sa_stats sa_st; 259 u64 reg; 260 261 if (dir == MCS_RX) 262 reg = MCSX_CSE_RX_SLAVE_CTRL; 263 else 264 reg = MCSX_CSE_TX_SLAVE_CTRL; 265 266 mcs_reg_write(mcs, reg, BIT_ULL(0)); 267 268 switch (type) { 269 case MCS_FLOWID_STATS: 270 mcs_get_flowid_stats(mcs, &flowid_st, id, dir); 271 break; 272 case MCS_SECY_STATS: 273 if (dir == MCS_RX) 274 mcs_get_rx_secy_stats(mcs, &secy_st, id); 275 else 276 mcs_get_tx_secy_stats(mcs, &secy_st, id); 277 break; 278 case MCS_SC_STATS: 279 mcs_get_sc_stats(mcs, &sc_st, id, dir); 280 break; 281 case MCS_SA_STATS: 282 mcs_get_sa_stats(mcs, &sa_st, id, dir); 283 break; 284 case MCS_PORT_STATS: 285 mcs_get_port_stats(mcs, &port_st, id, dir); 286 break; 287 } 288 289 mcs_reg_write(mcs, reg, 0x0); 290 } 291 292 int mcs_clear_all_stats(struct mcs *mcs, u16 pcifunc, int dir) 293 { 294 struct mcs_rsrc_map *map; 295 int id; 296 297 if (dir == MCS_RX) 298 map = &mcs->rx; 299 else 300 map = &mcs->tx; 301 302 /* Clear FLOWID stats */ 303 for (id = 0; id < map->flow_ids.max; id++) { 304 if (map->flowid2pf_map[id] != pcifunc) 305 continue; 306 mcs_clear_stats(mcs, MCS_FLOWID_STATS, id, dir); 307 } 308 309 /* Clear SECY stats */ 310 for (id = 0; id < map->secy.max; id++) { 311 if (map->secy2pf_map[id] != pcifunc) 312 continue; 313 mcs_clear_stats(mcs, MCS_SECY_STATS, id, dir); 314 } 315 316 /* Clear SC stats */ 317 for (id = 0; id < map->secy.max; id++) { 318 if (map->sc2pf_map[id] != pcifunc) 319 continue; 320 mcs_clear_stats(mcs, MCS_SC_STATS, id, dir); 321 } 322 323 /* Clear SA stats */ 324 for (id = 0; id < map->sa.max; id++) { 325 if (map->sa2pf_map[id] != pcifunc) 326 continue; 327 mcs_clear_stats(mcs, MCS_SA_STATS, id, dir); 328 } 329 return 0; 330 } 331 332 void mcs_pn_table_write(struct mcs *mcs, u8 pn_id, u64 next_pn, u8 dir) 333 { 334 u64 reg; 335 336 if (dir == MCS_RX) 337 reg = MCSX_CPM_RX_SLAVE_SA_PN_TABLE_MEMX(pn_id); 338 else 339 reg = MCSX_CPM_TX_SLAVE_SA_PN_TABLE_MEMX(pn_id); 340 mcs_reg_write(mcs, reg, next_pn); 341 } 342 343 void cn10kb_mcs_tx_sa_mem_map_write(struct mcs *mcs, struct mcs_tx_sc_sa_map *map) 344 { 345 u64 reg, val; 346 347 val = (map->sa_index0 & 0xFF) | 348 (map->sa_index1 & 0xFF) << 9 | 349 (map->rekey_ena & 0x1) << 18 | 350 (map->sa_index0_vld & 0x1) << 19 | 351 (map->sa_index1_vld & 0x1) << 20 | 352 (map->tx_sa_active & 0x1) << 21 | 353 map->sectag_sci << 22; 354 reg = MCSX_CPM_TX_SLAVE_SA_MAP_MEM_0X(map->sc_id); 355 mcs_reg_write(mcs, reg, val); 356 357 val = map->sectag_sci >> 42; 358 reg = MCSX_CPM_TX_SLAVE_SA_MAP_MEM_1X(map->sc_id); 359 mcs_reg_write(mcs, reg, val); 360 } 361 362 void cn10kb_mcs_rx_sa_mem_map_write(struct mcs *mcs, struct mcs_rx_sc_sa_map *map) 363 { 364 u64 val, reg; 365 366 val = (map->sa_index & 0xFF) | map->sa_in_use << 9; 367 368 reg = MCSX_CPM_RX_SLAVE_SA_MAP_MEMX((4 * map->sc_id) + map->an); 369 mcs_reg_write(mcs, reg, val); 370 } 371 372 void mcs_sa_plcy_write(struct mcs *mcs, u64 *plcy, int sa_id, int dir) 373 { 374 int reg_id; 375 u64 reg; 376 377 if (dir == MCS_RX) { 378 for (reg_id = 0; reg_id < 8; reg_id++) { 379 reg = MCSX_CPM_RX_SLAVE_SA_PLCY_MEMX(reg_id, sa_id); 380 mcs_reg_write(mcs, reg, plcy[reg_id]); 381 } 382 } else { 383 for (reg_id = 0; reg_id < 9; reg_id++) { 384 reg = MCSX_CPM_TX_SLAVE_SA_PLCY_MEMX(reg_id, sa_id); 385 mcs_reg_write(mcs, reg, plcy[reg_id]); 386 } 387 } 388 } 389 390 void mcs_ena_dis_sc_cam_entry(struct mcs *mcs, int sc_id, int ena) 391 { 392 u64 reg, val; 393 394 reg = MCSX_CPM_RX_SLAVE_SC_CAM_ENA(0); 395 if (sc_id > 63) 396 reg = MCSX_CPM_RX_SLAVE_SC_CAM_ENA(1); 397 398 if (ena) 399 val = mcs_reg_read(mcs, reg) | BIT_ULL(sc_id); 400 else 401 val = mcs_reg_read(mcs, reg) & ~BIT_ULL(sc_id); 402 403 mcs_reg_write(mcs, reg, val); 404 } 405 406 void mcs_rx_sc_cam_write(struct mcs *mcs, u64 sci, u64 secy, int sc_id) 407 { 408 mcs_reg_write(mcs, MCSX_CPM_RX_SLAVE_SC_CAMX(0, sc_id), sci); 409 mcs_reg_write(mcs, MCSX_CPM_RX_SLAVE_SC_CAMX(1, sc_id), secy); 410 /* Enable SC CAM */ 411 mcs_ena_dis_sc_cam_entry(mcs, sc_id, true); 412 } 413 414 void mcs_secy_plcy_write(struct mcs *mcs, u64 plcy, int secy_id, int dir) 415 { 416 u64 reg; 417 418 if (dir == MCS_RX) 419 reg = MCSX_CPM_RX_SLAVE_SECY_PLCY_MEM_0X(secy_id); 420 else 421 reg = MCSX_CPM_TX_SLAVE_SECY_PLCY_MEMX(secy_id); 422 423 mcs_reg_write(mcs, reg, plcy); 424 425 if (mcs->hw->mcs_blks == 1 && dir == MCS_RX) 426 mcs_reg_write(mcs, MCSX_CPM_RX_SLAVE_SECY_PLCY_MEM_1X(secy_id), 0x0ull); 427 } 428 429 void cn10kb_mcs_flowid_secy_map(struct mcs *mcs, struct secy_mem_map *map, int dir) 430 { 431 u64 reg, val; 432 433 val = (map->secy & 0x7F) | (map->ctrl_pkt & 0x1) << 8; 434 if (dir == MCS_RX) { 435 reg = MCSX_CPM_RX_SLAVE_SECY_MAP_MEMX(map->flow_id); 436 } else { 437 val |= (map->sc & 0x7F) << 9; 438 reg = MCSX_CPM_TX_SLAVE_SECY_MAP_MEM_0X(map->flow_id); 439 } 440 441 mcs_reg_write(mcs, reg, val); 442 } 443 444 void mcs_ena_dis_flowid_entry(struct mcs *mcs, int flow_id, int dir, int ena) 445 { 446 u64 reg, val; 447 448 if (dir == MCS_RX) { 449 reg = MCSX_CPM_RX_SLAVE_FLOWID_TCAM_ENA_0; 450 if (flow_id > 63) 451 reg = MCSX_CPM_RX_SLAVE_FLOWID_TCAM_ENA_1; 452 } else { 453 reg = MCSX_CPM_TX_SLAVE_FLOWID_TCAM_ENA_0; 454 if (flow_id > 63) 455 reg = MCSX_CPM_TX_SLAVE_FLOWID_TCAM_ENA_1; 456 } 457 458 /* Enable/Disable the tcam entry */ 459 if (ena) 460 val = mcs_reg_read(mcs, reg) | BIT_ULL(flow_id); 461 else 462 val = mcs_reg_read(mcs, reg) & ~BIT_ULL(flow_id); 463 464 mcs_reg_write(mcs, reg, val); 465 } 466 467 void mcs_flowid_entry_write(struct mcs *mcs, u64 *data, u64 *mask, int flow_id, int dir) 468 { 469 int reg_id; 470 u64 reg; 471 472 if (dir == MCS_RX) { 473 for (reg_id = 0; reg_id < 4; reg_id++) { 474 reg = MCSX_CPM_RX_SLAVE_FLOWID_TCAM_DATAX(reg_id, flow_id); 475 mcs_reg_write(mcs, reg, data[reg_id]); 476 } 477 for (reg_id = 0; reg_id < 4; reg_id++) { 478 reg = MCSX_CPM_RX_SLAVE_FLOWID_TCAM_MASKX(reg_id, flow_id); 479 mcs_reg_write(mcs, reg, mask[reg_id]); 480 } 481 } else { 482 for (reg_id = 0; reg_id < 4; reg_id++) { 483 reg = MCSX_CPM_TX_SLAVE_FLOWID_TCAM_DATAX(reg_id, flow_id); 484 mcs_reg_write(mcs, reg, data[reg_id]); 485 } 486 for (reg_id = 0; reg_id < 4; reg_id++) { 487 reg = MCSX_CPM_TX_SLAVE_FLOWID_TCAM_MASKX(reg_id, flow_id); 488 mcs_reg_write(mcs, reg, mask[reg_id]); 489 } 490 } 491 } 492 493 int mcs_install_flowid_bypass_entry(struct mcs *mcs) 494 { 495 int flow_id, secy_id, reg_id; 496 struct secy_mem_map map; 497 u64 reg, plcy = 0; 498 499 /* Flow entry */ 500 flow_id = mcs->hw->tcam_entries - MCS_RSRC_RSVD_CNT; 501 __set_bit(flow_id, mcs->rx.flow_ids.bmap); 502 __set_bit(flow_id, mcs->tx.flow_ids.bmap); 503 504 for (reg_id = 0; reg_id < 4; reg_id++) { 505 reg = MCSX_CPM_RX_SLAVE_FLOWID_TCAM_MASKX(reg_id, flow_id); 506 mcs_reg_write(mcs, reg, GENMASK_ULL(63, 0)); 507 } 508 for (reg_id = 0; reg_id < 4; reg_id++) { 509 reg = MCSX_CPM_TX_SLAVE_FLOWID_TCAM_MASKX(reg_id, flow_id); 510 mcs_reg_write(mcs, reg, GENMASK_ULL(63, 0)); 511 } 512 /* secy */ 513 secy_id = mcs->hw->secy_entries - MCS_RSRC_RSVD_CNT; 514 __set_bit(secy_id, mcs->rx.secy.bmap); 515 __set_bit(secy_id, mcs->tx.secy.bmap); 516 517 /* Set validate frames to NULL and enable control port */ 518 plcy = 0x7ull; 519 if (mcs->hw->mcs_blks > 1) 520 plcy = BIT_ULL(0) | 0x3ull << 4; 521 mcs_secy_plcy_write(mcs, plcy, secy_id, MCS_RX); 522 523 /* Enable control port and set mtu to max */ 524 plcy = BIT_ULL(0) | GENMASK_ULL(43, 28); 525 if (mcs->hw->mcs_blks > 1) 526 plcy = BIT_ULL(0) | GENMASK_ULL(63, 48); 527 mcs_secy_plcy_write(mcs, plcy, secy_id, MCS_TX); 528 529 /* Map flowid to secy */ 530 map.secy = secy_id; 531 map.ctrl_pkt = 0; 532 map.flow_id = flow_id; 533 mcs->mcs_ops->mcs_flowid_secy_map(mcs, &map, MCS_RX); 534 map.sc = secy_id; 535 mcs->mcs_ops->mcs_flowid_secy_map(mcs, &map, MCS_TX); 536 537 /* Enable Flowid entry */ 538 mcs_ena_dis_flowid_entry(mcs, flow_id, MCS_RX, true); 539 mcs_ena_dis_flowid_entry(mcs, flow_id, MCS_TX, true); 540 541 return 0; 542 } 543 544 void mcs_clear_secy_plcy(struct mcs *mcs, int secy_id, int dir) 545 { 546 struct mcs_rsrc_map *map; 547 int flow_id; 548 549 if (dir == MCS_RX) 550 map = &mcs->rx; 551 else 552 map = &mcs->tx; 553 554 /* Clear secy memory to zero */ 555 mcs_secy_plcy_write(mcs, 0, secy_id, dir); 556 557 /* Disable the tcam entry using this secy */ 558 for (flow_id = 0; flow_id < map->flow_ids.max; flow_id++) { 559 if (map->flowid2secy_map[flow_id] != secy_id) 560 continue; 561 mcs_ena_dis_flowid_entry(mcs, flow_id, dir, false); 562 } 563 } 564 565 int mcs_alloc_ctrlpktrule(struct rsrc_bmap *rsrc, u16 *pf_map, u16 offset, u16 pcifunc) 566 { 567 int rsrc_id; 568 569 if (!rsrc->bmap) 570 return -EINVAL; 571 572 rsrc_id = bitmap_find_next_zero_area(rsrc->bmap, rsrc->max, offset, 1, 0); 573 if (rsrc_id >= rsrc->max) 574 return -ENOSPC; 575 576 bitmap_set(rsrc->bmap, rsrc_id, 1); 577 pf_map[rsrc_id] = pcifunc; 578 579 return rsrc_id; 580 } 581 582 int mcs_free_ctrlpktrule(struct mcs *mcs, struct mcs_free_ctrl_pkt_rule_req *req) 583 { 584 u16 pcifunc = req->hdr.pcifunc; 585 struct mcs_rsrc_map *map; 586 u64 dis, reg; 587 int id, rc; 588 589 reg = (req->dir == MCS_RX) ? MCSX_PEX_RX_SLAVE_RULE_ENABLE : MCSX_PEX_TX_SLAVE_RULE_ENABLE; 590 map = (req->dir == MCS_RX) ? &mcs->rx : &mcs->tx; 591 592 if (req->all) { 593 for (id = 0; id < map->ctrlpktrule.max; id++) { 594 if (map->ctrlpktrule2pf_map[id] != pcifunc) 595 continue; 596 mcs_free_rsrc(&map->ctrlpktrule, map->ctrlpktrule2pf_map, id, pcifunc); 597 dis = mcs_reg_read(mcs, reg); 598 dis &= ~BIT_ULL(id); 599 mcs_reg_write(mcs, reg, dis); 600 } 601 return 0; 602 } 603 604 rc = mcs_free_rsrc(&map->ctrlpktrule, map->ctrlpktrule2pf_map, req->rule_idx, pcifunc); 605 dis = mcs_reg_read(mcs, reg); 606 dis &= ~BIT_ULL(req->rule_idx); 607 mcs_reg_write(mcs, reg, dis); 608 609 return rc; 610 } 611 612 int mcs_ctrlpktrule_write(struct mcs *mcs, struct mcs_ctrl_pkt_rule_write_req *req) 613 { 614 u64 reg, enb; 615 u64 idx; 616 617 switch (req->rule_type) { 618 case MCS_CTRL_PKT_RULE_TYPE_ETH: 619 req->data0 &= GENMASK(15, 0); 620 if (req->data0 != ETH_P_PAE) 621 return -EINVAL; 622 623 idx = req->rule_idx - MCS_CTRLPKT_ETYPE_RULE_OFFSET; 624 reg = (req->dir == MCS_RX) ? MCSX_PEX_RX_SLAVE_RULE_ETYPE_CFGX(idx) : 625 MCSX_PEX_TX_SLAVE_RULE_ETYPE_CFGX(idx); 626 627 mcs_reg_write(mcs, reg, req->data0); 628 break; 629 case MCS_CTRL_PKT_RULE_TYPE_DA: 630 if (!(req->data0 & BIT_ULL(40))) 631 return -EINVAL; 632 633 idx = req->rule_idx - MCS_CTRLPKT_DA_RULE_OFFSET; 634 reg = (req->dir == MCS_RX) ? MCSX_PEX_RX_SLAVE_RULE_DAX(idx) : 635 MCSX_PEX_TX_SLAVE_RULE_DAX(idx); 636 637 mcs_reg_write(mcs, reg, req->data0 & GENMASK_ULL(47, 0)); 638 break; 639 case MCS_CTRL_PKT_RULE_TYPE_RANGE: 640 if (!(req->data0 & BIT_ULL(40)) || !(req->data1 & BIT_ULL(40))) 641 return -EINVAL; 642 643 idx = req->rule_idx - MCS_CTRLPKT_DA_RANGE_RULE_OFFSET; 644 if (req->dir == MCS_RX) { 645 reg = MCSX_PEX_RX_SLAVE_RULE_DA_RANGE_MINX(idx); 646 mcs_reg_write(mcs, reg, req->data0 & GENMASK_ULL(47, 0)); 647 reg = MCSX_PEX_RX_SLAVE_RULE_DA_RANGE_MAXX(idx); 648 mcs_reg_write(mcs, reg, req->data1 & GENMASK_ULL(47, 0)); 649 } else { 650 reg = MCSX_PEX_TX_SLAVE_RULE_DA_RANGE_MINX(idx); 651 mcs_reg_write(mcs, reg, req->data0 & GENMASK_ULL(47, 0)); 652 reg = MCSX_PEX_TX_SLAVE_RULE_DA_RANGE_MAXX(idx); 653 mcs_reg_write(mcs, reg, req->data1 & GENMASK_ULL(47, 0)); 654 } 655 break; 656 case MCS_CTRL_PKT_RULE_TYPE_COMBO: 657 req->data2 &= GENMASK(15, 0); 658 if (req->data2 != ETH_P_PAE || !(req->data0 & BIT_ULL(40)) || 659 !(req->data1 & BIT_ULL(40))) 660 return -EINVAL; 661 662 idx = req->rule_idx - MCS_CTRLPKT_COMBO_RULE_OFFSET; 663 if (req->dir == MCS_RX) { 664 reg = MCSX_PEX_RX_SLAVE_RULE_COMBO_MINX(idx); 665 mcs_reg_write(mcs, reg, req->data0 & GENMASK_ULL(47, 0)); 666 reg = MCSX_PEX_RX_SLAVE_RULE_COMBO_MAXX(idx); 667 mcs_reg_write(mcs, reg, req->data1 & GENMASK_ULL(47, 0)); 668 reg = MCSX_PEX_RX_SLAVE_RULE_COMBO_ETX(idx); 669 mcs_reg_write(mcs, reg, req->data2); 670 } else { 671 reg = MCSX_PEX_TX_SLAVE_RULE_COMBO_MINX(idx); 672 mcs_reg_write(mcs, reg, req->data0 & GENMASK_ULL(47, 0)); 673 reg = MCSX_PEX_TX_SLAVE_RULE_COMBO_MAXX(idx); 674 mcs_reg_write(mcs, reg, req->data1 & GENMASK_ULL(47, 0)); 675 reg = MCSX_PEX_TX_SLAVE_RULE_COMBO_ETX(idx); 676 mcs_reg_write(mcs, reg, req->data2); 677 } 678 break; 679 case MCS_CTRL_PKT_RULE_TYPE_MAC: 680 if (!(req->data0 & BIT_ULL(40))) 681 return -EINVAL; 682 683 idx = req->rule_idx - MCS_CTRLPKT_MAC_EN_RULE_OFFSET; 684 reg = (req->dir == MCS_RX) ? MCSX_PEX_RX_SLAVE_RULE_MAC : 685 MCSX_PEX_TX_SLAVE_RULE_MAC; 686 687 mcs_reg_write(mcs, reg, req->data0 & GENMASK_ULL(47, 0)); 688 break; 689 } 690 691 reg = (req->dir == MCS_RX) ? MCSX_PEX_RX_SLAVE_RULE_ENABLE : MCSX_PEX_TX_SLAVE_RULE_ENABLE; 692 693 enb = mcs_reg_read(mcs, reg); 694 enb |= BIT_ULL(req->rule_idx); 695 mcs_reg_write(mcs, reg, enb); 696 697 return 0; 698 } 699 700 int mcs_free_rsrc(struct rsrc_bmap *rsrc, u16 *pf_map, int rsrc_id, u16 pcifunc) 701 { 702 /* Check if the rsrc_id is mapped to PF/VF */ 703 if (pf_map[rsrc_id] != pcifunc) 704 return -EINVAL; 705 706 rvu_free_rsrc(rsrc, rsrc_id); 707 pf_map[rsrc_id] = 0; 708 return 0; 709 } 710 711 /* Free all the cam resources mapped to pf */ 712 int mcs_free_all_rsrc(struct mcs *mcs, int dir, u16 pcifunc) 713 { 714 struct mcs_rsrc_map *map; 715 int id; 716 717 if (dir == MCS_RX) 718 map = &mcs->rx; 719 else 720 map = &mcs->tx; 721 722 /* free tcam entries */ 723 for (id = 0; id < map->flow_ids.max; id++) { 724 if (map->flowid2pf_map[id] != pcifunc) 725 continue; 726 mcs_free_rsrc(&map->flow_ids, map->flowid2pf_map, 727 id, pcifunc); 728 mcs_ena_dis_flowid_entry(mcs, id, dir, false); 729 } 730 731 /* free secy entries */ 732 for (id = 0; id < map->secy.max; id++) { 733 if (map->secy2pf_map[id] != pcifunc) 734 continue; 735 mcs_free_rsrc(&map->secy, map->secy2pf_map, 736 id, pcifunc); 737 mcs_clear_secy_plcy(mcs, id, dir); 738 } 739 740 /* free sc entries */ 741 for (id = 0; id < map->secy.max; id++) { 742 if (map->sc2pf_map[id] != pcifunc) 743 continue; 744 mcs_free_rsrc(&map->sc, map->sc2pf_map, id, pcifunc); 745 746 /* Disable SC CAM only on RX side */ 747 if (dir == MCS_RX) 748 mcs_ena_dis_sc_cam_entry(mcs, id, false); 749 } 750 751 /* free sa entries */ 752 for (id = 0; id < map->sa.max; id++) { 753 if (map->sa2pf_map[id] != pcifunc) 754 continue; 755 mcs_free_rsrc(&map->sa, map->sa2pf_map, id, pcifunc); 756 } 757 return 0; 758 } 759 760 int mcs_alloc_rsrc(struct rsrc_bmap *rsrc, u16 *pf_map, u16 pcifunc) 761 { 762 int rsrc_id; 763 764 rsrc_id = rvu_alloc_rsrc(rsrc); 765 if (rsrc_id < 0) 766 return -ENOMEM; 767 pf_map[rsrc_id] = pcifunc; 768 return rsrc_id; 769 } 770 771 int mcs_alloc_all_rsrc(struct mcs *mcs, u8 *flow_id, u8 *secy_id, 772 u8 *sc_id, u8 *sa1_id, u8 *sa2_id, u16 pcifunc, int dir) 773 { 774 struct mcs_rsrc_map *map; 775 int id; 776 777 if (dir == MCS_RX) 778 map = &mcs->rx; 779 else 780 map = &mcs->tx; 781 782 id = mcs_alloc_rsrc(&map->flow_ids, map->flowid2pf_map, pcifunc); 783 if (id < 0) 784 return -ENOMEM; 785 *flow_id = id; 786 787 id = mcs_alloc_rsrc(&map->secy, map->secy2pf_map, pcifunc); 788 if (id < 0) 789 return -ENOMEM; 790 *secy_id = id; 791 792 id = mcs_alloc_rsrc(&map->sc, map->sc2pf_map, pcifunc); 793 if (id < 0) 794 return -ENOMEM; 795 *sc_id = id; 796 797 id = mcs_alloc_rsrc(&map->sa, map->sa2pf_map, pcifunc); 798 if (id < 0) 799 return -ENOMEM; 800 *sa1_id = id; 801 802 id = mcs_alloc_rsrc(&map->sa, map->sa2pf_map, pcifunc); 803 if (id < 0) 804 return -ENOMEM; 805 *sa2_id = id; 806 807 return 0; 808 } 809 810 static void cn10kb_mcs_tx_pn_wrapped_handler(struct mcs *mcs) 811 { 812 struct mcs_intr_event event = { 0 }; 813 struct rsrc_bmap *sc_bmap; 814 u64 val; 815 int sc; 816 817 sc_bmap = &mcs->tx.sc; 818 819 event.mcs_id = mcs->mcs_id; 820 event.intr_mask = MCS_CPM_TX_PACKET_XPN_EQ0_INT; 821 822 for_each_set_bit(sc, sc_bmap->bmap, mcs->hw->sc_entries) { 823 val = mcs_reg_read(mcs, MCSX_CPM_TX_SLAVE_SA_MAP_MEM_0X(sc)); 824 825 if (mcs->tx_sa_active[sc]) 826 /* SA_index1 was used and got expired */ 827 event.sa_id = (val >> 9) & 0xFF; 828 else 829 /* SA_index0 was used and got expired */ 830 event.sa_id = val & 0xFF; 831 832 event.pcifunc = mcs->tx.sa2pf_map[event.sa_id]; 833 mcs_add_intr_wq_entry(mcs, &event); 834 } 835 } 836 837 static void cn10kb_mcs_tx_pn_thresh_reached_handler(struct mcs *mcs) 838 { 839 struct mcs_intr_event event = { 0 }; 840 struct rsrc_bmap *sc_bmap; 841 u64 val, status; 842 int sc; 843 844 sc_bmap = &mcs->tx.sc; 845 846 event.mcs_id = mcs->mcs_id; 847 event.intr_mask = MCS_CPM_TX_PN_THRESH_REACHED_INT; 848 849 /* TX SA interrupt is raised only if autorekey is enabled. 850 * MCS_CPM_TX_SLAVE_SA_MAP_MEM_0X[sc].tx_sa_active bit gets toggled if 851 * one of two SAs mapped to SC gets expired. If tx_sa_active=0 implies 852 * SA in SA_index1 got expired else SA in SA_index0 got expired. 853 */ 854 for_each_set_bit(sc, sc_bmap->bmap, mcs->hw->sc_entries) { 855 val = mcs_reg_read(mcs, MCSX_CPM_TX_SLAVE_SA_MAP_MEM_0X(sc)); 856 /* Auto rekey is enable */ 857 if (!((val >> 18) & 0x1)) 858 continue; 859 860 status = (val >> 21) & 0x1; 861 862 /* Check if tx_sa_active status had changed */ 863 if (status == mcs->tx_sa_active[sc]) 864 continue; 865 /* SA_index0 is expired */ 866 if (status) 867 event.sa_id = val & 0xFF; 868 else 869 event.sa_id = (val >> 9) & 0xFF; 870 871 event.pcifunc = mcs->tx.sa2pf_map[event.sa_id]; 872 mcs_add_intr_wq_entry(mcs, &event); 873 } 874 } 875 876 static void mcs_rx_pn_thresh_reached_handler(struct mcs *mcs) 877 { 878 struct mcs_intr_event event = { 0 }; 879 int sa, reg; 880 u64 intr; 881 882 /* Check expired SAs */ 883 for (reg = 0; reg < (mcs->hw->sa_entries / 64); reg++) { 884 /* Bit high in *PN_THRESH_REACHEDX implies 885 * corresponding SAs are expired. 886 */ 887 intr = mcs_reg_read(mcs, MCSX_CPM_RX_SLAVE_PN_THRESH_REACHEDX(reg)); 888 for (sa = 0; sa < 64; sa++) { 889 if (!(intr & BIT_ULL(sa))) 890 continue; 891 892 event.mcs_id = mcs->mcs_id; 893 event.intr_mask = MCS_CPM_RX_PN_THRESH_REACHED_INT; 894 event.sa_id = sa + (reg * 64); 895 event.pcifunc = mcs->rx.sa2pf_map[event.sa_id]; 896 mcs_add_intr_wq_entry(mcs, &event); 897 } 898 } 899 } 900 901 static void mcs_rx_misc_intr_handler(struct mcs *mcs, u64 intr) 902 { 903 struct mcs_intr_event event = { 0 }; 904 905 event.mcs_id = mcs->mcs_id; 906 event.pcifunc = mcs->pf_map[0]; 907 908 if (intr & MCS_CPM_RX_INT_SECTAG_V_EQ1) 909 event.intr_mask = MCS_CPM_RX_SECTAG_V_EQ1_INT; 910 if (intr & MCS_CPM_RX_INT_SECTAG_E_EQ0_C_EQ1) 911 event.intr_mask |= MCS_CPM_RX_SECTAG_E_EQ0_C_EQ1_INT; 912 if (intr & MCS_CPM_RX_INT_SL_GTE48) 913 event.intr_mask |= MCS_CPM_RX_SECTAG_SL_GTE48_INT; 914 if (intr & MCS_CPM_RX_INT_ES_EQ1_SC_EQ1) 915 event.intr_mask |= MCS_CPM_RX_SECTAG_ES_EQ1_SC_EQ1_INT; 916 if (intr & MCS_CPM_RX_INT_SC_EQ1_SCB_EQ1) 917 event.intr_mask |= MCS_CPM_RX_SECTAG_SC_EQ1_SCB_EQ1_INT; 918 if (intr & MCS_CPM_RX_INT_PACKET_XPN_EQ0) 919 event.intr_mask |= MCS_CPM_RX_PACKET_XPN_EQ0_INT; 920 921 mcs_add_intr_wq_entry(mcs, &event); 922 } 923 924 static void mcs_tx_misc_intr_handler(struct mcs *mcs, u64 intr) 925 { 926 struct mcs_intr_event event = { 0 }; 927 928 if (!(intr & MCS_CPM_TX_INT_SA_NOT_VALID)) 929 return; 930 931 event.mcs_id = mcs->mcs_id; 932 event.pcifunc = mcs->pf_map[0]; 933 934 event.intr_mask = MCS_CPM_TX_SA_NOT_VALID_INT; 935 936 mcs_add_intr_wq_entry(mcs, &event); 937 } 938 939 void cn10kb_mcs_bbe_intr_handler(struct mcs *mcs, u64 intr, 940 enum mcs_direction dir) 941 { 942 u64 val, reg; 943 int lmac; 944 945 if (!(intr & 0x6ULL)) 946 return; 947 948 if (intr & BIT_ULL(1)) 949 reg = (dir == MCS_RX) ? MCSX_BBE_RX_SLAVE_DFIFO_OVERFLOW_0 : 950 MCSX_BBE_TX_SLAVE_DFIFO_OVERFLOW_0; 951 else 952 reg = (dir == MCS_RX) ? MCSX_BBE_RX_SLAVE_PLFIFO_OVERFLOW_0 : 953 MCSX_BBE_TX_SLAVE_PLFIFO_OVERFLOW_0; 954 val = mcs_reg_read(mcs, reg); 955 956 /* policy/data over flow occurred */ 957 for (lmac = 0; lmac < mcs->hw->lmac_cnt; lmac++) { 958 if (!(val & BIT_ULL(lmac))) 959 continue; 960 dev_warn(mcs->dev, "BEE:Policy or data overflow occurred on lmac:%d\n", lmac); 961 } 962 } 963 964 void cn10kb_mcs_pab_intr_handler(struct mcs *mcs, u64 intr, 965 enum mcs_direction dir) 966 { 967 int lmac; 968 969 if (!(intr & 0xFFFFFULL)) 970 return; 971 972 for (lmac = 0; lmac < mcs->hw->lmac_cnt; lmac++) { 973 if (intr & BIT_ULL(lmac)) 974 dev_warn(mcs->dev, "PAB: overflow occurred on lmac:%d\n", lmac); 975 } 976 } 977 978 static irqreturn_t mcs_ip_intr_handler(int irq, void *mcs_irq) 979 { 980 struct mcs *mcs = (struct mcs *)mcs_irq; 981 u64 intr, cpm_intr, bbe_intr, pab_intr; 982 983 /* Disable the interrupt */ 984 mcs_reg_write(mcs, MCSX_IP_INT_ENA_W1C, BIT_ULL(0)); 985 986 /* Check which block has interrupt*/ 987 intr = mcs_reg_read(mcs, MCSX_TOP_SLAVE_INT_SUM); 988 989 /* CPM RX */ 990 if (intr & MCS_CPM_RX_INT_ENA) { 991 /* Check for PN thresh interrupt bit */ 992 cpm_intr = mcs_reg_read(mcs, MCSX_CPM_RX_SLAVE_RX_INT); 993 994 if (cpm_intr & MCS_CPM_RX_INT_PN_THRESH_REACHED) 995 mcs_rx_pn_thresh_reached_handler(mcs); 996 997 if (cpm_intr & MCS_CPM_RX_INT_ALL) 998 mcs_rx_misc_intr_handler(mcs, cpm_intr); 999 1000 /* Clear the interrupt */ 1001 mcs_reg_write(mcs, MCSX_CPM_RX_SLAVE_RX_INT, cpm_intr); 1002 } 1003 1004 /* CPM TX */ 1005 if (intr & MCS_CPM_TX_INT_ENA) { 1006 cpm_intr = mcs_reg_read(mcs, MCSX_CPM_TX_SLAVE_TX_INT); 1007 1008 if (cpm_intr & MCS_CPM_TX_INT_PN_THRESH_REACHED) { 1009 if (mcs->hw->mcs_blks > 1) 1010 cnf10kb_mcs_tx_pn_thresh_reached_handler(mcs); 1011 else 1012 cn10kb_mcs_tx_pn_thresh_reached_handler(mcs); 1013 } 1014 1015 if (cpm_intr & MCS_CPM_TX_INT_SA_NOT_VALID) 1016 mcs_tx_misc_intr_handler(mcs, cpm_intr); 1017 1018 if (cpm_intr & MCS_CPM_TX_INT_PACKET_XPN_EQ0) { 1019 if (mcs->hw->mcs_blks > 1) 1020 cnf10kb_mcs_tx_pn_wrapped_handler(mcs); 1021 else 1022 cn10kb_mcs_tx_pn_wrapped_handler(mcs); 1023 } 1024 /* Clear the interrupt */ 1025 mcs_reg_write(mcs, MCSX_CPM_TX_SLAVE_TX_INT, cpm_intr); 1026 } 1027 1028 /* BBE RX */ 1029 if (intr & MCS_BBE_RX_INT_ENA) { 1030 bbe_intr = mcs_reg_read(mcs, MCSX_BBE_RX_SLAVE_BBE_INT); 1031 mcs->mcs_ops->mcs_bbe_intr_handler(mcs, bbe_intr, MCS_RX); 1032 1033 /* Clear the interrupt */ 1034 mcs_reg_write(mcs, MCSX_BBE_RX_SLAVE_BBE_INT_INTR_RW, 0); 1035 mcs_reg_write(mcs, MCSX_BBE_RX_SLAVE_BBE_INT, bbe_intr); 1036 } 1037 1038 /* BBE TX */ 1039 if (intr & MCS_BBE_TX_INT_ENA) { 1040 bbe_intr = mcs_reg_read(mcs, MCSX_BBE_TX_SLAVE_BBE_INT); 1041 mcs->mcs_ops->mcs_bbe_intr_handler(mcs, bbe_intr, MCS_TX); 1042 1043 /* Clear the interrupt */ 1044 mcs_reg_write(mcs, MCSX_BBE_TX_SLAVE_BBE_INT_INTR_RW, 0); 1045 mcs_reg_write(mcs, MCSX_BBE_TX_SLAVE_BBE_INT, bbe_intr); 1046 } 1047 1048 /* PAB RX */ 1049 if (intr & MCS_PAB_RX_INT_ENA) { 1050 pab_intr = mcs_reg_read(mcs, MCSX_PAB_RX_SLAVE_PAB_INT); 1051 mcs->mcs_ops->mcs_pab_intr_handler(mcs, pab_intr, MCS_RX); 1052 1053 /* Clear the interrupt */ 1054 mcs_reg_write(mcs, MCSX_PAB_RX_SLAVE_PAB_INT_INTR_RW, 0); 1055 mcs_reg_write(mcs, MCSX_PAB_RX_SLAVE_PAB_INT, pab_intr); 1056 } 1057 1058 /* PAB TX */ 1059 if (intr & MCS_PAB_TX_INT_ENA) { 1060 pab_intr = mcs_reg_read(mcs, MCSX_PAB_TX_SLAVE_PAB_INT); 1061 mcs->mcs_ops->mcs_pab_intr_handler(mcs, pab_intr, MCS_TX); 1062 1063 /* Clear the interrupt */ 1064 mcs_reg_write(mcs, MCSX_PAB_TX_SLAVE_PAB_INT_INTR_RW, 0); 1065 mcs_reg_write(mcs, MCSX_PAB_TX_SLAVE_PAB_INT, pab_intr); 1066 } 1067 1068 /* Clear and enable the interrupt */ 1069 mcs_reg_write(mcs, MCSX_IP_INT, BIT_ULL(0)); 1070 mcs_reg_write(mcs, MCSX_IP_INT_ENA_W1S, BIT_ULL(0)); 1071 1072 return IRQ_HANDLED; 1073 } 1074 1075 static void *alloc_mem(struct mcs *mcs, int n) 1076 { 1077 return devm_kcalloc(mcs->dev, n, sizeof(u16), GFP_KERNEL); 1078 } 1079 1080 static int mcs_alloc_struct_mem(struct mcs *mcs, struct mcs_rsrc_map *res) 1081 { 1082 struct hwinfo *hw = mcs->hw; 1083 int err; 1084 1085 res->flowid2pf_map = alloc_mem(mcs, hw->tcam_entries); 1086 if (!res->flowid2pf_map) 1087 return -ENOMEM; 1088 1089 res->secy2pf_map = alloc_mem(mcs, hw->secy_entries); 1090 if (!res->secy2pf_map) 1091 return -ENOMEM; 1092 1093 res->sc2pf_map = alloc_mem(mcs, hw->sc_entries); 1094 if (!res->sc2pf_map) 1095 return -ENOMEM; 1096 1097 res->sa2pf_map = alloc_mem(mcs, hw->sa_entries); 1098 if (!res->sa2pf_map) 1099 return -ENOMEM; 1100 1101 res->flowid2secy_map = alloc_mem(mcs, hw->tcam_entries); 1102 if (!res->flowid2secy_map) 1103 return -ENOMEM; 1104 1105 res->ctrlpktrule2pf_map = alloc_mem(mcs, MCS_MAX_CTRLPKT_RULES); 1106 if (!res->ctrlpktrule2pf_map) 1107 return -ENOMEM; 1108 1109 res->flow_ids.max = hw->tcam_entries - MCS_RSRC_RSVD_CNT; 1110 err = rvu_alloc_bitmap(&res->flow_ids); 1111 if (err) 1112 return err; 1113 1114 res->secy.max = hw->secy_entries - MCS_RSRC_RSVD_CNT; 1115 err = rvu_alloc_bitmap(&res->secy); 1116 if (err) 1117 return err; 1118 1119 res->sc.max = hw->sc_entries; 1120 err = rvu_alloc_bitmap(&res->sc); 1121 if (err) 1122 return err; 1123 1124 res->sa.max = hw->sa_entries; 1125 err = rvu_alloc_bitmap(&res->sa); 1126 if (err) 1127 return err; 1128 1129 res->ctrlpktrule.max = MCS_MAX_CTRLPKT_RULES; 1130 err = rvu_alloc_bitmap(&res->ctrlpktrule); 1131 if (err) 1132 return err; 1133 1134 return 0; 1135 } 1136 1137 static int mcs_register_interrupts(struct mcs *mcs) 1138 { 1139 int ret = 0; 1140 1141 mcs->num_vec = pci_msix_vec_count(mcs->pdev); 1142 1143 ret = pci_alloc_irq_vectors(mcs->pdev, mcs->num_vec, 1144 mcs->num_vec, PCI_IRQ_MSIX); 1145 if (ret < 0) { 1146 dev_err(mcs->dev, "MCS Request for %d msix vector failed err:%d\n", 1147 mcs->num_vec, ret); 1148 return ret; 1149 } 1150 1151 ret = request_irq(pci_irq_vector(mcs->pdev, mcs->hw->ip_vec), 1152 mcs_ip_intr_handler, 0, "MCS_IP", mcs); 1153 if (ret) { 1154 dev_err(mcs->dev, "MCS IP irq registration failed\n"); 1155 goto exit; 1156 } 1157 1158 /* MCS enable IP interrupts */ 1159 mcs_reg_write(mcs, MCSX_IP_INT_ENA_W1S, BIT_ULL(0)); 1160 1161 /* Enable CPM Rx/Tx interrupts */ 1162 mcs_reg_write(mcs, MCSX_TOP_SLAVE_INT_SUM_ENB, 1163 MCS_CPM_RX_INT_ENA | MCS_CPM_TX_INT_ENA | 1164 MCS_BBE_RX_INT_ENA | MCS_BBE_TX_INT_ENA | 1165 MCS_PAB_RX_INT_ENA | MCS_PAB_TX_INT_ENA); 1166 1167 mcs_reg_write(mcs, MCSX_CPM_TX_SLAVE_TX_INT_ENB, 0x7ULL); 1168 mcs_reg_write(mcs, MCSX_CPM_RX_SLAVE_RX_INT_ENB, 0x7FULL); 1169 1170 mcs_reg_write(mcs, MCSX_BBE_RX_SLAVE_BBE_INT_ENB, 0xFFULL); 1171 mcs_reg_write(mcs, MCSX_BBE_TX_SLAVE_BBE_INT_ENB, 0xFFULL); 1172 1173 mcs_reg_write(mcs, MCSX_PAB_RX_SLAVE_PAB_INT_ENB, 0xFFFFFULL); 1174 mcs_reg_write(mcs, MCSX_PAB_TX_SLAVE_PAB_INT_ENB, 0xFFFFFULL); 1175 1176 mcs->tx_sa_active = alloc_mem(mcs, mcs->hw->sc_entries); 1177 if (!mcs->tx_sa_active) { 1178 ret = -ENOMEM; 1179 goto free_irq; 1180 } 1181 1182 return ret; 1183 1184 free_irq: 1185 free_irq(pci_irq_vector(mcs->pdev, mcs->hw->ip_vec), mcs); 1186 exit: 1187 pci_free_irq_vectors(mcs->pdev); 1188 mcs->num_vec = 0; 1189 return ret; 1190 } 1191 1192 int mcs_get_blkcnt(void) 1193 { 1194 struct mcs *mcs; 1195 int idmax = -ENODEV; 1196 1197 /* Check MCS block is present in hardware */ 1198 if (!pci_dev_present(mcs_id_table)) 1199 return 0; 1200 1201 list_for_each_entry(mcs, &mcs_list, mcs_list) 1202 if (mcs->mcs_id > idmax) 1203 idmax = mcs->mcs_id; 1204 1205 if (idmax < 0) 1206 return 0; 1207 1208 return idmax + 1; 1209 } 1210 1211 struct mcs *mcs_get_pdata(int mcs_id) 1212 { 1213 struct mcs *mcs_dev; 1214 1215 list_for_each_entry(mcs_dev, &mcs_list, mcs_list) { 1216 if (mcs_dev->mcs_id == mcs_id) 1217 return mcs_dev; 1218 } 1219 return NULL; 1220 } 1221 1222 void mcs_set_port_cfg(struct mcs *mcs, struct mcs_port_cfg_set_req *req) 1223 { 1224 u64 val = 0; 1225 1226 mcs_reg_write(mcs, MCSX_PAB_RX_SLAVE_PORT_CFGX(req->port_id), 1227 req->port_mode & MCS_PORT_MODE_MASK); 1228 1229 req->cstm_tag_rel_mode_sel &= 0x3; 1230 1231 if (mcs->hw->mcs_blks > 1) { 1232 req->fifo_skid &= MCS_PORT_FIFO_SKID_MASK; 1233 val = (u32)req->fifo_skid << 0x10; 1234 val |= req->fifo_skid; 1235 mcs_reg_write(mcs, MCSX_PAB_RX_SLAVE_FIFO_SKID_CFGX(req->port_id), val); 1236 mcs_reg_write(mcs, MCSX_PEX_TX_SLAVE_CUSTOM_TAG_REL_MODE_SEL(req->port_id), 1237 req->cstm_tag_rel_mode_sel); 1238 val = mcs_reg_read(mcs, MCSX_PEX_RX_SLAVE_PEX_CONFIGURATION); 1239 1240 if (req->custom_hdr_enb) 1241 val |= BIT_ULL(req->port_id); 1242 else 1243 val &= ~BIT_ULL(req->port_id); 1244 1245 mcs_reg_write(mcs, MCSX_PEX_RX_SLAVE_PEX_CONFIGURATION, val); 1246 } else { 1247 val = mcs_reg_read(mcs, MCSX_PEX_TX_SLAVE_PORT_CONFIG(req->port_id)); 1248 val |= (req->cstm_tag_rel_mode_sel << 2); 1249 mcs_reg_write(mcs, MCSX_PEX_TX_SLAVE_PORT_CONFIG(req->port_id), val); 1250 } 1251 } 1252 1253 void mcs_get_port_cfg(struct mcs *mcs, struct mcs_port_cfg_get_req *req, 1254 struct mcs_port_cfg_get_rsp *rsp) 1255 { 1256 u64 reg = 0; 1257 1258 rsp->port_mode = mcs_reg_read(mcs, MCSX_PAB_RX_SLAVE_PORT_CFGX(req->port_id)) & 1259 MCS_PORT_MODE_MASK; 1260 1261 if (mcs->hw->mcs_blks > 1) { 1262 reg = MCSX_PAB_RX_SLAVE_FIFO_SKID_CFGX(req->port_id); 1263 rsp->fifo_skid = mcs_reg_read(mcs, reg) & MCS_PORT_FIFO_SKID_MASK; 1264 reg = MCSX_PEX_TX_SLAVE_CUSTOM_TAG_REL_MODE_SEL(req->port_id); 1265 rsp->cstm_tag_rel_mode_sel = mcs_reg_read(mcs, reg) & 0x3; 1266 if (mcs_reg_read(mcs, MCSX_PEX_RX_SLAVE_PEX_CONFIGURATION) & BIT_ULL(req->port_id)) 1267 rsp->custom_hdr_enb = 1; 1268 } else { 1269 reg = MCSX_PEX_TX_SLAVE_PORT_CONFIG(req->port_id); 1270 rsp->cstm_tag_rel_mode_sel = mcs_reg_read(mcs, reg) >> 2; 1271 } 1272 1273 rsp->port_id = req->port_id; 1274 rsp->mcs_id = req->mcs_id; 1275 } 1276 1277 void mcs_get_custom_tag_cfg(struct mcs *mcs, struct mcs_custom_tag_cfg_get_req *req, 1278 struct mcs_custom_tag_cfg_get_rsp *rsp) 1279 { 1280 u64 reg = 0, val = 0; 1281 u8 idx; 1282 1283 for (idx = 0; idx < MCS_MAX_CUSTOM_TAGS; idx++) { 1284 if (mcs->hw->mcs_blks > 1) 1285 reg = (req->dir == MCS_RX) ? MCSX_PEX_RX_SLAVE_CUSTOM_TAGX(idx) : 1286 MCSX_PEX_TX_SLAVE_CUSTOM_TAGX(idx); 1287 else 1288 reg = (req->dir == MCS_RX) ? MCSX_PEX_RX_SLAVE_VLAN_CFGX(idx) : 1289 MCSX_PEX_TX_SLAVE_VLAN_CFGX(idx); 1290 1291 val = mcs_reg_read(mcs, reg); 1292 if (mcs->hw->mcs_blks > 1) { 1293 rsp->cstm_etype[idx] = val & GENMASK(15, 0); 1294 rsp->cstm_indx[idx] = (val >> 0x16) & 0x3; 1295 reg = (req->dir == MCS_RX) ? MCSX_PEX_RX_SLAVE_ETYPE_ENABLE : 1296 MCSX_PEX_TX_SLAVE_ETYPE_ENABLE; 1297 rsp->cstm_etype_en = mcs_reg_read(mcs, reg) & 0xFF; 1298 } else { 1299 rsp->cstm_etype[idx] = (val >> 0x1) & GENMASK(15, 0); 1300 rsp->cstm_indx[idx] = (val >> 0x11) & 0x3; 1301 rsp->cstm_etype_en |= (val & 0x1) << idx; 1302 } 1303 } 1304 1305 rsp->mcs_id = req->mcs_id; 1306 rsp->dir = req->dir; 1307 } 1308 1309 void mcs_reset_port(struct mcs *mcs, u8 port_id, u8 reset) 1310 { 1311 u64 reg = MCSX_MCS_TOP_SLAVE_PORT_RESET(port_id); 1312 1313 mcs_reg_write(mcs, reg, reset & 0x1); 1314 } 1315 1316 /* Set lmac to bypass/operational mode */ 1317 void mcs_set_lmac_mode(struct mcs *mcs, int lmac_id, u8 mode) 1318 { 1319 u64 reg; 1320 int id = lmac_id * 2; 1321 1322 reg = MCSX_MCS_TOP_SLAVE_CHANNEL_CFG(id); 1323 mcs_reg_write(mcs, reg, (u64)mode); 1324 reg = MCSX_MCS_TOP_SLAVE_CHANNEL_CFG((id + 1)); 1325 mcs_reg_write(mcs, reg, (u64)mode); 1326 } 1327 1328 void mcs_pn_threshold_set(struct mcs *mcs, struct mcs_set_pn_threshold *pn) 1329 { 1330 u64 reg; 1331 1332 if (pn->dir == MCS_RX) 1333 reg = pn->xpn ? MCSX_CPM_RX_SLAVE_XPN_THRESHOLD : MCSX_CPM_RX_SLAVE_PN_THRESHOLD; 1334 else 1335 reg = pn->xpn ? MCSX_CPM_TX_SLAVE_XPN_THRESHOLD : MCSX_CPM_TX_SLAVE_PN_THRESHOLD; 1336 1337 mcs_reg_write(mcs, reg, pn->threshold); 1338 } 1339 1340 void cn10kb_mcs_parser_cfg(struct mcs *mcs) 1341 { 1342 u64 reg, val; 1343 1344 /* VLAN CTag */ 1345 val = BIT_ULL(0) | (0x8100ull & 0xFFFF) << 1 | BIT_ULL(17); 1346 /* RX */ 1347 reg = MCSX_PEX_RX_SLAVE_VLAN_CFGX(0); 1348 mcs_reg_write(mcs, reg, val); 1349 1350 /* TX */ 1351 reg = MCSX_PEX_TX_SLAVE_VLAN_CFGX(0); 1352 mcs_reg_write(mcs, reg, val); 1353 1354 /* VLAN STag */ 1355 val = BIT_ULL(0) | (0x88a8ull & 0xFFFF) << 1 | BIT_ULL(18); 1356 /* RX */ 1357 reg = MCSX_PEX_RX_SLAVE_VLAN_CFGX(1); 1358 mcs_reg_write(mcs, reg, val); 1359 1360 /* TX */ 1361 reg = MCSX_PEX_TX_SLAVE_VLAN_CFGX(1); 1362 mcs_reg_write(mcs, reg, val); 1363 } 1364 1365 static void mcs_lmac_init(struct mcs *mcs, int lmac_id) 1366 { 1367 u64 reg; 1368 1369 /* Port mode 25GB */ 1370 reg = MCSX_PAB_RX_SLAVE_PORT_CFGX(lmac_id); 1371 mcs_reg_write(mcs, reg, 0); 1372 1373 if (mcs->hw->mcs_blks > 1) { 1374 reg = MCSX_PAB_RX_SLAVE_FIFO_SKID_CFGX(lmac_id); 1375 mcs_reg_write(mcs, reg, 0xe000e); 1376 return; 1377 } 1378 1379 reg = MCSX_PAB_TX_SLAVE_PORT_CFGX(lmac_id); 1380 mcs_reg_write(mcs, reg, 0); 1381 } 1382 1383 int mcs_set_lmac_channels(int mcs_id, u16 base) 1384 { 1385 struct mcs *mcs; 1386 int lmac; 1387 u64 cfg; 1388 1389 mcs = mcs_get_pdata(mcs_id); 1390 if (!mcs) 1391 return -ENODEV; 1392 for (lmac = 0; lmac < mcs->hw->lmac_cnt; lmac++) { 1393 cfg = mcs_reg_read(mcs, MCSX_LINK_LMACX_CFG(lmac)); 1394 cfg &= ~(MCSX_LINK_LMAC_BASE_MASK | MCSX_LINK_LMAC_RANGE_MASK); 1395 cfg |= FIELD_PREP(MCSX_LINK_LMAC_RANGE_MASK, ilog2(16)); 1396 cfg |= FIELD_PREP(MCSX_LINK_LMAC_BASE_MASK, base); 1397 mcs_reg_write(mcs, MCSX_LINK_LMACX_CFG(lmac), cfg); 1398 base += 16; 1399 } 1400 return 0; 1401 } 1402 1403 static int mcs_x2p_calibration(struct mcs *mcs) 1404 { 1405 unsigned long timeout = jiffies + usecs_to_jiffies(20000); 1406 int i, err = 0; 1407 u64 val; 1408 1409 /* set X2P calibration */ 1410 val = mcs_reg_read(mcs, MCSX_MIL_GLOBAL); 1411 val |= BIT_ULL(5); 1412 mcs_reg_write(mcs, MCSX_MIL_GLOBAL, val); 1413 1414 /* Wait for calibration to complete */ 1415 while (!(mcs_reg_read(mcs, MCSX_MIL_RX_GBL_STATUS) & BIT_ULL(0))) { 1416 if (time_before(jiffies, timeout)) { 1417 usleep_range(80, 100); 1418 continue; 1419 } else { 1420 err = -EBUSY; 1421 dev_err(mcs->dev, "MCS X2P calibration failed..ignoring\n"); 1422 return err; 1423 } 1424 } 1425 1426 val = mcs_reg_read(mcs, MCSX_MIL_RX_GBL_STATUS); 1427 for (i = 0; i < mcs->hw->mcs_x2p_intf; i++) { 1428 if (val & BIT_ULL(1 + i)) 1429 continue; 1430 err = -EBUSY; 1431 dev_err(mcs->dev, "MCS:%d didn't respond to X2P calibration\n", i); 1432 } 1433 /* Clear X2P calibrate */ 1434 mcs_reg_write(mcs, MCSX_MIL_GLOBAL, mcs_reg_read(mcs, MCSX_MIL_GLOBAL) & ~BIT_ULL(5)); 1435 1436 return err; 1437 } 1438 1439 static void mcs_set_external_bypass(struct mcs *mcs, u8 bypass) 1440 { 1441 u64 val; 1442 1443 /* Set MCS to external bypass */ 1444 val = mcs_reg_read(mcs, MCSX_MIL_GLOBAL); 1445 if (bypass) 1446 val |= BIT_ULL(6); 1447 else 1448 val &= ~BIT_ULL(6); 1449 mcs_reg_write(mcs, MCSX_MIL_GLOBAL, val); 1450 } 1451 1452 static void mcs_global_cfg(struct mcs *mcs) 1453 { 1454 /* Disable external bypass */ 1455 mcs_set_external_bypass(mcs, false); 1456 1457 /* Reset TX/RX stats memory */ 1458 mcs_reg_write(mcs, MCSX_CSE_RX_SLAVE_STATS_CLEAR, 0x1F); 1459 mcs_reg_write(mcs, MCSX_CSE_TX_SLAVE_STATS_CLEAR, 0x1F); 1460 1461 /* Set MCS to perform standard IEEE802.1AE macsec processing */ 1462 if (mcs->hw->mcs_blks == 1) { 1463 mcs_reg_write(mcs, MCSX_IP_MODE, BIT_ULL(3)); 1464 return; 1465 } 1466 1467 mcs_reg_write(mcs, MCSX_BBE_RX_SLAVE_CAL_ENTRY, 0xe4); 1468 mcs_reg_write(mcs, MCSX_BBE_RX_SLAVE_CAL_LEN, 4); 1469 } 1470 1471 void cn10kb_mcs_set_hw_capabilities(struct mcs *mcs) 1472 { 1473 struct hwinfo *hw = mcs->hw; 1474 1475 hw->tcam_entries = 128; /* TCAM entries */ 1476 hw->secy_entries = 128; /* SecY entries */ 1477 hw->sc_entries = 128; /* SC CAM entries */ 1478 hw->sa_entries = 256; /* SA entries */ 1479 hw->lmac_cnt = 20; /* lmacs/ports per mcs block */ 1480 hw->mcs_x2p_intf = 5; /* x2p clabration intf */ 1481 hw->mcs_blks = 1; /* MCS blocks */ 1482 hw->ip_vec = MCS_CN10KB_INT_VEC_IP; /* IP vector */ 1483 } 1484 1485 static struct mcs_ops cn10kb_mcs_ops = { 1486 .mcs_set_hw_capabilities = cn10kb_mcs_set_hw_capabilities, 1487 .mcs_parser_cfg = cn10kb_mcs_parser_cfg, 1488 .mcs_tx_sa_mem_map_write = cn10kb_mcs_tx_sa_mem_map_write, 1489 .mcs_rx_sa_mem_map_write = cn10kb_mcs_rx_sa_mem_map_write, 1490 .mcs_flowid_secy_map = cn10kb_mcs_flowid_secy_map, 1491 .mcs_bbe_intr_handler = cn10kb_mcs_bbe_intr_handler, 1492 .mcs_pab_intr_handler = cn10kb_mcs_pab_intr_handler, 1493 }; 1494 1495 static int mcs_probe(struct pci_dev *pdev, const struct pci_device_id *id) 1496 { 1497 struct device *dev = &pdev->dev; 1498 int lmac, err = 0; 1499 struct mcs *mcs; 1500 1501 mcs = devm_kzalloc(dev, sizeof(*mcs), GFP_KERNEL); 1502 if (!mcs) 1503 return -ENOMEM; 1504 1505 mcs->hw = devm_kzalloc(dev, sizeof(struct hwinfo), GFP_KERNEL); 1506 if (!mcs->hw) 1507 return -ENOMEM; 1508 1509 err = pci_enable_device(pdev); 1510 if (err) { 1511 dev_err(dev, "Failed to enable PCI device\n"); 1512 pci_set_drvdata(pdev, NULL); 1513 return err; 1514 } 1515 1516 err = pci_request_regions(pdev, DRV_NAME); 1517 if (err) { 1518 dev_err(dev, "PCI request regions failed 0x%x\n", err); 1519 goto exit; 1520 } 1521 1522 mcs->reg_base = pcim_iomap(pdev, PCI_CFG_REG_BAR_NUM, 0); 1523 if (!mcs->reg_base) { 1524 dev_err(dev, "mcs: Cannot map CSR memory space, aborting\n"); 1525 err = -ENOMEM; 1526 goto exit; 1527 } 1528 1529 pci_set_drvdata(pdev, mcs); 1530 mcs->pdev = pdev; 1531 mcs->dev = &pdev->dev; 1532 1533 if (pdev->subsystem_device == PCI_SUBSYS_DEVID_CN10K_B) 1534 mcs->mcs_ops = &cn10kb_mcs_ops; 1535 else 1536 mcs->mcs_ops = cnf10kb_get_mac_ops(); 1537 1538 /* Set hardware capabilities */ 1539 mcs->mcs_ops->mcs_set_hw_capabilities(mcs); 1540 1541 mcs_global_cfg(mcs); 1542 1543 /* Perform X2P clibration */ 1544 err = mcs_x2p_calibration(mcs); 1545 if (err) 1546 goto err_x2p; 1547 1548 mcs->mcs_id = (pci_resource_start(pdev, PCI_CFG_REG_BAR_NUM) >> 24) 1549 & MCS_ID_MASK; 1550 1551 /* Set mcs tx side resources */ 1552 err = mcs_alloc_struct_mem(mcs, &mcs->tx); 1553 if (err) 1554 goto err_x2p; 1555 1556 /* Set mcs rx side resources */ 1557 err = mcs_alloc_struct_mem(mcs, &mcs->rx); 1558 if (err) 1559 goto err_x2p; 1560 1561 /* per port config */ 1562 for (lmac = 0; lmac < mcs->hw->lmac_cnt; lmac++) 1563 mcs_lmac_init(mcs, lmac); 1564 1565 /* Parser configuration */ 1566 mcs->mcs_ops->mcs_parser_cfg(mcs); 1567 1568 err = mcs_register_interrupts(mcs); 1569 if (err) 1570 goto exit; 1571 1572 list_add(&mcs->mcs_list, &mcs_list); 1573 mutex_init(&mcs->stats_lock); 1574 1575 return 0; 1576 1577 err_x2p: 1578 /* Enable external bypass */ 1579 mcs_set_external_bypass(mcs, true); 1580 exit: 1581 pci_release_regions(pdev); 1582 pci_disable_device(pdev); 1583 pci_set_drvdata(pdev, NULL); 1584 return err; 1585 } 1586 1587 static void mcs_remove(struct pci_dev *pdev) 1588 { 1589 struct mcs *mcs = pci_get_drvdata(pdev); 1590 1591 /* Set MCS to external bypass */ 1592 mcs_set_external_bypass(mcs, true); 1593 free_irq(pci_irq_vector(pdev, mcs->hw->ip_vec), mcs); 1594 pci_free_irq_vectors(pdev); 1595 pci_release_regions(pdev); 1596 pci_disable_device(pdev); 1597 pci_set_drvdata(pdev, NULL); 1598 } 1599 1600 struct pci_driver mcs_driver = { 1601 .name = DRV_NAME, 1602 .id_table = mcs_id_table, 1603 .probe = mcs_probe, 1604 .remove = mcs_remove, 1605 }; 1606