sitaraif.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831
  1. /**
  2. * @file - sitaraif.c
  3. * lwIP Ethernet interface for Sitara Devices
  4. *
  5. */
  6. /**
  7. * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
  8. * All rights reserved.
  9. *
  10. * Redistribution and use in source and binary forms, with or without modification,
  11. * are permitted provided that the following conditions are met:
  12. *
  13. * 1. Redistributions of source code must retain the above copyright notice,
  14. * this list of conditions and the following disclaimer.
  15. * 2. Redistributions in binary form must reproduce the above copyright notice,
  16. * this list of conditions and the following disclaimer in the documentation
  17. * and/or other materials provided with the distribution.
  18. * 3. The name of the author may not be used to endorse or promote products
  19. * derived from this software without specific prior written permission.
  20. *
  21. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
  22. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  23. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
  24. * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  25. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
  26. * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  27. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  28. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  29. * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
  30. * OF SUCH DAMAGE.
  31. *
  32. * This file is part of the lwIP TCP/IP stack.
  33. *
  34. * Author: Adam Dunkels <adam@sics.se>
  35. *
  36. */
  37. /**
  38. * Copyright (c) 2010 Texas Instruments Incorporated
  39. *
  40. * This file is dervied from the "ethernetif.c" skeleton Ethernet network
  41. * interface driver for lwIP.
  42. *
  43. */
  44. #include "src/include/lwip/opt.h"
  45. #include "src/include/lwip/def.h"
  46. #include "src/include/lwip/mem.h"
  47. #include "src/include/lwip/pbuf.h"
  48. #include "src/include/lwip/sys.h"
  49. #include "src/include/lwip/stats.h"
  50. #include "src/include/lwip/snmp.h"
  51. #include "src/include/netif/etharp.h"
  52. #include "src/include/netif/ppp_oe.h"
  53. #include "src/include/lwip/err.h"
  54. #include "ports/am1808/include/netif/sitaraif.h"
  55. #include "ports/am1808/include/arch/cc.h"
  56. /* Sitara DriverLib Header Files required for this interface driver. */
  57. #include "hw_types.h"
  58. #include "emac.h"
  59. #include "mdio.h"
  60. #include "interrupt.h"
  61. #include "lan8710a.h"
  62. /* EMAC Control RAM size in bytes */
  63. #ifndef SIZE_EMAC_CTRL_RAM
  64. #define SIZE_EMAC_CTRL_RAM 0x2000
  65. #endif
  66. /* MDIO input and output frequencies in Hz */
  67. #define MDIO_FREQ_INPUT 75000000
  68. #define MDIO_FREQ_OUTPUT 1000000
  69. #define EMAC_BUF_DESC_OWNER 0x20000000
  70. #define EMAC_BUF_DESC_SOP 0x80000000
  71. #define EMAC_BUF_DESC_EOP 0x40000000
  72. #define EMAC_BUF_DESC_EOQ 0x10000000
  73. #define MAX_TRANSFER_UNIT 1500
  74. #define PBUF_LEN_MAX MAX_TRANSFER_UNIT
  75. /* Base Addresses */
  76. #define EMAC_CTRL_RAM_0_BASE 0x01E20000
  77. #define EMAC_0_BASE 0x01E23000
  78. #define EMAC_CTRL_0_BASE 0x01E22000
  79. #define MDIO_0_BASE 0x01E24000
  80. #define MAX_RX_PBUF_ALLOC 10
  81. #define MIN_PKT_LEN 60
  82. /* Define those to better describe the network interface. */
  83. #define IFNAME0 'e'
  84. #define IFNAME1 'n'
  85. /* EMAC TX Buffer descriptor data structure */
  86. struct emac_tx_bd {
  87. volatile struct emac_tx_bd *next;
  88. volatile u32_t bufptr;
  89. volatile u32_t bufoff_len;
  90. volatile u32_t flags_pktlen;
  91. /* helper to know which pbuf this tx bd corresponds to */
  92. volatile struct pbuf *pbuf;
  93. }emac_tx_bd;
  94. /* EMAC RX Buffer descriptor data structure */
  95. struct emac_rx_bd {
  96. volatile struct emac_rx_bd *next;
  97. volatile u32_t bufptr;
  98. volatile u32_t bufoff_len;
  99. volatile u32_t flags_pktlen;
  100. /* helper to know which pbuf this rx bd corresponds to */
  101. volatile struct pbuf *pbuf;
  102. }emac_rx_bd;
  103. /**
  104. * Helper struct to hold the data used to operate on a particular
  105. * receive channel
  106. */
  107. struct rxch {
  108. volatile struct emac_rx_bd *free_head;
  109. volatile struct emac_rx_bd *active_head;
  110. volatile struct emac_rx_bd *active_tail;
  111. u32_t freed_pbuf_len;
  112. }rxch;
  113. /**
  114. * Helper struct to hold the data used to operate on a particular
  115. * transmit channel
  116. */
  117. struct txch {
  118. volatile struct emac_tx_bd *free_head;
  119. volatile struct emac_tx_bd *active_tail;
  120. volatile struct emac_tx_bd *next_bd_to_process;
  121. }txch;
  122. /**
  123. * Helper struct to hold private data used to operate the ethernet interface.
  124. */
  125. struct sitaraif {
  126. /* emac instance number */
  127. u32_t inst_num;
  128. u8_t mac_addr[6];
  129. /* emac base address */
  130. u32_t emac_base;
  131. /* emac controller base address */
  132. volatile u32_t emac_ctrl_base;
  133. volatile u32_t emac_ctrl_ram;
  134. /* mdio base address */
  135. volatile u32_t mdio_base;
  136. /* phy parameters for this instance - for future use */
  137. u32_t phy_addr;
  138. u32_t (*phy_autoneg)(u32_t, u32_t, u16_t);
  139. u32_t (*phy_partnerability)(u32_t, u32_t, u16_t*);
  140. /* The tx/rx channels for the interface */
  141. struct txch txch;
  142. struct rxch rxch;
  143. }sitaraif;
  144. /* Defining interface for all the emac instances */
  145. static struct sitaraif sitaraif_data[MAX_EMAC_INSTANCE];
  146. /**
  147. * Function to set the MAC address to the interface
  148. * @param inst_num the instance number
  149. * @return none.
  150. */
  151. void
  152. sitaraif_macaddrset(u32_t inst_num, u8_t *mac_addr) {
  153. struct sitaraif *sitaraif;
  154. u32_t temp;
  155. sitaraif = &sitaraif_data[inst_num];
  156. /* set MAC hardware address */
  157. for(temp = 0; temp < ETHARP_HWADDR_LEN; temp++) {
  158. sitaraif->mac_addr[temp] = mac_addr[(ETHARP_HWADDR_LEN - 1) - temp];
  159. }
  160. }
  161. /**
  162. * Function to setup the instance parameters inside the interface
  163. * @param sitaraif
  164. * @return none.
  165. */
  166. static void
  167. sitaraif_inst_config(struct sitaraif *sitaraif) {
  168. if(sitaraif->inst_num == 0) {
  169. sitaraif->emac_base = EMAC_0_BASE;
  170. sitaraif->emac_ctrl_base = EMAC_CTRL_0_BASE;
  171. sitaraif->emac_ctrl_ram = EMAC_CTRL_RAM_0_BASE;
  172. sitaraif->mdio_base = MDIO_0_BASE;
  173. #if defined(lcdkOMAPL138) || defined(lcdkC6748)
  174. sitaraif->phy_addr = 7;
  175. #else
  176. sitaraif->phy_addr = 0;
  177. #endif
  178. sitaraif->phy_autoneg = Lan8710aAutoNegotiate;
  179. sitaraif->phy_partnerability = Lan8710aPartnerAbilityGet;
  180. }
  181. }
  182. /**
  183. * Function to setup the link. AutoNegotiates with the phy for link
  184. * setup and set the EMAC with the result of autonegotiation.
  185. * @param sitaraif
  186. * @return ERR_OK if everything passed
  187. * others if not passed
  188. */
  189. static err_t
  190. sitaraif_link_setup(struct sitaraif *sitaraif) {
  191. err_t linkstat = ERR_CONN;
  192. u16_t partnr_ablty;
  193. u32_t phyduplex = EMAC_DUPLEX_HALF;
  194. volatile unsigned int delay = 0xFFFFF;
  195. if(sitaraif->inst_num == 0) {
  196. if(Lan8710aAutoNegotiate(sitaraif->mdio_base, sitaraif->phy_addr,
  197. (LAN8710A_100BTX | LAN8710A_100BTX_FD
  198. | LAN8710A_10BT | LAN8710A_10BT_FD)) == TRUE) {
  199. linkstat = ERR_OK;
  200. Lan8710aPartnerAbilityGet(sitaraif->mdio_base, sitaraif->phy_addr,
  201. &partnr_ablty);
  202. /* Check for 100 Mbps and duplex capability */
  203. if(partnr_ablty & LAN8710A_100BTX_FD) {
  204. phyduplex = EMAC_DUPLEX_FULL;
  205. }
  206. }
  207. else {
  208. linkstat = ERR_CONN;
  209. }
  210. }
  211. else {
  212. linkstat = ERR_CONN;
  213. }
  214. /* Set the EMAC with the negotiation results if it is successful */
  215. if(linkstat == ERR_OK) {
  216. EMACDuplexSet(sitaraif->emac_base, phyduplex);
  217. }
  218. /* Wait for the MII to settle down */
  219. while(delay--);
  220. return linkstat;
  221. }
  222. /**
  223. * This function should do the actual transmission of the packet. The packet is
  224. * contained in the pbuf that is passed to the function. This pbuf might be
  225. * chained. That is, one pbuf can span more than one tx buffer descriptors
  226. *
  227. * @param sitaraif the network interface state for this ethernetif
  228. * @param pbuf the pbuf which is to be sent over EMAC
  229. * @return None
  230. */
  231. static void
  232. sitaraif_transmit(struct sitaraif *sitaraif, struct pbuf *pbuf) {
  233. struct pbuf *q;
  234. struct txch *txch;
  235. volatile struct emac_tx_bd *curr_bd, *active_head, *bd_end;
  236. txch = &(sitaraif->txch);
  237. /* Get the buffer descriptor which is free to transmit */
  238. curr_bd = txch->free_head;
  239. active_head = curr_bd;
  240. /* Update the total packet length */
  241. curr_bd->flags_pktlen &= ~0xFFFF;
  242. curr_bd->flags_pktlen |= pbuf->tot_len;
  243. /* Indicate the start of the packet */
  244. curr_bd->flags_pktlen |= (EMAC_BUF_DESC_SOP | EMAC_BUF_DESC_OWNER);
  245. /* Copy pbuf information into TX buffer descriptors */
  246. for(q = pbuf; q != NULL; q = q->next) {
  247. /* Intialize the buffer pointer and length */
  248. curr_bd->bufptr = (u32_t)(q->payload);
  249. curr_bd->bufoff_len = (q->len) & 0xFFFF;
  250. bd_end = curr_bd;
  251. curr_bd->pbuf = pbuf;
  252. curr_bd = curr_bd->next;
  253. }
  254. /* Indicate the end of the packet */
  255. bd_end->next = NULL;
  256. bd_end->flags_pktlen |= EMAC_BUF_DESC_EOP;
  257. txch->free_head = curr_bd;
  258. /* For the first time, write the HDP with the filled bd */
  259. if(txch->active_tail == NULL) {
  260. EMACTxHdrDescPtrWrite(sitaraif->emac_base, (unsigned int)(active_head), 0);
  261. }
  262. /*
  263. * Chain the bd's. If the DMA engine, already reached the end of the chain,
  264. * the EOQ will be set. In that case, the HDP shall be written again.
  265. */
  266. else {
  267. curr_bd = txch->active_tail;
  268. curr_bd->next = active_head;
  269. //while((curr_bd->flags_pktlen & EMAC_BUF_DESC_EOQ) != EMAC_BUF_DESC_EOQ);
  270. if(curr_bd->flags_pktlen & EMAC_BUF_DESC_EOQ) {
  271. /* Write the Header Descriptor Pointer and start DMA */
  272. EMACTxHdrDescPtrWrite(sitaraif->emac_base, (unsigned int)(active_head), 0);
  273. }
  274. }
  275. txch->active_tail = bd_end;
  276. }
  277. /**
  278. * This function will send a packet through the emac if the channel is
  279. * available. Otherwise, the packet will be queued in a pbuf queue.
  280. *
  281. * @param netif the lwip network interface structure for this ethernetif
  282. * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type)
  283. * @return ERR_OK if the packet could be sent
  284. * an err_t value if the packet couldn't be sent
  285. *
  286. */
  287. static err_t
  288. sitaraif_output(struct netif *netif, struct pbuf *p) {
  289. SYS_ARCH_DECL_PROTECT(lev);
  290. /**
  291. * This entire function must run within a "critical section" to preserve
  292. * the integrity of the transmit pbuf queue.
  293. *
  294. */
  295. SYS_ARCH_PROTECT(lev);
  296. /* adjust the packet length if less than minimum required */
  297. if(p->tot_len < MIN_PKT_LEN) {
  298. p->tot_len = MIN_PKT_LEN;
  299. p->len = MIN_PKT_LEN;
  300. }
  301. /**
  302. * Bump the reference count on the pbuf to prevent it from being
  303. * freed till we are done with it.
  304. *
  305. */
  306. pbuf_ref(p);
  307. /* call the actual transmit function */
  308. sitaraif_transmit(netif->state, p);
  309. /* Return to prior interrupt state and return. */
  310. SYS_ARCH_UNPROTECT(lev);
  311. return ERR_OK;
  312. }
  313. /**
  314. * In this function, the hardware should be initialized.
  315. * Called from sitaraif_init().
  316. *
  317. * @param netif the already initialized lwip network interface structure
  318. * for this ethernetif
  319. */
  320. static err_t
  321. sitaraif_hw_init(struct netif *netif)
  322. {
  323. u32_t temp, channel;
  324. u32_t num_bd, pbuf_cnt = 0;
  325. #if defined(lcdkOMAPL138) || defined(lcdkC6748)
  326. volatile u32_t delay = 0xfffff;
  327. #else
  328. volatile u32_t delay = 0xfff;
  329. #endif
  330. volatile struct emac_tx_bd *curr_txbd, *last_txbd;
  331. volatile struct emac_rx_bd *curr_bd, *last_bd;
  332. struct sitaraif *sitaraif;
  333. struct txch *txch;
  334. struct rxch *rxch;
  335. struct pbuf *p, *q;
  336. sitaraif = netif->state;
  337. /* set MAC hardware address length */
  338. netif->hwaddr_len = ETHARP_HWADDR_LEN;
  339. /* set MAC hardware address */
  340. for(temp = 0; temp < ETHARP_HWADDR_LEN; temp++) {
  341. netif->hwaddr[temp] = sitaraif->mac_addr[(ETHARP_HWADDR_LEN - 1) - temp];
  342. }
  343. /* maximum transfer unit */
  344. netif->mtu = MAX_TRANSFER_UNIT;
  345. /* device capabilities */
  346. /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
  347. netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
  348. EMACInit(sitaraif->emac_ctrl_base, sitaraif->emac_base);
  349. MDIOInit(sitaraif->mdio_base, MDIO_FREQ_INPUT, MDIO_FREQ_OUTPUT);
  350. while(delay--);
  351. EMACRxBroadCastEnable(sitaraif->emac_base, 0);
  352. /* Set the MAC Addresses in EMAC hardware */
  353. EMACMACSrcAddrSet(sitaraif->emac_base, sitaraif->mac_addr);
  354. for(channel = 0; channel < 8; channel++) {
  355. EMACMACAddrSet(sitaraif->emac_base, channel, sitaraif->mac_addr, EMAC_MACADDR_MATCH);
  356. }
  357. if(!((MDIOPhyAliveStatusGet(sitaraif->mdio_base)
  358. >> sitaraif->phy_addr) & 0x01 )) {
  359. return ERR_CONN;
  360. }
  361. if(!Lan8710aLinkStatusGet(sitaraif->mdio_base, sitaraif->phy_addr, 10000)) {
  362. return ERR_CONN;
  363. }
  364. if(sitaraif_link_setup(sitaraif) != ERR_OK) {
  365. return ERR_CONN;
  366. }
  367. txch = &(sitaraif->txch);
  368. /**
  369. * Initialize the Descriptor Memory For TX and RX
  370. * Only Channel 0 is supported for both TX and RX
  371. */
  372. txch->free_head = (volatile struct emac_tx_bd*)(sitaraif->emac_ctrl_ram);
  373. txch->next_bd_to_process = txch->free_head;
  374. txch->active_tail = NULL;
  375. /* Set the number of descriptors for the channel */
  376. num_bd = (SIZE_EMAC_CTRL_RAM >> 1) / sizeof(emac_tx_bd);
  377. curr_txbd = txch->free_head;
  378. /* Initialize all the TX buffer Descriptors */
  379. while(num_bd--) {
  380. curr_txbd->next = curr_txbd + 1;
  381. curr_txbd->flags_pktlen = 0;
  382. last_txbd = curr_txbd;
  383. curr_txbd = curr_txbd->next;
  384. }
  385. last_txbd->next = txch->free_head;
  386. /* Initialize the descriptors for the RX channel */
  387. rxch = &(sitaraif->rxch);
  388. rxch->active_head = (volatile struct emac_rx_bd*)(curr_txbd + 1);
  389. rxch->free_head = NULL;
  390. rxch->freed_pbuf_len = 0;
  391. num_bd = ((SIZE_EMAC_CTRL_RAM >> 1) / sizeof(emac_rx_bd) - 1);
  392. curr_bd = rxch->active_head;
  393. last_bd = curr_bd;
  394. /*
  395. ** Allocate the pbufs for the maximum count permitted or till the
  396. ** number of buffer desceriptors expire, which ever is earlier.
  397. */
  398. while(pbuf_cnt < MAX_RX_PBUF_ALLOC) {
  399. p = pbuf_alloc(PBUF_RAW, PBUF_LEN_MAX, PBUF_POOL);
  400. pbuf_cnt++;
  401. if(p != NULL) {
  402. /* write the descriptors if there are enough numbers to hold the pbuf*/
  403. if(((u32_t)pbuf_clen(p)) <= num_bd) {
  404. for(q = p; q != NULL; q = q->next) {
  405. curr_bd->bufptr = (u32_t)(q->payload);
  406. curr_bd->bufoff_len = q->len;
  407. curr_bd->next = curr_bd + 1;
  408. curr_bd->flags_pktlen = EMAC_BUF_DESC_OWNER;
  409. /* Save the pbuf */
  410. curr_bd->pbuf = q;
  411. last_bd = curr_bd;
  412. curr_bd = curr_bd->next;
  413. num_bd--;
  414. }
  415. }
  416. /* free the allocated pbuf if no free descriptors are left */
  417. else {
  418. pbuf_free(p);
  419. break;
  420. }
  421. }
  422. else {
  423. break;
  424. }
  425. }
  426. last_bd->next = NULL;
  427. rxch->active_tail = last_bd;
  428. /* Acknowledge receive and transmit interrupts for proper interrupt pulsing*/
  429. EMACCoreIntAck(sitaraif->emac_base, EMAC_INT_CORE0_RX);
  430. EMACCoreIntAck(sitaraif->emac_base, EMAC_INT_CORE0_TX);
  431. EMACRxUnicastSet(sitaraif->emac_base, 0);
  432. EMACNumFreeBufSet(sitaraif->emac_base, 0, 10);
  433. EMACTxEnable(sitaraif->emac_base);
  434. EMACRxEnable(sitaraif->emac_base);
  435. /* Write the RX HDP for channel 0 */
  436. EMACRxHdrDescPtrWrite(sitaraif->emac_base, (u32_t)rxch->active_head, 0);
  437. EMACMIIEnable(sitaraif->emac_base);
  438. /**
  439. * Enable the Transmission and reception, enable the interrupts for
  440. * channel 0 and for control core 0
  441. */
  442. EMACTxIntPulseEnable(sitaraif->emac_base, sitaraif->emac_ctrl_base, 0, 0);
  443. EMACRxIntPulseEnable(sitaraif->emac_base, sitaraif->emac_ctrl_base, 0, 0);
  444. return ERR_OK;
  445. }
  446. /**
  447. * Should be called at the beginning of the program to set up the
  448. * network interface. It calls the function sitaraif_hw_init() to do the
  449. * low level initializations.
  450. *
  451. * @param netif the lwip network interface structure for this ethernetif
  452. * @return ERR_OK if the loopif is initialized
  453. * ERR_MEM if private data couldn't be allocated
  454. * any other err_t on error
  455. */
  456. err_t
  457. sitaraif_init(struct netif *netif)
  458. {
  459. /* Get the instance number first */
  460. unsigned int inst_num = *(unsigned int*)(netif->state);
  461. struct sitaraif *sitaraif;
  462. #if LWIP_NETIF_HOSTNAME
  463. /* Initialize interface hostname */
  464. netif->hostname = "lwip";
  465. #endif /* LWIP_NETIF_HOSTNAME */
  466. sitaraif = &sitaraif_data[inst_num];
  467. netif->state = sitaraif;
  468. /*
  469. * Initialize the snmp variables and counters inside the struct netif.
  470. * The last argument should be replaced with your link speed, in units
  471. * of bits per second.
  472. */
  473. NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 10000000);
  474. sitaraif->inst_num = inst_num;
  475. netif->name[0] = IFNAME0;
  476. netif->name[1] = IFNAME1;
  477. netif->num = (u8_t)inst_num;
  478. /* We directly use etharp_output() here to save a function call.
  479. * You can instead declare your own function an call etharp_output()
  480. * from it if you have to do some checks before sending (e.g. if link
  481. * is available...)
  482. */
  483. netif->output = etharp_output;
  484. netif->linkoutput = sitaraif_output;
  485. /* initialize the hardware */
  486. sitaraif_inst_config(sitaraif);
  487. return (sitaraif_hw_init(netif));
  488. }
  489. /**
  490. * Handler for Receive interrupt. Packet processing is done in this
  491. * interrupt handler itself.
  492. *
  493. * @param netif the lwip network interface structure for this ethernetif
  494. * @return none
  495. */
  496. void
  497. sitaraif_rx_inthandler(struct netif *netif) {
  498. struct sitaraif *sitaraif;
  499. struct rxch *rxch;
  500. volatile struct emac_rx_bd *curr_bd, *processed_bd, *curr_tail, *last_bd;
  501. volatile struct pbuf *pbuf, *q, *new_pbuf;
  502. u32_t ex_len = 0, len_to_alloc = 0;
  503. u16_t tot_len;
  504. sitaraif = netif->state;
  505. rxch = &(sitaraif->rxch);
  506. /* Get the bd which contains the earliest filled data */
  507. curr_bd = rxch->active_head;
  508. last_bd = rxch->active_tail;
  509. /**
  510. * Process the descriptors as long as data is available
  511. * when the DMA is receiving data, SOP flag will be set
  512. */
  513. while(curr_bd->flags_pktlen & EMAC_BUF_DESC_SOP) {
  514. ex_len = 0;
  515. len_to_alloc = 0;
  516. /* Start processing once the packet is loaded */
  517. if((curr_bd->flags_pktlen & EMAC_BUF_DESC_OWNER)
  518. != EMAC_BUF_DESC_OWNER) {
  519. if(rxch->free_head == NULL) {
  520. /* this bd chain will be freed after processing */
  521. rxch->free_head = curr_bd;
  522. }
  523. /* Get the total length of the packet. curr_bd points to the start
  524. * of the packet.
  525. */
  526. tot_len = (curr_bd->flags_pktlen) & 0xFFFF;
  527. /* Get the start of the pbuf queue */
  528. q = curr_bd->pbuf;
  529. do {
  530. /* Get the pbuf pointer which is associated with the current bd */
  531. pbuf = curr_bd->pbuf;
  532. /* If the earlier pbuf ended, update the chain */
  533. if(pbuf->next == NULL) {
  534. pbuf->next = (struct pbuf*)(curr_bd->next)->pbuf;
  535. }
  536. len_to_alloc += pbuf->len;
  537. /* Update the len and tot_len fields for the pbuf in the chain*/
  538. pbuf->len = (curr_bd->bufoff_len) & 0xFFFF;
  539. pbuf->tot_len = tot_len - ex_len ;
  540. processed_bd = curr_bd;
  541. ex_len += pbuf->len;
  542. curr_bd = curr_bd->next;
  543. } while((processed_bd->flags_pktlen & EMAC_BUF_DESC_EOP)
  544. != EMAC_BUF_DESC_EOP);
  545. /**
  546. * Close the chain for this pbuf. A full packet is received in
  547. * this pbuf chain. Now this pbuf can be given to upper layers for
  548. * processing. The start of the pbuf chain is now 'q'.
  549. */
  550. pbuf->next = NULL;
  551. /* Adjust the link statistics */
  552. LINK_STATS_INC(link.recv);
  553. /* Process the packet */
  554. if(ethernet_input((struct pbuf *)q, netif) != ERR_OK) {
  555. /* Adjust the link statistics */
  556. LINK_STATS_INC(link.memerr);
  557. LINK_STATS_INC(link.drop);
  558. }
  559. /* Acknowledge that this packet is processed */
  560. EMACRxCPWrite(sitaraif->emac_base, 0, (unsigned int)processed_bd);
  561. rxch->active_head = curr_bd;
  562. /**
  563. * The earlier pbuf chain is freed from the upper layer. So, we need to
  564. * allocate a new pbuf chain and update the descriptors with the pbuf info.
  565. * To support chaining, the total length freed by the upper layer is tracked.
  566. * Care should be taken even if the allocation fails.
  567. */
  568. /**
  569. * now len_to_alloc will contain the length of the pbuf which was freed
  570. * from the upper layer
  571. */
  572. rxch->freed_pbuf_len += len_to_alloc;
  573. new_pbuf = pbuf_alloc(PBUF_RAW, (rxch->freed_pbuf_len), PBUF_POOL);
  574. /* Write the descriptors with the pbuf info till either of them expires */
  575. if(new_pbuf != NULL) {
  576. curr_bd = rxch->free_head;
  577. for(q = new_pbuf; (q != NULL) && (curr_bd != rxch->active_head); q = q->next) {
  578. curr_bd->bufptr = (u32_t)(q->payload);
  579. /* no support for buf_offset. RXBUFFEROFFEST register is 0 */
  580. curr_bd->bufoff_len = (q->len) & 0xFFFF;
  581. curr_bd->flags_pktlen = EMAC_BUF_DESC_OWNER;
  582. rxch->freed_pbuf_len -= q->len;
  583. /* Save the pbuf */
  584. curr_bd->pbuf = q;
  585. last_bd = curr_bd;
  586. curr_bd = curr_bd->next;
  587. }
  588. /**
  589. * At this point either pbuf expired or no rxbd to allocate. If
  590. * there are no, enough rx bds to allocate all pbufs in the chain,
  591. * free the rest of the pbuf
  592. */
  593. if(q != NULL) {
  594. pbuf_free((struct pbuf *)q);
  595. }
  596. curr_tail = rxch->active_tail;
  597. last_bd->next = NULL;
  598. curr_tail->next = rxch->free_head;
  599. /**
  600. * Check if the reception has ended. If the EOQ flag is set, the NULL
  601. * Pointer is taken by the DMA engine. So we need to write the RX HDP
  602. * with the next descriptor.
  603. */
  604. if(curr_tail->flags_pktlen & EMAC_BUF_DESC_EOQ) {
  605. EMACRxHdrDescPtrWrite(sitaraif->emac_base, (u32_t)(rxch->free_head), 0);
  606. }
  607. rxch->free_head = curr_bd;
  608. rxch->active_tail = last_bd;
  609. }
  610. }
  611. curr_bd = rxch->active_head;
  612. }
  613. EMACCoreIntAck(sitaraif->emac_base, EMAC_INT_CORE0_RX);
  614. EMACCoreIntAck(sitaraif->emac_base, EMAC_INT_CORE0_TX);
  615. }
  616. /**
  617. * Handler for EMAC Transmit interrupt
  618. *
  619. * @param netif the lwip network interface structure for this ethernetif
  620. * @return none
  621. */
  622. void
  623. sitaraif_tx_inthandler(struct netif *netif) {
  624. struct txch *txch;
  625. struct sitaraif *sitaraif;
  626. volatile struct emac_tx_bd *curr_bd, *next_bd_to_process;
  627. sitaraif = netif->state;
  628. txch = &(sitaraif->txch);
  629. next_bd_to_process = txch->next_bd_to_process;
  630. curr_bd = next_bd_to_process;
  631. /* Check for correct start of packet */
  632. while((curr_bd->flags_pktlen) & EMAC_BUF_DESC_SOP) {
  633. /* Make sure that the transmission is over */
  634. while((curr_bd->flags_pktlen & EMAC_BUF_DESC_OWNER)
  635. == EMAC_BUF_DESC_OWNER);
  636. /* Traverse till the end of packet is reached */
  637. while(((curr_bd->flags_pktlen) & EMAC_BUF_DESC_EOP) != EMAC_BUF_DESC_EOP) {
  638. curr_bd = curr_bd->next;
  639. }
  640. next_bd_to_process->flags_pktlen &= ~(EMAC_BUF_DESC_SOP);
  641. curr_bd->flags_pktlen &= ~(EMAC_BUF_DESC_EOP);
  642. /**
  643. * If there are no more data transmitted, the next interrupt
  644. * shall happen with the pbuf associated with the free_head
  645. */
  646. if(curr_bd->next == NULL) {
  647. txch->next_bd_to_process = txch->free_head;
  648. }
  649. else {
  650. txch->next_bd_to_process = curr_bd->next;
  651. }
  652. /* Acknowledge the EMAC and free the corresponding pbuf */
  653. EMACTxCPWrite(sitaraif->emac_base, 0, (u32_t)curr_bd);
  654. pbuf_free((struct pbuf *)curr_bd->pbuf);
  655. LINK_STATS_INC(link.xmit);
  656. next_bd_to_process = txch->next_bd_to_process;
  657. curr_bd = next_bd_to_process;
  658. }
  659. EMACCoreIntAck(sitaraif->emac_base, EMAC_INT_CORE0_RX);
  660. EMACCoreIntAck(sitaraif->emac_base, EMAC_INT_CORE0_TX);
  661. }
  662. /**
  663. * Gets the netif status
  664. *
  665. * @param the netif whoes status to be checked
  666. * @return the status
  667. */
  668. u32_t
  669. sitaraif_netif_status(struct netif *netif) {
  670. return (netif_is_up(netif));
  671. }
  672. /**
  673. * returns the link status
  674. *
  675. * @param the netif whoes link to be checked
  676. * @return the status
  677. */
  678. u32_t
  679. sitaraif_link_status(struct netif *netif) {
  680. struct sitaraif *sitaraif = netif->state;
  681. return (Lan8710aLinkStatusGet(sitaraif->mdio_base,
  682. sitaraif->phy_addr,
  683. 10000));
  684. }