ldpaa_eth.c 25 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright 2014-2016 Freescale Semiconductor, Inc.
  4. * Copyright 2017, 2023 NXP
  5. */
  6. #include <common.h>
  7. #include <cpu_func.h>
  8. #include <dm/device_compat.h>
  9. #include <fsl-mc/fsl_dpmac.h>
  10. #include <fsl-mc/ldpaa_wriop.h>
  11. #include <hwconfig.h>
  12. #include <log.h>
  13. #include <malloc.h>
  14. #include <miiphy.h>
  15. #include <net.h>
  16. #include <phy.h>
  17. #include <asm/io.h>
  18. #include <asm/types.h>
  19. #include <linux/bug.h>
  20. #include <linux/compat.h>
  21. #include <linux/delay.h>
  22. #include <asm/global_data.h>
  23. #include <net/ldpaa_eth.h>
  24. #include "ldpaa_eth.h"
  25. #ifdef CONFIG_PHYLIB
  26. static void init_phy(struct udevice *dev)
  27. {
  28. struct ldpaa_eth_priv *priv = dev_get_priv(dev);
  29. priv->phy = dm_eth_phy_connect(dev);
  30. if (!priv->phy)
  31. return;
  32. phy_config(priv->phy);
  33. }
  34. #endif
  35. static void ldpaa_eth_collect_dpni_stats(struct udevice *dev, u64 *data)
  36. {
  37. union dpni_statistics dpni_stats;
  38. int dpni_stats_page_size[DPNI_STATISTICS_CNT] = {
  39. sizeof(dpni_stats.page_0),
  40. sizeof(dpni_stats.page_1),
  41. sizeof(dpni_stats.page_2),
  42. sizeof(dpni_stats.page_3),
  43. sizeof(dpni_stats.page_4),
  44. sizeof(dpni_stats.page_5),
  45. sizeof(dpni_stats.page_6),
  46. };
  47. int j, k, num_cnt, err, i = 0;
  48. for (j = 0; j <= 6; j++) {
  49. /* We're not interested in pages 4 & 5 for now */
  50. if (j == 4 || j == 5)
  51. continue;
  52. err = dpni_get_statistics(dflt_mc_io, MC_CMD_NO_FLAGS,
  53. dflt_dpni->dpni_handle,
  54. j, 0, &dpni_stats);
  55. if (err) {
  56. memset(&dpni_stats, 0, sizeof(dpni_stats));
  57. printf("dpni_get_stats(%d) failed\n", j);
  58. }
  59. num_cnt = dpni_stats_page_size[j] / sizeof(u64);
  60. for (k = 0; k < num_cnt; k++)
  61. *(data + i++) = dpni_stats.raw.counter[k];
  62. }
  63. }
  64. static void ldpaa_eth_add_dpni_stats(struct udevice *dev, u64 *data)
  65. {
  66. struct ldpaa_eth_priv *priv = dev_get_priv(dev);
  67. int i;
  68. for (i = 0; i < LDPAA_ETH_DPNI_NUM_STATS; i++)
  69. priv->dpni_stats[i] += data[i];
  70. }
  71. static void ldpaa_eth_collect_dpmac_stats(struct udevice *dev, u64 *data)
  72. {
  73. struct ldpaa_eth_priv *priv = dev_get_priv(dev);
  74. int err, i;
  75. u64 value;
  76. for (i = 0; i < LDPAA_ETH_DPMAC_NUM_STATS; i++) {
  77. err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
  78. priv->dpmac_handle, i,
  79. &value);
  80. if (err)
  81. printf("dpmac_get_counter(%d) failed\n", i);
  82. *(data + i) = value;
  83. }
  84. }
  85. static void ldpaa_eth_add_dpmac_stats(struct udevice *dev, u64 *data)
  86. {
  87. struct ldpaa_eth_priv *priv = dev_get_priv(dev);
  88. int i;
  89. for (i = 0; i < LDPAA_ETH_DPMAC_NUM_STATS; i++)
  90. priv->dpmac_stats[i] += data[i];
  91. }
  92. #ifdef DEBUG
  93. static void ldpaa_eth_dump_dpni_stats(struct udevice *dev, u64 *data)
  94. {
  95. int i;
  96. printf("DPNI counters:\n");
  97. for (i = 0; i < LDPAA_ETH_DPNI_NUM_STATS; i++)
  98. printf(" %s: %llu\n", ldpaa_eth_dpni_stat_strings[i], data[i]);
  99. }
  100. static void ldpaa_eth_dump_dpmac_stats(struct udevice *dev, u64 *data)
  101. {
  102. int i;
  103. printf("DPMAC counters:\n");
  104. for (i = 0; i < LDPAA_ETH_DPMAC_NUM_STATS; i++)
  105. printf(" %s: %llu\n", ldpaa_eth_dpmac_stat_strings[i], data[i]);
  106. }
  107. #endif
  108. static void ldpaa_eth_rx(struct ldpaa_eth_priv *priv,
  109. const struct dpaa_fd *fd)
  110. {
  111. u64 fd_addr;
  112. uint16_t fd_offset;
  113. uint32_t fd_length;
  114. struct ldpaa_fas *fas;
  115. uint32_t status, err;
  116. u32 timeo = (CONFIG_SYS_HZ * 2) / 1000;
  117. u32 time_start;
  118. struct qbman_release_desc releasedesc;
  119. struct qbman_swp *swp = dflt_dpio->sw_portal;
  120. fd_addr = ldpaa_fd_get_addr(fd);
  121. fd_offset = ldpaa_fd_get_offset(fd);
  122. fd_length = ldpaa_fd_get_len(fd);
  123. debug("Rx frame:data addr=0x%p size=0x%x\n", (u64 *)fd_addr, fd_length);
  124. if (fd->simple.frc & LDPAA_FD_FRC_FASV) {
  125. /* Read the frame annotation status word and check for errors */
  126. fas = (struct ldpaa_fas *)
  127. ((uint8_t *)(fd_addr) +
  128. dflt_dpni->buf_layout.private_data_size);
  129. status = le32_to_cpu(fas->status);
  130. if (status & LDPAA_ETH_RX_ERR_MASK) {
  131. printf("Rx frame error(s): 0x%08x\n",
  132. status & LDPAA_ETH_RX_ERR_MASK);
  133. goto error;
  134. } else if (status & LDPAA_ETH_RX_UNSUPP_MASK) {
  135. printf("Unsupported feature in bitmask: 0x%08x\n",
  136. status & LDPAA_ETH_RX_UNSUPP_MASK);
  137. goto error;
  138. }
  139. }
  140. debug("Rx frame: To Upper layer\n");
  141. net_process_received_packet((uint8_t *)(fd_addr) + fd_offset,
  142. fd_length);
  143. error:
  144. flush_dcache_range(fd_addr, fd_addr + LDPAA_ETH_RX_BUFFER_SIZE);
  145. qbman_release_desc_clear(&releasedesc);
  146. qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid);
  147. time_start = get_timer(0);
  148. do {
  149. /* Release buffer into the QBMAN */
  150. err = qbman_swp_release(swp, &releasedesc, &fd_addr, 1);
  151. } while (get_timer(time_start) < timeo && err == -EBUSY);
  152. if (err == -EBUSY)
  153. printf("Rx frame: QBMAN buffer release fails\n");
  154. return;
  155. }
  156. static int ldpaa_eth_pull_dequeue_rx(struct udevice *dev,
  157. int flags, uchar **packetp)
  158. {
  159. struct ldpaa_eth_priv *priv = dev_get_priv(dev);
  160. const struct ldpaa_dq *dq;
  161. const struct dpaa_fd *fd;
  162. int i = 5, err = 0, status;
  163. u32 timeo = (CONFIG_SYS_HZ * 2) / 1000;
  164. u32 time_start;
  165. static struct qbman_pull_desc pulldesc;
  166. struct qbman_swp *swp = dflt_dpio->sw_portal;
  167. while (--i) {
  168. qbman_pull_desc_clear(&pulldesc);
  169. qbman_pull_desc_set_numframes(&pulldesc, 1);
  170. qbman_pull_desc_set_fq(&pulldesc, priv->rx_dflt_fqid);
  171. err = qbman_swp_pull(swp, &pulldesc);
  172. if (err < 0) {
  173. printf("Dequeue frames error:0x%08x\n", err);
  174. continue;
  175. }
  176. time_start = get_timer(0);
  177. do {
  178. dq = qbman_swp_dqrr_next(swp);
  179. } while (get_timer(time_start) < timeo && !dq);
  180. if (dq) {
  181. /* Check for valid frame. If not sent a consume
  182. * confirmation to QBMAN otherwise give it to NADK
  183. * application and then send consume confirmation to
  184. * QBMAN.
  185. */
  186. status = (uint8_t)ldpaa_dq_flags(dq);
  187. if ((status & LDPAA_DQ_STAT_VALIDFRAME) == 0) {
  188. debug("Dequeue RX frames:");
  189. debug("No frame delivered\n");
  190. qbman_swp_dqrr_consume(swp, dq);
  191. continue;
  192. }
  193. fd = ldpaa_dq_fd(dq);
  194. /* Obtain FD and process it */
  195. ldpaa_eth_rx(priv, fd);
  196. qbman_swp_dqrr_consume(swp, dq);
  197. break;
  198. } else {
  199. err = -ENODATA;
  200. debug("No DQRR entries\n");
  201. break;
  202. }
  203. }
  204. return err;
  205. }
  206. static int ldpaa_eth_tx(struct udevice *dev, void *buf, int len)
  207. {
  208. struct ldpaa_eth_priv *priv = dev_get_priv(dev);
  209. struct dpaa_fd fd;
  210. u64 buffer_start;
  211. int data_offset, err;
  212. u32 timeo = (CONFIG_SYS_HZ * 10) / 1000;
  213. u32 time_start;
  214. struct qbman_swp *swp = dflt_dpio->sw_portal;
  215. struct qbman_eq_desc ed;
  216. struct qbman_release_desc releasedesc;
  217. /* Setup the FD fields */
  218. memset(&fd, 0, sizeof(fd));
  219. data_offset = priv->tx_data_offset;
  220. do {
  221. err = qbman_swp_acquire(dflt_dpio->sw_portal,
  222. dflt_dpbp->dpbp_attr.bpid,
  223. &buffer_start, 1);
  224. } while (err == -EBUSY);
  225. if (err <= 0) {
  226. printf("qbman_swp_acquire() failed\n");
  227. return -ENOMEM;
  228. }
  229. debug("TX data: malloc buffer start=0x%p\n", (u64 *)buffer_start);
  230. memcpy(((uint8_t *)(buffer_start) + data_offset), buf, len);
  231. flush_dcache_range(buffer_start, buffer_start +
  232. LDPAA_ETH_RX_BUFFER_SIZE);
  233. ldpaa_fd_set_addr(&fd, (u64)buffer_start);
  234. ldpaa_fd_set_offset(&fd, (uint16_t)(data_offset));
  235. ldpaa_fd_set_bpid(&fd, dflt_dpbp->dpbp_attr.bpid);
  236. ldpaa_fd_set_len(&fd, len);
  237. fd.simple.ctrl = LDPAA_FD_CTRL_ASAL | LDPAA_FD_CTRL_PTA |
  238. LDPAA_FD_CTRL_PTV1;
  239. qbman_eq_desc_clear(&ed);
  240. qbman_eq_desc_set_no_orp(&ed, 0);
  241. qbman_eq_desc_set_qd(&ed, priv->tx_qdid, priv->tx_flow_id, 0);
  242. time_start = get_timer(0);
  243. while (get_timer(time_start) < timeo) {
  244. err = qbman_swp_enqueue(swp, &ed,
  245. (const struct qbman_fd *)(&fd));
  246. if (err != -EBUSY)
  247. break;
  248. }
  249. if (err < 0) {
  250. printf("error enqueueing Tx frame\n");
  251. goto error;
  252. }
  253. return err;
  254. error:
  255. qbman_release_desc_clear(&releasedesc);
  256. qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid);
  257. time_start = get_timer(0);
  258. do {
  259. /* Release buffer into the QBMAN */
  260. err = qbman_swp_release(swp, &releasedesc, &buffer_start, 1);
  261. } while (get_timer(time_start) < timeo && err == -EBUSY);
  262. if (err == -EBUSY)
  263. printf("TX data: QBMAN buffer release fails\n");
  264. return err;
  265. }
  266. static int ldpaa_get_dpmac_state(struct ldpaa_eth_priv *priv,
  267. struct dpmac_link_state *state)
  268. {
  269. phy_interface_t enet_if;
  270. struct phy_device *phydev = NULL;
  271. int err;
  272. /* let's start off with maximum capabilities */
  273. enet_if = wriop_get_enet_if(priv->dpmac_id);
  274. switch (enet_if) {
  275. case PHY_INTERFACE_MODE_XGMII:
  276. state->rate = SPEED_10000;
  277. break;
  278. default:
  279. state->rate = SPEED_1000;
  280. break;
  281. }
  282. state->up = 1;
  283. state->options |= DPMAC_LINK_OPT_AUTONEG;
  284. phydev = priv->phy;
  285. if (phydev) {
  286. err = phy_startup(phydev);
  287. if (err) {
  288. printf("%s: Could not initialize\n", phydev->dev->name);
  289. state->up = 0;
  290. } else if (phydev->link) {
  291. state->rate = min(state->rate, (uint32_t)phydev->speed);
  292. if (!phydev->duplex)
  293. state->options |= DPMAC_LINK_OPT_HALF_DUPLEX;
  294. if (!phydev->autoneg)
  295. state->options &= ~DPMAC_LINK_OPT_AUTONEG;
  296. } else {
  297. state->up = 0;
  298. }
  299. }
  300. if (!phydev)
  301. state->options &= ~DPMAC_LINK_OPT_AUTONEG;
  302. if (!state->up) {
  303. state->rate = 0;
  304. state->options = 0;
  305. return -ENOLINK;
  306. }
  307. return 0;
  308. }
  309. static int ldpaa_eth_open(struct udevice *dev)
  310. {
  311. struct eth_pdata *plat = dev_get_plat(dev);
  312. struct ldpaa_eth_priv *priv = dev_get_priv(dev);
  313. struct dpmac_link_state dpmac_link_state = { 0 };
  314. #ifdef DEBUG
  315. struct dpni_link_state link_state;
  316. #endif
  317. int err = 0;
  318. struct dpni_queue d_queue_cfg = { 0 };
  319. struct dpni_queue_id d_queue;
  320. if (eth_is_active(dev))
  321. return 0;
  322. if (get_mc_boot_status() != 0) {
  323. printf("ERROR (MC is not booted)\n");
  324. return -ENODEV;
  325. }
  326. if (get_dpl_apply_status() == 0) {
  327. printf("ERROR (DPL is deployed. No device available)\n");
  328. return -ENODEV;
  329. }
  330. /* DPMAC initialization */
  331. err = ldpaa_dpmac_setup(priv);
  332. if (err < 0)
  333. goto err_dpmac_setup;
  334. err = ldpaa_get_dpmac_state(priv, &dpmac_link_state);
  335. if (err < 0)
  336. goto err_dpmac_bind;
  337. /* DPMAC binding DPNI */
  338. err = ldpaa_dpmac_bind(priv);
  339. if (err)
  340. goto err_dpmac_bind;
  341. /* DPNI initialization */
  342. err = ldpaa_dpni_setup(priv);
  343. if (err < 0)
  344. goto err_dpni_setup;
  345. err = ldpaa_dpbp_setup();
  346. if (err < 0)
  347. goto err_dpbp_setup;
  348. /* DPNI binding DPBP */
  349. err = ldpaa_dpni_bind(priv);
  350. if (err)
  351. goto err_dpni_bind;
  352. err = dpni_add_mac_addr(dflt_mc_io, MC_CMD_NO_FLAGS,
  353. dflt_dpni->dpni_handle, plat->enetaddr, 0, 0, 0);
  354. if (err) {
  355. printf("dpni_add_mac_addr() failed\n");
  356. return err;
  357. }
  358. err = dpni_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
  359. if (err < 0) {
  360. printf("dpni_enable() failed\n");
  361. return err;
  362. }
  363. err = dpmac_set_link_state(dflt_mc_io, MC_CMD_NO_FLAGS,
  364. priv->dpmac_handle, &dpmac_link_state);
  365. if (err < 0) {
  366. printf("dpmac_set_link_state() failed\n");
  367. return err;
  368. }
  369. #ifdef DEBUG
  370. printf("DPMAC link status: %d - ", dpmac_link_state.up);
  371. dpmac_link_state.up == 0 ? printf("down\n") :
  372. dpmac_link_state.up == 1 ? printf("up\n") : printf("error state\n");
  373. err = dpni_get_link_state(dflt_mc_io, MC_CMD_NO_FLAGS,
  374. dflt_dpni->dpni_handle, &link_state);
  375. if (err < 0) {
  376. printf("dpni_get_link_state() failed\n");
  377. return err;
  378. }
  379. printf("DPNI link status: %d - ", link_state.up);
  380. link_state.up == 0 ? printf("down\n") :
  381. link_state.up == 1 ? printf("up\n") : printf("error state\n");
  382. #endif
  383. memset(&d_queue, 0, sizeof(struct dpni_queue));
  384. err = dpni_get_queue(dflt_mc_io, MC_CMD_NO_FLAGS,
  385. dflt_dpni->dpni_handle, DPNI_QUEUE_RX,
  386. 0, 0, &d_queue_cfg, &d_queue);
  387. if (err) {
  388. printf("dpni_get_queue failed\n");
  389. goto err_get_queue;
  390. }
  391. priv->rx_dflt_fqid = d_queue.fqid;
  392. err = dpni_get_qdid(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle,
  393. DPNI_QUEUE_TX, &priv->tx_qdid);
  394. if (err) {
  395. printf("dpni_get_qdid() failed\n");
  396. goto err_qdid;
  397. }
  398. return dpmac_link_state.up;
  399. err_qdid:
  400. err_get_queue:
  401. dpni_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
  402. err_dpni_bind:
  403. ldpaa_dpbp_free();
  404. err_dpbp_setup:
  405. dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
  406. err_dpni_setup:
  407. err_dpmac_bind:
  408. dpmac_close(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpmac_handle);
  409. dpmac_destroy(dflt_mc_io,
  410. dflt_dprc_handle,
  411. MC_CMD_NO_FLAGS, priv->dpmac_id);
  412. err_dpmac_setup:
  413. return err;
  414. }
  415. static void ldpaa_eth_stop(struct udevice *dev)
  416. {
  417. struct ldpaa_eth_priv *priv = dev_get_priv(dev);
  418. struct phy_device *phydev = NULL;
  419. int err = 0;
  420. u64 *data;
  421. if (!eth_is_active(dev))
  422. return;
  423. data = kzalloc(sizeof(u64) * LDPAA_ETH_DPNI_NUM_STATS, GFP_KERNEL);
  424. if (data) {
  425. ldpaa_eth_collect_dpni_stats(dev, data);
  426. ldpaa_eth_add_dpni_stats(dev, data);
  427. #ifdef DEBUG
  428. ldpaa_eth_dump_dpni_stats(dev, data);
  429. #endif
  430. }
  431. kfree(data);
  432. data = kzalloc(sizeof(u64) * LDPAA_ETH_DPMAC_NUM_STATS, GFP_KERNEL);
  433. if (data) {
  434. ldpaa_eth_collect_dpmac_stats(dev, data);
  435. ldpaa_eth_add_dpmac_stats(dev, data);
  436. #ifdef DEBUG
  437. ldpaa_eth_dump_dpmac_stats(dev, data);
  438. #endif
  439. }
  440. kfree(data);
  441. err = dprc_disconnect(dflt_mc_io, MC_CMD_NO_FLAGS,
  442. dflt_dprc_handle, &dpmac_endpoint);
  443. if (err < 0)
  444. printf("dprc_disconnect() failed dpmac_endpoint\n");
  445. err = dpmac_close(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpmac_handle);
  446. if (err < 0)
  447. printf("dpmac_close() failed\n");
  448. err = dpmac_destroy(dflt_mc_io,
  449. dflt_dprc_handle,
  450. MC_CMD_NO_FLAGS,
  451. priv->dpmac_id);
  452. if (err < 0)
  453. printf("dpmac_destroy() failed\n");
  454. /* Stop Tx and Rx traffic */
  455. err = dpni_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
  456. if (err < 0)
  457. printf("dpni_disable() failed\n");
  458. phydev = priv->phy;
  459. if (phydev)
  460. phy_shutdown(phydev);
  461. /* Free DPBP handle and reset. */
  462. ldpaa_dpbp_free();
  463. dpni_reset(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
  464. if (err < 0)
  465. printf("dpni_reset() failed\n");
  466. dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
  467. if (err < 0)
  468. printf("dpni_close() failed\n");
  469. }
  470. static void ldpaa_dpbp_drain_cnt(int count)
  471. {
  472. uint64_t buf_array[7];
  473. void *addr;
  474. int ret, i;
  475. BUG_ON(count > 7);
  476. do {
  477. ret = qbman_swp_acquire(dflt_dpio->sw_portal,
  478. dflt_dpbp->dpbp_attr.bpid,
  479. buf_array, count);
  480. if (ret < 0) {
  481. printf("qbman_swp_acquire() failed\n");
  482. return;
  483. }
  484. for (i = 0; i < ret; i++) {
  485. addr = (void *)buf_array[i];
  486. debug("Free: buffer addr =0x%p\n", addr);
  487. free(addr);
  488. }
  489. } while (ret);
  490. }
  491. static void ldpaa_dpbp_drain(void)
  492. {
  493. int i;
  494. for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7)
  495. ldpaa_dpbp_drain_cnt(7);
  496. }
  497. static int ldpaa_bp_add_7(uint16_t bpid)
  498. {
  499. uint64_t buf_array[7];
  500. u8 *addr;
  501. int i;
  502. struct qbman_release_desc rd;
  503. for (i = 0; i < 7; i++) {
  504. addr = memalign(LDPAA_ETH_BUF_ALIGN, LDPAA_ETH_RX_BUFFER_SIZE);
  505. if (!addr) {
  506. printf("addr allocation failed\n");
  507. goto err_alloc;
  508. }
  509. memset(addr, 0x00, LDPAA_ETH_RX_BUFFER_SIZE);
  510. flush_dcache_range((u64)addr,
  511. (u64)(addr + LDPAA_ETH_RX_BUFFER_SIZE));
  512. buf_array[i] = (uint64_t)addr;
  513. debug("Release: buffer addr =0x%p\n", addr);
  514. }
  515. release_bufs:
  516. /* In case the portal is busy, retry until successful.
  517. * This function is guaranteed to succeed in a reasonable amount
  518. * of time.
  519. */
  520. do {
  521. mdelay(1);
  522. qbman_release_desc_clear(&rd);
  523. qbman_release_desc_set_bpid(&rd, bpid);
  524. } while (qbman_swp_release(dflt_dpio->sw_portal, &rd, buf_array, i));
  525. return i;
  526. err_alloc:
  527. if (i)
  528. goto release_bufs;
  529. return 0;
  530. }
  531. static int ldpaa_dpbp_seed(uint16_t bpid)
  532. {
  533. int i;
  534. int count;
  535. for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7) {
  536. count = ldpaa_bp_add_7(bpid);
  537. if (count < 7)
  538. printf("Buffer Seed= %d\n", count);
  539. }
  540. return 0;
  541. }
  542. static int ldpaa_dpbp_setup(void)
  543. {
  544. int err;
  545. err = dpbp_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_attr.id,
  546. &dflt_dpbp->dpbp_handle);
  547. if (err) {
  548. printf("dpbp_open() failed\n");
  549. goto err_open;
  550. }
  551. err = dpbp_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
  552. if (err) {
  553. printf("dpbp_enable() failed\n");
  554. goto err_enable;
  555. }
  556. err = dpbp_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS,
  557. dflt_dpbp->dpbp_handle,
  558. &dflt_dpbp->dpbp_attr);
  559. if (err) {
  560. printf("dpbp_get_attributes() failed\n");
  561. goto err_get_attr;
  562. }
  563. err = ldpaa_dpbp_seed(dflt_dpbp->dpbp_attr.bpid);
  564. if (err) {
  565. printf("Buffer seeding failed for DPBP %d (bpid=%d)\n",
  566. dflt_dpbp->dpbp_attr.id, dflt_dpbp->dpbp_attr.bpid);
  567. goto err_seed;
  568. }
  569. return 0;
  570. err_seed:
  571. err_get_attr:
  572. dpbp_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
  573. err_enable:
  574. dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
  575. err_open:
  576. return err;
  577. }
  578. static void ldpaa_dpbp_free(void)
  579. {
  580. ldpaa_dpbp_drain();
  581. dpbp_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
  582. dpbp_reset(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
  583. dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
  584. }
  585. static int ldpaa_dpmac_version_check(struct fsl_mc_io *mc_io,
  586. struct ldpaa_eth_priv *priv)
  587. {
  588. int error;
  589. uint16_t major_ver, minor_ver;
  590. error = dpmac_get_api_version(dflt_mc_io, 0,
  591. &major_ver,
  592. &minor_ver);
  593. if ((major_ver < DPMAC_VER_MAJOR) ||
  594. (major_ver == DPMAC_VER_MAJOR && minor_ver < DPMAC_VER_MINOR)) {
  595. printf("DPMAC version mismatch found %u.%u,",
  596. major_ver, minor_ver);
  597. printf("supported version is %u.%u\n",
  598. DPMAC_VER_MAJOR, DPMAC_VER_MINOR);
  599. return error;
  600. }
  601. return error;
  602. }
  603. static int ldpaa_dpmac_setup(struct ldpaa_eth_priv *priv)
  604. {
  605. int err = 0;
  606. struct dpmac_cfg dpmac_cfg;
  607. dpmac_cfg.mac_id = priv->dpmac_id;
  608. err = dpmac_create(dflt_mc_io,
  609. dflt_dprc_handle,
  610. MC_CMD_NO_FLAGS, &dpmac_cfg,
  611. &priv->dpmac_id);
  612. if (err)
  613. printf("dpmac_create() failed\n");
  614. err = ldpaa_dpmac_version_check(dflt_mc_io, priv);
  615. if (err < 0) {
  616. printf("ldpaa_dpmac_version_check() failed: %d\n", err);
  617. goto err_version_check;
  618. }
  619. err = dpmac_open(dflt_mc_io,
  620. MC_CMD_NO_FLAGS,
  621. priv->dpmac_id,
  622. &priv->dpmac_handle);
  623. if (err < 0) {
  624. printf("dpmac_open() failed: %d\n", err);
  625. goto err_open;
  626. }
  627. return err;
  628. err_open:
  629. err_version_check:
  630. dpmac_destroy(dflt_mc_io,
  631. dflt_dprc_handle,
  632. MC_CMD_NO_FLAGS, priv->dpmac_id);
  633. return err;
  634. }
  635. static int ldpaa_dpmac_bind(struct ldpaa_eth_priv *priv)
  636. {
  637. int err = 0;
  638. struct dprc_connection_cfg dprc_connection_cfg = {
  639. /* If both rates are zero the connection */
  640. /* will be configured in "best effort" mode. */
  641. .committed_rate = 0,
  642. .max_rate = 0
  643. };
  644. #ifdef DEBUG
  645. struct dprc_endpoint dbg_endpoint;
  646. int state = 0;
  647. #endif
  648. memset(&dpmac_endpoint, 0, sizeof(struct dprc_endpoint));
  649. strcpy(dpmac_endpoint.type, "dpmac");
  650. dpmac_endpoint.id = priv->dpmac_id;
  651. memset(&dpni_endpoint, 0, sizeof(struct dprc_endpoint));
  652. strcpy(dpni_endpoint.type, "dpni");
  653. dpni_endpoint.id = dflt_dpni->dpni_id;
  654. err = dprc_connect(dflt_mc_io, MC_CMD_NO_FLAGS,
  655. dflt_dprc_handle,
  656. &dpmac_endpoint,
  657. &dpni_endpoint,
  658. &dprc_connection_cfg);
  659. if (err)
  660. printf("dprc_connect() failed\n");
  661. #ifdef DEBUG
  662. err = dprc_get_connection(dflt_mc_io, MC_CMD_NO_FLAGS,
  663. dflt_dprc_handle, &dpni_endpoint,
  664. &dbg_endpoint, &state);
  665. printf("%s, DPMAC Type= %s\n", __func__, dbg_endpoint.type);
  666. printf("%s, DPMAC ID= %d\n", __func__, dbg_endpoint.id);
  667. printf("%s, DPMAC State= %d\n", __func__, state);
  668. memset(&dbg_endpoint, 0, sizeof(struct dprc_endpoint));
  669. err = dprc_get_connection(dflt_mc_io, MC_CMD_NO_FLAGS,
  670. dflt_dprc_handle, &dpmac_endpoint,
  671. &dbg_endpoint, &state);
  672. printf("%s, DPNI Type= %s\n", __func__, dbg_endpoint.type);
  673. printf("%s, DPNI ID= %d\n", __func__, dbg_endpoint.id);
  674. printf("%s, DPNI State= %d\n", __func__, state);
  675. #endif
  676. return err;
  677. }
  678. static int ldpaa_dpni_setup(struct ldpaa_eth_priv *priv)
  679. {
  680. int err;
  681. /* and get a handle for the DPNI this interface is associate with */
  682. err = dpni_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_id,
  683. &dflt_dpni->dpni_handle);
  684. if (err) {
  685. printf("dpni_open() failed\n");
  686. goto err_open;
  687. }
  688. err = dpni_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS,
  689. dflt_dpni->dpni_handle,
  690. &dflt_dpni->dpni_attrs);
  691. if (err) {
  692. printf("dpni_get_attributes() failed (err=%d)\n", err);
  693. goto err_get_attr;
  694. }
  695. /* Configure our buffers' layout */
  696. dflt_dpni->buf_layout.options = DPNI_BUF_LAYOUT_OPT_PARSER_RESULT |
  697. DPNI_BUF_LAYOUT_OPT_FRAME_STATUS |
  698. DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE |
  699. DPNI_BUF_LAYOUT_OPT_DATA_ALIGN;
  700. dflt_dpni->buf_layout.pass_parser_result = true;
  701. dflt_dpni->buf_layout.pass_frame_status = true;
  702. dflt_dpni->buf_layout.private_data_size = LDPAA_ETH_SWA_SIZE;
  703. /* HW erratum mandates data alignment in multiples of 256 */
  704. dflt_dpni->buf_layout.data_align = LDPAA_ETH_BUF_ALIGN;
  705. /* ...rx, ... */
  706. err = dpni_set_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS,
  707. dflt_dpni->dpni_handle,
  708. DPNI_QUEUE_RX, &dflt_dpni->buf_layout);
  709. if (err) {
  710. printf("dpni_set_buffer_layout() failed");
  711. goto err_buf_layout;
  712. }
  713. /* ... tx, ... */
  714. /* remove Rx-only options */
  715. dflt_dpni->buf_layout.options &= ~(DPNI_BUF_LAYOUT_OPT_DATA_ALIGN |
  716. DPNI_BUF_LAYOUT_OPT_PARSER_RESULT);
  717. err = dpni_set_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS,
  718. dflt_dpni->dpni_handle,
  719. DPNI_QUEUE_TX, &dflt_dpni->buf_layout);
  720. if (err) {
  721. printf("dpni_set_buffer_layout() failed");
  722. goto err_buf_layout;
  723. }
  724. /* ... tx-confirm. */
  725. dflt_dpni->buf_layout.options &= ~DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE;
  726. err = dpni_set_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS,
  727. dflt_dpni->dpni_handle,
  728. DPNI_QUEUE_TX_CONFIRM, &dflt_dpni->buf_layout);
  729. if (err) {
  730. printf("dpni_set_buffer_layout() failed");
  731. goto err_buf_layout;
  732. }
  733. /* Now that we've set our tx buffer layout, retrieve the minimum
  734. * required tx data offset.
  735. */
  736. err = dpni_get_tx_data_offset(dflt_mc_io, MC_CMD_NO_FLAGS,
  737. dflt_dpni->dpni_handle,
  738. &priv->tx_data_offset);
  739. if (err) {
  740. printf("dpni_get_tx_data_offset() failed\n");
  741. goto err_data_offset;
  742. }
  743. /* Warn in case TX data offset is not multiple of 64 bytes. */
  744. WARN_ON(priv->tx_data_offset % 64);
  745. /* Accomodate SWA space. */
  746. priv->tx_data_offset += LDPAA_ETH_SWA_SIZE;
  747. debug("priv->tx_data_offset=%d\n", priv->tx_data_offset);
  748. return 0;
  749. err_data_offset:
  750. err_buf_layout:
  751. err_get_attr:
  752. dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
  753. err_open:
  754. return err;
  755. }
  756. static int ldpaa_dpni_bind(struct ldpaa_eth_priv *priv)
  757. {
  758. struct dpni_pools_cfg pools_params;
  759. struct dpni_queue tx_queue;
  760. int err = 0;
  761. memset(&pools_params, 0, sizeof(pools_params));
  762. pools_params.num_dpbp = 1;
  763. pools_params.pools[0].dpbp_id = (uint16_t)dflt_dpbp->dpbp_attr.id;
  764. pools_params.pools[0].buffer_size = LDPAA_ETH_RX_BUFFER_SIZE;
  765. err = dpni_set_pools(dflt_mc_io, MC_CMD_NO_FLAGS,
  766. dflt_dpni->dpni_handle, &pools_params);
  767. if (err) {
  768. printf("dpni_set_pools() failed\n");
  769. return err;
  770. }
  771. memset(&tx_queue, 0, sizeof(struct dpni_queue));
  772. err = dpni_set_queue(dflt_mc_io, MC_CMD_NO_FLAGS,
  773. dflt_dpni->dpni_handle,
  774. DPNI_QUEUE_TX, 0, 0, 0, &tx_queue);
  775. if (err) {
  776. printf("dpni_set_queue() failed\n");
  777. return err;
  778. }
  779. err = dpni_set_tx_confirmation_mode(dflt_mc_io, MC_CMD_NO_FLAGS,
  780. dflt_dpni->dpni_handle,
  781. 0, DPNI_CONF_DISABLE);
  782. if (err) {
  783. printf("dpni_set_tx_confirmation_mode() failed\n");
  784. return err;
  785. }
  786. return 0;
  787. }
  788. static int ldpaa_eth_probe(struct udevice *dev)
  789. {
  790. struct ofnode_phandle_args phandle;
  791. /* Nothing to do if there is no "phy-handle" in the DTS node */
  792. if (dev_read_phandle_with_args(dev, "phy-handle", NULL,
  793. 0, 0, &phandle)) {
  794. return 0;
  795. }
  796. init_phy(dev);
  797. return 0;
  798. }
  799. uint32_t ldpaa_eth_get_dpmac_id(struct udevice *dev)
  800. {
  801. int port_node = dev_of_offset(dev);
  802. return fdtdec_get_uint(gd->fdt_blob, port_node, "reg", -1);
  803. }
  804. static int ldpaa_eth_bind(struct udevice *dev)
  805. {
  806. uint32_t dpmac_id;
  807. char eth_name[16];
  808. int phy_mode = -1;
  809. phy_mode = dev_read_phy_mode(dev);
  810. if (phy_mode == PHY_INTERFACE_MODE_NA) {
  811. dev_err(dev, "incorrect phy mode\n");
  812. return -EINVAL;
  813. }
  814. dpmac_id = ldpaa_eth_get_dpmac_id(dev);
  815. if (dpmac_id == -1) {
  816. dev_err(dev, "missing reg field from the dpmac node\n");
  817. return -EINVAL;
  818. }
  819. sprintf(eth_name, "DPMAC%d@%s", dpmac_id,
  820. phy_string_for_interface(phy_mode));
  821. device_set_name(dev, eth_name);
  822. return 0;
  823. }
  824. static int ldpaa_eth_of_to_plat(struct udevice *dev)
  825. {
  826. struct ldpaa_eth_priv *priv = dev_get_priv(dev);
  827. priv->dpmac_id = ldpaa_eth_get_dpmac_id(dev);
  828. priv->phy_mode = dev_read_phy_mode(dev);
  829. return 0;
  830. }
  831. static int ldpaa_eth_get_sset_count(struct udevice *dev)
  832. {
  833. return LDPAA_ETH_DPNI_NUM_STATS + LDPAA_ETH_DPMAC_NUM_STATS;
  834. }
  835. static void ldpaa_eth_get_strings(struct udevice *dev, u8 *data)
  836. {
  837. u8 *p = data;
  838. int i;
  839. for (i = 0; i < LDPAA_ETH_DPNI_NUM_STATS; i++) {
  840. strlcpy(p, ldpaa_eth_dpni_stat_strings[i], ETH_GSTRING_LEN);
  841. p += ETH_GSTRING_LEN;
  842. }
  843. for (i = 0; i < LDPAA_ETH_DPMAC_NUM_STATS; i++) {
  844. strlcpy(p, ldpaa_eth_dpmac_stat_strings[i], ETH_GSTRING_LEN);
  845. p += ETH_GSTRING_LEN;
  846. }
  847. }
  848. static void ldpaa_eth_get_stats(struct udevice *dev, u64 *data)
  849. {
  850. struct ldpaa_eth_priv *priv = dev_get_priv(dev);
  851. int i, j = 0;
  852. for (i = 0; i < LDPAA_ETH_DPNI_NUM_STATS; i++)
  853. *(data + j++) = priv->dpni_stats[i];
  854. for (i = 0; i < LDPAA_ETH_DPMAC_NUM_STATS; i++)
  855. *(data + j++) = priv->dpmac_stats[i];
  856. }
  857. static const struct eth_ops ldpaa_eth_ops = {
  858. .start = ldpaa_eth_open,
  859. .send = ldpaa_eth_tx,
  860. .recv = ldpaa_eth_pull_dequeue_rx,
  861. .stop = ldpaa_eth_stop,
  862. .get_sset_count = ldpaa_eth_get_sset_count,
  863. .get_strings = ldpaa_eth_get_strings,
  864. .get_stats = ldpaa_eth_get_stats,
  865. };
  866. static const struct udevice_id ldpaa_eth_of_ids[] = {
  867. { .compatible = "fsl,qoriq-mc-dpmac" },
  868. };
  869. U_BOOT_DRIVER(ldpaa_eth) = {
  870. .name = LDPAA_ETH_DRIVER_NAME,
  871. .id = UCLASS_ETH,
  872. .of_match = ldpaa_eth_of_ids,
  873. .of_to_plat = ldpaa_eth_of_to_plat,
  874. .bind = ldpaa_eth_bind,
  875. .probe = ldpaa_eth_probe,
  876. .ops = &ldpaa_eth_ops,
  877. .priv_auto = sizeof(struct ldpaa_eth_priv),
  878. .plat_auto = sizeof(struct eth_pdata),
  879. };