drv_eth.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637
  1. /*
  2. * Copyright (c) 2006-2020, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2020-10-30 bigmagic first version
  9. */
  10. #include <rthw.h>
  11. #include <stdint.h>
  12. #include <rtthread.h>
  13. #include <lwip/sys.h>
  14. #include <netif/ethernetif.h>
  15. #include "mbox.h"
  16. #include "raspi4.h"
  17. #include "drv_eth.h"
  18. #define RECV_CACHE_BUF (1024)
  19. #define SEND_DATA_NO_CACHE (0x08200000)
  20. #define RECV_DATA_NO_CACHE (0x08400000)
  21. #define DMA_DISC_ADDR_SIZE (4 * 1024 *1024)
  22. #define RX_DESC_BASE (MAC_REG + GENET_RX_OFF)
  23. #define TX_DESC_BASE (MAC_REG + GENET_TX_OFF)
  24. #define MAX_ADDR_LEN (6)
  25. #define upper_32_bits(n) ((rt_uint32_t)(((n) >> 16) >> 16))
  26. #define lower_32_bits(n) ((rt_uint32_t)(n))
  27. #define BIT(nr) (1UL << (nr))
  28. static rt_uint32_t tx_index = 0;
  29. static rt_uint32_t rx_index = 0;
  30. static rt_uint32_t index_flag = 0;
  31. static rt_uint32_t send_cache_pbuf[RECV_CACHE_BUF];
  32. struct rt_eth_dev
  33. {
  34. struct eth_device parent;
  35. rt_uint8_t dev_addr[MAX_ADDR_LEN];
  36. char *name;
  37. void *iobase;
  38. int state;
  39. int index;
  40. struct rt_timer link_timer;
  41. struct rt_timer rx_poll_timer;
  42. void *priv;
  43. };
  44. static struct rt_eth_dev eth_dev;
  45. static struct rt_semaphore sem_lock;
  46. static inline rt_uint32_t read32(void *addr)
  47. {
  48. return (*((volatile unsigned int*)(addr)));
  49. }
  50. static inline void write32(void *addr, rt_uint32_t value)
  51. {
  52. (*((volatile unsigned int*)(addr))) = value;
  53. }
  54. void eth_rx_irq(void *param)
  55. {
  56. eth_device_ready(&eth_dev.parent);
  57. }
  58. /* We only support RGMII (as used on the RPi4). */
  59. static int bcmgenet_interface_set(void)
  60. {
  61. int phy_mode = PHY_INTERFACE_MODE_RGMII;
  62. switch (phy_mode) {
  63. case PHY_INTERFACE_MODE_RGMII:
  64. case PHY_INTERFACE_MODE_RGMII_RXID:
  65. write32(MAC_REG + SYS_PORT_CTRL,PORT_MODE_EXT_GPHY);
  66. break;
  67. default:
  68. rt_kprintf("unknown phy mode: %d\n", MAC_REG);
  69. return -1;
  70. }
  71. return 0;
  72. }
  73. static void bcmgenet_umac_reset(void)
  74. {
  75. rt_uint32_t reg;
  76. reg = read32(MAC_REG + SYS_RBUF_FLUSH_CTRL);
  77. reg |= BIT(1);
  78. write32((MAC_REG + SYS_RBUF_FLUSH_CTRL), reg);
  79. reg &= ~BIT(1);
  80. write32((MAC_REG + SYS_RBUF_FLUSH_CTRL),reg);
  81. DELAY_MICROS(10);
  82. write32((MAC_REG + SYS_RBUF_FLUSH_CTRL),0);
  83. DELAY_MICROS(10);
  84. write32(MAC_REG + UMAC_CMD, 0);
  85. write32(MAC_REG + UMAC_CMD, (CMD_SW_RESET | CMD_LCL_LOOP_EN));
  86. DELAY_MICROS(2);
  87. write32(MAC_REG + UMAC_CMD, 0);
  88. /* clear tx/rx counter */
  89. write32(MAC_REG + UMAC_MIB_CTRL, MIB_RESET_RX | MIB_RESET_TX | MIB_RESET_RUNT);
  90. write32(MAC_REG + UMAC_MIB_CTRL, 0);
  91. write32(MAC_REG + UMAC_MAX_FRAME_LEN, ENET_MAX_MTU_SIZE);
  92. /* init rx registers, enable ip header optimization */
  93. reg = read32(MAC_REG + RBUF_CTRL);
  94. reg |= RBUF_ALIGN_2B;
  95. write32(MAC_REG + RBUF_CTRL, reg);
  96. write32(MAC_REG + RBUF_TBUF_SIZE_CTRL, 1);
  97. }
  98. static void bcmgenet_disable_dma(void)
  99. {
  100. rt_uint32_t tdma_reg = 0, rdma_reg = 0;
  101. tdma_reg = read32(MAC_REG + TDMA_REG_BASE + DMA_CTRL);
  102. tdma_reg &= ~(1UL << DMA_EN);
  103. write32(MAC_REG + TDMA_REG_BASE + DMA_CTRL, tdma_reg);
  104. rdma_reg = read32(MAC_REG + RDMA_REG_BASE + DMA_CTRL);
  105. rdma_reg &= ~(1UL << DMA_EN);
  106. write32(MAC_REG + RDMA_REG_BASE + DMA_CTRL, rdma_reg);
  107. write32(MAC_REG + UMAC_TX_FLUSH, 1);
  108. DELAY_MICROS(100);
  109. write32(MAC_REG + UMAC_TX_FLUSH, 0);
  110. }
  111. static void bcmgenet_enable_dma(void)
  112. {
  113. rt_uint32_t reg = 0;
  114. rt_uint32_t dma_ctrl = 0;
  115. dma_ctrl = (1 << (DEFAULT_Q + DMA_RING_BUF_EN_SHIFT)) | DMA_EN;
  116. write32(MAC_REG + TDMA_REG_BASE + DMA_CTRL, dma_ctrl);
  117. reg = read32(MAC_REG + RDMA_REG_BASE + DMA_CTRL);
  118. write32(MAC_REG + RDMA_REG_BASE + DMA_CTRL, dma_ctrl | reg);
  119. }
  120. static int bcmgenet_mdio_write(rt_uint32_t addr, rt_uint32_t reg, rt_uint32_t value)
  121. {
  122. int count = 10000;
  123. rt_uint32_t val;
  124. val = MDIO_WR | (addr << MDIO_PMD_SHIFT) |(reg << MDIO_REG_SHIFT) | (0xffff & value);
  125. write32(MAC_REG + MDIO_CMD, val);
  126. rt_uint32_t reg_val = read32(MAC_REG + MDIO_CMD);
  127. reg_val = reg_val | MDIO_START_BUSY;
  128. write32(MAC_REG + MDIO_CMD, reg_val);
  129. while ((read32(MAC_REG + MDIO_CMD) & MDIO_START_BUSY) && (--count))
  130. DELAY_MICROS(1);
  131. reg_val = read32(MAC_REG + MDIO_CMD);
  132. return reg_val & 0xffff;
  133. }
  134. static int bcmgenet_mdio_read(rt_uint32_t addr, rt_uint32_t reg)
  135. {
  136. int count = 10000;
  137. rt_uint32_t val = 0;
  138. rt_uint32_t reg_val = 0;
  139. val = MDIO_RD | (addr << MDIO_PMD_SHIFT) | (reg << MDIO_REG_SHIFT);
  140. write32(MAC_REG + MDIO_CMD, val);
  141. reg_val = read32(MAC_REG + MDIO_CMD);
  142. reg_val = reg_val | MDIO_START_BUSY;
  143. write32(MAC_REG + MDIO_CMD, reg_val);
  144. while ((read32(MAC_REG + MDIO_CMD) & MDIO_START_BUSY) && (--count))
  145. DELAY_MICROS(1);
  146. reg_val = read32(MAC_REG + MDIO_CMD);
  147. return reg_val & 0xffff;
  148. }
  149. static int bcmgenet_gmac_write_hwaddr(void)
  150. {
  151. //{0xdc,0xa6,0x32,0x28,0x22,0x50};
  152. rt_uint8_t addr[6];
  153. rt_uint32_t reg;
  154. bcm271x_mbox_hardware_get_mac_address(&addr[0]);
  155. reg = addr[0] << 24 | addr[1] << 16 | addr[2] << 8 | addr[3];
  156. write32(MAC_REG + UMAC_MAC0, reg);
  157. reg = addr[4] << 8 | addr[5];
  158. write32(MAC_REG + UMAC_MAC1, reg);
  159. return 0;
  160. }
  161. static int get_ethernet_uid(void)
  162. {
  163. rt_uint32_t uid_high = 0;
  164. rt_uint32_t uid_low = 0;
  165. rt_uint32_t uid = 0;
  166. uid_high = bcmgenet_mdio_read(1, BCM54213PE_PHY_IDENTIFIER_HIGH);
  167. uid_low = bcmgenet_mdio_read(1, BCM54213PE_PHY_IDENTIFIER_LOW);
  168. uid = (uid_high << 16 | uid_low);
  169. if(BCM54213PE_VERSION_B1 == uid)
  170. {
  171. rt_kprintf("version is B1\n");
  172. }
  173. return uid;
  174. }
  175. static void bcmgenet_mdio_init(void)
  176. {
  177. rt_uint32_t ret = 0;
  178. /*get ethernet uid*/
  179. ret = get_ethernet_uid();
  180. if(ret == 0)
  181. {
  182. return;
  183. }
  184. /* reset phy */
  185. bcmgenet_mdio_write(1, BCM54213PE_MII_CONTROL, MII_CONTROL_PHY_RESET);
  186. /* read control reg */
  187. bcmgenet_mdio_read(1, BCM54213PE_MII_CONTROL);
  188. /* reset phy again */
  189. bcmgenet_mdio_write(1, BCM54213PE_MII_CONTROL, MII_CONTROL_PHY_RESET);
  190. /* read control reg */
  191. bcmgenet_mdio_read(1, BCM54213PE_MII_CONTROL);
  192. /* read status reg */
  193. bcmgenet_mdio_read(1, BCM54213PE_MII_STATUS);
  194. /* read status reg */
  195. bcmgenet_mdio_read(1, BCM54213PE_IEEE_EXTENDED_STATUS);
  196. bcmgenet_mdio_read(1, BCM54213PE_AUTO_NEGOTIATION_ADV);
  197. bcmgenet_mdio_read(1, BCM54213PE_MII_STATUS);
  198. bcmgenet_mdio_read(1, BCM54213PE_CONTROL);
  199. /* half full duplex capability */
  200. bcmgenet_mdio_write(1, BCM54213PE_CONTROL, (CONTROL_HALF_DUPLEX_CAPABILITY | CONTROL_FULL_DUPLEX_CAPABILITY));
  201. bcmgenet_mdio_read(1, BCM54213PE_MII_CONTROL);
  202. /* set mii control */
  203. bcmgenet_mdio_write(1,BCM54213PE_MII_CONTROL,(MII_CONTROL_AUTO_NEGOTIATION_ENABLED | MII_CONTROL_AUTO_NEGOTIATION_RESTART| MII_CONTROL_PHY_FULL_DUPLEX| MII_CONTROL_SPEED_SELECTION));
  204. }
  205. static void rx_ring_init(void)
  206. {
  207. write32(MAC_REG + RDMA_REG_BASE + DMA_SCB_BURST_SIZE, DMA_MAX_BURST_LENGTH);
  208. write32(MAC_REG + RDMA_RING_REG_BASE + DMA_START_ADDR,0x0 );
  209. write32(MAC_REG + RDMA_READ_PTR, 0x0);
  210. write32(MAC_REG + RDMA_WRITE_PTR, 0x0);
  211. write32(MAC_REG + RDMA_RING_REG_BASE + DMA_END_ADDR, RX_DESCS * DMA_DESC_SIZE / 4 - 1);
  212. write32(MAC_REG + RDMA_PROD_INDEX, 0x0);
  213. write32(MAC_REG + RDMA_CONS_INDEX, 0x0);
  214. write32(MAC_REG + RDMA_RING_REG_BASE + DMA_RING_BUF_SIZE, (RX_DESCS << DMA_RING_SIZE_SHIFT) | RX_BUF_LENGTH);
  215. write32(MAC_REG + RDMA_XON_XOFF_THRESH, DMA_FC_THRESH_VALUE);
  216. write32(MAC_REG + RDMA_REG_BASE + DMA_RING_CFG,1 << DEFAULT_Q);
  217. }
  218. static void tx_ring_init(void)
  219. {
  220. write32(MAC_REG + TDMA_REG_BASE + DMA_SCB_BURST_SIZE, DMA_MAX_BURST_LENGTH);
  221. write32(MAC_REG + TDMA_RING_REG_BASE + DMA_START_ADDR, 0x0);
  222. write32(MAC_REG + TDMA_READ_PTR, 0x0);
  223. write32(MAC_REG + TDMA_READ_PTR, 0x0);
  224. write32(MAC_REG + TDMA_READ_PTR, 0x0);
  225. write32(MAC_REG + TDMA_WRITE_PTR, 0x0);
  226. write32(MAC_REG + TDMA_RING_REG_BASE + DMA_END_ADDR,TX_DESCS * DMA_DESC_SIZE / 4 - 1);
  227. write32(MAC_REG + TDMA_PROD_INDEX, 0x0);
  228. write32(MAC_REG + TDMA_CONS_INDEX, 0x0);
  229. write32(MAC_REG + TDMA_RING_REG_BASE + DMA_MBUF_DONE_THRESH,0x1);
  230. write32(MAC_REG + TDMA_FLOW_PERIOD,0x0);
  231. write32(MAC_REG + TDMA_RING_REG_BASE + DMA_RING_BUF_SIZE, (TX_DESCS << DMA_RING_SIZE_SHIFT) | RX_BUF_LENGTH);
  232. write32(MAC_REG + TDMA_REG_BASE + DMA_RING_CFG,1 << DEFAULT_Q);
  233. }
  234. static void rx_descs_init(void)
  235. {
  236. char *rxbuffs = (char *)RECV_DATA_NO_CACHE;
  237. rt_uint32_t len_stat, i;
  238. void *desc_base = (void *)RX_DESC_BASE;
  239. len_stat = (RX_BUF_LENGTH << DMA_BUFLENGTH_SHIFT) | DMA_OWN;
  240. for (i = 0; i < RX_DESCS; i++) {
  241. write32((desc_base + i * DMA_DESC_SIZE + DMA_DESC_ADDRESS_LO), lower_32_bits((uintptr_t)&rxbuffs[i * RX_BUF_LENGTH]));
  242. write32((desc_base + i * DMA_DESC_SIZE + DMA_DESC_ADDRESS_HI),upper_32_bits((uintptr_t)&rxbuffs[i * RX_BUF_LENGTH]));
  243. write32((desc_base + i * DMA_DESC_SIZE + DMA_DESC_LENGTH_STATUS),len_stat);
  244. }
  245. }
  246. static int phy_startup(void)
  247. {
  248. int count = 1000000;
  249. while ((bcmgenet_mdio_read(1, BCM54213PE_MII_STATUS) & MII_STATUS_LINK_UP) && (--count))
  250. DELAY_MICROS(1);
  251. if(count > 0)
  252. {
  253. rt_kprintf("bcmgenet: PHY startup ok!\n");
  254. }
  255. else
  256. {
  257. rt_kprintf("bcmgenet: PHY startup err!\n");
  258. return 1;
  259. }
  260. if(bcmgenet_mdio_read(1, BCM54213PE_STATUS) == 0)
  261. {
  262. //todo
  263. }
  264. else
  265. {
  266. rt_kprintf("bcmgenet: BCM54213PE_STATUS err!\n");
  267. }
  268. if(bcmgenet_mdio_read(1, BCM54213PE_CONTROL) == (CONTROL_FULL_DUPLEX_CAPABILITY| CONTROL_HALF_DUPLEX_CAPABILITY))
  269. {
  270. //todo
  271. }
  272. else
  273. {
  274. rt_kprintf("bcmgenet: BCM54213PE_CONTROL err!\n");
  275. }
  276. return 0;
  277. }
  278. static int bcmgenet_adjust_link(void)
  279. {
  280. rt_uint32_t speed;
  281. rt_uint32_t phy_dev_speed = SPEED_100;
  282. switch (phy_dev_speed) {
  283. case SPEED_1000:
  284. speed = UMAC_SPEED_1000;
  285. break;
  286. case SPEED_100:
  287. speed = UMAC_SPEED_100;
  288. break;
  289. case SPEED_10:
  290. speed = UMAC_SPEED_10;
  291. break;
  292. default:
  293. rt_kprintf("bcmgenet: Unsupported PHY speed: %d\n", phy_dev_speed);
  294. return -1;
  295. }
  296. rt_uint32_t reg1 = read32(MAC_REG + EXT_RGMII_OOB_CTRL);
  297. //reg1 &= ~(1UL << OOB_DISABLE);
  298. //rt_kprintf("OOB_DISABLE is %d\n", OOB_DISABLE);
  299. reg1 |= (RGMII_LINK | RGMII_MODE_EN | ID_MODE_DIS);
  300. write32(MAC_REG + EXT_RGMII_OOB_CTRL, reg1);
  301. DELAY_MICROS(1000);
  302. write32(MAC_REG + UMAC_CMD, speed << CMD_SPEED_SHIFT);
  303. return 0;
  304. }
  305. static int bcmgenet_gmac_eth_start(void)
  306. {
  307. rt_uint32_t ret;
  308. rt_uint32_t count = 10000;
  309. bcmgenet_umac_reset();
  310. bcmgenet_gmac_write_hwaddr();
  311. /* Disable RX/TX DMA and flush TX queues */
  312. bcmgenet_disable_dma();
  313. rx_ring_init();
  314. rx_descs_init();
  315. tx_ring_init();
  316. /* Enable RX/TX DMA */
  317. bcmgenet_enable_dma();
  318. /* read PHY properties over the wire from generic PHY set-up */
  319. ret = phy_startup();
  320. if (ret) {
  321. rt_kprintf("bcmgenet: PHY startup failed: %d\n", ret);
  322. return ret;
  323. }
  324. /* Update MAC registers based on PHY property */
  325. ret = bcmgenet_adjust_link();
  326. if (ret) {
  327. rt_kprintf("bcmgenet: adjust PHY link failed: %d\n", ret);
  328. return ret;
  329. }
  330. /* wait tx index clear */
  331. while ((read32(MAC_REG + TDMA_CONS_INDEX) != 0) && (--count))
  332. DELAY_MICROS(1);
  333. tx_index = read32(MAC_REG + TDMA_CONS_INDEX);
  334. write32(MAC_REG + TDMA_PROD_INDEX, tx_index);
  335. index_flag = read32(MAC_REG + RDMA_PROD_INDEX);
  336. rx_index = index_flag % 256;
  337. write32(MAC_REG + RDMA_CONS_INDEX, index_flag);
  338. write32(MAC_REG + RDMA_PROD_INDEX, index_flag);
  339. /* Enable Rx/Tx */
  340. rt_uint32_t rx_tx_en;
  341. rx_tx_en = read32(MAC_REG + UMAC_CMD);
  342. rx_tx_en |= (CMD_TX_EN | CMD_RX_EN);
  343. write32(MAC_REG + UMAC_CMD, rx_tx_en);
  344. return 0;
  345. }
  346. static rt_uint32_t prev_recv_cnt = 0;
  347. static rt_uint32_t cur_recv_cnt = 0;
  348. static rt_uint32_t bcmgenet_gmac_eth_recv(rt_uint8_t **packetp)
  349. {
  350. void* desc_base;
  351. rt_uint32_t length = 0, addr = 0;
  352. rt_uint32_t prod_index = read32(MAC_REG + RDMA_PROD_INDEX);
  353. //get next
  354. if(prod_index == index_flag)
  355. {
  356. cur_recv_cnt = index_flag;
  357. //no buff
  358. return 0;
  359. }
  360. else
  361. {
  362. if(prev_recv_cnt == prod_index)
  363. {
  364. return 0;
  365. }
  366. desc_base = RX_DESC_BASE + rx_index * DMA_DESC_SIZE;
  367. length = read32(desc_base + DMA_DESC_LENGTH_STATUS);
  368. length = (length >> DMA_BUFLENGTH_SHIFT) & DMA_BUFLENGTH_MASK;
  369. addr = read32(desc_base + DMA_DESC_ADDRESS_LO);
  370. /* To cater for the IP headepr alignment the hardware does.
  371. * This would actually not be needed if we don't program
  372. * RBUF_ALIGN_2B
  373. */
  374. *packetp = (rt_uint8_t *)(addr + RX_BUF_OFFSET);
  375. rx_index = rx_index + 1;
  376. if(rx_index >= 256)
  377. {
  378. rx_index = 0;
  379. }
  380. write32(MAC_REG + RDMA_CONS_INDEX, cur_recv_cnt);
  381. cur_recv_cnt = cur_recv_cnt + 1;
  382. prev_recv_cnt = cur_recv_cnt;
  383. return length;
  384. }
  385. }
  386. static int bcmgenet_gmac_eth_send(void *packet, int length)
  387. {
  388. void* desc_base = (TX_DESC_BASE + tx_index * DMA_DESC_SIZE);
  389. rt_uint32_t len_stat = length << DMA_BUFLENGTH_SHIFT;
  390. rt_uint32_t prod_index, cons;
  391. rt_uint32_t tries = 100;
  392. prod_index = read32(MAC_REG + TDMA_PROD_INDEX);
  393. len_stat |= 0x3F << DMA_TX_QTAG_SHIFT;
  394. len_stat |= DMA_TX_APPEND_CRC | DMA_SOP | DMA_EOP;
  395. write32((desc_base + DMA_DESC_ADDRESS_LO),SEND_DATA_NO_CACHE);
  396. write32((desc_base + DMA_DESC_ADDRESS_HI),0);
  397. write32((desc_base + DMA_DESC_LENGTH_STATUS),len_stat);
  398. if(++tx_index>= TX_DESCS)
  399. {
  400. tx_index = 0;
  401. }
  402. prod_index++;
  403. /* Start Transmisson */
  404. write32(MAC_REG + TDMA_PROD_INDEX,prod_index);
  405. do {
  406. cons = read32(MAC_REG + TDMA_CONS_INDEX);
  407. } while ((cons & 0xffff) < prod_index && --tries);
  408. if (!tries)
  409. {
  410. return -1;
  411. }
  412. return 0;
  413. }
  414. static rt_err_t bcmgenet_eth_init(rt_device_t device)
  415. {
  416. struct eth_device *eth_device = (struct eth_device *)device;
  417. RT_ASSERT(eth_device != RT_NULL);
  418. rt_uint32_t ret = 0;
  419. rt_uint32_t hw_reg = 0;
  420. struct rt_eth_dev *dev = &eth_dev;
  421. /* Read GENET HW version */
  422. rt_uint8_t major = 0;
  423. hw_reg = read32(MAC_REG + SYS_REV_CTRL);
  424. major = (hw_reg >> 24) & 0x0f;
  425. if (major != 6) {
  426. if (major == 5)
  427. major = 4;
  428. else if (major == 0)
  429. major = 1;
  430. rt_kprintf("Uns upported GENETv%d.%d\n", major, (hw_reg >> 16) & 0x0f);
  431. return RT_ERROR;
  432. }
  433. /* set interface */
  434. ret = bcmgenet_interface_set();
  435. if (ret)
  436. {
  437. return ret;
  438. }
  439. /* rbuf clear */
  440. write32(MAC_REG + SYS_RBUF_FLUSH_CTRL, 0);
  441. /* disable MAC while updating its registers */
  442. write32(MAC_REG + UMAC_CMD, 0);
  443. /* issue soft reset with (rg)mii loopback to ensure a stable rxclk */
  444. write32(MAC_REG + UMAC_CMD, CMD_SW_RESET | CMD_LCL_LOOP_EN);
  445. bcmgenet_mdio_init();
  446. bcmgenet_gmac_write_hwaddr();
  447. bcmgenet_gmac_write_hwaddr();
  448. bcmgenet_gmac_eth_start();
  449. //irq or poll
  450. rt_timer_init(&dev->rx_poll_timer, "rx_poll_timer",
  451. eth_rx_irq,
  452. NULL,
  453. 1,
  454. RT_TIMER_FLAG_PERIODIC);
  455. rt_timer_start(&dev->rx_poll_timer);
  456. return RT_EOK;
  457. }
  458. static rt_err_t bcmgenet_eth_control(rt_device_t dev, int cmd, void *args)
  459. {
  460. switch (cmd)
  461. {
  462. case NIOCTL_GADDR:
  463. if (args) rt_memcpy(args, eth_dev.dev_addr, 6);
  464. else return -RT_ERROR;
  465. break;
  466. default :
  467. break;
  468. }
  469. return RT_EOK;
  470. }
  471. rt_err_t rt_eth_tx(rt_device_t device, struct pbuf *p)
  472. {
  473. rt_uint32_t sendbuf = SEND_DATA_NO_CACHE;
  474. /* lock eth device */
  475. rt_sem_take(&sem_lock, RT_WAITING_FOREVER);
  476. //struct rt_eth_dev *dev = (struct rt_eth_dev *) device;
  477. pbuf_copy_partial(p, (void *)&send_cache_pbuf[0], p->tot_len, 0);
  478. rt_memcpy((void *)sendbuf, send_cache_pbuf, p->tot_len);
  479. bcmgenet_gmac_eth_send((void *)sendbuf, p->tot_len);
  480. rt_sem_release(&sem_lock);
  481. return RT_EOK;
  482. }
  483. char recv_data[RX_BUF_LENGTH];
  484. struct pbuf *rt_eth_rx(rt_device_t device)
  485. {
  486. int recv_len = 0;
  487. rt_uint32_t addr_point[8];
  488. struct pbuf *pbuf = RT_NULL;
  489. rt_sem_take(&sem_lock, RT_WAITING_FOREVER);
  490. recv_len = bcmgenet_gmac_eth_recv((rt_uint8_t **)&addr_point[0]);
  491. if(recv_len > 0)
  492. {
  493. pbuf = pbuf_alloc(PBUF_LINK, recv_len, PBUF_RAM);
  494. rt_memcpy(pbuf->payload, (char *)addr_point[0], recv_len);
  495. }
  496. rt_sem_release(&sem_lock);
  497. return pbuf;
  498. }
  499. int rt_hw_eth_init(void)
  500. {
  501. rt_uint8_t mac_addr[6];
  502. rt_sem_init(&sem_lock, "eth_lock", 1, RT_IPC_FLAG_FIFO);
  503. memset(&eth_dev, 0, sizeof(eth_dev));
  504. memset((void *)SEND_DATA_NO_CACHE, 0, sizeof(DMA_DISC_ADDR_SIZE));
  505. memset((void *)RECV_DATA_NO_CACHE, 0, sizeof(DMA_DISC_ADDR_SIZE));
  506. bcm271x_mbox_hardware_get_mac_address(&mac_addr[0]);
  507. eth_dev.iobase = MAC_REG;
  508. eth_dev.name = "e0";
  509. eth_dev.dev_addr[0] = mac_addr[0];
  510. eth_dev.dev_addr[1] = mac_addr[1];
  511. eth_dev.dev_addr[2] = mac_addr[2];
  512. eth_dev.dev_addr[3] = mac_addr[3];
  513. eth_dev.dev_addr[4] = mac_addr[4];
  514. eth_dev.dev_addr[5] = mac_addr[5];
  515. eth_dev.parent.parent.type = RT_Device_Class_NetIf;
  516. eth_dev.parent.parent.init = bcmgenet_eth_init;
  517. eth_dev.parent.parent.open = RT_NULL;
  518. eth_dev.parent.parent.close = RT_NULL;
  519. eth_dev.parent.parent.read = RT_NULL;
  520. eth_dev.parent.parent.write = RT_NULL;
  521. eth_dev.parent.parent.control = bcmgenet_eth_control;
  522. eth_dev.parent.parent.user_data = RT_NULL;
  523. eth_dev.parent.eth_tx = rt_eth_tx;
  524. eth_dev.parent.eth_rx = rt_eth_rx;
  525. eth_device_init(&(eth_dev.parent), "e0");
  526. eth_device_linkchange(&eth_dev.parent, RT_TRUE); //linkup the e0 for lwip to check
  527. return 0;
  528. }
  529. INIT_COMPONENT_EXPORT(rt_hw_eth_init);