ldpaa_eth.c 30 KB

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