ethernet_enc28j60.c 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259
  1. /*
  2. * Copyright (C) 2016 YunOS Project. All rights reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include <stdint.h>
  17. #include <string.h>
  18. #include <assert.h>
  19. #include <stdio.h>
  20. #include <unistd.h>
  21. #include <fcntl.h>
  22. #include <sys/types.h>
  23. #include <sys/stat.h>
  24. #include <syslog.h>
  25. #ifndef CONFIG_KERNEL_NONE
  26. #include <csi_kernel.h>
  27. #endif
  28. #include "ethernet_enc28j60.h"
  29. #include "pin.h"
  30. #include "soc.h"
  31. #include "drv_spi.h"
  32. #include "drv_gpio.h"
  33. #include "drv_eth.h"
  34. #include "drv_eth_phy.h"
  35. #include "drv_eth_mac.h"
  36. #include <errno.h>
  37. #define NET_HWADDR_LEN 6
  38. #define THIS_MODULE MODULE_DEV_ETH
  39. #define MAX_SPI_TRANSFER_LEN 512
  40. #define MAX_RECV_ERROR_CNT 50
  41. static uint8_t Enc28j60Bank;
  42. static uint16_t NextPacketPtr;
  43. gpio_pin_handle_t pin_int = NULL;
  44. typedef int (*gpio_interrupt_t)(int irqno);
  45. static spi_handle_t g_net_spi_hd = NULL;
  46. static gpio_pin_handle_t pgpio_pin_handle1;
  47. //static k_sem_handle_t g_sem_spi_tx_hd = NULL;
  48. //static k_sem_handle_t g_sem_spi_rx_hd = NULL;
  49. static eth_mac_priv_t s_eth_instance[CONFIG_ETH_NUM];
  50. static eth_phy_priv_t s_phy_instance[CONFIG_ETH_NUM];
  51. static uint8_t g_hw_addr[NET_HWADDR_LEN] = {0};
  52. static uint8_t enc28j60ReadOp(uint8_t op, uint8_t address);
  53. static void enc28j60WriteOp(uint8_t op, uint8_t address, uint8_t data);
  54. static void enc28j60ReadBuffer(const uint16_t len, uint8_t *data);
  55. static void enc28j60WriteBuffer(uint16_t len, uint8_t *data);
  56. static void enc28j60SetBank(uint8_t address);
  57. static uint8_t enc28j60Read(uint8_t address);
  58. static void enc28j60Write(uint8_t address, uint8_t data);
  59. static uint32_t enc28j60PhyWrite(uint8_t phy_addr, uint8_t reg_addr, uint16_t data);
  60. static uint32_t enc28j60Phyregread(uint8_t phy_addr, uint8_t reg_addr, uint16_t *data);
  61. static void enc28j60Init(const uint8_t *macaddr);
  62. static int enc28j60Reset(int obj);
  63. static uint16_t enc28j60GetRxFreeSpace(void);
  64. static void enc28j60_int_handle(uint32_t event);
  65. static int enc28j60_set_interrupt(pin_t gpio_pin);
  66. extern void mdelay(uint32_t ms);
  67. /**
  68. * interrupt handle function to post sem for handle
  69. *
  70. * @param irqno the irq number of network
  71. *
  72. */
  73. static void enc28j60_int_handle(uint32_t event)
  74. {
  75. eth_mac_priv_t *eth_priv = &s_eth_instance[0];
  76. uint8_t int_stat, ptkcnt, estat;
  77. uint16_t freespace;
  78. uint16_t status_vec_ptr;
  79. uint8_t status_vec[7];
  80. bool reset = 0;
  81. csi_gpio_pin_irq_set(pin_int, GPIO_IRQ_MODE_LOW_LEVEL, 0);
  82. //enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, EIE, EIE_INTIE);
  83. int_stat = enc28j60Read(EIR); /* read EIR register data */;
  84. // error flags to be handled first
  85. if (int_stat & EIR_RXERIF) {
  86. ptkcnt = enc28j60Read(EPKTCNT);
  87. freespace = enc28j60GetRxFreeSpace();
  88. #ifndef CONFIG_TEST_TTCP
  89. if ((ptkcnt == 0xFF) || (freespace < MAX_FRAMELEN)) {
  90. /* do nothing, data in buffer will be read out */
  91. printf("Rx buffer has %d packets and %d bytes free space\n", ptkcnt, freespace);
  92. } else {
  93. printf("something is wrong other than no buffer.\n");
  94. }
  95. #endif
  96. enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, EIR, EIR_RXERIF);
  97. if (ptkcnt > MAX_RECV_ERROR_CNT) {
  98. reset = 1;
  99. }
  100. }
  101. if (int_stat & EIR_TXERIF) {
  102. estat = enc28j60Read(ESTAT);
  103. if ((estat & ESTAT_TXABRT) || (estat & ESTAT_LATECOL)) {
  104. printf("ESTAT=0x%x\n", estat);
  105. status_vec_ptr = enc28j60Read(ETXNDL);
  106. status_vec_ptr |= enc28j60Read(ETXNDH) << 8;
  107. status_vec_ptr++;
  108. enc28j60Write(ERDPTL, status_vec_ptr);
  109. enc28j60Write(ERDPTH, status_vec_ptr >> 8);
  110. enc28j60ReadBuffer(7, status_vec);
  111. printf("status vector:0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x\n",
  112. status_vec[0], status_vec[1], status_vec[2], status_vec[3], status_vec[4], status_vec[5], status_vec[6]);
  113. reset = 1;
  114. }
  115. enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, EIR, EIR_TXERIF);
  116. }
  117. if (reset) {
  118. if (enc28j60Reset(RST_ENC28J60_ALL) == 0) {
  119. printf("reset OK \n");
  120. /* init enc28j60 module */
  121. uint8_t macaddr[6];
  122. csi_eth_mac_get_macaddr(NULL, (eth_mac_addr_t *)macaddr);
  123. enc28j60Init(macaddr);
  124. printf("enc28j60 init OK \n");
  125. enc28j60_set_interrupt(PA5_A8);
  126. enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE);
  127. return;
  128. }
  129. }
  130. if (int_stat & EIR_PKTIF) {
  131. ptkcnt = enc28j60Read(EPKTCNT); //just for debugging
  132. //EIR_PKTIF will be cleared if all data is read out
  133. eth_priv->cb_event((eth_mac_handle_t)eth_priv, CSI_ETH_MAC_EVENT_RX_FRAME);
  134. }
  135. if (int_stat & EIR_TXIF) {
  136. enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, EIR, EIR_TXIF);
  137. //eth_priv->cb_event((eth_mac_handle_t)eth_priv, CSI_ETH_MAC_EVENT_TX_FRAME);
  138. }
  139. if (int_stat & EIR_LINKIF) {
  140. enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, EIR, EIR_LINKIF);
  141. eth_priv->cb_event((eth_mac_handle_t)eth_priv, CSI_ETH_MAC_EVENT_LINK_CHANGE);
  142. }
  143. //clear all interrupt falgs. In fact, EIR_PKTIF can not be cleared
  144. enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, EIR, 0xFF & (~(EIR_PKTIF | EIR_LINKIF)));
  145. // don't enable interrupt if events not handled
  146. if (!(int_stat & (EIR_PKTIF | EIR_LINKIF))) {
  147. //enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE);
  148. csi_gpio_pin_irq_set(pin_int, GPIO_IRQ_MODE_LOW_LEVEL, 1);
  149. }
  150. }
  151. void enc28j60_spi_transfer_callback(spi_event_e event)
  152. {
  153. if (event == SPI_EVENT_TRANSFER_COMPLETE) {
  154. } else if (event == SPI_EVENT_TX_COMPLETE) {
  155. //csi_kernel_sem_post(g_sem_spi_tx_hd);
  156. } else if (event == SPI_EVENT_RX_COMPLETE) {
  157. //csi_kernel_sem_post(g_sem_spi_rx_hd);
  158. } else if (event == SPI_EVENT_DATA_LOST) {
  159. printf("TRANSFER_DATA_LOST\n");
  160. } else {
  161. printf("TRANSFER_MODE_FAULT\n");
  162. }
  163. }
  164. void enc28j60_spi_cs_status_change(int status)
  165. {
  166. csi_gpio_pin_write(pgpio_pin_handle1, status);
  167. }
  168. static int32_t enc28j60_spi_send(spi_handle_t handle, const void *data, uint32_t num)
  169. {
  170. csi_spi_send(handle, data, num, 1);
  171. // csi_kernel_sem_wait(g_sem_spi_tx_hd, -1);
  172. return 0;
  173. }
  174. static int32_t enc28j60_spi_receive(spi_handle_t handle, void *data, uint32_t num)
  175. {
  176. csi_spi_receive(handle, data, num, 1);
  177. //csi_kernel_sem_wait(g_sem_spi_rx_hd, -1);
  178. return 0;
  179. }
  180. /**
  181. * read ctrl register
  182. * @param op operation cmd
  183. * @param register address
  184. *
  185. * @return
  186. * -register data
  187. */
  188. static uint8_t enc28j60ReadOp(uint8_t op, uint8_t address)
  189. {
  190. uint8_t dat = 0;
  191. ENC28J60_CSL();
  192. dat = (op | (address & ADDR_MASK));
  193. uint8_t rdata[1] = {0};
  194. enc28j60_spi_send(g_net_spi_hd, &dat, 1);
  195. enc28j60_spi_receive(g_net_spi_hd, &rdata[0], 1);
  196. /* do dummy read if needed (for mac and mii, see datasheet page 29) */
  197. if (address & 0x80) {
  198. enc28j60_spi_receive(g_net_spi_hd, &rdata[0], 1);
  199. }
  200. /* release CS */
  201. ENC28J60_CSH();
  202. return rdata[0];
  203. }
  204. /**
  205. * write ctrl cmd to register
  206. * @param op operation cmd
  207. * @param register address
  208. * @param data the data to be set
  209. *
  210. * @return
  211. * -NULL
  212. */
  213. static void enc28j60WriteOp(uint8_t op, uint8_t address, uint8_t data)
  214. {
  215. char dat = 0;
  216. ENC28J60_CSL();
  217. /* issue write command */
  218. dat = op | (address & ADDR_MASK);
  219. enc28j60_spi_send(g_net_spi_hd, &dat, 1);
  220. dat = data;
  221. enc28j60_spi_send(g_net_spi_hd, &dat, 1);
  222. ENC28J60_CSH();
  223. }
  224. /**
  225. * read buffer data
  226. * @param len the data length waint to read
  227. * @param data the data buffer
  228. *
  229. * @return
  230. * -NULL
  231. */
  232. static void enc28j60ReadBuffer(uint16_t len, uint8_t *data)
  233. {
  234. char ops_ctr = ENC28J60_READ_BUF_MEM;
  235. ENC28J60_CSL();
  236. /* issue read command */
  237. enc28j60_spi_send(g_net_spi_hd, &ops_ctr, 1);
  238. enc28j60_spi_receive(g_net_spi_hd, (char *)&data[0], len);
  239. ENC28J60_CSH();
  240. }
  241. /**
  242. * write data to buffer
  243. * @param len the data length waint to write
  244. * @param data the data buffer pointer
  245. *
  246. * @return
  247. * -NULL
  248. */
  249. static void enc28j60WriteBuffer(uint16_t len, uint8_t *data)
  250. {
  251. char ops_ctr = ENC28J60_WRITE_BUF_MEM;
  252. ENC28J60_CSL();
  253. /* issue write command */
  254. //drv_porting_spi_write(NULL, &ops_ctr, 1);
  255. enc28j60_spi_send(g_net_spi_hd, &ops_ctr, 1);
  256. enc28j60_spi_send(g_net_spi_hd, &data[0], len);
  257. ENC28J60_CSH();
  258. }
  259. /**
  260. * select the bank to operation
  261. * @param address the bank address
  262. *
  263. * @return
  264. * -NULL
  265. */
  266. static void enc28j60SetBank(uint8_t address)
  267. {
  268. /* set the bank (if needed) */
  269. if ((address & BANK_MASK) != Enc28j60Bank) {
  270. /* set the bank */
  271. enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, (ECON1_BSEL1 | ECON1_BSEL0));
  272. enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, (address & BANK_MASK) >> 5);
  273. Enc28j60Bank = (address & BANK_MASK);
  274. }
  275. }
  276. /**
  277. * read ctrl register data
  278. * @param address the ctrl register address
  279. *
  280. * @return
  281. * -ctrl register data
  282. */
  283. static uint8_t enc28j60Read(uint8_t address)
  284. {
  285. /* set the bank */
  286. enc28j60SetBank(address);
  287. /* do the read */
  288. return enc28j60ReadOp(ENC28J60_READ_CTRL_REG, address);
  289. }
  290. /**
  291. * write data to ctrl register
  292. * @param address the ctrl register address
  293. * @param data ctrl register cmd
  294. *
  295. * @return
  296. * - NULL
  297. */
  298. static void enc28j60Write(uint8_t address, uint8_t data)
  299. {
  300. /* set the bank */
  301. enc28j60SetBank(address);
  302. /* do the write */
  303. enc28j60WriteOp(ENC28J60_WRITE_CTRL_REG, address, data);
  304. }
  305. /**
  306. * write data to phy register
  307. * @param address the phy register address
  308. * @param data phy register cmd
  309. *
  310. * @return
  311. * - NULL
  312. */
  313. static uint32_t enc28j60PhyWrite(uint8_t phy_addr, uint8_t reg_addr, uint16_t data)
  314. {
  315. int retry = 0;
  316. /* set the PHY register address */
  317. enc28j60Write(MIREGADR, phy_addr);
  318. /* write the PHY data */
  319. enc28j60Write(MIWRL, data);
  320. enc28j60Write(MIWRH, data >> 8);
  321. /* wait until the PHY write completes */
  322. while (enc28j60Read(MISTAT) & MISTAT_BUSY) {
  323. retry++;
  324. if (retry > 0xFFF) {
  325. printf("write Phyreg_status error \n");
  326. return -1;
  327. }
  328. }
  329. return 0;
  330. }
  331. /**
  332. * read data from phy register
  333. * @param address the phy register address
  334. *
  335. * @return
  336. * -the data of phy register
  337. */
  338. static uint32_t enc28j60Phyregread(uint8_t phy_addr, uint8_t reg_addr, uint16_t *data)
  339. {
  340. uint8_t temp;
  341. int retry = 0;
  342. temp = enc28j60Read(MICMD);
  343. /* set the PHY register address */
  344. enc28j60Write(MIREGADR, phy_addr);
  345. enc28j60Write(MICMD, temp | MICMD_MIIRD);
  346. /* Loop to wait until the PHY register has been read through the MII */
  347. while ((enc28j60Read(MISTAT) & MISTAT_BUSY)) {
  348. if (retry++ > 0xFFF) {
  349. printf("read Phyreg_status error \n");
  350. return -1;
  351. }
  352. }
  353. enc28j60Write(MICMD, temp & (~MICMD_MIIRD)); /* clear bit MICMD.MIIRD */
  354. /* Obtain results and return */
  355. *data = enc28j60Read(MIRDL);
  356. *data |= (enc28j60Read(MIRDH) << 8);
  357. return *data;
  358. }
  359. /**
  360. * init ethernet ctrl register
  361. * @param address the MAC address
  362. *
  363. * @return
  364. * - NULL
  365. */
  366. static void enc28j60Init(const uint8_t *macaddr)
  367. {
  368. /* check CLKRDY bit to see if reset is complete */
  369. /* The CLKRDY does not work. See Rev. B4 Silicon Errata point. Just wait. */
  370. NextPacketPtr = RXSTART_INIT;
  371. /* Rx start */
  372. enc28j60Write(ERXSTL, RXSTART_INIT & 0xFF);
  373. enc28j60Write(ERXSTH, RXSTART_INIT >> 8);
  374. /* set receive pointer address */
  375. enc28j60Write(ERXRDPTL, RXSTART_INIT & 0xFF);
  376. enc28j60Write(ERXRDPTH, RXSTART_INIT >> 8);
  377. /* RX end */
  378. enc28j60Write(ERXNDL, RXSTOP_INIT & 0xFF);
  379. enc28j60Write(ERXNDH, RXSTOP_INIT >> 8);
  380. /* TX start */
  381. enc28j60Write(ETXSTL, TXSTART_INIT & 0xFF);
  382. enc28j60Write(ETXSTH, TXSTART_INIT >> 8);
  383. /* TX end */
  384. enc28j60Write(ETXNDL, TXSTOP_INIT & 0xFF);
  385. enc28j60Write(ETXNDH, TXSTOP_INIT >> 8);
  386. /* do bank 1 stuff, packet filter:
  387. For broadcast packets we allow only ARP packtets
  388. All other packets should be unicast only for our mac (MAADR) */
  389. #if LWIP_IPV4 && LWIP_IPV6
  390. enc28j60Write(ERXFCON, ERXFCON_UCEN | ERXFCON_CRCEN | ERXFCON_PMEN | ERXFCON_MCEN);
  391. enc28j60Write(EPMM0, 0x3f); /* ARP Pattern Match Filter */
  392. enc28j60Write(EPMM1, 0x30);
  393. enc28j60Write(EPMCSL, 0xf9);
  394. enc28j60Write(EPMCSH, 0xf7);
  395. #elif LWIP_IPV6
  396. enc28j60Write(ERXFCON, ERXFCON_UCEN | ERXFCON_CRCEN | ERXFCON_MCEN);
  397. #else /* for IPv6 without ARP and BC */
  398. enc28j60Write(ERXFCON, ERXFCON_UCEN | ERXFCON_CRCEN | ERXFCON_PMEN);
  399. enc28j60Write(EPMM0, 0x3f); /* ARP Pattern Match Filter */
  400. enc28j60Write(EPMM1, 0x30);
  401. enc28j60Write(EPMCSL, 0xf9);
  402. enc28j60Write(EPMCSH, 0xf7);
  403. #endif
  404. /* do bank 2 stuff */
  405. /* enable MAC receive */
  406. enc28j60Write(MACON1, MACON1_MARXEN | MACON1_TXPAUS | MACON1_RXPAUS);
  407. /* bring MAC out of reset */
  408. enc28j60Write(MACON2, 0x00);
  409. /* enable automatic padding to 60bytes and CRC operations */
  410. enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, MACON3, MACON3_PADCFG0 | MACON3_TXCRCEN | MACON3_FRMLNEN | MACON3_FULDPX); /* MACON3_HFRMLEN */
  411. /* set inter-frame gap (non-back-to-back) */
  412. enc28j60Write(MAIPGL, 0x12);
  413. enc28j60Write(MAIPGH, 0x0C);
  414. /* set inter-frame gap (back-to-back) */
  415. enc28j60Write(MABBIPG, 0x15);
  416. /* Set the maximum packet size which the controller will accept */
  417. /* Do not send packets longer than MAX_FRAMELEN: */
  418. enc28j60Write(MAMXFLL, MAX_FRAMELEN & 0xFF);
  419. enc28j60Write(MAMXFLH, MAX_FRAMELEN >> 8);
  420. /* do bank 3 stuff */
  421. /* write MAC address */
  422. /* NOTE: MAC address in ENC28J60 is byte-backward */
  423. enc28j60Write(MAADR5, macaddr[0]);
  424. enc28j60Write(MAADR4, macaddr[1]);
  425. enc28j60Write(MAADR3, macaddr[2]);
  426. enc28j60Write(MAADR2, macaddr[3]);
  427. enc28j60Write(MAADR1, macaddr[4]);
  428. enc28j60Write(MAADR0, macaddr[5]);
  429. enc28j60PhyWrite(PHCON1, 0, PHCON1_PDPXMD);
  430. /* no loopback of transmitted frames */
  431. enc28j60PhyWrite(PHCON2, 0, PHCON2_HDLDIS);
  432. enc28j60PhyWrite(PHIE, 0, PHIE_PLNKIE | PHIE_PGEIE);
  433. /* switch to bank 0 */
  434. enc28j60SetBank(ECON1);
  435. /* enable interrutps */
  436. enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_PKTIE | EIE_LINKIE | EIE_TXIE | EIE_TXERIE | EIE_RXERIE);
  437. /* enable packet reception */
  438. enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN);
  439. enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE);
  440. }
  441. /**
  442. * set mac addr
  443. * @param macaddr the macaddr for net
  444. *
  445. * @return
  446. * - NULL
  447. */
  448. static void enc28j60Setmacaddr(const uint8_t *macaddr)
  449. {
  450. ENC28J60_CSH();
  451. /* enable MAC receive */
  452. enc28j60Write(MACON1, MACON1_MARXEN | MACON1_TXPAUS | MACON1_RXPAUS);
  453. /* bring MAC out of reset */
  454. enc28j60Write(MACON2, 0x00);
  455. /* enable automatic padding to 60bytes and CRC operations */
  456. enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, MACON3, MACON3_PADCFG0 | MACON3_TXCRCEN | MACON3_FULDPX);
  457. /* write MAC address */
  458. /* NOTE: MAC address in ENC28J60 is byte-backward */
  459. enc28j60Write(MAADR5, macaddr[0]);
  460. enc28j60Write(MAADR4, macaddr[1]);
  461. enc28j60Write(MAADR3, macaddr[2]);
  462. enc28j60Write(MAADR2, macaddr[3]);
  463. enc28j60Write(MAADR1, macaddr[4]);
  464. enc28j60Write(MAADR0, macaddr[5]);
  465. }
  466. /**
  467. * Hard reset enc28j60
  468. * @param void
  469. *
  470. */
  471. static void enc28j60hardreset(void)
  472. {
  473. gpio_pin_handle_t pin = NULL;
  474. pin = csi_gpio_pin_initialize(PA1);
  475. csi_gpio_pin_config(pin, GPIO_MODE_PULLNONE, GPIO_DIRECTION_OUTPUT);
  476. csi_gpio_pin_write(pin, 0); /* LOW */
  477. mdelay(3);
  478. csi_gpio_pin_write(pin, 1);
  479. mdelay(3);
  480. printf("NET HARD RESET\n");
  481. }
  482. /**
  483. * reset enc28j60
  484. * @param obj the net work object
  485. *
  486. * @return
  487. * - status
  488. */
  489. static int enc28j60Reset(int obj)
  490. {
  491. int retry = 0;
  492. ENC28J60_CSH();
  493. if (obj == RST_ENC28J60_ALL) {
  494. /* first net hard reset */
  495. enc28j60hardreset();
  496. enc28j60WriteOp(ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET);
  497. while (!(enc28j60Read(ESTAT) & ESTAT_CLKRDY)) {
  498. if (retry++ > 0xFFF) {
  499. return -1;
  500. }
  501. }
  502. } else if (obj == RST_ENC28J60_TX) {
  503. enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRST);
  504. enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRST);
  505. } else if (obj == RST_ENC28J60_RX) {
  506. enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXRST);
  507. enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_RXRST);
  508. }
  509. return 0;
  510. }
  511. /**
  512. * get rx free space
  513. * @param void
  514. *
  515. * @return
  516. * - status 0
  517. */
  518. static uint16_t enc28j60GetRxFreeSpace(void)
  519. {
  520. uint16_t free_space;
  521. uint16_t erxrdpt;
  522. uint16_t erxwrpt;
  523. erxrdpt = enc28j60Read(ERXRDPTL);
  524. erxrdpt |= enc28j60Read(ERXRDPTH) << 8;
  525. erxwrpt = enc28j60Read(ERXWRPTL);
  526. erxwrpt |= enc28j60Read(ERXWRPTH) << 8;
  527. if (erxwrpt > erxrdpt) {
  528. free_space = (RXSTOP_INIT - RXSTART_INIT) - (erxwrpt - erxrdpt);
  529. } else if (erxwrpt == erxrdpt) {
  530. free_space = (RXSTOP_INIT - RXSTART_INIT);
  531. } else {
  532. free_space = erxrdpt - erxwrpt - 1;
  533. }
  534. return free_space;
  535. }
  536. /**
  537. * enc28j60 interrupt set
  538. * @param interrupt_cb the interrupt callback function
  539. *
  540. * @return
  541. * - status 0
  542. */
  543. static int enc28j60_set_interrupt(pin_t gpio_pin)
  544. {
  545. uint32_t ret = 0;
  546. pin_int = csi_gpio_pin_initialize(gpio_pin);
  547. ret = csi_gpio_pin_config(pin_int, GPIO_MODE_PULLUP, GPIO_DIRECTION_INPUT);
  548. ret = csi_gpio_pin_irq_set(pin_int, GPIO_IRQ_MODE_LOW_LEVEL, 1);
  549. return 0;
  550. }
  551. csi_drv_version_t csi_eth_phy_get_version(eth_phy_handle_t handle)
  552. {
  553. csi_drv_version_t version = {0xff, 0xff};
  554. uint16_t dev_version, dev_version1;
  555. if (handle == NULL) {
  556. return version;
  557. }
  558. enc28j60Phyregread(PHHID1, 0, &dev_version);
  559. enc28j60Phyregread(PHHID2, 0, &dev_version1);
  560. version.api = CSI_ETH_PHY_API_VERSION;
  561. version.drv = (dev_version << 16) + dev_version1;
  562. return version;
  563. }
  564. eth_phy_handle_t csi_eth_phy_initialize(csi_eth_phy_read_t fn_read, csi_eth_phy_write_t fn_write)
  565. {
  566. eth_phy_priv_t *phy_priv;
  567. if ((fn_read == NULL) || (fn_write == NULL)) {
  568. return NULL;
  569. }
  570. csi_gpio_port_initialize(0, (gpio_event_cb_t)enc28j60_int_handle);
  571. phy_priv = &s_phy_instance[0];
  572. phy_priv->phy_read = fn_read ;
  573. phy_priv->phy_write = fn_write;
  574. return (eth_mac_handle_t)phy_priv;
  575. }
  576. int32_t csi_eth_phy_uninitialize(eth_phy_handle_t handle)
  577. {
  578. if (handle == NULL) {
  579. return -1;
  580. }
  581. return 0;
  582. }
  583. int32_t csi_eth_phy_deinit(void)
  584. {
  585. /* no loopback of transmitted frames */
  586. enc28j60PhyWrite(PHCON2, 0, PHCON2_HDLDIS);
  587. /* LINK AND ALL PHY Interrupt Enable */
  588. enc28j60PhyWrite(PHIE, 0, PHIE_PLNKIE | PHIE_PGEIE);
  589. return 0;
  590. }
  591. int32_t csi_eth_phy_power_control(eth_phy_handle_t handle, eth_power_state_t state)
  592. {
  593. uint16_t power_control;
  594. if (handle == NULL) {
  595. return -1;
  596. }
  597. enc28j60Phyregread(PHCON1, 0, &power_control);
  598. if (state == CSI_ETH_POWER_FULL) {
  599. power_control &= ~(1 << 11);
  600. } else if (state == CSI_ETH_POWER_OFF) {
  601. power_control |= (1 << 11);
  602. } else if (state == CSI_ETH_POWER_LOW) {
  603. } else {
  604. return -1;
  605. }
  606. enc28j60PhyWrite(PHCON1, 0, power_control);
  607. return 0;
  608. }
  609. int32_t csi_eth_phy_set_interface(eth_phy_handle_t handle, uint32_t interface)
  610. {
  611. if (handle == NULL) {
  612. return -1;
  613. }
  614. return 0;
  615. }
  616. eth_link_info_t csi_eth_phy_get_linkinfo(eth_phy_handle_t handle)
  617. {
  618. eth_link_info_t net_link_info = {0};
  619. if (handle == NULL) {
  620. return net_link_info;
  621. }
  622. net_link_info.duplex = 1;
  623. net_link_info.speed = 1;
  624. return net_link_info;
  625. }
  626. int32_t csi_eth_phy_set_mode(eth_phy_handle_t handle, uint32_t mode)
  627. {
  628. uint32_t phy_mode = 0;
  629. if (handle == NULL) {
  630. return -1;
  631. }
  632. eth_phy_priv_t *phy_priv = (eth_phy_priv_t *)handle;
  633. phy_priv->link_info.speed = (mode & 0x03);
  634. phy_priv->link_info.duplex = (mode & 0x04);
  635. phy_priv->link_info.Loopback = (mode & 0x05);
  636. if (phy_priv->link_info.duplex) {
  637. phy_mode |= PHCON1_PDPXMD;
  638. } else {
  639. phy_mode &= ~(PHCON1_PDPXMD);
  640. }
  641. if (phy_priv->link_info.Loopback) {
  642. phy_mode |= PHCON1_PLOOPBK;
  643. } else {
  644. phy_mode &= ~(PHCON1_PLOOPBK);
  645. }
  646. enc28j60PhyWrite(PHCON1, 0, phy_mode);
  647. return 0;
  648. }
  649. eth_link_state_t csi_eth_phy_get_linkstate(eth_phy_handle_t handle)
  650. {
  651. uint16_t phstat1;
  652. uint16_t phstat2;
  653. eth_link_state_t state;
  654. if (handle == NULL) {
  655. return -1;
  656. }
  657. uint8_t status = enc28j60Read(EIR);
  658. if (status & EIR_LINKIF) {
  659. /* as tested, need to read twice */
  660. enc28j60Phyregread(PHSTAT1, 0, &phstat1);
  661. enc28j60Phyregread(PHSTAT1, 0, &phstat2);
  662. phstat1 |= phstat2;
  663. if (phstat1 & 0x0004) {
  664. state = ETH_LINK_UP;
  665. } else {
  666. state = ETH_LINK_DOWN;
  667. }
  668. /* resets to "0" when read */
  669. enc28j60Phyregread(PHIR, 0, NULL);
  670. return state;
  671. }
  672. return -1;
  673. }
  674. eth_mac_handle_t csi_eth_mac_initialize(eth_event_cb_t cb)
  675. {
  676. eth_mac_priv_t *eth_priv;
  677. static int eth_mac_init = 0;
  678. int ret = -1;
  679. if (cb == NULL) {
  680. printf("cb == null\n");
  681. return NULL;
  682. }
  683. eth_priv = &s_eth_instance[0];
  684. eth_priv->cb_event = cb;
  685. if (eth_mac_init == 0) {
  686. //init spi get spi_handle
  687. g_net_spi_hd = csi_spi_initialize(SPI1_TX, SPI1_RX, SPI1_CLK, SPI1_CS, (spi_event_cb_t)enc28j60_spi_transfer_callback, NULL);
  688. //spi_handle success goto config spi
  689. if (g_net_spi_hd != NULL) {
  690. ret = csi_spi_config(g_net_spi_hd, SYSTEM_CLOCK, 2000000, SPI_MODE_MASTER, SPI_FORMAT_CPOL0_CPHA0,
  691. SPI_ORDER_MSB2LSB, SPI_SS_MASTER_SW, 7);
  692. pgpio_pin_handle1 = csi_gpio_pin_initialize(SPI1_CS);
  693. csi_gpio_pin_config(pgpio_pin_handle1, GPIO_MODE_PULLNONE, GPIO_DIRECTION_OUTPUT);
  694. }
  695. eth_mac_init = 1;
  696. }
  697. if ((ret == 0) || (eth_mac_init == 1)) {
  698. if (enc28j60Reset(RST_ENC28J60_ALL) == 0) {
  699. printf("reset OK \n");
  700. /* init enc28j60 module */
  701. uint8_t macaddr[6];
  702. csi_eth_mac_get_macaddr(NULL, (eth_mac_addr_t *)macaddr);
  703. enc28j60Init(macaddr);
  704. printf("enc28j60 init OK \n");
  705. enc28j60_set_interrupt(PA5_A8);
  706. //g_sem_spi_tx_hd = csi_kernel_sem_new(1, 0);
  707. //g_sem_spi_rx_hd = csi_kernel_sem_new(1, 0);
  708. return (eth_mac_handle_t)eth_priv;
  709. }
  710. }
  711. return NULL;
  712. }
  713. int32_t csi_eth_mac_uninitialize(eth_mac_handle_t handle)
  714. {
  715. if (handle == NULL) {
  716. return -1;
  717. }
  718. return 0;
  719. }
  720. csi_drv_version_t csi_eth_mac_get_version(eth_mac_handle_t handle)
  721. {
  722. csi_drv_version_t mac_version = {0xff, 0xff};
  723. if (handle == NULL) {
  724. return mac_version;
  725. }
  726. mac_version.api = CSI_ETH_PHY_API_VERSION;
  727. mac_version.drv = enc28j60Read(EREVID);
  728. return mac_version;
  729. }
  730. int32_t csi_eth_mac_power_control(eth_mac_handle_t handle, eth_power_state_t state)
  731. {
  732. uint8_t pw_control;
  733. if (handle == NULL) {
  734. return -1;
  735. }
  736. pw_control = enc28j60Read(ECON2);
  737. if (state == CSI_ETH_POWER_FULL) {
  738. pw_control &= ~(1 << 11);
  739. } else if (state == CSI_ETH_POWER_LOW) {
  740. pw_control |= (1 << 11);
  741. } else if (state == CSI_ETH_POWER_OFF) {
  742. } else {
  743. return -1;
  744. }
  745. enc28j60Write(ECON2, pw_control);
  746. return 0;
  747. }
  748. int32_t csi_eth_mac_get_macaddr(eth_mac_handle_t handle, eth_mac_addr_t *mac)
  749. {
  750. if ((handle == NULL) || (mac == NULL)) {
  751. return -1;
  752. }
  753. memcpy(mac, g_hw_addr, NET_HWADDR_LEN);
  754. return 0;
  755. }
  756. int32_t csi_eth_mac_set_macaddr(eth_mac_handle_t handle, const eth_mac_addr_t *mac)
  757. {
  758. if ((handle == NULL) || (mac == NULL)) {
  759. return -1;
  760. }
  761. memcpy(g_hw_addr, mac, NET_HWADDR_LEN);
  762. printf("csiMAC: %02x:%02x:%02x:%02x:%02x:%02x\n", g_hw_addr[0], g_hw_addr[1], g_hw_addr[2],
  763. g_hw_addr[3], g_hw_addr[4], g_hw_addr[5]);
  764. enc28j60Setmacaddr(g_hw_addr);
  765. return 0;
  766. }
  767. int32_t csi_eth_mac_set_addrfilter(eth_mac_handle_t handle, const eth_mac_addr_t *addr, uint32_t num_addr)
  768. {
  769. if ((handle == NULL) || (addr == NULL)) {
  770. return -1;
  771. }
  772. return 0;
  773. }
  774. int32_t csi_eth_mac_get_rx_framesize(eth_mac_handle_t handle)
  775. {
  776. uint16_t len;
  777. uint16_t rxstat;
  778. if (handle == NULL) {
  779. return -1;
  780. }
  781. /* check if a packet has been received and buffered
  782. if( !(enc28j60Read(EIR) & EIR_PKTIF) ){
  783. The above does not work. See Rev. B4 Silicon Errata point 6. */
  784. if (enc28j60Read(EPKTCNT) == 0) {
  785. return (0);
  786. }
  787. /* Set the read pointer to the start of the received packet */
  788. enc28j60Write(ERDPTL, (NextPacketPtr));
  789. enc28j60Write(ERDPTH, (NextPacketPtr) >> 8);
  790. /* read the next packet pointer */
  791. NextPacketPtr = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0);
  792. NextPacketPtr |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0) << 8;
  793. /* read the packet length (see datasheet page 43) */
  794. len = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0);
  795. len |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0) << 8;
  796. len -= 4; /* remove the CRC count */
  797. /* limit retrieve length */
  798. if (len > MAX_FRAMELEN - 1) {
  799. printf("rx packet length is %d\n", len);
  800. len = MAX_FRAMELEN - 1;
  801. return -1;
  802. }
  803. /* read the receive status (see datasheet page 43) */
  804. rxstat = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0);
  805. rxstat |= (uint16_t)enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0) << 8;
  806. /* check CRC and symbol errors (see datasheet page 44, table 7-3): */
  807. /* The ERXFCON.CRCEN is set by default. Normally we should not */
  808. /* need to check this. */
  809. if ((rxstat & 0x80) == 0) {
  810. printf("rx status vector is 0x%x\n", rxstat);
  811. len = 0; // invalid
  812. return -1;
  813. }
  814. return len;
  815. }
  816. int32_t csi_eth_mac_get_rx_frametime(eth_mac_handle_t handle, eth_mac_time_t *time)
  817. {
  818. if ((handle == NULL)) {
  819. return -1;
  820. }
  821. return 0;
  822. }
  823. int32_t csi_eth_mac_get_tx_frametime(eth_mac_handle_t handle, eth_mac_time_t *time)
  824. {
  825. if (handle == NULL) {
  826. return -1;
  827. }
  828. return 0;
  829. }
  830. int32_t csi_eth_mac_control(eth_mac_handle_t handle, uint32_t control, uint32_t arg)
  831. {
  832. if (handle == NULL) {
  833. return -1;
  834. }
  835. if (control == CSI_ETH_MAC_CONTROL_RX) {
  836. if (arg) {
  837. //enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE);
  838. csi_gpio_pin_irq_set(pin_int, GPIO_IRQ_MODE_LOW_LEVEL, 1);
  839. } else {
  840. //enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, EIE, EIE_INTIE);
  841. csi_gpio_pin_irq_set(pin_int, GPIO_IRQ_MODE_LOW_LEVEL, 0);
  842. }
  843. return 0;
  844. }
  845. return 0;
  846. }
  847. /**
  848. * send a packet data
  849. * @param address the packet data length
  850. *
  851. * @return
  852. * - sent data length
  853. */
  854. int32_t csi_eth_mac_send_frame(eth_mac_handle_t handle, const uint8_t *frame, uint32_t len, uint32_t flags)
  855. {
  856. int retry = 0;
  857. if ((handle == NULL) || (frame == NULL)) {
  858. return -1;
  859. }
  860. if (len > MAX_FRAMELEN) {
  861. printf("TX len %d is too large to send\n", len);
  862. return 0;
  863. }
  864. while (enc28j60Read(ECON1) & ECON1_TXRTS) {
  865. if (retry++ > 0xFFF) {
  866. printf("data not be sent out\n");
  867. return -1;
  868. }
  869. }
  870. /* Set the write pointer to start of transmit buffer area */
  871. enc28j60Write(EWRPTL, TXSTART_INIT & 0xFF);
  872. enc28j60Write(EWRPTH, TXSTART_INIT >> 8);
  873. /* Set the TXND pointer to correspond to the packet size given */
  874. /* Status vector will be written at ETXND+1. */
  875. enc28j60Write(ETXNDL, (TXSTART_INIT + len) & 0xFF);
  876. enc28j60Write(ETXNDH, (TXSTART_INIT + len) >> 8);
  877. /* write per-packet control byte (0x00 means use macon3 settings) */
  878. enc28j60WriteOp(ENC28J60_WRITE_BUF_MEM, 0, 0x00);
  879. /* copy the packet into the transmit buffer */
  880. enc28j60WriteBuffer(len, (uint8_t *)frame);
  881. /* send the contents of the transmit buffer onto the network */
  882. enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRTS);
  883. /* Reset the transmit logic problem. See Rev. B4 Silicon Errata point 12. */
  884. if ((enc28j60Read(EIR) & EIR_TXERIF)) {
  885. enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRTS);
  886. }
  887. return len;
  888. }
  889. int32_t csi_eth_mac_read_frame(eth_mac_handle_t handle, uint8_t *frame, uint32_t len)
  890. {
  891. uint32_t rlen;
  892. uint16_t rxstat;
  893. if ((handle == NULL) || (frame == NULL)) {
  894. return -1;
  895. }
  896. /* check if a packet has been received and buffered
  897. if( !(enc28j60Read(EIR) & EIR_PKTIF) ){
  898. The above does not work. See Rev. B4 Silicon Errata point 6. */
  899. if (enc28j60Read(EPKTCNT) == 0) {
  900. return (0);
  901. }
  902. /* Set the read pointer to the start of the received packet */
  903. enc28j60Write(ERDPTL, (NextPacketPtr));
  904. enc28j60Write(ERDPTH, (NextPacketPtr) >> 8);
  905. /* read the next packet pointer */
  906. NextPacketPtr = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0);
  907. NextPacketPtr |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0) << 8;
  908. /* read the packet length (see datasheet page 43) */
  909. rlen = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0);
  910. rlen |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0) << 8;
  911. rlen -= 4; /* remove the CRC count */
  912. /* limit retrieve length */
  913. if (rlen > MAX_FRAMELEN - 1) {
  914. printf("rx packet length is %d\n", rlen);
  915. rlen = MAX_FRAMELEN - 1;
  916. return -1;
  917. }
  918. /* read the receive status (see datasheet page 43) */
  919. rxstat = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0);
  920. rxstat |= (uint16_t)enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0) << 8;
  921. /* check CRC and symbol errors (see datasheet page 44, table 7-3): */
  922. /* The ERXFCON.CRCEN is set by default. Normally we should not */
  923. /* need to check this. */
  924. if ((rxstat & 0x80) == 0) {
  925. printf("rx status vector is 0x%x\n", rxstat);
  926. rlen = 0; // invalid
  927. return -1;
  928. }
  929. /* copy the packet from the receive buffer */
  930. enc28j60ReadBuffer(rlen, frame);
  931. /* Move the RX read pointer to the start of the next received packet */
  932. /* This frees the memory we just read out */
  933. enc28j60Write(ERXRDPTL, (NextPacketPtr));
  934. enc28j60Write(ERXRDPTH, (NextPacketPtr) >> 8);
  935. /* decrement the packet counter indicate we are done with this packet */
  936. enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_AUTOINC | ECON2_PKTDEC);
  937. return rlen;
  938. }
  939. eth_capabilities_t csi_eth_mac_get_capabilities(eth_mac_handle_t handle)
  940. {
  941. eth_capabilities_t capab = {0};
  942. if (handle == NULL) {
  943. return capab;
  944. }
  945. eth_mac_priv_t *mac_priv = (eth_mac_priv_t *)handle;
  946. mac_priv->capabilities.mac_address = 1;
  947. capab = mac_priv->capabilities;
  948. return capab;
  949. }
  950. void csi_eth_mac_signal_event(eth_mac_handle_t handle, uint32_t event)
  951. {
  952. if (handle == NULL) {
  953. return;
  954. }
  955. }
  956. int32_t csi_eth_mac_control_time(eth_mac_handle_t handle, uint32_t control, eth_mac_time_t *time)
  957. {
  958. if (handle == NULL) {
  959. return -1;
  960. }
  961. return 0;
  962. }
  963. int32_t csi_eth_mac_phy_read(eth_mac_handle_t handle, uint8_t phy_addr, uint8_t reg_addr, uint16_t *data)
  964. {
  965. if ((handle == NULL) || (data == NULL)) {
  966. return -1;
  967. }
  968. return 0;
  969. }
  970. int32_t csi_eth_mac_phy_write(eth_mac_handle_t handle, uint8_t phy_addr, uint8_t reg_addr, uint16_t data)
  971. {
  972. if ((handle == NULL)) {
  973. return -1;
  974. }
  975. return 0;
  976. }
  977. int32_t csi_eth_mac_add_framefilter(eth_mac_handle_t handle, const eth_frame_filter_t *filter)
  978. {
  979. if ((handle == NULL) || (filter == NULL)) {
  980. return -1;
  981. }
  982. return 0;
  983. }
  984. int32_t csi_eth_mac_remove_framefilter(eth_mac_handle_t handle, uint32_t filter_id)
  985. {
  986. if (handle == NULL) {
  987. return -1;
  988. }
  989. return 0;
  990. }
  991. int32_t csi_eth_mac_en_framefilter(eth_mac_handle_t handle, uint32_t filter_id, bool en)
  992. {
  993. if (handle == NULL) {
  994. return -1;
  995. }
  996. return 0;
  997. }
  998. int32_t csi_eth_mac_get_framefilter(eth_mac_handle_t handle, eth_frame_filter_list_t *list, uint32_t *count_out, uint32_t max_count)
  999. {
  1000. if ((handle == NULL) || (list == NULL)) {
  1001. return -1;
  1002. }
  1003. return 0;
  1004. }