synopGMAC.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928
  1. /*
  2. * File : synopGMAC.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) chinesebear
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License along
  17. * with this program; if not, write to the Free Software Foundation, Inc.,
  18. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  19. *
  20. * Change Logs:
  21. * Date Author Notes
  22. * 2017-08-24 chinesebear first version
  23. */
  24. #include <rtthread.h>
  25. #include <rtdef.h>
  26. //#include <lwip/pbuf.h>
  27. #include "synopGMAC.h"
  28. #include "mii.c"
  29. #include "synopGMAC_debug.h"
  30. #include <ls1c.h>
  31. #define RMII
  32. #define Gmac_base 0xbfe10000
  33. #define Buffer_Size 2048
  34. #define MAX_ADDR_LEN 6
  35. #define NAMESIZE 16
  36. #define LS1B_GMAC0_IRQ 34
  37. #define BUS_SIZE_ALIGN(x) ((x+15)&~15)
  38. #define DEFAULT_MAC_ADDRESS {0x00, 0x55, 0x7B, 0xB5, 0x7D, 0xF7}
  39. u32 regbase = 0xbfe10000;
  40. static u32 GMAC_Power_down;
  41. extern void *plat_alloc_consistent_dmaable_memory(synopGMACdevice *pcidev, u32 size, u32 *addr) ;
  42. extern s32 synopGMAC_check_phy_init (synopGMACPciNetworkAdapter *adapter) ;
  43. extern int init_phy(synopGMACdevice *gmacdev);
  44. dma_addr_t plat_dma_map_single(void *hwdev, void *ptr,u32 size);
  45. void eth_rx_irq(int irqno,void *param);
  46. static char Rx_Buffer[Buffer_Size];
  47. static char Tx_Buffer[Buffer_Size];
  48. struct rt_eth_dev
  49. {
  50. struct eth_device parent;
  51. rt_uint8_t dev_addr[MAX_ADDR_LEN];
  52. char *name;
  53. int iobase;
  54. int state;
  55. int index;
  56. struct rt_timer link_timer;
  57. struct rt_timer rx_poll_timer;
  58. void *priv;
  59. };
  60. static struct rt_eth_dev eth_dev;
  61. static struct rt_semaphore sem_ack, sem_lock;
  62. /**
  63. * This sets up the transmit Descriptor queue in ring or chain mode.
  64. * This function is tightly coupled to the platform and operating system
  65. * Device is interested only after the descriptors are setup. Therefore this function
  66. * is not included in the device driver API. This function should be treated as an
  67. * example code to design the descriptor structures for ring mode or chain mode.
  68. * This function depends on the pcidev structure for allocation consistent dma-able memory in case
  69. * of linux.
  70. * This limitation is due to the fact that linux uses pci structure to allocate a dmable memory
  71. * - Allocates the memory for the descriptors.
  72. * - Initialize the Busy and Next descriptors indices to 0(Indicating first descriptor).
  73. * - Initialize the Busy and Next descriptors to first descriptor address.
  74. * - Initialize the last descriptor with the endof ring in case of ring mode.
  75. * - Initialize the descriptors in chain mode.
  76. * @param[in] pointer to synopGMACdevice.
  77. * @param[in] pointer to pci_device structure.
  78. * @param[in] number of descriptor expected in tx descriptor queue.
  79. * @param[in] whether descriptors to be created in RING mode or CHAIN mode.
  80. * \return 0 upon success. Error code upon failure.
  81. * \note This function fails if allocation fails for required number of descriptors in Ring mode,
  82. * but in chain mode
  83. * function returns -ESYNOPGMACNOMEM in the process of descriptor chain creation. once returned from
  84. * this function
  85. * user should for gmacdev->TxDescCount to see how many descriptors are there in the chain. Should
  86. * continue further
  87. * only if the number of descriptors in the chain meets the requirements
  88. */
  89. s32 synopGMAC_setup_tx_desc_queue(synopGMACdevice * gmacdev,u32 no_of_desc, u32 desc_mode)
  90. {
  91. s32 i;
  92. DmaDesc * bf1;
  93. DmaDesc *first_desc = NULL;
  94. dma_addr_t dma_addr;
  95. gmacdev->TxDescCount = 0;
  96. first_desc = (DmaDesc *)plat_alloc_consistent_dmaable_memory (gmacdev, sizeof(DmaDesc) * no_of_desc,&dma_addr);
  97. if(first_desc == NULL){
  98. rt_kprintf("Error in Tx Descriptors memory allocation\n");
  99. return -ESYNOPGMACNOMEM;
  100. }
  101. DEBUG_MES("tx_first_desc_addr = %p\n", first_desc);
  102. DEBUG_MES("dmaadr = %p\n", dma_addr);
  103. gmacdev->TxDescCount = no_of_desc;
  104. gmacdev->TxDesc = first_desc;
  105. gmacdev->TxDescDma = dma_addr;
  106. for(i =0; i < gmacdev->TxDescCount; i++){
  107. synopGMAC_tx_desc_init_ring(gmacdev->TxDesc + i, i == gmacdev->TxDescCount-1);
  108. #if SYNOP_TOP_DEBUG
  109. rt_kprintf("\n%02d %08x \n",i,(unsigned int)(gmacdev->TxDesc + i));
  110. rt_kprintf("%08x ",(unsigned int)((gmacdev->TxDesc + i))->status);
  111. rt_kprintf("%08x ",(unsigned int)((gmacdev->TxDesc + i)->length));
  112. rt_kprintf("%08x ",(unsigned int)((gmacdev->TxDesc + i)->buffer1));
  113. rt_kprintf("%08x ",(unsigned int)((gmacdev->TxDesc + i)->buffer2));
  114. rt_kprintf("%08x ",(unsigned int)((gmacdev->TxDesc + i)->data1));
  115. rt_kprintf("%08x ",(unsigned int)((gmacdev->TxDesc + i)->data2));
  116. rt_kprintf("%08x ",(unsigned int)((gmacdev->TxDesc + i)->dummy1));
  117. rt_kprintf("%08x ",(unsigned int)((gmacdev->TxDesc + i)->dummy2));
  118. #endif
  119. }
  120. gmacdev->TxNext = 0;
  121. gmacdev->TxBusy = 0;
  122. gmacdev->TxNextDesc = gmacdev->TxDesc;
  123. gmacdev->TxBusyDesc = gmacdev->TxDesc;
  124. gmacdev->BusyTxDesc = 0;
  125. return -ESYNOPGMACNOERR;
  126. }
  127. /**
  128. * This sets up the receive Descriptor queue in ring or chain mode.
  129. * This function is tightly coupled to the platform and operating system
  130. * Device is interested only after the descriptors are setup. Therefore this function
  131. * is not included in the device driver API. This function should be treated as an
  132. * example code to design the descriptor structures in ring mode or chain mode.
  133. * This function depends on the pcidev structure for allocation of consistent dma-able memory in
  134. * case of linux.
  135. * This limitation is due to the fact that linux uses pci structure to allocate a dmable memory
  136. * - Allocates the memory for the descriptors.
  137. * - Initialize the Busy and Next descriptors indices to 0(Indicating first descriptor).
  138. * - Initialize the Busy and Next descriptors to first descriptor address.
  139. * - Initialize the last descriptor with the endof ring in case of ring mode.
  140. * - Initialize the descriptors in chain mode.
  141. * @param[in] pointer to synopGMACdevice.
  142. * @param[in] pointer to pci_device structure.
  143. * @param[in] number of descriptor expected in rx descriptor queue.
  144. * @param[in] whether descriptors to be created in RING mode or CHAIN mode.
  145. * \return 0 upon success. Error code upon failure.
  146. * \note This function fails if allocation fails for required number of descriptors in Ring mode,
  147. * but in chain mode
  148. * function returns -ESYNOPGMACNOMEM in the process of descriptor chain creation. once returned from
  149. * this function
  150. * user should for gmacdev->RxDescCount to see how many descriptors are there in the chain. Should
  151. * continue further
  152. * only if the number of descriptors in the chain meets the requirements
  153. */
  154. s32 synopGMAC_setup_rx_desc_queue(synopGMACdevice * gmacdev,u32 no_of_desc, u32 desc_mode)
  155. {
  156. s32 i;
  157. DmaDesc * bf1;
  158. DmaDesc *first_desc = NULL;
  159. dma_addr_t dma_addr;
  160. gmacdev->RxDescCount = 0;
  161. first_desc =(DmaDesc *)plat_alloc_consistent_dmaable_memory (gmacdev, sizeof(DmaDesc) * no_of_desc, &dma_addr);
  162. if(first_desc == NULL){
  163. rt_kprintf("Error in Rx Descriptor Memory allocation in Ring mode\n");
  164. return -ESYNOPGMACNOMEM;
  165. }
  166. DEBUG_MES("rx_first_desc_addr = %p\n", first_desc);
  167. DEBUG_MES("dmaadr = %p\n", dma_addr);
  168. gmacdev->RxDescCount = no_of_desc;
  169. gmacdev->RxDesc = (DmaDesc *)first_desc;
  170. gmacdev->RxDescDma = dma_addr;
  171. for(i =0; i < gmacdev->RxDescCount; i++){
  172. synopGMAC_rx_desc_init_ring(gmacdev->RxDesc + i, i == gmacdev->RxDescCount-1);
  173. }
  174. gmacdev->RxNext = 0;
  175. gmacdev->RxBusy = 0;
  176. gmacdev->RxNextDesc = gmacdev->RxDesc;
  177. gmacdev->RxBusyDesc = gmacdev->RxDesc;
  178. gmacdev->BusyRxDesc = 0;
  179. return -ESYNOPGMACNOERR;
  180. }
  181. void synopGMAC_linux_cable_unplug_function(void *adaptr)
  182. {
  183. s32 data;
  184. synopGMACPciNetworkAdapter *adapter = (synopGMACPciNetworkAdapter *)adaptr;
  185. synopGMACdevice *gmacdev = adapter->synopGMACdev;
  186. struct ethtool_cmd cmd;
  187. //rt_kprintf("%s\n",__FUNCTION__);
  188. if(!mii_link_ok(&adapter->mii)){
  189. if(gmacdev->LinkState)
  190. rt_kprintf("\r\nNo Link\r\n");
  191. gmacdev->DuplexMode = 0;
  192. gmacdev->Speed = 0;
  193. gmacdev->LoopBackMode = 0;
  194. gmacdev->LinkState = 0;
  195. }
  196. else{
  197. data = synopGMAC_check_phy_init(adapter);
  198. if(gmacdev->LinkState != data){
  199. gmacdev->LinkState = data;
  200. synopGMAC_mac_init(gmacdev);
  201. rt_kprintf("Link is up in %s mode\n",(gmacdev->DuplexMode == FULLDUPLEX) ? "FULL DUPLEX": "HALF DUPLEX");
  202. if(gmacdev->Speed == SPEED1000)
  203. rt_kprintf("Link is with 1000M Speed \r\n");
  204. if(gmacdev->Speed == SPEED100)
  205. rt_kprintf("Link is with 100M Speed \n");
  206. if(gmacdev->Speed == SPEED10)
  207. rt_kprintf("Link is with 10M Speed \n");
  208. }
  209. }
  210. }
  211. s32 synopGMAC_check_phy_init (synopGMACPciNetworkAdapter *adapter)
  212. {
  213. struct ethtool_cmd cmd;
  214. synopGMACdevice *gmacdev = adapter->synopGMACdev;
  215. if(!mii_link_ok(&adapter->mii))
  216. {
  217. gmacdev->DuplexMode = FULLDUPLEX;
  218. gmacdev->Speed = SPEED100;
  219. return 0;
  220. }
  221. else
  222. {
  223. mii_ethtool_gset(&adapter->mii, &cmd);
  224. gmacdev->DuplexMode = (cmd.duplex == DUPLEX_FULL) ? FULLDUPLEX: HALFDUPLEX ;
  225. if(cmd.speed == SPEED_1000)
  226. gmacdev->Speed = SPEED1000;
  227. else if(cmd.speed == SPEED_100)
  228. gmacdev->Speed = SPEED100;
  229. else
  230. gmacdev->Speed = SPEED10;
  231. }
  232. return gmacdev->Speed|(gmacdev->DuplexMode<<4);
  233. }
  234. static int Mac_change_check(u8 *macaddr0, u8 *macaddr1)
  235. {
  236. int i;
  237. for(i = 0; i < 6; i++){
  238. if(macaddr0[i] != macaddr1[i])
  239. return 1;
  240. }
  241. return 0;
  242. }
  243. static rt_err_t eth_init(rt_device_t device )
  244. {
  245. struct eth_device *eth_device = (struct eth_device *)device;
  246. RT_ASSERT(eth_device != RT_NULL);
  247. s32 ijk;
  248. s32 status = 0;
  249. u64 dma_addr;
  250. u32 Mac_changed = 0;
  251. struct pbuf *pbuf;
  252. u8 macaddr[6] = DEFAULT_MAC_ADDRESS;
  253. struct rt_eth_dev *dev = &eth_dev;
  254. struct synopGMACNetworkAdapter *adapter = dev->priv;
  255. synopGMACdevice * gmacdev = (synopGMACdevice *)adapter->synopGMACdev;
  256. synopGMAC_reset(gmacdev);
  257. synopGMAC_attach(gmacdev,(regbase + MACBASE),(regbase + DMABASE), DEFAULT_PHY_BASE, macaddr);
  258. synopGMAC_read_version(gmacdev);
  259. synopGMAC_set_mdc_clk_div(gmacdev,GmiiCsrClk3);
  260. gmacdev->ClockDivMdc = synopGMAC_get_mdc_clk_div(gmacdev);
  261. init_phy(adapter->synopGMACdev);
  262. rt_kprintf("tx desc_queue\n");
  263. synopGMAC_setup_tx_desc_queue(gmacdev,TRANSMIT_DESC_SIZE, RINGMODE);
  264. synopGMAC_init_tx_desc_base(gmacdev);
  265. rt_kprintf("rx desc_queue\n");
  266. synopGMAC_setup_rx_desc_queue(gmacdev,RECEIVE_DESC_SIZE, RINGMODE);
  267. synopGMAC_init_rx_desc_base(gmacdev);
  268. DEBUG_MES("DmaRxBaseAddr = %08x\n",synopGMACReadReg(gmacdev->DmaBase,DmaRxBaseAddr));
  269. // u32 dmaRx_Base_addr = synopGMACReadReg(gmacdev->DmaBase,DmaRxBaseAddr);
  270. // rt_kprintf("first_desc_addr = 0x%x\n", dmaRx_Base_addr);
  271. #ifdef ENH_DESC_8W
  272. synopGMAC_dma_bus_mode_init(gmacdev, DmaBurstLength32 | DmaDescriptorSkip2 | DmaDescriptor8Words );
  273. #else
  274. //synopGMAC_dma_bus_mode_init(gmacdev, DmaBurstLength4 | DmaDescriptorSkip1);
  275. synopGMAC_dma_bus_mode_init(gmacdev, DmaBurstLength4 | DmaDescriptorSkip2);
  276. #endif
  277. synopGMAC_dma_control_init(gmacdev,DmaStoreAndForward |DmaTxSecondFrame|DmaRxThreshCtrl128);
  278. status = synopGMAC_check_phy_init(adapter);
  279. synopGMAC_mac_init(gmacdev);
  280. synopGMAC_pause_control(gmacdev);
  281. #ifdef IPC_OFFLOAD
  282. synopGMAC_enable_rx_chksum_offload(gmacdev);
  283. synopGMAC_rx_tcpip_chksum_drop_enable(gmacdev);
  284. #endif
  285. u32 skb;
  286. do{
  287. skb = (u32)plat_alloc_memory(RX_BUF_SIZE); //should skb aligned here?
  288. if(skb == RT_NULL){
  289. rt_kprintf("ERROR in skb buffer allocation\n");
  290. break;
  291. }
  292. dma_addr = plat_dma_map_single(gmacdev,(void *)skb,RX_BUF_SIZE); //获取 skb 的 dma 地址
  293. status = synopGMAC_set_rx_qptr(gmacdev,dma_addr,RX_BUF_SIZE,(u32)skb,0,0,0);
  294. if(status < 0)
  295. {
  296. rt_kprintf("status < 0!!\n");
  297. plat_free_memory((void *)skb);
  298. }
  299. }while(status >= 0 && (status < (RECEIVE_DESC_SIZE - 1)));
  300. synopGMAC_clear_interrupt(gmacdev);
  301. synopGMAC_disable_mmc_tx_interrupt(gmacdev, 0xFFFFFFFF);
  302. synopGMAC_disable_mmc_rx_interrupt(gmacdev, 0xFFFFFFFF);
  303. synopGMAC_disable_mmc_ipc_rx_interrupt(gmacdev, 0xFFFFFFFF);
  304. // synopGMAC_disable_interrupt_all(gmacdev);
  305. synopGMAC_enable_interrupt(gmacdev, DmaIntEnable);
  306. synopGMAC_enable_dma_rx(gmacdev);
  307. synopGMAC_enable_dma_tx(gmacdev);
  308. plat_delay(DEFAULT_LOOP_VARIABLE);
  309. synopGMAC_check_phy_init(adapter);
  310. synopGMAC_mac_init(gmacdev);
  311. rt_timer_init(&dev->link_timer, "link_timer",
  312. synopGMAC_linux_cable_unplug_function,
  313. (void *)adapter,
  314. RT_TICK_PER_SECOND,
  315. RT_TIMER_FLAG_PERIODIC);
  316. rt_timer_start(&dev->link_timer);
  317. #ifdef RT_USING_GMAC_INT_MODE
  318. /* installl isr */
  319. DEBUG_MES("%s\n", __FUNCTION__);
  320. rt_hw_interrupt_install(LS1C_MAC_IRQ, eth_rx_irq, RT_NULL, "e0_isr");
  321. rt_hw_interrupt_umask(LS1C_MAC_IRQ);
  322. #else
  323. rt_timer_init(&dev->rx_poll_timer, "rx_poll_timer",
  324. eth_rx_irq,
  325. (void *)adapter,
  326. 1,
  327. RT_TIMER_FLAG_PERIODIC);
  328. rt_timer_start(&dev->rx_poll_timer);
  329. #endif /*RT_USING_GMAC_INT_MODE*/
  330. rt_kprintf("eth_inited!\n");
  331. return RT_EOK;
  332. }
  333. static rt_err_t eth_open(rt_device_t dev, rt_uint16_t oflag)
  334. {
  335. rt_kprintf("eth_open!!\n");
  336. return RT_EOK;
  337. }
  338. static rt_err_t eth_close(rt_device_t dev)
  339. {
  340. return RT_EOK;
  341. }
  342. static rt_size_t eth_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
  343. {
  344. rt_set_errno(-RT_ENOSYS);
  345. return 0;
  346. }
  347. static rt_size_t eth_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
  348. {
  349. rt_set_errno(-RT_ENOSYS);
  350. return 0;
  351. }
  352. static rt_err_t eth_control(rt_device_t dev, int cmd, void *args)
  353. {
  354. switch (cmd)
  355. {
  356. case NIOCTL_GADDR:
  357. if(args) rt_memcpy(args, eth_dev.dev_addr, 6);
  358. else return -RT_ERROR;
  359. break;
  360. default :
  361. break;
  362. }
  363. return RT_EOK;
  364. }
  365. rt_err_t rt_eth_tx(rt_device_t device, struct pbuf* p)
  366. {
  367. /* lock eth device */
  368. rt_sem_take(&sem_lock, RT_WAITING_FOREVER);
  369. DEBUG_MES("in %s\n", __FUNCTION__);
  370. s32 status;
  371. u32 pbuf;
  372. u64 dma_addr;
  373. u32 offload_needed = 0;
  374. u32 index;
  375. DmaDesc * dpr;
  376. struct rt_eth_dev *dev = (struct rt_eth_dev *) device;
  377. struct synopGMACNetworkAdapter *adapter;
  378. synopGMACdevice * gmacdev;
  379. adapter = (struct synopGMACNetworkAdapter *) dev->priv;
  380. if(adapter == NULL)
  381. return -1;
  382. gmacdev = (synopGMACdevice *) adapter->synopGMACdev;
  383. if(gmacdev == NULL)
  384. return -1;
  385. if(!synopGMAC_is_desc_owned_by_dma(gmacdev->TxNextDesc))
  386. {
  387. pbuf = (u32)plat_alloc_memory(p->len);
  388. //pbuf = (u32)pbuf_alloc(PBUF_LINK, p->len, PBUF_RAM);
  389. if(pbuf == 0)
  390. {
  391. rt_kprintf("===error in alloc bf1\n");
  392. return -1;
  393. }
  394. DEBUG_MES("p->len = %d\n", p->len);
  395. memcpy((void *)pbuf, p->payload, p->len);
  396. dma_addr = plat_dma_map_single(gmacdev,(void*)pbuf,p->len);
  397. status = synopGMAC_set_tx_qptr(gmacdev,dma_addr,p->len,pbuf,0,0,0,offload_needed,&index,dpr);
  398. if(status < 0){
  399. rt_kprintf("%s No More Free Tx Descriptors\n",__FUNCTION__);
  400. plat_free_memory((void *)pbuf);
  401. return -16;
  402. }
  403. }
  404. synopGMAC_resume_dma_tx(gmacdev);
  405. s32 desc_index;
  406. u32 data1, data2;
  407. u32 dma_addr1, dma_addr2;
  408. u32 length1, length2;
  409. #ifdef ENH_DESC_8W
  410. u32 ext_status;
  411. u16 time_stamp_higher;
  412. u32 time_stamp_high;
  413. u32 time_stamp_low;
  414. #endif
  415. do {
  416. #ifdef ENH_DESC_8W
  417. desc_index = synopGMAC_get_tx_qptr(gmacdev, &status, &dma_addr1, &length1, &data1, &dma_addr2, &length2, &data2,&ext_status,&time_stamp_high,&time_stamp_low);
  418. synopGMAC_TS_read_timestamp_higher_val(gmacdev, &time_stamp_higher);
  419. #else
  420. desc_index = synopGMAC_get_tx_qptr(gmacdev, &status, &dma_addr1, &length1, &data1, &dma_addr2, &length2, &data2);
  421. #endif
  422. if(desc_index >= 0 && data1 != 0){
  423. #ifdef IPC_OFFLOAD
  424. if(synopGMAC_is_tx_ipv4header_checksum_error(gmacdev, status)){
  425. rt_kprintf("Harware Failed to Insert IPV4 Header Checksum\n");
  426. }
  427. if(synopGMAC_is_tx_payload_checksum_error(gmacdev, status)){
  428. rt_kprintf("Harware Failed to Insert Payload Checksum\n");
  429. }
  430. #endif
  431. plat_free_memory((void *)(data1)); //sw: data1 = buffer1
  432. if(synopGMAC_is_desc_valid(status)){
  433. adapter->synopGMACNetStats.tx_bytes += length1;
  434. adapter->synopGMACNetStats.tx_packets++;
  435. }
  436. else {
  437. adapter->synopGMACNetStats.tx_errors++;
  438. adapter->synopGMACNetStats.tx_aborted_errors += synopGMAC_is_tx_aborted(status);
  439. adapter->synopGMACNetStats.tx_carrier_errors += synopGMAC_is_tx_carrier_error(status);
  440. }
  441. } adapter->synopGMACNetStats.collisions += synopGMAC_get_tx_collision_count(status);
  442. } while(desc_index >= 0);
  443. /* unlock eth device */
  444. rt_sem_release(&sem_lock);
  445. // rt_kprintf("output %d bytes\n", p->len);
  446. u32 test_data;
  447. test_data = synopGMACReadReg(gmacdev->DmaBase, DmaStatus);
  448. return RT_EOK;
  449. }
  450. struct pbuf *rt_eth_rx(rt_device_t device)
  451. {
  452. DEBUG_MES("%s : \n", __FUNCTION__);
  453. struct rt_eth_dev *dev = &eth_dev;
  454. struct synopGMACNetworkAdapter *adapter;
  455. synopGMACdevice * gmacdev;
  456. // struct PmonInet * pinetdev;
  457. s32 desc_index;
  458. int i;
  459. char * ptr;
  460. u32 bf1;
  461. u32 data1;
  462. u32 data2;
  463. u32 len;
  464. u32 status;
  465. u32 dma_addr1;
  466. u32 dma_addr2;
  467. struct pbuf *pbuf = RT_NULL;
  468. rt_sem_take(&sem_lock, RT_WAITING_FOREVER);
  469. adapter = (struct synopGMACNetworkAdapter *) dev->priv;
  470. if(adapter == NULL){
  471. rt_kprintf("%S : Unknown Device !!\n", __FUNCTION__);
  472. return NULL;
  473. }
  474. gmacdev = (synopGMACdevice *) adapter->synopGMACdev;
  475. if(gmacdev == NULL){
  476. rt_kprintf("%s : GMAC device structure is missing\n", __FUNCTION__);
  477. return NULL;
  478. }
  479. /*Handle the Receive Descriptors*/
  480. // do{
  481. desc_index = synopGMAC_get_rx_qptr(gmacdev, &status,&dma_addr1,NULL, &data1,&dma_addr2,NULL,&data2);
  482. if(desc_index >= 0 && data1 != 0){
  483. DEBUG_MES("Received Data at Rx Descriptor %d for skb 0x%08x whose status is %08x\n",desc_index,dma_addr1,status);
  484. if(synopGMAC_is_rx_desc_valid(status)||SYNOP_PHY_LOOPBACK)
  485. {
  486. pbuf = pbuf_alloc(PBUF_LINK, MAX_ETHERNET_PAYLOAD, PBUF_RAM);
  487. if(pbuf == 0) rt_kprintf("===error in pbuf_alloc\n");
  488. dma_addr1 = plat_dma_map_single(gmacdev,(void*)data1,RX_BUF_SIZE);
  489. len = synopGMAC_get_rx_desc_frame_length(status); //Not interested in Ethernet CRC bytes
  490. rt_memcpy( pbuf->payload, (char *)data1, len);
  491. DEBUG_MES("==get pkg len: %d\n",len);
  492. }
  493. else
  494. {
  495. rt_kprintf("s: %08x\n",status);
  496. adapter->synopGMACNetStats.rx_errors++;
  497. adapter->synopGMACNetStats.collisions += synopGMAC_is_rx_frame_collision(status);
  498. adapter->synopGMACNetStats.rx_crc_errors += synopGMAC_is_rx_crc(status);
  499. adapter->synopGMACNetStats.rx_frame_errors += synopGMAC_is_frame_dribbling_errors(status);
  500. adapter->synopGMACNetStats.rx_length_errors += synopGMAC_is_rx_frame_length_errors(status);
  501. }
  502. desc_index = synopGMAC_set_rx_qptr(gmacdev,dma_addr1, RX_BUF_SIZE, (u32)data1,0,0,0);
  503. if(desc_index < 0){
  504. #if SYNOP_RX_DEBUG
  505. rt_kprintf("Cannot set Rx Descriptor for data1 %08x\n",(u32)data1);
  506. #endif
  507. plat_free_memory((void *)data1);
  508. }
  509. }
  510. // }while(desc_index >= 0);
  511. rt_sem_release(&sem_lock);
  512. DEBUG_MES("%s : before return \n", __FUNCTION__);
  513. return pbuf;
  514. }
  515. static int rtl88e1111_config_init(synopGMACdevice *gmacdev)
  516. {
  517. int retval, err;
  518. u16 data;
  519. DEBUG_MES("in %s\n", __FUNCTION__);
  520. synopGMAC_read_phy_reg(gmacdev->MacBase,gmacdev->PhyBase,0x14,&data);
  521. data = data | 0x82;
  522. err = synopGMAC_write_phy_reg(gmacdev->MacBase,gmacdev->PhyBase,0x14,data);
  523. synopGMAC_read_phy_reg(gmacdev->MacBase,gmacdev->PhyBase,0x00,&data);
  524. data = data | 0x8000;
  525. err = synopGMAC_write_phy_reg(gmacdev->MacBase,gmacdev->PhyBase,0x00,data);
  526. #if SYNOP_PHY_LOOPBACK
  527. synopGMAC_read_phy_reg(gmacdev->MacBase,gmacdev->PhyBase,0x14,&data);
  528. data = data | 0x70;
  529. data = data & 0xffdf;
  530. err = synopGMAC_write_phy_reg(gmacdev->MacBase,gmacdev->PhyBase,0x14,data);
  531. data = 0x8000;
  532. err = synopGMAC_write_phy_reg(gmacdev->MacBase,gmacdev->PhyBase,0x00,data);
  533. data = 0x5140;
  534. err = synopGMAC_write_phy_reg(gmacdev->MacBase,gmacdev->PhyBase,0x00,data);
  535. #endif
  536. if (err < 0)
  537. return err;
  538. return 0;
  539. }
  540. int init_phy(synopGMACdevice *gmacdev)
  541. {
  542. u16 data;
  543. synopGMAC_read_phy_reg(gmacdev->MacBase,gmacdev->PhyBase,2,&data);
  544. /*set 88e1111 clock phase delay*/
  545. if(data == 0x141)
  546. rtl88e1111_config_init(gmacdev);
  547. #if defined (RMII)
  548. else if(data == 0x8201)
  549. {
  550. //RTL8201
  551. data = 0x400; // set RMII mode
  552. synopGMAC_write_phy_reg(gmacdev->MacBase,gmacdev->PhyBase,0x19,data);
  553. synopGMAC_read_phy_reg(gmacdev->MacBase,gmacdev->PhyBase,0x19,&data);
  554. TR("phy reg25 is %0x \n",data);
  555. data = 0x3100; //set 100M speed
  556. synopGMAC_write_phy_reg(gmacdev->MacBase,gmacdev->PhyBase,0x0,data);
  557. }
  558. else if(data == 0x0180 || data == 0x0181)
  559. {
  560. //DM9161
  561. synopGMAC_read_phy_reg(gmacdev->MacBase,gmacdev->PhyBase,0x10,&data);
  562. data |= (1 << 8); //set RMII mode
  563. synopGMAC_write_phy_reg(gmacdev->MacBase,gmacdev->PhyBase,0x10,data); //set RMII mode
  564. synopGMAC_read_phy_reg(gmacdev->MacBase,gmacdev->PhyBase,0x10,&data);
  565. TR("phy reg16 is 0x%0x \n",data);
  566. // synopGMAC_read_phy_reg(gmacdev->MacBase,gmacdev->PhyBase,0x0,&data);
  567. // data &= ~(1<<10);
  568. data = 0x3100; //set auto-
  569. //data = 0x0100; //set 10M speed
  570. synopGMAC_write_phy_reg(gmacdev->MacBase,gmacdev->PhyBase,0x0,data);
  571. }
  572. #endif
  573. return 0;
  574. }
  575. u32 synopGMAC_wakeup_filter_config3[] = {
  576. 0x00000000,
  577. 0x000000FF,
  578. 0x00000000,
  579. 0x00000000,
  580. 0x00000100,
  581. 0x00003200,
  582. 0x7eED0000,
  583. 0x00000000
  584. };
  585. static void synopGMAC_linux_powerdown_mac(synopGMACdevice *gmacdev)
  586. {
  587. rt_kprintf("Put the GMAC to power down mode..\n");
  588. GMAC_Power_down = 1;
  589. synopGMAC_disable_dma_tx(gmacdev);
  590. plat_delay(10000);
  591. synopGMAC_tx_disable(gmacdev);
  592. synopGMAC_rx_disable(gmacdev);
  593. plat_delay(10000);
  594. synopGMAC_disable_dma_rx(gmacdev);
  595. synopGMAC_magic_packet_enable(gmacdev);
  596. synopGMAC_write_wakeup_frame_register(gmacdev, synopGMAC_wakeup_filter_config3);
  597. synopGMAC_wakeup_frame_enable(gmacdev);
  598. synopGMAC_rx_enable(gmacdev);
  599. synopGMAC_pmt_int_enable(gmacdev);
  600. synopGMAC_power_down_enable(gmacdev);
  601. return;
  602. }
  603. static void synopGMAC_linux_powerup_mac(synopGMACdevice *gmacdev)
  604. {
  605. GMAC_Power_down = 0;
  606. if( synopGMAC_is_magic_packet_received(gmacdev))
  607. rt_kprintf("GMAC wokeup due to Magic Pkt Received\n");
  608. if(synopGMAC_is_wakeup_frame_received(gmacdev))
  609. rt_kprintf("GMAC wokeup due to Wakeup Frame Received\n");
  610. synopGMAC_pmt_int_disable(gmacdev);
  611. synopGMAC_rx_enable(gmacdev);
  612. synopGMAC_enable_dma_rx(gmacdev);
  613. synopGMAC_tx_enable(gmacdev);
  614. synopGMAC_enable_dma_tx(gmacdev);
  615. return;
  616. }
  617. static int mdio_read(synopGMACPciNetworkAdapter *adapter, int addr, int reg)
  618. {
  619. synopGMACdevice * gmacdev;
  620. u16 data;
  621. gmacdev = adapter->synopGMACdev;
  622. synopGMAC_read_phy_reg(gmacdev->MacBase,addr,reg, &data);
  623. return data;
  624. }
  625. static void mdio_write(synopGMACPciNetworkAdapter *adapter, int addr, int reg, int data)
  626. {
  627. synopGMACdevice * gmacdev;
  628. gmacdev = adapter->synopGMACdev;
  629. synopGMAC_write_phy_reg(gmacdev->MacBase,addr,reg,data);
  630. }
  631. void eth_rx_irq(int irqno,void *param)
  632. {
  633. struct rt_eth_dev *dev = &eth_dev;
  634. struct synopGMACNetworkAdapter *adapter = dev->priv;
  635. //DEBUG_MES("in irq!!\n");
  636. #ifdef RT_USING_GMAC_INT_MODE
  637. int i ;
  638. for(i = 0; i < 7200; i++)
  639. ;
  640. #endif /*RT_USING_GMAC_INT_MODE*/
  641. synopGMACdevice * gmacdev = (synopGMACdevice *)adapter->synopGMACdev;
  642. u32 interrupt,dma_status_reg;
  643. s32 status;
  644. u32 dma_addr;
  645. //rt_kprintf("irq i = %d\n", i++);
  646. dma_status_reg = synopGMACReadReg(gmacdev->DmaBase, DmaStatus);
  647. if(dma_status_reg == 0)
  648. {
  649. rt_kprintf("dma_status ==0 \n");
  650. return;
  651. }
  652. //rt_kprintf("dma_status_reg is 0x%x\n", dma_status_reg);
  653. u32 gmacstatus;
  654. synopGMAC_disable_interrupt_all(gmacdev);
  655. gmacstatus = synopGMACReadReg(gmacdev->MacBase,GmacStatus);
  656. if(dma_status_reg & GmacPmtIntr){
  657. rt_kprintf("%s:: Interrupt due to PMT module\n",__FUNCTION__);
  658. //synopGMAC_linux_powerup_mac(gmacdev);
  659. }
  660. if(dma_status_reg & GmacMmcIntr){
  661. rt_kprintf("%s:: Interrupt due to MMC module\n",__FUNCTION__);
  662. DEBUG_MES("%s:: synopGMAC_rx_int_status = %08x\n",__FUNCTION__,synopGMAC_read_mmc_rx_int_status(gmacdev));
  663. DEBUG_MES("%s:: synopGMAC_tx_int_status = %08x\n",__FUNCTION__,synopGMAC_read_mmc_tx_int_status(gmacdev));
  664. }
  665. if(dma_status_reg & GmacLineIntfIntr){
  666. rt_kprintf("%s:: Interrupt due to GMAC LINE module\n",__FUNCTION__);
  667. }
  668. interrupt = synopGMAC_get_interrupt_type(gmacdev);
  669. //rt_kprintf("%s:Interrupts to be handled: 0x%08x\n",__FUNCTION__,interrupt);
  670. if(interrupt & synopGMACDmaError){
  671. u8 mac_addr0[6];
  672. rt_kprintf("%s::Fatal Bus Error Inetrrupt Seen\n",__FUNCTION__);
  673. memcpy(mac_addr0,dev->dev_addr,6);
  674. synopGMAC_disable_dma_tx(gmacdev);
  675. synopGMAC_disable_dma_rx(gmacdev);
  676. synopGMAC_take_desc_ownership_tx(gmacdev);
  677. synopGMAC_take_desc_ownership_rx(gmacdev);
  678. synopGMAC_init_tx_rx_desc_queue(gmacdev);
  679. synopGMAC_reset(gmacdev);
  680. synopGMAC_set_mac_addr(gmacdev,GmacAddr0High,GmacAddr0Low, mac_addr0);
  681. synopGMAC_dma_bus_mode_init(gmacdev,DmaFixedBurstEnable| DmaBurstLength8 | DmaDescriptorSkip2 );
  682. synopGMAC_dma_control_init(gmacdev,DmaStoreAndForward);
  683. synopGMAC_init_rx_desc_base(gmacdev);
  684. synopGMAC_init_tx_desc_base(gmacdev);
  685. synopGMAC_mac_init(gmacdev);
  686. synopGMAC_enable_dma_rx(gmacdev);
  687. synopGMAC_enable_dma_tx(gmacdev);
  688. }
  689. if(interrupt & synopGMACDmaRxNormal){
  690. //DEBUG_MES("%s:: Rx Normal \n", __FUNCTION__);
  691. //synop_handle_received_data(netdev);
  692. eth_device_ready(&eth_dev.parent);
  693. }
  694. if(interrupt & synopGMACDmaRxAbnormal){
  695. //rt_kprintf("%s::Abnormal Rx Interrupt Seen\n",__FUNCTION__);
  696. if(GMAC_Power_down == 0){
  697. adapter->synopGMACNetStats.rx_over_errors++;
  698. synopGMACWriteReg(gmacdev->DmaBase, DmaStatus ,0x80);
  699. synopGMAC_resume_dma_rx(gmacdev);
  700. }
  701. }
  702. if(interrupt & synopGMACDmaRxStopped){
  703. rt_kprintf("%s::Receiver stopped seeing Rx interrupts\n",__FUNCTION__); //Receiver gone in to stopped state
  704. }
  705. if(interrupt & synopGMACDmaTxNormal){
  706. DEBUG_MES("%s::Finished Normal Transmission \n",__FUNCTION__);
  707. // synop_handle_transmit_over(netdev);
  708. }
  709. if(interrupt & synopGMACDmaTxAbnormal){
  710. rt_kprintf("%s::Abnormal Tx Interrupt Seen\n",__FUNCTION__);
  711. }
  712. if(interrupt & synopGMACDmaTxStopped){
  713. TR("%s::Transmitter stopped sending the packets\n",__FUNCTION__);
  714. if(GMAC_Power_down == 0){ // If Mac is not in powerdown
  715. synopGMAC_disable_dma_tx(gmacdev);
  716. synopGMAC_take_desc_ownership_tx(gmacdev);
  717. synopGMAC_enable_dma_tx(gmacdev);
  718. // netif_wake_queue(netdev);
  719. TR("%s::Transmission Resumed\n",__FUNCTION__);
  720. }
  721. }
  722. /* Enable the interrrupt before returning from ISR*/
  723. synopGMAC_enable_interrupt(gmacdev,DmaIntEnable);
  724. return;
  725. }
  726. void rt_hw_eth_init(void)
  727. {
  728. u64 base_addr = Gmac_base;
  729. struct synopGMACNetworkAdapter * synopGMACadapter;
  730. static u8 mac_addr0[6] = DEFAULT_MAC_ADDRESS;
  731. rt_sem_init(&sem_ack, "tx_ack", 1, RT_IPC_FLAG_FIFO);
  732. rt_sem_init(&sem_lock, "eth_lock", 1, RT_IPC_FLAG_FIFO);
  733. memset(&eth_dev, 0, sizeof(eth_dev));
  734. synopGMACadapter = (struct synopGMACNetworkAdapter * )plat_alloc_memory(sizeof (struct synopGMACNetworkAdapter));
  735. if(!synopGMACadapter){
  736. rt_kprintf("Error in Memory Allocataion, Founction : %s \n", __FUNCTION__);
  737. }
  738. memset((char *)synopGMACadapter ,0, sizeof (struct synopGMACNetworkAdapter));
  739. synopGMACadapter->synopGMACdev = NULL;
  740. synopGMACadapter->synopGMACdev = (synopGMACdevice *) plat_alloc_memory(sizeof (synopGMACdevice));
  741. if(!synopGMACadapter->synopGMACdev){
  742. rt_kprintf("Error in Memory Allocataion, Founction : %s \n", __FUNCTION__);
  743. }
  744. memset((char *)synopGMACadapter->synopGMACdev ,0, sizeof (synopGMACdevice));
  745. /*
  746. * Attach the device to MAC struct This will configure all the required base addresses
  747. * such as Mac base, configuration base, phy base address(out of 32 possible phys)
  748. * */
  749. synopGMAC_attach(synopGMACadapter->synopGMACdev,(regbase + MACBASE), regbase + DMABASE, DEFAULT_PHY_BASE, mac_addr0);
  750. init_phy(synopGMACadapter->synopGMACdev);
  751. synopGMAC_reset(synopGMACadapter->synopGMACdev);
  752. /* MII setup */
  753. synopGMACadapter->mii.phy_id_mask = 0x1F;
  754. synopGMACadapter->mii.reg_num_mask = 0x1F;
  755. synopGMACadapter->mii.dev = synopGMACadapter;
  756. synopGMACadapter->mii.mdio_read = mdio_read;
  757. synopGMACadapter->mii.mdio_write = mdio_write;
  758. synopGMACadapter->mii.phy_id = synopGMACadapter->synopGMACdev->PhyBase;
  759. synopGMACadapter->mii.supports_gmii = mii_check_gmii_support(&synopGMACadapter->mii);
  760. eth_dev.iobase = base_addr;
  761. eth_dev.name = "e0";
  762. eth_dev.priv = synopGMACadapter;
  763. eth_dev.dev_addr[0] = mac_addr0[0];
  764. eth_dev.dev_addr[1] = mac_addr0[1];
  765. eth_dev.dev_addr[2] = mac_addr0[2];
  766. eth_dev.dev_addr[3] = mac_addr0[3];
  767. eth_dev.dev_addr[4] = mac_addr0[4];
  768. eth_dev.dev_addr[5] = mac_addr0[5];
  769. eth_dev.parent.parent.type = RT_Device_Class_NetIf;
  770. eth_dev.parent.parent.init = eth_init;
  771. eth_dev.parent.parent.open = eth_open;
  772. eth_dev.parent.parent.close = eth_close;
  773. eth_dev.parent.parent.read = eth_read;
  774. eth_dev.parent.parent.write = eth_write;
  775. eth_dev.parent.parent.control = eth_control;
  776. eth_dev.parent.parent.user_data = RT_NULL;
  777. eth_dev.parent.eth_tx = rt_eth_tx;
  778. eth_dev.parent.eth_rx = rt_eth_rx;
  779. eth_device_init(&(eth_dev.parent), "e0");
  780. }