fbnic_mac.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920
  1. // SPDX-License-Identifier: GPL-2.0
  2. /* Copyright (c) Meta Platforms, Inc. and affiliates. */
  3. #include <linux/bitfield.h>
  4. #include <net/tcp.h>
  5. #include "fbnic.h"
  6. #include "fbnic_mac.h"
  7. #include "fbnic_netdev.h"
  8. static void fbnic_init_readrq(struct fbnic_dev *fbd, unsigned int offset,
  9. unsigned int cls, unsigned int readrq)
  10. {
  11. u32 val = rd32(fbd, offset);
  12. /* The TDF_CTL masks are a superset of the RNI_RBP ones. So we can
  13. * use them when setting either the TDE_CTF or RNI_RBP registers.
  14. */
  15. val &= FBNIC_QM_TNI_TDF_CTL_MAX_OT | FBNIC_QM_TNI_TDF_CTL_MAX_OB;
  16. val |= FIELD_PREP(FBNIC_QM_TNI_TDF_CTL_MRRS, readrq) |
  17. FIELD_PREP(FBNIC_QM_TNI_TDF_CTL_CLS, cls);
  18. wr32(fbd, offset, val);
  19. }
  20. static void fbnic_init_mps(struct fbnic_dev *fbd, unsigned int offset,
  21. unsigned int cls, unsigned int mps)
  22. {
  23. u32 val = rd32(fbd, offset);
  24. /* Currently all MPS masks are identical so just use the first one */
  25. val &= ~(FBNIC_QM_TNI_TCM_CTL_MPS | FBNIC_QM_TNI_TCM_CTL_CLS);
  26. val |= FIELD_PREP(FBNIC_QM_TNI_TCM_CTL_MPS, mps) |
  27. FIELD_PREP(FBNIC_QM_TNI_TCM_CTL_CLS, cls);
  28. wr32(fbd, offset, val);
  29. }
  30. static void fbnic_mac_init_axi(struct fbnic_dev *fbd)
  31. {
  32. bool override_1k = false;
  33. int readrq, mps, cls;
  34. /* All of the values are based on being a power of 2 starting
  35. * with 64 == 0. Therefore we can either divide by 64 in the
  36. * case of constants, or just subtract 6 from the log2 of the value
  37. * in order to get the value we will be programming into the
  38. * registers.
  39. */
  40. readrq = ilog2(fbd->readrq) - 6;
  41. if (readrq > 3)
  42. override_1k = true;
  43. readrq = clamp(readrq, 0, 3);
  44. mps = ilog2(fbd->mps) - 6;
  45. mps = clamp(mps, 0, 3);
  46. cls = ilog2(L1_CACHE_BYTES) - 6;
  47. cls = clamp(cls, 0, 3);
  48. /* Configure Tx/Rx AXI Paths w/ Read Request and Max Payload sizes */
  49. fbnic_init_readrq(fbd, FBNIC_QM_TNI_TDF_CTL, cls, readrq);
  50. fbnic_init_mps(fbd, FBNIC_QM_TNI_TCM_CTL, cls, mps);
  51. /* Configure QM TNI TDE:
  52. * - Max outstanding AXI beats to 704(768 - 64) - guaranetees 8% of
  53. * buffer capacity to descriptors.
  54. * - Max outstanding transactions to 128
  55. */
  56. wr32(fbd, FBNIC_QM_TNI_TDE_CTL,
  57. FIELD_PREP(FBNIC_QM_TNI_TDE_CTL_MRRS_1K, override_1k ? 1 : 0) |
  58. FIELD_PREP(FBNIC_QM_TNI_TDE_CTL_MAX_OB, 704) |
  59. FIELD_PREP(FBNIC_QM_TNI_TDE_CTL_MAX_OT, 128) |
  60. FIELD_PREP(FBNIC_QM_TNI_TDE_CTL_MRRS, readrq) |
  61. FIELD_PREP(FBNIC_QM_TNI_TDE_CTL_CLS, cls));
  62. fbnic_init_readrq(fbd, FBNIC_QM_RNI_RBP_CTL, cls, readrq);
  63. fbnic_init_mps(fbd, FBNIC_QM_RNI_RDE_CTL, cls, mps);
  64. fbnic_init_mps(fbd, FBNIC_QM_RNI_RCM_CTL, cls, mps);
  65. }
  66. static void fbnic_mac_init_qm(struct fbnic_dev *fbd)
  67. {
  68. u64 default_meta = FIELD_PREP(FBNIC_TWD_L2_HLEN_MASK, ETH_HLEN) |
  69. FBNIC_TWD_FLAG_REQ_COMPLETION;
  70. u32 clock_freq;
  71. /* Configure default TWQ Metadata descriptor */
  72. wr32(fbd, FBNIC_QM_TWQ_DEFAULT_META_L,
  73. lower_32_bits(default_meta));
  74. wr32(fbd, FBNIC_QM_TWQ_DEFAULT_META_H,
  75. upper_32_bits(default_meta));
  76. /* Configure TSO behavior */
  77. wr32(fbd, FBNIC_QM_TQS_CTL0,
  78. FIELD_PREP(FBNIC_QM_TQS_CTL0_LSO_TS_MASK,
  79. FBNIC_QM_TQS_CTL0_LSO_TS_LAST) |
  80. FIELD_PREP(FBNIC_QM_TQS_CTL0_PREFETCH_THRESH,
  81. FBNIC_QM_TQS_CTL0_PREFETCH_THRESH_MIN));
  82. /* Limit EDT to INT_MAX as this is the limit of the EDT Qdisc */
  83. wr32(fbd, FBNIC_QM_TQS_EDT_TS_RANGE, INT_MAX);
  84. /* Configure MTU
  85. * Due to known HW issue we cannot set the MTU to within 16 octets
  86. * of a 64 octet aligned boundary. So we will set the TQS_MTU(s) to
  87. * MTU + 1.
  88. */
  89. wr32(fbd, FBNIC_QM_TQS_MTU_CTL0, FBNIC_MAX_JUMBO_FRAME_SIZE + 1);
  90. wr32(fbd, FBNIC_QM_TQS_MTU_CTL1,
  91. FIELD_PREP(FBNIC_QM_TQS_MTU_CTL1_BULK,
  92. FBNIC_MAX_JUMBO_FRAME_SIZE + 1));
  93. clock_freq = FBNIC_CLOCK_FREQ;
  94. /* Be aggressive on the timings. We will have the interrupt
  95. * threshold timer tick once every 1 usec and coalesce writes for
  96. * up to 80 usecs.
  97. */
  98. wr32(fbd, FBNIC_QM_TCQ_CTL0,
  99. FIELD_PREP(FBNIC_QM_TCQ_CTL0_TICK_CYCLES,
  100. clock_freq / 1000000) |
  101. FIELD_PREP(FBNIC_QM_TCQ_CTL0_COAL_WAIT,
  102. clock_freq / 12500));
  103. /* We will have the interrupt threshold timer tick once every
  104. * 1 usec and coalesce writes for up to 2 usecs.
  105. */
  106. wr32(fbd, FBNIC_QM_RCQ_CTL0,
  107. FIELD_PREP(FBNIC_QM_RCQ_CTL0_TICK_CYCLES,
  108. clock_freq / 1000000) |
  109. FIELD_PREP(FBNIC_QM_RCQ_CTL0_COAL_WAIT,
  110. clock_freq / 500000));
  111. /* Configure spacer control to 64 beats. */
  112. wr32(fbd, FBNIC_FAB_AXI4_AR_SPACER_2_CFG,
  113. FBNIC_FAB_AXI4_AR_SPACER_MASK |
  114. FIELD_PREP(FBNIC_FAB_AXI4_AR_SPACER_THREADSHOLD, 2));
  115. }
  116. #define FBNIC_DROP_EN_MASK 0x7d
  117. #define FBNIC_PAUSE_EN_MASK 0x14
  118. #define FBNIC_ECN_EN_MASK 0x10
  119. struct fbnic_fifo_config {
  120. unsigned int addr;
  121. unsigned int size;
  122. };
  123. /* Rx FIFO Configuration
  124. * The table consists of 8 entries, of which only 4 are currently used
  125. * The starting addr is in units of 64B and the size is in 2KB units
  126. * Below is the human readable version of the table defined below:
  127. * Function Addr Size
  128. * ----------------------------------
  129. * Network to Host/BMC 384K 64K
  130. * Unused
  131. * Unused
  132. * Network to BMC 448K 32K
  133. * Network to Host 0 384K
  134. * Unused
  135. * BMC to Host 480K 32K
  136. * Unused
  137. */
  138. static const struct fbnic_fifo_config fifo_config[] = {
  139. { .addr = 0x1800, .size = 0x20 }, /* Network to Host/BMC */
  140. { }, /* Unused */
  141. { }, /* Unused */
  142. { .addr = 0x1c00, .size = 0x10 }, /* Network to BMC */
  143. { .addr = 0x0000, .size = 0xc0 }, /* Network to Host */
  144. { }, /* Unused */
  145. { .addr = 0x1e00, .size = 0x10 }, /* BMC to Host */
  146. { } /* Unused */
  147. };
  148. static void fbnic_mac_init_rxb(struct fbnic_dev *fbd)
  149. {
  150. bool rx_enable;
  151. int i;
  152. rx_enable = !!(rd32(fbd, FBNIC_RPC_RMI_CONFIG) &
  153. FBNIC_RPC_RMI_CONFIG_ENABLE);
  154. for (i = 0; i < 8; i++) {
  155. unsigned int size = fifo_config[i].size;
  156. /* If we are coming up on a system that already has the
  157. * Rx data path enabled we don't need to reconfigure the
  158. * FIFOs. Instead we can check to verify the values are
  159. * large enough to meet our needs, and use the values to
  160. * populate the flow control, ECN, and drop thresholds.
  161. */
  162. if (rx_enable) {
  163. size = FIELD_GET(FBNIC_RXB_PBUF_SIZE,
  164. rd32(fbd, FBNIC_RXB_PBUF_CFG(i)));
  165. if (size < fifo_config[i].size)
  166. dev_warn(fbd->dev,
  167. "fifo%d size of %d smaller than expected value of %d\n",
  168. i, size << 11,
  169. fifo_config[i].size << 11);
  170. } else {
  171. /* Program RXB Cuthrough */
  172. wr32(fbd, FBNIC_RXB_CT_SIZE(i),
  173. FIELD_PREP(FBNIC_RXB_CT_SIZE_HEADER, 4) |
  174. FIELD_PREP(FBNIC_RXB_CT_SIZE_PAYLOAD, 2));
  175. /* The granularity for the packet buffer size is 2KB
  176. * granularity while the packet buffer base address is
  177. * only 64B granularity
  178. */
  179. wr32(fbd, FBNIC_RXB_PBUF_CFG(i),
  180. FIELD_PREP(FBNIC_RXB_PBUF_BASE_ADDR,
  181. fifo_config[i].addr) |
  182. FIELD_PREP(FBNIC_RXB_PBUF_SIZE, size));
  183. /* The granularity for the credits is 64B. This is
  184. * based on RXB_PBUF_SIZE * 32 + 4.
  185. */
  186. wr32(fbd, FBNIC_RXB_PBUF_CREDIT(i),
  187. FIELD_PREP(FBNIC_RXB_PBUF_CREDIT_MASK,
  188. size ? size * 32 + 4 : 0));
  189. }
  190. if (!size)
  191. continue;
  192. /* Pause is size of FIFO with 56KB skid to start/stop */
  193. wr32(fbd, FBNIC_RXB_PAUSE_THLD(i),
  194. !(FBNIC_PAUSE_EN_MASK & (1u << i)) ? 0x1fff :
  195. FIELD_PREP(FBNIC_RXB_PAUSE_THLD_ON,
  196. size * 32 - 0x380) |
  197. FIELD_PREP(FBNIC_RXB_PAUSE_THLD_OFF, 0x380));
  198. /* Enable Drop when only one packet is left in the FIFO */
  199. wr32(fbd, FBNIC_RXB_DROP_THLD(i),
  200. !(FBNIC_DROP_EN_MASK & (1u << i)) ? 0x1fff :
  201. FIELD_PREP(FBNIC_RXB_DROP_THLD_ON,
  202. size * 32 -
  203. FBNIC_MAX_JUMBO_FRAME_SIZE / 64) |
  204. FIELD_PREP(FBNIC_RXB_DROP_THLD_OFF,
  205. size * 32 -
  206. FBNIC_MAX_JUMBO_FRAME_SIZE / 64));
  207. /* Enable ECN bit when 1/4 of RXB is filled with at least
  208. * 1 room for one full jumbo frame before setting ECN
  209. */
  210. wr32(fbd, FBNIC_RXB_ECN_THLD(i),
  211. !(FBNIC_ECN_EN_MASK & (1u << i)) ? 0x1fff :
  212. FIELD_PREP(FBNIC_RXB_ECN_THLD_ON,
  213. max_t(unsigned int,
  214. size * 32 / 4,
  215. FBNIC_MAX_JUMBO_FRAME_SIZE / 64)) |
  216. FIELD_PREP(FBNIC_RXB_ECN_THLD_OFF,
  217. max_t(unsigned int,
  218. size * 32 / 4,
  219. FBNIC_MAX_JUMBO_FRAME_SIZE / 64)));
  220. }
  221. /* For now only enable drop and ECN. We need to add driver/kernel
  222. * interfaces for configuring pause.
  223. */
  224. wr32(fbd, FBNIC_RXB_PAUSE_DROP_CTRL,
  225. FIELD_PREP(FBNIC_RXB_PAUSE_DROP_CTRL_DROP_ENABLE,
  226. FBNIC_DROP_EN_MASK) |
  227. FIELD_PREP(FBNIC_RXB_PAUSE_DROP_CTRL_ECN_ENABLE,
  228. FBNIC_ECN_EN_MASK));
  229. /* Program INTF credits */
  230. wr32(fbd, FBNIC_RXB_INTF_CREDIT,
  231. FBNIC_RXB_INTF_CREDIT_MASK0 |
  232. FBNIC_RXB_INTF_CREDIT_MASK1 |
  233. FBNIC_RXB_INTF_CREDIT_MASK2 |
  234. FIELD_PREP(FBNIC_RXB_INTF_CREDIT_MASK3, 8));
  235. /* Configure calendar slots.
  236. * Rx: 0 - 62 RDE 1st, BMC 2nd
  237. * 63 BMC 1st, RDE 2nd
  238. */
  239. for (i = 0; i < 16; i++) {
  240. u32 calendar_val = (i == 15) ? 0x1e1b1b1b : 0x1b1b1b1b;
  241. wr32(fbd, FBNIC_RXB_CLDR_PRIO_CFG(i), calendar_val);
  242. }
  243. /* Split the credits for the DRR up as follows:
  244. * Quantum0: 8000 Network to Host
  245. * Quantum1: 0 Not used
  246. * Quantum2: 80 BMC to Host
  247. * Quantum3: 0 Not used
  248. * Quantum4: 8000 Multicast to Host and BMC
  249. */
  250. wr32(fbd, FBNIC_RXB_DWRR_RDE_WEIGHT0,
  251. FIELD_PREP(FBNIC_RXB_DWRR_RDE_WEIGHT0_QUANTUM0, 0x40) |
  252. FIELD_PREP(FBNIC_RXB_DWRR_RDE_WEIGHT0_QUANTUM2, 0x50));
  253. wr32(fbd, FBNIC_RXB_DWRR_RDE_WEIGHT0_EXT,
  254. FIELD_PREP(FBNIC_RXB_DWRR_RDE_WEIGHT0_QUANTUM0, 0x1f));
  255. wr32(fbd, FBNIC_RXB_DWRR_RDE_WEIGHT1,
  256. FIELD_PREP(FBNIC_RXB_DWRR_RDE_WEIGHT1_QUANTUM4, 0x40));
  257. wr32(fbd, FBNIC_RXB_DWRR_RDE_WEIGHT1_EXT,
  258. FIELD_PREP(FBNIC_RXB_DWRR_RDE_WEIGHT1_QUANTUM4, 0x1f));
  259. /* Program RXB FCS Endian register */
  260. wr32(fbd, FBNIC_RXB_ENDIAN_FCS, 0x0aaaaaa0);
  261. }
  262. static void fbnic_mac_init_txb(struct fbnic_dev *fbd)
  263. {
  264. int i;
  265. wr32(fbd, FBNIC_TCE_TXB_CTRL, 0);
  266. /* Configure Tx QM Credits */
  267. wr32(fbd, FBNIC_QM_TQS_CTL1,
  268. FIELD_PREP(FBNIC_QM_TQS_CTL1_MC_MAX_CREDITS, 0x40) |
  269. FIELD_PREP(FBNIC_QM_TQS_CTL1_BULK_MAX_CREDITS, 0x20));
  270. /* Initialize internal Tx queues */
  271. wr32(fbd, FBNIC_TCE_TXB_TEI_Q0_CTRL, 0);
  272. wr32(fbd, FBNIC_TCE_TXB_TEI_Q1_CTRL, 0);
  273. wr32(fbd, FBNIC_TCE_TXB_MC_Q_CTRL,
  274. FIELD_PREP(FBNIC_TCE_TXB_Q_CTRL_SIZE, 0x400) |
  275. FIELD_PREP(FBNIC_TCE_TXB_Q_CTRL_START, 0x000));
  276. wr32(fbd, FBNIC_TCE_TXB_RX_TEI_Q_CTRL, 0);
  277. wr32(fbd, FBNIC_TCE_TXB_TX_BMC_Q_CTRL,
  278. FIELD_PREP(FBNIC_TCE_TXB_Q_CTRL_SIZE, 0x200) |
  279. FIELD_PREP(FBNIC_TCE_TXB_Q_CTRL_START, 0x400));
  280. wr32(fbd, FBNIC_TCE_TXB_RX_BMC_Q_CTRL,
  281. FIELD_PREP(FBNIC_TCE_TXB_Q_CTRL_SIZE, 0x200) |
  282. FIELD_PREP(FBNIC_TCE_TXB_Q_CTRL_START, 0x600));
  283. wr32(fbd, FBNIC_TCE_LSO_CTRL,
  284. FBNIC_TCE_LSO_CTRL_IPID_MODE_INC |
  285. FIELD_PREP(FBNIC_TCE_LSO_CTRL_TCPF_CLR_1ST, TCPHDR_PSH |
  286. TCPHDR_FIN) |
  287. FIELD_PREP(FBNIC_TCE_LSO_CTRL_TCPF_CLR_MID, TCPHDR_PSH |
  288. TCPHDR_CWR |
  289. TCPHDR_FIN) |
  290. FIELD_PREP(FBNIC_TCE_LSO_CTRL_TCPF_CLR_END, TCPHDR_CWR));
  291. wr32(fbd, FBNIC_TCE_CSO_CTRL, 0);
  292. wr32(fbd, FBNIC_TCE_BMC_MAX_PKTSZ,
  293. FIELD_PREP(FBNIC_TCE_BMC_MAX_PKTSZ_TX,
  294. FBNIC_MAX_JUMBO_FRAME_SIZE) |
  295. FIELD_PREP(FBNIC_TCE_BMC_MAX_PKTSZ_RX,
  296. FBNIC_MAX_JUMBO_FRAME_SIZE));
  297. wr32(fbd, FBNIC_TCE_MC_MAX_PKTSZ,
  298. FIELD_PREP(FBNIC_TCE_MC_MAX_PKTSZ_TMI,
  299. FBNIC_MAX_JUMBO_FRAME_SIZE));
  300. /* Configure calendar slots.
  301. * Tx: 0 - 62 TMI 1st, BMC 2nd
  302. * 63 BMC 1st, TMI 2nd
  303. */
  304. for (i = 0; i < 16; i++) {
  305. u32 calendar_val = (i == 15) ? 0x1e1b1b1b : 0x1b1b1b1b;
  306. wr32(fbd, FBNIC_TCE_TXB_CLDR_SLOT_CFG(i), calendar_val);
  307. }
  308. /* Configure DWRR */
  309. wr32(fbd, FBNIC_TCE_TXB_ENQ_WRR_CTRL,
  310. FIELD_PREP(FBNIC_TCE_TXB_ENQ_WRR_CTRL_WEIGHT0, 0x64) |
  311. FIELD_PREP(FBNIC_TCE_TXB_ENQ_WRR_CTRL_WEIGHT2, 0x04));
  312. wr32(fbd, FBNIC_TCE_TXB_TEI_DWRR_CTRL, 0);
  313. wr32(fbd, FBNIC_TCE_TXB_TEI_DWRR_CTRL_EXT, 0);
  314. wr32(fbd, FBNIC_TCE_TXB_BMC_DWRR_CTRL,
  315. FIELD_PREP(FBNIC_TCE_TXB_BMC_DWRR_CTRL_QUANTUM0, 0x50) |
  316. FIELD_PREP(FBNIC_TCE_TXB_BMC_DWRR_CTRL_QUANTUM1, 0x82));
  317. wr32(fbd, FBNIC_TCE_TXB_BMC_DWRR_CTRL_EXT, 0);
  318. wr32(fbd, FBNIC_TCE_TXB_NTWRK_DWRR_CTRL,
  319. FIELD_PREP(FBNIC_TCE_TXB_NTWRK_DWRR_CTRL_QUANTUM1, 0x50) |
  320. FIELD_PREP(FBNIC_TCE_TXB_NTWRK_DWRR_CTRL_QUANTUM2, 0x20));
  321. wr32(fbd, FBNIC_TCE_TXB_NTWRK_DWRR_CTRL_EXT,
  322. FIELD_PREP(FBNIC_TCE_TXB_NTWRK_DWRR_CTRL_QUANTUM2, 0x03));
  323. /* Configure SOP protocol protection */
  324. wr32(fbd, FBNIC_TCE_SOP_PROT_CTRL,
  325. FIELD_PREP(FBNIC_TCE_SOP_PROT_CTRL_TBI, 0x78) |
  326. FIELD_PREP(FBNIC_TCE_SOP_PROT_CTRL_TTI_FRM, 0x40) |
  327. FIELD_PREP(FBNIC_TCE_SOP_PROT_CTRL_TTI_CM, 0x0c));
  328. /* Conservative configuration on MAC interface Start of Packet
  329. * protection FIFO. This sets the minimum depth of the FIFO before
  330. * we start sending packets to the MAC measured in 64B units and
  331. * up to 160 entries deep.
  332. *
  333. * For the ASIC the clock is fast enough that we will likely fill
  334. * the SOP FIFO before the MAC can drain it. So just use a minimum
  335. * value of 8.
  336. */
  337. wr32(fbd, FBNIC_TMI_SOP_PROT_CTRL, 8);
  338. wrfl(fbd);
  339. wr32(fbd, FBNIC_TCE_TXB_CTRL, FBNIC_TCE_TXB_CTRL_TCAM_ENABLE |
  340. FBNIC_TCE_TXB_CTRL_LOAD);
  341. }
  342. static void fbnic_mac_init_regs(struct fbnic_dev *fbd)
  343. {
  344. fbnic_mac_init_axi(fbd);
  345. fbnic_mac_init_qm(fbd);
  346. fbnic_mac_init_rxb(fbd);
  347. fbnic_mac_init_txb(fbd);
  348. }
  349. static void __fbnic_mac_stat_rd64(struct fbnic_dev *fbd, bool reset, u32 reg,
  350. struct fbnic_stat_counter *stat)
  351. {
  352. u64 new_reg_value;
  353. new_reg_value = fbnic_stat_rd64(fbd, reg, 1);
  354. if (!reset)
  355. stat->value += new_reg_value - stat->u.old_reg_value_64;
  356. stat->u.old_reg_value_64 = new_reg_value;
  357. stat->reported = true;
  358. }
  359. #define fbnic_mac_stat_rd64(fbd, reset, __stat, __CSR) \
  360. __fbnic_mac_stat_rd64(fbd, reset, FBNIC_##__CSR##_L, &(__stat))
  361. static void fbnic_mac_tx_pause_config(struct fbnic_dev *fbd, bool tx_pause)
  362. {
  363. u32 rxb_pause_ctrl;
  364. /* Enable generation of pause frames if enabled */
  365. rxb_pause_ctrl = rd32(fbd, FBNIC_RXB_PAUSE_DROP_CTRL);
  366. rxb_pause_ctrl &= ~FBNIC_RXB_PAUSE_DROP_CTRL_PAUSE_ENABLE;
  367. if (tx_pause)
  368. rxb_pause_ctrl |=
  369. FIELD_PREP(FBNIC_RXB_PAUSE_DROP_CTRL_PAUSE_ENABLE,
  370. FBNIC_PAUSE_EN_MASK);
  371. wr32(fbd, FBNIC_RXB_PAUSE_DROP_CTRL, rxb_pause_ctrl);
  372. }
  373. static int fbnic_mac_get_link_event(struct fbnic_dev *fbd)
  374. {
  375. u32 intr_mask = rd32(fbd, FBNIC_SIG_PCS_INTR_STS);
  376. if (intr_mask & FBNIC_SIG_PCS_INTR_LINK_DOWN)
  377. return FBNIC_LINK_EVENT_DOWN;
  378. return (intr_mask & FBNIC_SIG_PCS_INTR_LINK_UP) ?
  379. FBNIC_LINK_EVENT_UP : FBNIC_LINK_EVENT_NONE;
  380. }
  381. static u32 __fbnic_mac_cmd_config_asic(struct fbnic_dev *fbd,
  382. bool tx_pause, bool rx_pause)
  383. {
  384. /* Enable MAC Promiscuous mode and Tx padding */
  385. u32 command_config = FBNIC_MAC_COMMAND_CONFIG_TX_PAD_EN |
  386. FBNIC_MAC_COMMAND_CONFIG_PROMISC_EN;
  387. struct fbnic_net *fbn = netdev_priv(fbd->netdev);
  388. /* Disable pause frames if not enabled */
  389. if (!tx_pause)
  390. command_config |= FBNIC_MAC_COMMAND_CONFIG_TX_PAUSE_DIS;
  391. if (!rx_pause)
  392. command_config |= FBNIC_MAC_COMMAND_CONFIG_RX_PAUSE_DIS;
  393. /* Disable fault handling if no FEC is requested */
  394. if (fbn->fec == FBNIC_FEC_OFF)
  395. command_config |= FBNIC_MAC_COMMAND_CONFIG_FLT_HDL_DIS;
  396. return command_config;
  397. }
  398. static bool fbnic_mac_get_link_status(struct fbnic_dev *fbd, u8 aui, u8 fec)
  399. {
  400. u32 pcs_status, lane_mask = ~0;
  401. pcs_status = rd32(fbd, FBNIC_SIG_PCS_OUT0);
  402. if (!(pcs_status & FBNIC_SIG_PCS_OUT0_LINK))
  403. return false;
  404. /* Define the expected lane mask for the status bits we need to check */
  405. switch (aui) {
  406. case FBNIC_AUI_100GAUI2:
  407. lane_mask = 0xf;
  408. break;
  409. case FBNIC_AUI_50GAUI1:
  410. lane_mask = 3;
  411. break;
  412. case FBNIC_AUI_LAUI2:
  413. switch (fec) {
  414. case FBNIC_FEC_OFF:
  415. lane_mask = 0x63;
  416. break;
  417. case FBNIC_FEC_RS:
  418. lane_mask = 5;
  419. break;
  420. case FBNIC_FEC_BASER:
  421. lane_mask = 0xf;
  422. break;
  423. }
  424. break;
  425. case FBNIC_AUI_25GAUI:
  426. lane_mask = 1;
  427. break;
  428. }
  429. /* Use an XOR to remove the bits we expect to see set */
  430. switch (fec) {
  431. case FBNIC_FEC_OFF:
  432. lane_mask ^= FIELD_GET(FBNIC_SIG_PCS_OUT0_BLOCK_LOCK,
  433. pcs_status);
  434. break;
  435. case FBNIC_FEC_RS:
  436. lane_mask ^= FIELD_GET(FBNIC_SIG_PCS_OUT0_AMPS_LOCK,
  437. pcs_status);
  438. break;
  439. case FBNIC_FEC_BASER:
  440. lane_mask ^= FIELD_GET(FBNIC_SIG_PCS_OUT1_FCFEC_LOCK,
  441. rd32(fbd, FBNIC_SIG_PCS_OUT1));
  442. break;
  443. }
  444. /* If all lanes cancelled then we have a lock on all lanes */
  445. return !lane_mask;
  446. }
  447. static bool fbnic_pmd_update_state(struct fbnic_dev *fbd, bool signal_detect)
  448. {
  449. /* Delay link up for 4 seconds to allow for link training.
  450. * The state transitions for this are as follows:
  451. *
  452. * All states have the following two transitions in common:
  453. * Loss of signal -> FBNIC_PMD_INITIALIZE
  454. * The condition handled below (!signal)
  455. * Reconfiguration -> FBNIC_PMD_INITIALIZE
  456. * Occurs when mac_prepare starts a PHY reconfig
  457. * FBNIC_PMD_TRAINING:
  458. * signal still detected && 4s have passed -> Report link up
  459. * When link is brought up in link_up -> FBNIC_PMD_SEND_DATA
  460. * FBNIC_PMD_INITIALIZE:
  461. * signal detected -> FBNIC_PMD_TRAINING
  462. */
  463. if (!signal_detect) {
  464. fbd->pmd_state = FBNIC_PMD_INITIALIZE;
  465. return false;
  466. }
  467. switch (fbd->pmd_state) {
  468. case FBNIC_PMD_TRAINING:
  469. return time_before(fbd->end_of_pmd_training, jiffies);
  470. case FBNIC_PMD_LINK_READY:
  471. case FBNIC_PMD_SEND_DATA:
  472. return true;
  473. }
  474. fbd->end_of_pmd_training = jiffies + 4 * HZ;
  475. /* Ensure end_of_training is visible before the state change */
  476. smp_wmb();
  477. fbd->pmd_state = FBNIC_PMD_TRAINING;
  478. return false;
  479. }
  480. static bool fbnic_mac_get_link(struct fbnic_dev *fbd, u8 aui, u8 fec)
  481. {
  482. bool link;
  483. /* Flush status bits to clear possible stale data,
  484. * bits should reset themselves back to 1 if link is truly up
  485. */
  486. wr32(fbd, FBNIC_SIG_PCS_OUT0, FBNIC_SIG_PCS_OUT0_LINK |
  487. FBNIC_SIG_PCS_OUT0_BLOCK_LOCK |
  488. FBNIC_SIG_PCS_OUT0_AMPS_LOCK);
  489. wr32(fbd, FBNIC_SIG_PCS_OUT1, FBNIC_SIG_PCS_OUT1_FCFEC_LOCK);
  490. wrfl(fbd);
  491. /* Clear interrupt state due to recent changes. */
  492. wr32(fbd, FBNIC_SIG_PCS_INTR_STS,
  493. FBNIC_SIG_PCS_INTR_LINK_DOWN | FBNIC_SIG_PCS_INTR_LINK_UP);
  494. link = fbnic_mac_get_link_status(fbd, aui, fec);
  495. link = fbnic_pmd_update_state(fbd, link);
  496. /* Enable interrupt to only capture changes in link state */
  497. wr32(fbd, FBNIC_SIG_PCS_INTR_MASK,
  498. ~FBNIC_SIG_PCS_INTR_LINK_DOWN & ~FBNIC_SIG_PCS_INTR_LINK_UP);
  499. wr32(fbd, FBNIC_INTR_MASK_CLEAR(0), 1u << FBNIC_PCS_MSIX_ENTRY);
  500. return link;
  501. }
  502. void fbnic_mac_get_fw_settings(struct fbnic_dev *fbd, u8 *aui, u8 *fec)
  503. {
  504. /* Retrieve default speed from FW */
  505. switch (fbd->fw_cap.link_speed) {
  506. case FBNIC_FW_LINK_MODE_25CR:
  507. *aui = FBNIC_AUI_25GAUI;
  508. break;
  509. case FBNIC_FW_LINK_MODE_50CR2:
  510. *aui = FBNIC_AUI_LAUI2;
  511. break;
  512. case FBNIC_FW_LINK_MODE_50CR:
  513. *aui = FBNIC_AUI_50GAUI1;
  514. *fec = FBNIC_FEC_RS;
  515. return;
  516. case FBNIC_FW_LINK_MODE_100CR2:
  517. *aui = FBNIC_AUI_100GAUI2;
  518. *fec = FBNIC_FEC_RS;
  519. return;
  520. default:
  521. *aui = FBNIC_AUI_UNKNOWN;
  522. return;
  523. }
  524. /* Update FEC first to reflect FW current mode */
  525. switch (fbd->fw_cap.link_fec) {
  526. case FBNIC_FW_LINK_FEC_NONE:
  527. *fec = FBNIC_FEC_OFF;
  528. break;
  529. case FBNIC_FW_LINK_FEC_RS:
  530. default:
  531. *fec = FBNIC_FEC_RS;
  532. break;
  533. case FBNIC_FW_LINK_FEC_BASER:
  534. *fec = FBNIC_FEC_BASER;
  535. break;
  536. }
  537. }
  538. static void fbnic_mac_prepare(struct fbnic_dev *fbd, u8 aui, u8 fec)
  539. {
  540. /* Mask and clear the PCS interrupt, will be enabled by link handler */
  541. wr32(fbd, FBNIC_SIG_PCS_INTR_MASK, ~0);
  542. wr32(fbd, FBNIC_SIG_PCS_INTR_STS, ~0);
  543. /* If we don't have link tear it all down and start over */
  544. if (!fbnic_mac_get_link_status(fbd, aui, fec))
  545. fbd->pmd_state = FBNIC_PMD_INITIALIZE;
  546. }
  547. static void fbnic_mac_link_down_asic(struct fbnic_dev *fbd)
  548. {
  549. u32 cmd_cfg, mac_ctrl;
  550. cmd_cfg = __fbnic_mac_cmd_config_asic(fbd, false, false);
  551. mac_ctrl = rd32(fbd, FBNIC_SIG_MAC_IN0);
  552. mac_ctrl |= FBNIC_SIG_MAC_IN0_RESET_FF_TX_CLK |
  553. FBNIC_SIG_MAC_IN0_RESET_TX_CLK |
  554. FBNIC_SIG_MAC_IN0_RESET_FF_RX_CLK |
  555. FBNIC_SIG_MAC_IN0_RESET_RX_CLK;
  556. wr32(fbd, FBNIC_SIG_MAC_IN0, mac_ctrl);
  557. wr32(fbd, FBNIC_MAC_COMMAND_CONFIG, cmd_cfg);
  558. }
  559. static void fbnic_mac_link_up_asic(struct fbnic_dev *fbd,
  560. bool tx_pause, bool rx_pause)
  561. {
  562. u32 cmd_cfg, mac_ctrl;
  563. fbnic_mac_tx_pause_config(fbd, tx_pause);
  564. cmd_cfg = __fbnic_mac_cmd_config_asic(fbd, tx_pause, rx_pause);
  565. mac_ctrl = rd32(fbd, FBNIC_SIG_MAC_IN0);
  566. mac_ctrl &= ~(FBNIC_SIG_MAC_IN0_RESET_FF_TX_CLK |
  567. FBNIC_SIG_MAC_IN0_RESET_TX_CLK |
  568. FBNIC_SIG_MAC_IN0_RESET_FF_RX_CLK |
  569. FBNIC_SIG_MAC_IN0_RESET_RX_CLK);
  570. cmd_cfg |= FBNIC_MAC_COMMAND_CONFIG_RX_ENA |
  571. FBNIC_MAC_COMMAND_CONFIG_TX_ENA;
  572. wr32(fbd, FBNIC_SIG_MAC_IN0, mac_ctrl);
  573. wr32(fbd, FBNIC_MAC_COMMAND_CONFIG, cmd_cfg);
  574. }
  575. static void
  576. fbnic_pcs_rsfec_stat_rd32(struct fbnic_dev *fbd, u32 reg, bool reset,
  577. struct fbnic_stat_counter *stat)
  578. {
  579. u32 pcs_rsfec_stat;
  580. /* The PCS/RFSEC registers are only 16b wide each. So what we will
  581. * have after the 64b read is 0x0000xxxx0000xxxx. To make it usable
  582. * as a full stat we will shift the upper bits into the lower set of
  583. * 0s and then mask off the math at 32b.
  584. *
  585. * Read ordering must be lower reg followed by upper reg.
  586. */
  587. pcs_rsfec_stat = rd32(fbd, reg) & 0xffff;
  588. pcs_rsfec_stat |= rd32(fbd, reg + 1) << 16;
  589. /* RFSEC registers clear themselves upon being read so there is no
  590. * need to store the old_reg_value.
  591. */
  592. if (!reset)
  593. stat->value += pcs_rsfec_stat;
  594. }
  595. static void
  596. fbnic_mac_get_fec_stats(struct fbnic_dev *fbd, bool reset,
  597. struct fbnic_fec_stats *s)
  598. {
  599. fbnic_pcs_rsfec_stat_rd32(fbd, FBNIC_RSFEC_CCW_LO(0), reset,
  600. &s->corrected_blocks);
  601. fbnic_pcs_rsfec_stat_rd32(fbd, FBNIC_RSFEC_NCCW_LO(0), reset,
  602. &s->uncorrectable_blocks);
  603. }
  604. static void
  605. fbnic_mac_get_pcs_stats(struct fbnic_dev *fbd, bool reset,
  606. struct fbnic_pcs_stats *s)
  607. {
  608. int i;
  609. for (i = 0; i < FBNIC_PCS_MAX_LANES; i++)
  610. fbnic_pcs_rsfec_stat_rd32(fbd, FBNIC_PCS_SYMBLERR_LO(i), reset,
  611. &s->SymbolErrorDuringCarrier.lanes[i]);
  612. }
  613. static void
  614. fbnic_mac_get_eth_mac_stats(struct fbnic_dev *fbd, bool reset,
  615. struct fbnic_eth_mac_stats *mac_stats)
  616. {
  617. fbnic_mac_stat_rd64(fbd, reset, mac_stats->OctetsReceivedOK,
  618. MAC_STAT_RX_BYTE_COUNT);
  619. fbnic_mac_stat_rd64(fbd, reset, mac_stats->AlignmentErrors,
  620. MAC_STAT_RX_ALIGN_ERROR);
  621. fbnic_mac_stat_rd64(fbd, reset, mac_stats->FrameTooLongErrors,
  622. MAC_STAT_RX_TOOLONG);
  623. fbnic_mac_stat_rd64(fbd, reset, mac_stats->FramesReceivedOK,
  624. MAC_STAT_RX_RECEIVED_OK);
  625. fbnic_mac_stat_rd64(fbd, reset, mac_stats->FrameCheckSequenceErrors,
  626. MAC_STAT_RX_PACKET_BAD_FCS);
  627. fbnic_mac_stat_rd64(fbd, reset,
  628. mac_stats->FramesLostDueToIntMACRcvError,
  629. MAC_STAT_RX_IFINERRORS);
  630. fbnic_mac_stat_rd64(fbd, reset, mac_stats->MulticastFramesReceivedOK,
  631. MAC_STAT_RX_MULTICAST);
  632. fbnic_mac_stat_rd64(fbd, reset, mac_stats->BroadcastFramesReceivedOK,
  633. MAC_STAT_RX_BROADCAST);
  634. fbnic_mac_stat_rd64(fbd, reset, mac_stats->OctetsTransmittedOK,
  635. MAC_STAT_TX_BYTE_COUNT);
  636. fbnic_mac_stat_rd64(fbd, reset, mac_stats->FramesTransmittedOK,
  637. MAC_STAT_TX_TRANSMITTED_OK);
  638. fbnic_mac_stat_rd64(fbd, reset,
  639. mac_stats->FramesLostDueToIntMACXmitError,
  640. MAC_STAT_TX_IFOUTERRORS);
  641. fbnic_mac_stat_rd64(fbd, reset, mac_stats->MulticastFramesXmittedOK,
  642. MAC_STAT_TX_MULTICAST);
  643. fbnic_mac_stat_rd64(fbd, reset, mac_stats->BroadcastFramesXmittedOK,
  644. MAC_STAT_TX_BROADCAST);
  645. }
  646. static void
  647. fbnic_mac_get_pause_stats(struct fbnic_dev *fbd, bool reset,
  648. struct fbnic_pause_stats *pause_stats)
  649. {
  650. fbnic_mac_stat_rd64(fbd, reset, pause_stats->tx_pause_frames,
  651. MAC_STAT_TX_XOFF_STB);
  652. fbnic_mac_stat_rd64(fbd, reset, pause_stats->rx_pause_frames,
  653. MAC_STAT_RX_XOFF_STB);
  654. }
  655. static void
  656. fbnic_mac_get_eth_ctrl_stats(struct fbnic_dev *fbd, bool reset,
  657. struct fbnic_eth_ctrl_stats *ctrl_stats)
  658. {
  659. fbnic_mac_stat_rd64(fbd, reset, ctrl_stats->MACControlFramesReceived,
  660. MAC_STAT_RX_CONTROL_FRAMES);
  661. fbnic_mac_stat_rd64(fbd, reset, ctrl_stats->MACControlFramesTransmitted,
  662. MAC_STAT_TX_CONTROL_FRAMES);
  663. }
  664. static void
  665. fbnic_mac_get_rmon_stats(struct fbnic_dev *fbd, bool reset,
  666. struct fbnic_rmon_stats *rmon_stats)
  667. {
  668. fbnic_mac_stat_rd64(fbd, reset, rmon_stats->undersize_pkts,
  669. MAC_STAT_RX_UNDERSIZE);
  670. fbnic_mac_stat_rd64(fbd, reset, rmon_stats->oversize_pkts,
  671. MAC_STAT_RX_OVERSIZE);
  672. fbnic_mac_stat_rd64(fbd, reset, rmon_stats->fragments,
  673. MAC_STAT_RX_FRAGMENT);
  674. fbnic_mac_stat_rd64(fbd, reset, rmon_stats->jabbers,
  675. MAC_STAT_RX_JABBER);
  676. fbnic_mac_stat_rd64(fbd, reset, rmon_stats->hist[0],
  677. MAC_STAT_RX_PACKET_64_BYTES);
  678. fbnic_mac_stat_rd64(fbd, reset, rmon_stats->hist[1],
  679. MAC_STAT_RX_PACKET_65_127_BYTES);
  680. fbnic_mac_stat_rd64(fbd, reset, rmon_stats->hist[2],
  681. MAC_STAT_RX_PACKET_128_255_BYTES);
  682. fbnic_mac_stat_rd64(fbd, reset, rmon_stats->hist[3],
  683. MAC_STAT_RX_PACKET_256_511_BYTES);
  684. fbnic_mac_stat_rd64(fbd, reset, rmon_stats->hist[4],
  685. MAC_STAT_RX_PACKET_512_1023_BYTES);
  686. fbnic_mac_stat_rd64(fbd, reset, rmon_stats->hist[5],
  687. MAC_STAT_RX_PACKET_1024_1518_BYTES);
  688. fbnic_mac_stat_rd64(fbd, reset, rmon_stats->hist[6],
  689. RPC_STAT_RX_PACKET_1519_2047_BYTES);
  690. fbnic_mac_stat_rd64(fbd, reset, rmon_stats->hist[7],
  691. RPC_STAT_RX_PACKET_2048_4095_BYTES);
  692. fbnic_mac_stat_rd64(fbd, reset, rmon_stats->hist[8],
  693. RPC_STAT_RX_PACKET_4096_8191_BYTES);
  694. fbnic_mac_stat_rd64(fbd, reset, rmon_stats->hist[9],
  695. RPC_STAT_RX_PACKET_8192_9216_BYTES);
  696. fbnic_mac_stat_rd64(fbd, reset, rmon_stats->hist[10],
  697. RPC_STAT_RX_PACKET_9217_MAX_BYTES);
  698. fbnic_mac_stat_rd64(fbd, reset, rmon_stats->hist_tx[0],
  699. MAC_STAT_TX_PACKET_64_BYTES);
  700. fbnic_mac_stat_rd64(fbd, reset, rmon_stats->hist_tx[1],
  701. MAC_STAT_TX_PACKET_65_127_BYTES);
  702. fbnic_mac_stat_rd64(fbd, reset, rmon_stats->hist_tx[2],
  703. MAC_STAT_TX_PACKET_128_255_BYTES);
  704. fbnic_mac_stat_rd64(fbd, reset, rmon_stats->hist_tx[3],
  705. MAC_STAT_TX_PACKET_256_511_BYTES);
  706. fbnic_mac_stat_rd64(fbd, reset, rmon_stats->hist_tx[4],
  707. MAC_STAT_TX_PACKET_512_1023_BYTES);
  708. fbnic_mac_stat_rd64(fbd, reset, rmon_stats->hist_tx[5],
  709. MAC_STAT_TX_PACKET_1024_1518_BYTES);
  710. fbnic_mac_stat_rd64(fbd, reset, rmon_stats->hist_tx[6],
  711. TMI_STAT_TX_PACKET_1519_2047_BYTES);
  712. fbnic_mac_stat_rd64(fbd, reset, rmon_stats->hist_tx[7],
  713. TMI_STAT_TX_PACKET_2048_4095_BYTES);
  714. fbnic_mac_stat_rd64(fbd, reset, rmon_stats->hist_tx[8],
  715. TMI_STAT_TX_PACKET_4096_8191_BYTES);
  716. fbnic_mac_stat_rd64(fbd, reset, rmon_stats->hist_tx[9],
  717. TMI_STAT_TX_PACKET_8192_9216_BYTES);
  718. fbnic_mac_stat_rd64(fbd, reset, rmon_stats->hist_tx[10],
  719. TMI_STAT_TX_PACKET_9217_MAX_BYTES);
  720. }
  721. static int fbnic_mac_get_sensor_asic(struct fbnic_dev *fbd, int id,
  722. long *val)
  723. {
  724. struct fbnic_fw_completion *fw_cmpl;
  725. int err = 0;
  726. s32 *sensor;
  727. fw_cmpl = fbnic_fw_alloc_cmpl(FBNIC_TLV_MSG_ID_TSENE_READ_RESP);
  728. if (!fw_cmpl)
  729. return -ENOMEM;
  730. switch (id) {
  731. case FBNIC_SENSOR_TEMP:
  732. sensor = &fw_cmpl->u.tsene.millidegrees;
  733. break;
  734. case FBNIC_SENSOR_VOLTAGE:
  735. sensor = &fw_cmpl->u.tsene.millivolts;
  736. break;
  737. default:
  738. err = -EINVAL;
  739. goto exit_free;
  740. }
  741. err = fbnic_fw_xmit_tsene_read_msg(fbd, fw_cmpl);
  742. if (err) {
  743. dev_err(fbd->dev,
  744. "Failed to transmit TSENE read msg, err %d\n",
  745. err);
  746. goto exit_free;
  747. }
  748. if (!wait_for_completion_timeout(&fw_cmpl->done, 10 * HZ)) {
  749. dev_err(fbd->dev, "Timed out waiting for TSENE read\n");
  750. err = -ETIMEDOUT;
  751. goto exit_cleanup;
  752. }
  753. /* Handle error returned by firmware */
  754. if (fw_cmpl->result) {
  755. err = fw_cmpl->result;
  756. dev_err(fbd->dev, "%s: Firmware returned error %d\n",
  757. __func__, err);
  758. goto exit_cleanup;
  759. }
  760. *val = *sensor;
  761. exit_cleanup:
  762. fbnic_mbx_clear_cmpl(fbd, fw_cmpl);
  763. exit_free:
  764. fbnic_fw_put_cmpl(fw_cmpl);
  765. return err;
  766. }
  767. static const struct fbnic_mac fbnic_mac_asic = {
  768. .init_regs = fbnic_mac_init_regs,
  769. .get_link = fbnic_mac_get_link,
  770. .get_link_event = fbnic_mac_get_link_event,
  771. .prepare = fbnic_mac_prepare,
  772. .get_fec_stats = fbnic_mac_get_fec_stats,
  773. .get_pcs_stats = fbnic_mac_get_pcs_stats,
  774. .get_eth_mac_stats = fbnic_mac_get_eth_mac_stats,
  775. .get_pause_stats = fbnic_mac_get_pause_stats,
  776. .get_eth_ctrl_stats = fbnic_mac_get_eth_ctrl_stats,
  777. .get_rmon_stats = fbnic_mac_get_rmon_stats,
  778. .link_down = fbnic_mac_link_down_asic,
  779. .link_up = fbnic_mac_link_up_asic,
  780. .get_sensor = fbnic_mac_get_sensor_asic,
  781. };
  782. /**
  783. * fbnic_mac_init - Assign a MAC type and initialize the fbnic device
  784. * @fbd: Device pointer to device to initialize
  785. *
  786. * Return: zero on success, negative on failure
  787. *
  788. * Initialize the MAC function pointers and initializes the MAC of
  789. * the device.
  790. **/
  791. int fbnic_mac_init(struct fbnic_dev *fbd)
  792. {
  793. fbd->mac = &fbnic_mac_asic;
  794. fbd->mac->init_regs(fbd);
  795. return 0;
  796. }