1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) Meta Platforms, Inc. and affiliates. */ 3 4 #include <linux/bitfield.h> 5 #include <net/tcp.h> 6 7 #include "fbnic.h" 8 #include "fbnic_mac.h" 9 #include "fbnic_netdev.h" 10 11 static void fbnic_init_readrq(struct fbnic_dev *fbd, unsigned int offset, 12 unsigned int cls, unsigned int readrq) 13 { 14 u32 val = rd32(fbd, offset); 15 16 /* The TDF_CTL masks are a superset of the RNI_RBP ones. So we can 17 * use them when setting either the TDE_CTF or RNI_RBP registers. 18 */ 19 val &= FBNIC_QM_TNI_TDF_CTL_MAX_OT | FBNIC_QM_TNI_TDF_CTL_MAX_OB; 20 21 val |= FIELD_PREP(FBNIC_QM_TNI_TDF_CTL_MRRS, readrq) | 22 FIELD_PREP(FBNIC_QM_TNI_TDF_CTL_CLS, cls); 23 24 wr32(fbd, offset, val); 25 } 26 27 static void fbnic_init_mps(struct fbnic_dev *fbd, unsigned int offset, 28 unsigned int cls, unsigned int mps) 29 { 30 u32 val = rd32(fbd, offset); 31 32 /* Currently all MPS masks are identical so just use the first one */ 33 val &= ~(FBNIC_QM_TNI_TCM_CTL_MPS | FBNIC_QM_TNI_TCM_CTL_CLS); 34 35 val |= FIELD_PREP(FBNIC_QM_TNI_TCM_CTL_MPS, mps) | 36 FIELD_PREP(FBNIC_QM_TNI_TCM_CTL_CLS, cls); 37 38 wr32(fbd, offset, val); 39 } 40 41 static void fbnic_mac_init_axi(struct fbnic_dev *fbd) 42 { 43 bool override_1k = false; 44 int readrq, mps, cls; 45 46 /* All of the values are based on being a power of 2 starting 47 * with 64 == 0. Therefore we can either divide by 64 in the 48 * case of constants, or just subtract 6 from the log2 of the value 49 * in order to get the value we will be programming into the 50 * registers. 51 */ 52 readrq = ilog2(fbd->readrq) - 6; 53 if (readrq > 3) 54 override_1k = true; 55 readrq = clamp(readrq, 0, 3); 56 57 mps = ilog2(fbd->mps) - 6; 58 mps = clamp(mps, 0, 3); 59 60 cls = ilog2(L1_CACHE_BYTES) - 6; 61 cls = clamp(cls, 0, 3); 62 63 /* Configure Tx/Rx AXI Paths w/ Read Request and Max Payload sizes */ 64 fbnic_init_readrq(fbd, FBNIC_QM_TNI_TDF_CTL, cls, readrq); 65 fbnic_init_mps(fbd, FBNIC_QM_TNI_TCM_CTL, cls, mps); 66 67 /* Configure QM TNI TDE: 68 * - Max outstanding AXI beats to 704(768 - 64) - guaranetees 8% of 69 * buffer capacity to descriptors. 70 * - Max outstanding transactions to 128 71 */ 72 wr32(fbd, FBNIC_QM_TNI_TDE_CTL, 73 FIELD_PREP(FBNIC_QM_TNI_TDE_CTL_MRRS_1K, override_1k ? 1 : 0) | 74 FIELD_PREP(FBNIC_QM_TNI_TDE_CTL_MAX_OB, 704) | 75 FIELD_PREP(FBNIC_QM_TNI_TDE_CTL_MAX_OT, 128) | 76 FIELD_PREP(FBNIC_QM_TNI_TDE_CTL_MRRS, readrq) | 77 FIELD_PREP(FBNIC_QM_TNI_TDE_CTL_CLS, cls)); 78 79 fbnic_init_readrq(fbd, FBNIC_QM_RNI_RBP_CTL, cls, readrq); 80 fbnic_init_mps(fbd, FBNIC_QM_RNI_RDE_CTL, cls, mps); 81 fbnic_init_mps(fbd, FBNIC_QM_RNI_RCM_CTL, cls, mps); 82 83 /* Enable XALI AR/AW outbound */ 84 wr32(fbd, FBNIC_PUL_OB_TLP_HDR_AW_CFG, 85 FBNIC_PUL_OB_TLP_HDR_AW_CFG_BME); 86 wr32(fbd, FBNIC_PUL_OB_TLP_HDR_AR_CFG, 87 FBNIC_PUL_OB_TLP_HDR_AR_CFG_BME); 88 } 89 90 static void fbnic_mac_init_qm(struct fbnic_dev *fbd) 91 { 92 u32 clock_freq; 93 94 /* Configure TSO behavior */ 95 wr32(fbd, FBNIC_QM_TQS_CTL0, 96 FIELD_PREP(FBNIC_QM_TQS_CTL0_LSO_TS_MASK, 97 FBNIC_QM_TQS_CTL0_LSO_TS_LAST) | 98 FIELD_PREP(FBNIC_QM_TQS_CTL0_PREFETCH_THRESH, 99 FBNIC_QM_TQS_CTL0_PREFETCH_THRESH_MIN)); 100 101 /* Limit EDT to INT_MAX as this is the limit of the EDT Qdisc */ 102 wr32(fbd, FBNIC_QM_TQS_EDT_TS_RANGE, INT_MAX); 103 104 /* Configure MTU 105 * Due to known HW issue we cannot set the MTU to within 16 octets 106 * of a 64 octet aligned boundary. So we will set the TQS_MTU(s) to 107 * MTU + 1. 108 */ 109 wr32(fbd, FBNIC_QM_TQS_MTU_CTL0, FBNIC_MAX_JUMBO_FRAME_SIZE + 1); 110 wr32(fbd, FBNIC_QM_TQS_MTU_CTL1, 111 FIELD_PREP(FBNIC_QM_TQS_MTU_CTL1_BULK, 112 FBNIC_MAX_JUMBO_FRAME_SIZE + 1)); 113 114 clock_freq = FBNIC_CLOCK_FREQ; 115 116 /* Be aggressive on the timings. We will have the interrupt 117 * threshold timer tick once every 1 usec and coalesce writes for 118 * up to 80 usecs. 119 */ 120 wr32(fbd, FBNIC_QM_TCQ_CTL0, 121 FIELD_PREP(FBNIC_QM_TCQ_CTL0_TICK_CYCLES, 122 clock_freq / 1000000) | 123 FIELD_PREP(FBNIC_QM_TCQ_CTL0_COAL_WAIT, 124 clock_freq / 12500)); 125 126 /* We will have the interrupt threshold timer tick once every 127 * 1 usec and coalesce writes for up to 2 usecs. 128 */ 129 wr32(fbd, FBNIC_QM_RCQ_CTL0, 130 FIELD_PREP(FBNIC_QM_RCQ_CTL0_TICK_CYCLES, 131 clock_freq / 1000000) | 132 FIELD_PREP(FBNIC_QM_RCQ_CTL0_COAL_WAIT, 133 clock_freq / 500000)); 134 135 /* Configure spacer control to 64 beats. */ 136 wr32(fbd, FBNIC_FAB_AXI4_AR_SPACER_2_CFG, 137 FBNIC_FAB_AXI4_AR_SPACER_MASK | 138 FIELD_PREP(FBNIC_FAB_AXI4_AR_SPACER_THREADSHOLD, 2)); 139 } 140 141 #define FBNIC_DROP_EN_MASK 0x7d 142 #define FBNIC_PAUSE_EN_MASK 0x14 143 #define FBNIC_ECN_EN_MASK 0x10 144 145 struct fbnic_fifo_config { 146 unsigned int addr; 147 unsigned int size; 148 }; 149 150 /* Rx FIFO Configuration 151 * The table consists of 8 entries, of which only 4 are currently used 152 * The starting addr is in units of 64B and the size is in 2KB units 153 * Below is the human readable version of the table defined below: 154 * Function Addr Size 155 * ---------------------------------- 156 * Network to Host/BMC 384K 64K 157 * Unused 158 * Unused 159 * Network to BMC 448K 32K 160 * Network to Host 0 384K 161 * Unused 162 * BMC to Host 480K 32K 163 * Unused 164 */ 165 static const struct fbnic_fifo_config fifo_config[] = { 166 { .addr = 0x1800, .size = 0x20 }, /* Network to Host/BMC */ 167 { }, /* Unused */ 168 { }, /* Unused */ 169 { .addr = 0x1c00, .size = 0x10 }, /* Network to BMC */ 170 { .addr = 0x0000, .size = 0xc0 }, /* Network to Host */ 171 { }, /* Unused */ 172 { .addr = 0x1e00, .size = 0x10 }, /* BMC to Host */ 173 { } /* Unused */ 174 }; 175 176 static void fbnic_mac_init_rxb(struct fbnic_dev *fbd) 177 { 178 bool rx_enable; 179 int i; 180 181 rx_enable = !!(rd32(fbd, FBNIC_RPC_RMI_CONFIG) & 182 FBNIC_RPC_RMI_CONFIG_ENABLE); 183 184 for (i = 0; i < 8; i++) { 185 unsigned int size = fifo_config[i].size; 186 187 /* If we are coming up on a system that already has the 188 * Rx data path enabled we don't need to reconfigure the 189 * FIFOs. Instead we can check to verify the values are 190 * large enough to meet our needs, and use the values to 191 * populate the flow control, ECN, and drop thresholds. 192 */ 193 if (rx_enable) { 194 size = FIELD_GET(FBNIC_RXB_PBUF_SIZE, 195 rd32(fbd, FBNIC_RXB_PBUF_CFG(i))); 196 if (size < fifo_config[i].size) 197 dev_warn(fbd->dev, 198 "fifo%d size of %d smaller than expected value of %d\n", 199 i, size << 11, 200 fifo_config[i].size << 11); 201 } else { 202 /* Program RXB Cuthrough */ 203 wr32(fbd, FBNIC_RXB_CT_SIZE(i), 204 FIELD_PREP(FBNIC_RXB_CT_SIZE_HEADER, 4) | 205 FIELD_PREP(FBNIC_RXB_CT_SIZE_PAYLOAD, 2)); 206 207 /* The granularity for the packet buffer size is 2KB 208 * granularity while the packet buffer base address is 209 * only 64B granularity 210 */ 211 wr32(fbd, FBNIC_RXB_PBUF_CFG(i), 212 FIELD_PREP(FBNIC_RXB_PBUF_BASE_ADDR, 213 fifo_config[i].addr) | 214 FIELD_PREP(FBNIC_RXB_PBUF_SIZE, size)); 215 216 /* The granularity for the credits is 64B. This is 217 * based on RXB_PBUF_SIZE * 32 + 4. 218 */ 219 wr32(fbd, FBNIC_RXB_PBUF_CREDIT(i), 220 FIELD_PREP(FBNIC_RXB_PBUF_CREDIT_MASK, 221 size ? size * 32 + 4 : 0)); 222 } 223 224 if (!size) 225 continue; 226 227 /* Pause is size of FIFO with 56KB skid to start/stop */ 228 wr32(fbd, FBNIC_RXB_PAUSE_THLD(i), 229 !(FBNIC_PAUSE_EN_MASK & (1u << i)) ? 0x1fff : 230 FIELD_PREP(FBNIC_RXB_PAUSE_THLD_ON, 231 size * 32 - 0x380) | 232 FIELD_PREP(FBNIC_RXB_PAUSE_THLD_OFF, 0x380)); 233 234 /* Enable Drop when only one packet is left in the FIFO */ 235 wr32(fbd, FBNIC_RXB_DROP_THLD(i), 236 !(FBNIC_DROP_EN_MASK & (1u << i)) ? 0x1fff : 237 FIELD_PREP(FBNIC_RXB_DROP_THLD_ON, 238 size * 32 - 239 FBNIC_MAX_JUMBO_FRAME_SIZE / 64) | 240 FIELD_PREP(FBNIC_RXB_DROP_THLD_OFF, 241 size * 32 - 242 FBNIC_MAX_JUMBO_FRAME_SIZE / 64)); 243 244 /* Enable ECN bit when 1/4 of RXB is filled with at least 245 * 1 room for one full jumbo frame before setting ECN 246 */ 247 wr32(fbd, FBNIC_RXB_ECN_THLD(i), 248 !(FBNIC_ECN_EN_MASK & (1u << i)) ? 0x1fff : 249 FIELD_PREP(FBNIC_RXB_ECN_THLD_ON, 250 max_t(unsigned int, 251 size * 32 / 4, 252 FBNIC_MAX_JUMBO_FRAME_SIZE / 64)) | 253 FIELD_PREP(FBNIC_RXB_ECN_THLD_OFF, 254 max_t(unsigned int, 255 size * 32 / 4, 256 FBNIC_MAX_JUMBO_FRAME_SIZE / 64))); 257 } 258 259 /* For now only enable drop and ECN. We need to add driver/kernel 260 * interfaces for configuring pause. 261 */ 262 wr32(fbd, FBNIC_RXB_PAUSE_DROP_CTRL, 263 FIELD_PREP(FBNIC_RXB_PAUSE_DROP_CTRL_DROP_ENABLE, 264 FBNIC_DROP_EN_MASK) | 265 FIELD_PREP(FBNIC_RXB_PAUSE_DROP_CTRL_ECN_ENABLE, 266 FBNIC_ECN_EN_MASK)); 267 268 /* Program INTF credits */ 269 wr32(fbd, FBNIC_RXB_INTF_CREDIT, 270 FBNIC_RXB_INTF_CREDIT_MASK0 | 271 FBNIC_RXB_INTF_CREDIT_MASK1 | 272 FBNIC_RXB_INTF_CREDIT_MASK2 | 273 FIELD_PREP(FBNIC_RXB_INTF_CREDIT_MASK3, 8)); 274 275 /* Configure calendar slots. 276 * Rx: 0 - 62 RDE 1st, BMC 2nd 277 * 63 BMC 1st, RDE 2nd 278 */ 279 for (i = 0; i < 16; i++) { 280 u32 calendar_val = (i == 15) ? 0x1e1b1b1b : 0x1b1b1b1b; 281 282 wr32(fbd, FBNIC_RXB_CLDR_PRIO_CFG(i), calendar_val); 283 } 284 285 /* Split the credits for the DRR up as follows: 286 * Quantum0: 8000 Network to Host 287 * Quantum1: 0 Not used 288 * Quantum2: 80 BMC to Host 289 * Quantum3: 0 Not used 290 * Quantum4: 8000 Multicast to Host and BMC 291 */ 292 wr32(fbd, FBNIC_RXB_DWRR_RDE_WEIGHT0, 293 FIELD_PREP(FBNIC_RXB_DWRR_RDE_WEIGHT0_QUANTUM0, 0x40) | 294 FIELD_PREP(FBNIC_RXB_DWRR_RDE_WEIGHT0_QUANTUM2, 0x50)); 295 wr32(fbd, FBNIC_RXB_DWRR_RDE_WEIGHT0_EXT, 296 FIELD_PREP(FBNIC_RXB_DWRR_RDE_WEIGHT0_QUANTUM0, 0x1f)); 297 wr32(fbd, FBNIC_RXB_DWRR_RDE_WEIGHT1, 298 FIELD_PREP(FBNIC_RXB_DWRR_RDE_WEIGHT1_QUANTUM4, 0x40)); 299 wr32(fbd, FBNIC_RXB_DWRR_RDE_WEIGHT1_EXT, 300 FIELD_PREP(FBNIC_RXB_DWRR_RDE_WEIGHT1_QUANTUM4, 0x1f)); 301 302 /* Program RXB FCS Endian register */ 303 wr32(fbd, FBNIC_RXB_ENDIAN_FCS, 0x0aaaaaa0); 304 } 305 306 static void fbnic_mac_init_txb(struct fbnic_dev *fbd) 307 { 308 int i; 309 310 wr32(fbd, FBNIC_TCE_TXB_CTRL, 0); 311 312 /* Configure Tx QM Credits */ 313 wr32(fbd, FBNIC_QM_TQS_CTL1, 314 FIELD_PREP(FBNIC_QM_TQS_CTL1_MC_MAX_CREDITS, 0x40) | 315 FIELD_PREP(FBNIC_QM_TQS_CTL1_BULK_MAX_CREDITS, 0x20)); 316 317 /* Initialize internal Tx queues */ 318 wr32(fbd, FBNIC_TCE_TXB_TEI_Q0_CTRL, 0); 319 wr32(fbd, FBNIC_TCE_TXB_TEI_Q1_CTRL, 0); 320 wr32(fbd, FBNIC_TCE_TXB_MC_Q_CTRL, 321 FIELD_PREP(FBNIC_TCE_TXB_Q_CTRL_SIZE, 0x400) | 322 FIELD_PREP(FBNIC_TCE_TXB_Q_CTRL_START, 0x000)); 323 wr32(fbd, FBNIC_TCE_TXB_RX_TEI_Q_CTRL, 0); 324 wr32(fbd, FBNIC_TCE_TXB_TX_BMC_Q_CTRL, 325 FIELD_PREP(FBNIC_TCE_TXB_Q_CTRL_SIZE, 0x200) | 326 FIELD_PREP(FBNIC_TCE_TXB_Q_CTRL_START, 0x400)); 327 wr32(fbd, FBNIC_TCE_TXB_RX_BMC_Q_CTRL, 328 FIELD_PREP(FBNIC_TCE_TXB_Q_CTRL_SIZE, 0x200) | 329 FIELD_PREP(FBNIC_TCE_TXB_Q_CTRL_START, 0x600)); 330 331 wr32(fbd, FBNIC_TCE_LSO_CTRL, 332 FBNIC_TCE_LSO_CTRL_IPID_MODE_INC | 333 FIELD_PREP(FBNIC_TCE_LSO_CTRL_TCPF_CLR_1ST, TCPHDR_PSH | 334 TCPHDR_FIN) | 335 FIELD_PREP(FBNIC_TCE_LSO_CTRL_TCPF_CLR_MID, TCPHDR_PSH | 336 TCPHDR_CWR | 337 TCPHDR_FIN) | 338 FIELD_PREP(FBNIC_TCE_LSO_CTRL_TCPF_CLR_END, TCPHDR_CWR)); 339 wr32(fbd, FBNIC_TCE_CSO_CTRL, 0); 340 341 wr32(fbd, FBNIC_TCE_BMC_MAX_PKTSZ, 342 FIELD_PREP(FBNIC_TCE_BMC_MAX_PKTSZ_TX, 343 FBNIC_MAX_JUMBO_FRAME_SIZE) | 344 FIELD_PREP(FBNIC_TCE_BMC_MAX_PKTSZ_RX, 345 FBNIC_MAX_JUMBO_FRAME_SIZE)); 346 wr32(fbd, FBNIC_TCE_MC_MAX_PKTSZ, 347 FIELD_PREP(FBNIC_TCE_MC_MAX_PKTSZ_TMI, 348 FBNIC_MAX_JUMBO_FRAME_SIZE)); 349 350 /* Configure calendar slots. 351 * Tx: 0 - 62 TMI 1st, BMC 2nd 352 * 63 BMC 1st, TMI 2nd 353 */ 354 for (i = 0; i < 16; i++) { 355 u32 calendar_val = (i == 15) ? 0x1e1b1b1b : 0x1b1b1b1b; 356 357 wr32(fbd, FBNIC_TCE_TXB_CLDR_SLOT_CFG(i), calendar_val); 358 } 359 360 /* Configure DWRR */ 361 wr32(fbd, FBNIC_TCE_TXB_ENQ_WRR_CTRL, 362 FIELD_PREP(FBNIC_TCE_TXB_ENQ_WRR_CTRL_WEIGHT0, 0x64) | 363 FIELD_PREP(FBNIC_TCE_TXB_ENQ_WRR_CTRL_WEIGHT2, 0x04)); 364 wr32(fbd, FBNIC_TCE_TXB_TEI_DWRR_CTRL, 0); 365 wr32(fbd, FBNIC_TCE_TXB_TEI_DWRR_CTRL_EXT, 0); 366 wr32(fbd, FBNIC_TCE_TXB_BMC_DWRR_CTRL, 367 FIELD_PREP(FBNIC_TCE_TXB_BMC_DWRR_CTRL_QUANTUM0, 0x50) | 368 FIELD_PREP(FBNIC_TCE_TXB_BMC_DWRR_CTRL_QUANTUM1, 0x82)); 369 wr32(fbd, FBNIC_TCE_TXB_BMC_DWRR_CTRL_EXT, 0); 370 wr32(fbd, FBNIC_TCE_TXB_NTWRK_DWRR_CTRL, 371 FIELD_PREP(FBNIC_TCE_TXB_NTWRK_DWRR_CTRL_QUANTUM1, 0x50) | 372 FIELD_PREP(FBNIC_TCE_TXB_NTWRK_DWRR_CTRL_QUANTUM2, 0x20)); 373 wr32(fbd, FBNIC_TCE_TXB_NTWRK_DWRR_CTRL_EXT, 374 FIELD_PREP(FBNIC_TCE_TXB_NTWRK_DWRR_CTRL_QUANTUM2, 0x03)); 375 376 /* Configure SOP protocol protection */ 377 wr32(fbd, FBNIC_TCE_SOP_PROT_CTRL, 378 FIELD_PREP(FBNIC_TCE_SOP_PROT_CTRL_TBI, 0x78) | 379 FIELD_PREP(FBNIC_TCE_SOP_PROT_CTRL_TTI_FRM, 0x40) | 380 FIELD_PREP(FBNIC_TCE_SOP_PROT_CTRL_TTI_CM, 0x0c)); 381 382 /* Conservative configuration on MAC interface Start of Packet 383 * protection FIFO. This sets the minimum depth of the FIFO before 384 * we start sending packets to the MAC measured in 64B units and 385 * up to 160 entries deep. 386 * 387 * For the ASIC the clock is fast enough that we will likely fill 388 * the SOP FIFO before the MAC can drain it. So just use a minimum 389 * value of 8. 390 */ 391 wr32(fbd, FBNIC_TMI_SOP_PROT_CTRL, 8); 392 393 wrfl(fbd); 394 wr32(fbd, FBNIC_TCE_TXB_CTRL, FBNIC_TCE_TXB_CTRL_TCAM_ENABLE | 395 FBNIC_TCE_TXB_CTRL_LOAD); 396 } 397 398 static void fbnic_mac_init_regs(struct fbnic_dev *fbd) 399 { 400 fbnic_mac_init_axi(fbd); 401 fbnic_mac_init_qm(fbd); 402 fbnic_mac_init_rxb(fbd); 403 fbnic_mac_init_txb(fbd); 404 } 405 406 static void fbnic_mac_tx_pause_config(struct fbnic_dev *fbd, bool tx_pause) 407 { 408 u32 rxb_pause_ctrl; 409 410 /* Enable generation of pause frames if enabled */ 411 rxb_pause_ctrl = rd32(fbd, FBNIC_RXB_PAUSE_DROP_CTRL); 412 rxb_pause_ctrl &= ~FBNIC_RXB_PAUSE_DROP_CTRL_PAUSE_ENABLE; 413 if (tx_pause) 414 rxb_pause_ctrl |= 415 FIELD_PREP(FBNIC_RXB_PAUSE_DROP_CTRL_PAUSE_ENABLE, 416 FBNIC_PAUSE_EN_MASK); 417 wr32(fbd, FBNIC_RXB_PAUSE_DROP_CTRL, rxb_pause_ctrl); 418 } 419 420 static int fbnic_pcs_get_link_event_asic(struct fbnic_dev *fbd) 421 { 422 u32 pcs_intr_mask = rd32(fbd, FBNIC_SIG_PCS_INTR_STS); 423 424 if (pcs_intr_mask & FBNIC_SIG_PCS_INTR_LINK_DOWN) 425 return FBNIC_LINK_EVENT_DOWN; 426 427 return (pcs_intr_mask & FBNIC_SIG_PCS_INTR_LINK_UP) ? 428 FBNIC_LINK_EVENT_UP : FBNIC_LINK_EVENT_NONE; 429 } 430 431 static u32 __fbnic_mac_cmd_config_asic(struct fbnic_dev *fbd, 432 bool tx_pause, bool rx_pause) 433 { 434 /* Enable MAC Promiscuous mode and Tx padding */ 435 u32 command_config = FBNIC_MAC_COMMAND_CONFIG_TX_PAD_EN | 436 FBNIC_MAC_COMMAND_CONFIG_PROMISC_EN; 437 struct fbnic_net *fbn = netdev_priv(fbd->netdev); 438 439 /* Disable pause frames if not enabled */ 440 if (!tx_pause) 441 command_config |= FBNIC_MAC_COMMAND_CONFIG_TX_PAUSE_DIS; 442 if (!rx_pause) 443 command_config |= FBNIC_MAC_COMMAND_CONFIG_RX_PAUSE_DIS; 444 445 /* Disable fault handling if no FEC is requested */ 446 if ((fbn->fec & FBNIC_FEC_MODE_MASK) == FBNIC_FEC_OFF) 447 command_config |= FBNIC_MAC_COMMAND_CONFIG_FLT_HDL_DIS; 448 449 return command_config; 450 } 451 452 static bool fbnic_mac_get_pcs_link_status(struct fbnic_dev *fbd) 453 { 454 struct fbnic_net *fbn = netdev_priv(fbd->netdev); 455 u32 pcs_status, lane_mask = ~0; 456 457 pcs_status = rd32(fbd, FBNIC_SIG_PCS_OUT0); 458 if (!(pcs_status & FBNIC_SIG_PCS_OUT0_LINK)) 459 return false; 460 461 /* Define the expected lane mask for the status bits we need to check */ 462 switch (fbn->link_mode & FBNIC_LINK_MODE_MASK) { 463 case FBNIC_LINK_100R2: 464 lane_mask = 0xf; 465 break; 466 case FBNIC_LINK_50R1: 467 lane_mask = 3; 468 break; 469 case FBNIC_LINK_50R2: 470 switch (fbn->fec & FBNIC_FEC_MODE_MASK) { 471 case FBNIC_FEC_OFF: 472 lane_mask = 0x63; 473 break; 474 case FBNIC_FEC_RS: 475 lane_mask = 5; 476 break; 477 case FBNIC_FEC_BASER: 478 lane_mask = 0xf; 479 break; 480 } 481 break; 482 case FBNIC_LINK_25R1: 483 lane_mask = 1; 484 break; 485 } 486 487 /* Use an XOR to remove the bits we expect to see set */ 488 switch (fbn->fec & FBNIC_FEC_MODE_MASK) { 489 case FBNIC_FEC_OFF: 490 lane_mask ^= FIELD_GET(FBNIC_SIG_PCS_OUT0_BLOCK_LOCK, 491 pcs_status); 492 break; 493 case FBNIC_FEC_RS: 494 lane_mask ^= FIELD_GET(FBNIC_SIG_PCS_OUT0_AMPS_LOCK, 495 pcs_status); 496 break; 497 case FBNIC_FEC_BASER: 498 lane_mask ^= FIELD_GET(FBNIC_SIG_PCS_OUT1_FCFEC_LOCK, 499 rd32(fbd, FBNIC_SIG_PCS_OUT1)); 500 break; 501 } 502 503 /* If all lanes cancelled then we have a lock on all lanes */ 504 return !lane_mask; 505 } 506 507 static bool fbnic_pcs_get_link_asic(struct fbnic_dev *fbd) 508 { 509 bool link; 510 511 /* Flush status bits to clear possible stale data, 512 * bits should reset themselves back to 1 if link is truly up 513 */ 514 wr32(fbd, FBNIC_SIG_PCS_OUT0, FBNIC_SIG_PCS_OUT0_LINK | 515 FBNIC_SIG_PCS_OUT0_BLOCK_LOCK | 516 FBNIC_SIG_PCS_OUT0_AMPS_LOCK); 517 wr32(fbd, FBNIC_SIG_PCS_OUT1, FBNIC_SIG_PCS_OUT1_FCFEC_LOCK); 518 wrfl(fbd); 519 520 /* Clear interrupt state due to recent changes. */ 521 wr32(fbd, FBNIC_SIG_PCS_INTR_STS, 522 FBNIC_SIG_PCS_INTR_LINK_DOWN | FBNIC_SIG_PCS_INTR_LINK_UP); 523 524 link = fbnic_mac_get_pcs_link_status(fbd); 525 526 /* Enable interrupt to only capture changes in link state */ 527 wr32(fbd, FBNIC_SIG_PCS_INTR_MASK, 528 ~FBNIC_SIG_PCS_INTR_LINK_DOWN & ~FBNIC_SIG_PCS_INTR_LINK_UP); 529 wr32(fbd, FBNIC_INTR_MASK_CLEAR(0), 1u << FBNIC_PCS_MSIX_ENTRY); 530 531 return link; 532 } 533 534 static void fbnic_pcs_get_fw_settings(struct fbnic_dev *fbd) 535 { 536 struct fbnic_net *fbn = netdev_priv(fbd->netdev); 537 u8 link_mode = fbn->link_mode; 538 u8 fec = fbn->fec; 539 540 /* Update FEC first to reflect FW current mode */ 541 if (fbn->fec & FBNIC_FEC_AUTO) { 542 switch (fbd->fw_cap.link_fec) { 543 case FBNIC_FW_LINK_FEC_NONE: 544 fec = FBNIC_FEC_OFF; 545 break; 546 case FBNIC_FW_LINK_FEC_RS: 547 fec = FBNIC_FEC_RS; 548 break; 549 case FBNIC_FW_LINK_FEC_BASER: 550 fec = FBNIC_FEC_BASER; 551 break; 552 default: 553 return; 554 } 555 556 fbn->fec = fec; 557 } 558 559 /* Do nothing if AUTO mode is not engaged */ 560 if (fbn->link_mode & FBNIC_LINK_AUTO) { 561 switch (fbd->fw_cap.link_speed) { 562 case FBNIC_FW_LINK_SPEED_25R1: 563 link_mode = FBNIC_LINK_25R1; 564 break; 565 case FBNIC_FW_LINK_SPEED_50R2: 566 link_mode = FBNIC_LINK_50R2; 567 break; 568 case FBNIC_FW_LINK_SPEED_50R1: 569 link_mode = FBNIC_LINK_50R1; 570 fec = FBNIC_FEC_RS; 571 break; 572 case FBNIC_FW_LINK_SPEED_100R2: 573 link_mode = FBNIC_LINK_100R2; 574 fec = FBNIC_FEC_RS; 575 break; 576 default: 577 return; 578 } 579 580 fbn->link_mode = link_mode; 581 } 582 } 583 584 static int fbnic_pcs_enable_asic(struct fbnic_dev *fbd) 585 { 586 /* Mask and clear the PCS interrupt, will be enabled by link handler */ 587 wr32(fbd, FBNIC_SIG_PCS_INTR_MASK, ~0); 588 wr32(fbd, FBNIC_SIG_PCS_INTR_STS, ~0); 589 590 /* Pull in settings from FW */ 591 fbnic_pcs_get_fw_settings(fbd); 592 593 return 0; 594 } 595 596 static void fbnic_pcs_disable_asic(struct fbnic_dev *fbd) 597 { 598 /* Mask and clear the PCS interrupt */ 599 wr32(fbd, FBNIC_SIG_PCS_INTR_MASK, ~0); 600 wr32(fbd, FBNIC_SIG_PCS_INTR_STS, ~0); 601 } 602 603 static void fbnic_mac_link_down_asic(struct fbnic_dev *fbd) 604 { 605 u32 cmd_cfg, mac_ctrl; 606 607 cmd_cfg = __fbnic_mac_cmd_config_asic(fbd, false, false); 608 mac_ctrl = rd32(fbd, FBNIC_SIG_MAC_IN0); 609 610 mac_ctrl |= FBNIC_SIG_MAC_IN0_RESET_FF_TX_CLK | 611 FBNIC_SIG_MAC_IN0_RESET_TX_CLK | 612 FBNIC_SIG_MAC_IN0_RESET_FF_RX_CLK | 613 FBNIC_SIG_MAC_IN0_RESET_RX_CLK; 614 615 wr32(fbd, FBNIC_SIG_MAC_IN0, mac_ctrl); 616 wr32(fbd, FBNIC_MAC_COMMAND_CONFIG, cmd_cfg); 617 } 618 619 static void fbnic_mac_link_up_asic(struct fbnic_dev *fbd, 620 bool tx_pause, bool rx_pause) 621 { 622 u32 cmd_cfg, mac_ctrl; 623 624 fbnic_mac_tx_pause_config(fbd, tx_pause); 625 626 cmd_cfg = __fbnic_mac_cmd_config_asic(fbd, tx_pause, rx_pause); 627 mac_ctrl = rd32(fbd, FBNIC_SIG_MAC_IN0); 628 629 mac_ctrl &= ~(FBNIC_SIG_MAC_IN0_RESET_FF_TX_CLK | 630 FBNIC_SIG_MAC_IN0_RESET_TX_CLK | 631 FBNIC_SIG_MAC_IN0_RESET_FF_RX_CLK | 632 FBNIC_SIG_MAC_IN0_RESET_RX_CLK); 633 cmd_cfg |= FBNIC_MAC_COMMAND_CONFIG_RX_ENA | 634 FBNIC_MAC_COMMAND_CONFIG_TX_ENA; 635 636 wr32(fbd, FBNIC_SIG_MAC_IN0, mac_ctrl); 637 wr32(fbd, FBNIC_MAC_COMMAND_CONFIG, cmd_cfg); 638 } 639 640 static const struct fbnic_mac fbnic_mac_asic = { 641 .init_regs = fbnic_mac_init_regs, 642 .pcs_enable = fbnic_pcs_enable_asic, 643 .pcs_disable = fbnic_pcs_disable_asic, 644 .pcs_get_link = fbnic_pcs_get_link_asic, 645 .pcs_get_link_event = fbnic_pcs_get_link_event_asic, 646 .link_down = fbnic_mac_link_down_asic, 647 .link_up = fbnic_mac_link_up_asic, 648 }; 649 650 /** 651 * fbnic_mac_init - Assign a MAC type and initialize the fbnic device 652 * @fbd: Device pointer to device to initialize 653 * 654 * Return: zero on success, negative on failure 655 * 656 * Initialize the MAC function pointers and initializes the MAC of 657 * the device. 658 **/ 659 int fbnic_mac_init(struct fbnic_dev *fbd) 660 { 661 fbd->mac = &fbnic_mac_asic; 662 663 fbd->mac->init_regs(fbd); 664 665 return 0; 666 } 667