fgmac.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497
  1. /*
  2. * Copyright : (C) 2022 Phytium Information Technology, Inc.
  3. * All Rights Reserved.
  4. *
  5. * This program is OPEN SOURCE software: you can redistribute it and/or modify it
  6. * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd,
  7. * either version 1.0 of the License, or (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY;
  10. * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. * See the Phytium Public License for more details.
  12. *
  13. *
  14. * FilePath: fgmac.c
  15. * Date: 2022-04-06 14:46:52
  16. * LastEditTime: 2022-04-06 14:46:58
  17. * Description:  This file is for
  18. *
  19. * Modify History:
  20. * Ver   Who        Date         Changes
  21. * ----- ------     --------    --------------------------------------
  22. */
  23. /***************************** Include Files *********************************/
  24. #include <string.h>
  25. #include "fio.h"
  26. #include "ferror_code.h"
  27. #include "ftypes.h"
  28. #include "fdebug.h"
  29. #include "fassert.h"
  30. #include "fgmac_hw.h"
  31. #include "fgmac_phy.h"
  32. #include "fgmac.h"
  33. /************************** Constant Definitions *****************************/
  34. /**************************** Type Definitions *******************************/
  35. /***************** Macros (Inline Functions) Definitions *********************/
  36. #define FGMAC_DEBUG_TAG "FGMAC"
  37. #define FGMAC_ERROR(format, ...) FT_DEBUG_PRINT_E(FGMAC_DEBUG_TAG, format, ##__VA_ARGS__)
  38. #define FGMAC_WARN(format, ...) FT_DEBUG_PRINT_W(FGMAC_DEBUG_TAG, format, ##__VA_ARGS__)
  39. #define FGMAC_INFO(format, ...) FT_DEBUG_PRINT_I(FGMAC_DEBUG_TAG, format, ##__VA_ARGS__)
  40. #define FGMAC_DEBUG(format, ...) FT_DEBUG_PRINT_D(FGMAC_DEBUG_TAG, format, ##__VA_ARGS__)
  41. /************************** Function Prototypes ******************************/
  42. static FError FGmacReset(FGmac *instance_p);
  43. static FError FGmacDmaConfigure(FGmac *instance_p);
  44. static FError FGmacControllerConfigure(FGmac *instance_p);
  45. /************************** Variable Definitions *****************************/
  46. /*****************************************************************************/
  47. /* 此文件主要为了完成用户对外接口,用户可以使用这些接口直接开始工作 */
  48. /* - 包括用户API的定义和实现
  49. - 同时包含必要的OPTION方法,方便用户进行配置
  50. - 如果驱动可以直接进行I/O操作,在此源文件下可以将API 进行实现 */
  51. /* - 包括用户API的定义和实现
  52. - 同时包含必要的OPTION方法,方便用户进行配置
  53. - 如果驱动可以直接进行I/O操作,在此源文件下可以将API 进行实现 */
  54. /*
  55. * @name: FGmacStop
  56. * @msg: 停止FGMAC控制器寄存器
  57. * @return {*}
  58. * @param {FGmac} *instance_p 驱动控制数据
  59. */
  60. void FGmacStop(FGmac *instance_p)
  61. {
  62. FASSERT(instance_p);
  63. uintptr base_addr = instance_p->config.base_addr;
  64. u32 reg_val;
  65. /* disable dma tx and rx */
  66. reg_val = FGMAC_READ_REG32(base_addr, FGMAC_DMA_OP_OFFSET);
  67. reg_val &= (~FGMAC_DMA_OP_ST);
  68. reg_val &= (~FGMAC_DMA_OP_SR);
  69. FGMAC_WRITE_REG32(base_addr, FGMAC_DMA_OP_OFFSET, reg_val);
  70. /* disable gmac tx and rx */
  71. reg_val = FGMAC_READ_REG32(base_addr, FGMAC_CONF_OFFSET);
  72. reg_val &= (~FGMAC_CONF_TX_EN);
  73. reg_val &= (~FGMAC_CONF_RX_EN);
  74. FGMAC_WRITE_REG32(base_addr, FGMAC_CONF_OFFSET, reg_val);
  75. }
  76. /**
  77. * @name: FGmacCfgInitialize
  78. * @msg: init FGMAC controller
  79. * @param {FGmac} *instance_p, instance of FGmac controller
  80. * @param {FGmacConfig} *cofig_p, input configuration parameters
  81. * @return err code information, FGMAC_SUCCESS indicates success,others indicates failed
  82. */
  83. FError FGmacCfgInitialize(FGmac *instance_p, const FGmacConfig *input_config_p)
  84. {
  85. FASSERT(instance_p && input_config_p);
  86. FError ret = FGMAC_SUCCESS;
  87. /* indicating device is started */
  88. if (FT_COMPONENT_IS_READY == instance_p->is_ready)
  89. {
  90. FGMAC_WARN("device is already initialized!!!");
  91. }
  92. /* de-initialize device instance */
  93. FGmacDeInitialize(instance_p);
  94. instance_p->config = *input_config_p;
  95. /*Phy Awaken*/
  96. ret = FGmacPhyAwaken(instance_p);
  97. if (FGMAC_SUCCESS != ret)
  98. {
  99. FGMAC_ERROR("phy awaken failed!");
  100. return ret;
  101. }
  102. /* initialize the gmac controller */
  103. ret = FGmacReset(instance_p); // permmit failed
  104. if (FGMAC_SUCCESS != ret)
  105. {
  106. printf("FGmacReset failed \r\n");
  107. }
  108. ret = FGmacControllerConfigure(instance_p);
  109. if (FGMAC_SUCCESS != ret)
  110. return ret;
  111. /* initialize the gmac dma controller */
  112. ret = FGmacDmaConfigure(instance_p);
  113. if (FGMAC_SUCCESS == ret)
  114. {
  115. instance_p->is_ready = FT_COMPONENT_IS_READY;
  116. }
  117. return ret;
  118. }
  119. /**
  120. * @name: FGmacDeInitialize
  121. * @msg: deinit FGMAC controller
  122. * @param {FGmac} *instance_p, instance of FGmac controller
  123. * @return err code information, FGMAC_SUCCESS indicates success,others indicates failed
  124. */
  125. FError FGmacDeInitialize(FGmac *instance_p)
  126. {
  127. FASSERT(instance_p);
  128. FError ret = FGMAC_SUCCESS;
  129. instance_p->is_ready = 0;
  130. memset(instance_p, 0, sizeof(*instance_p));
  131. return ret;
  132. }
  133. /**
  134. * @name: FGmacReset
  135. * @msg: reset FGMAC controller
  136. * @param {FGmac} *instance_p, instance of FGmac controller
  137. * @return err code information, FGMAC_SUCCESS indicates success,others indicates failed
  138. */
  139. static FError FGmacReset(FGmac *instance_p)
  140. {
  141. FASSERT(instance_p);
  142. FGmacMacAddr mac_addr;
  143. uintptr base_addr = instance_p->config.base_addr;
  144. FError ret = FGMAC_SUCCESS;
  145. u32 reg_val;
  146. /* backup mac address before software reset */
  147. memset(mac_addr, 0, sizeof(mac_addr));
  148. FGmacGetMacAddr(base_addr, mac_addr);
  149. /* disable all gmac & dma intr */
  150. FGmacSetInterruptMask(instance_p, FGMAC_CTRL_INTR, FGMAC_ISR_MASK_ALL_BITS);
  151. FGmacSetInterruptMask(instance_p, FGMAC_DMA_INTR, FGMAC_DMA_INTR_ENA_ALL_MASK);
  152. /* stop gmac/dma tx and rx */
  153. FGmacStop(instance_p);
  154. /* do software reset per init */
  155. ret = FGmacSoftwareReset(base_addr, FGMAC_RETRY_TIMES);
  156. /* disable gmac & dma interrupts */
  157. FGmacSetInterruptMask(instance_p, FGMAC_CTRL_INTR, FGMAC_ISR_MASK_ALL_BITS);
  158. FGmacSetInterruptMask(instance_p, FGMAC_DMA_INTR, FGMAC_DMA_INTR_ENA_ALL_MASK);
  159. /* recover mac address after softwate reset */
  160. FGmacSetMacAddr(base_addr, mac_addr);
  161. return ret;// may return error
  162. }
  163. /**
  164. * @name: FGmacControllerSpeedConfig
  165. * @msg: fgmac speed configuration
  166. * @param {FGmac} *instance_p, instance of FGmac controller
  167. * @param {u32} speed, speed value
  168. * @return {*}
  169. */
  170. void FGmacControllerSpeedConfig(FGmac *instance_p, u32 speed)
  171. {
  172. FASSERT(instance_p);
  173. uintptr base_addr = instance_p->config.base_addr;
  174. u32 reg_val = 0;
  175. /* MAC配置寄存器 */
  176. reg_val = FGMAC_READ_REG32(base_addr, FGMAC_CONF_OFFSET);
  177. /* 设置通信速度FES=1000Mbps */
  178. if (speed == FGMAC_PHY_SPEED_1000)
  179. {
  180. reg_val &= (~FGMAC_CONF_PORTSELECT);
  181. reg_val &= (~FGMAC_CONF_FES);
  182. }
  183. /* 设置通信速度FES=100Mbps */
  184. if (speed == FGMAC_PHY_SPEED_100)
  185. {
  186. reg_val |= FGMAC_CONF_PORTSELECT;
  187. reg_val |= FGMAC_CONF_FES;
  188. }
  189. /* 设置通信速度FES=10Mbps */
  190. if (speed == FGMAC_PHY_SPEED_10)
  191. {
  192. reg_val |= FGMAC_CONF_PORTSELECT;
  193. reg_val &= (~FGMAC_CONF_FES);
  194. }
  195. FGMAC_WRITE_REG32(base_addr, FGMAC_CONF_OFFSET, reg_val);
  196. }
  197. /**
  198. * @name: FGmacControllerDuplexConfig
  199. * @msg: fgmac deplex mode configuration
  200. * @param {FGmac} *instance_p, instance of FGmac controller
  201. * @param {u32} duplex, duplex mode
  202. * @return {*}
  203. */
  204. void FGmacControllerDuplexConfig(FGmac *instance_p, u32 duplex)
  205. {
  206. FASSERT(instance_p);
  207. uintptr base_addr = instance_p->config.base_addr;
  208. u32 reg_val = 0;
  209. /* MAC配置寄存器 */
  210. reg_val = FGMAC_READ_REG32(base_addr, FGMAC_CONF_OFFSET);
  211. /* 设置双工模式 */
  212. if (duplex == FGMAC_PHY_MODE_FULLDUPLEX)
  213. reg_val |= FGMAC_CONF_DUPLEX_MODE;
  214. else
  215. reg_val &= ~FGMAC_CONF_DUPLEX_MODE;
  216. FGMAC_WRITE_REG32(base_addr, FGMAC_CONF_OFFSET, reg_val);
  217. }
  218. /**
  219. * @name: FGmacControllerConfigure
  220. * @msg: config FGMAC controller
  221. * @param {FGmac} *instance_p, instance of FGmac controller
  222. * @return err code information, FGMAC_SUCCESS indicates success,others indicates failed
  223. */
  224. static FError FGmacControllerConfigure(FGmac *instance_p)
  225. {
  226. FASSERT(instance_p);
  227. FGmacMacAddr mac_addr;
  228. uintptr base_addr = instance_p->config.base_addr;
  229. FError ret = FGMAC_SUCCESS;
  230. u32 reg_val = 0;
  231. /********gmac ctrl reg init*********/
  232. /* Set the WD bit according to ETH Watchdog value */
  233. /* Set the JD: bit according to ETH Jabber value */
  234. /* Set the IFG bit according to ETH InterFrameGap value */
  235. /* Set the DCRS bit according to ETH CarrierSense value */
  236. /* Set the FES bit according to ETH Speed value */
  237. /* Set the DO bit according to ETH ReceiveOwn value */
  238. /* Set the LM bit according to ETH LoopbackMode value */
  239. /* Set the DM bit according to ETH Mode value */
  240. /* Set the IPCO bit according to ETH ChecksumOffload value */
  241. /* Set the DR bit according to ETH RetryTransmission value */
  242. /* Set the ACS bit according to ETH AutomaticPadCRCStrip value */
  243. /* Set the BL bit according to ETH BackOffLimit value */
  244. /* Set the DC bit according to ETH DeferralCheck value */
  245. /* MAC配置寄存器 */
  246. reg_val = FGMAC_READ_REG32(base_addr, FGMAC_CONF_OFFSET);
  247. /* 使能载波侦听DCRS、失能环回模式LM */
  248. reg_val &= ~(FGMAC_CONF_DCRS | FGMAC_CONF_LOOPBACK_MODE);
  249. /* 设置帧内间隔IFG */
  250. reg_val |= FGMAC_CONF_IFG(0);
  251. /* 1000Mbps default */
  252. reg_val &= (~FGMAC_CONF_PORTSELECT);
  253. reg_val &= (~FGMAC_CONF_FES);
  254. /* 双工模式 */
  255. if (instance_p->config.duplex_mode)
  256. reg_val |= FGMAC_CONF_DUPLEX_MODE;
  257. else
  258. reg_val &= ~FGMAC_CONF_DUPLEX_MODE;
  259. /* 使能校验和卸载IPS */
  260. if (FGMAC_CHECKSUM_BY_HARDWARE == instance_p->config.cheksum_mode)
  261. reg_val |= FGMAC_CONF_IPC;
  262. else
  263. reg_val &= ~FGMAC_CONF_IPC;
  264. /* 重发DR=1, 重发一次 */
  265. reg_val |= FGMAC_CONF_DISABLE_RETRY;
  266. /* 自动 PAD/ CRC 剥线, 全双工模式保留 */
  267. reg_val |= FGMAC_CONF_ACS;
  268. /* 后退限制, 全双工模式保留 */
  269. reg_val |= FGMAC_CONF_BL(0);
  270. /* 延期检查禁用 */
  271. reg_val &= ~FGMAC_CONF_DC;
  272. /* 使能类型帧的CRC剥离、禁用看门狗WD、禁用Jabber JD、帧突发启用BE、不能自接收DO(全双工保留)*/
  273. reg_val |= (FGMAC_CONF_CST | FGMAC_CONF_WD | FGMAC_CONF_JD | FGMAC_CONF_BE | FGMAC_CONF_DO);
  274. FGMAC_WRITE_REG32(base_addr, FGMAC_CONF_OFFSET, reg_val);
  275. /********gmac filter reg init*********/
  276. /* Set the RA bit according to ETH ReceiveAll value */
  277. /* Set the SAF and SAIF bits according to ETH SourceAddrFilter value */
  278. /* Set the PCF bit according to ETH PassControlFrames value */
  279. /* Set the DBF bit according to ETH BroadcastFramesReception value */
  280. /* Set the DAIF bit according to ETH DestinationAddrFilter value */
  281. /* Set the PR bit according to ETH PromiscuousMode value */
  282. /* Set the PM, HMC and HPF bits according to ETH MulticastFramesFilter value */
  283. /* Set the HUC and HPF bits according to ETH UnicastFramesFilter value */
  284. /* MAC帧过滤寄存器 */
  285. reg_val = FGMAC_READ_REG32(base_addr, FGMAC_FRAME_FILTER_OFFSET);
  286. /* 全部接收RA */
  287. reg_val |= FGMAC_FRAME_FILTER_RA;
  288. /* 通过控制帧PCF 10b */
  289. reg_val |= FGMAC_FRAME_FILTER_PCF(2);
  290. /* 失能禁用广播帧DBF */
  291. reg_val &= ~FGMAC_FRAME_FILTER_DBF;
  292. /* 失能通过所有多播PM */
  293. reg_val &= ~FGMAC_FRAME_FILTER_PM;
  294. /* 失能目的地址反向过滤DAIF */
  295. reg_val &= ~FGMAC_FRAME_FILTER_DAIF;
  296. /* 失能哈希单播PR */
  297. reg_val &= ~FGMAC_FRAME_FILTER_PR;
  298. FGMAC_WRITE_REG32(base_addr, FGMAC_FRAME_FILTER_OFFSET, reg_val);
  299. /********hash reg*********/
  300. FGMAC_WRITE_REG32(base_addr, FGMAC_HASH_HIGH_OFFSET, 0x0);
  301. FGMAC_WRITE_REG32(base_addr, FGMAC_HASH_LOW_OFFSET, 0x0);
  302. /********gmac flow ctrl reg init*********/
  303. /* Set the PT bit according to ETH PauseTime value */
  304. /* Set the DZPQ bit according to ETH ZeroQuantaPause value */
  305. /* Set the PLT bit according to ETH PauseLowThreshold value */
  306. /* Set the UP bit according to ETH UnicastPauseFrameDetect value */
  307. /* Set the RFE bit according to ETH ReceiveFlowControl value */
  308. /* Set the TFE bit according to ETH TransmitFlowControl value */
  309. reg_val = FGMAC_READ_REG32(base_addr, FGMAC_FLOW_CTRL_OFFSET);
  310. /* 禁用自动零暂停帧生成DZPQ */
  311. reg_val |= FGMAC_FLOW_DZPQ;
  312. /* 暂停低阈值PLT */
  313. reg_val |= FGMAC_FLOW_PLT(0);
  314. /* 禁用接收流控制RFE */
  315. reg_val &= ~FGMAC_FLOW_RFE;
  316. /* 禁用传输流控制TFE */
  317. reg_val &= ~FGMAC_FLOW_TFE;
  318. FGMAC_WRITE_REG32(base_addr, FGMAC_FLOW_CTRL_OFFSET, reg_val);
  319. /********vlan tag reg*********/
  320. /* Set the ETV bit according to ETH VLANTagComparison value */
  321. /* Set the VL bit according to ETH VLANTagIdentifier value */
  322. /* 接收帧的 VLAN 标记标识符 VL */
  323. reg_val = FGMAC_VLAN_TAG_VL(0);
  324. /* 设置VLAN 标记比较的位数ETV 1-12bit 0-16bit */
  325. reg_val &= ~FGMAC_VLAN_TAG_ETV;
  326. FGMAC_WRITE_REG32(base_addr, FGMAC_VLAN_TAG_OFFSET, reg_val);
  327. return ret;
  328. }
  329. static FError FGmacDmaConfigure(FGmac *instance_p)
  330. {
  331. FASSERT(instance_p);
  332. u32 reg_val;
  333. FError ret = FGMAC_SUCCESS;
  334. uintptr base_addr = instance_p->config.base_addr;
  335. /********DMA总线模式寄存器*********/
  336. /* Set the AAL bit according to ETH AddressAlignedBeats value */
  337. /* Set the FB bit according to ETH FixedBurst value */
  338. /* Set the RPBL and 4*PBL bits according to ETH RxDMABurstLength value */
  339. /* Set the PBL and 4*PBL bits according to ETH TxDMABurstLength value */
  340. /* Set the Enhanced DMA descriptors bit according to ETH EnhancedDescriptorFormat value*/
  341. /* Set the DSL bit according to ETH DesciptorSkipLength value */
  342. /* Set the PR and DA bits according to ETH DMAArbitration value */
  343. reg_val = FGMAC_READ_REG32(base_addr, FGMAC_DMA_BUS_MODE_OFFSET);
  344. reg_val |= FGMAC_DMA_BUS_AAL;
  345. /* 使用单独的 PBL USP */
  346. reg_val |= FGMAC_DMA_BUS_USP;
  347. /* RxDMA PBL RPBL */
  348. reg_val |= FGMAC_DMA_BUS_RPBL(32);
  349. /* 固定突发 FB */
  350. reg_val |= FGMAC_DMA_BUS_FB;
  351. /* 控制 RxDMA 和 TxDMA 之间的加权循环仲裁中的优先级比率 PR */
  352. reg_val |= FGMAC_DMA_BUS_PR(0);
  353. /* 可编程突发长度 PBL */
  354. reg_val |= FGMAC_DMA_BUS_PBL(32);
  355. /* 交替描述表大小 ATDS */
  356. reg_val |= FGMAC_DMA_BUS_ATDS;
  357. FGMAC_WRITE_REG32(base_addr, FGMAC_DMA_BUS_MODE_OFFSET, reg_val);
  358. /* dma set bus mode */
  359. // FGMAC_WRITE_REG32(base_addr, FGMAC_DMA_BUS_MODE_OFFSET, FGMAC_DMA_BUS_INIT);
  360. /********DMA操作模式寄存器*********/
  361. /* Set the DT bit according to ETH DropTCPIPChecksumErrorFrame value */
  362. /* Set the RSF bit according to ETH ReceiveStoreForward value */
  363. /* Set the DFF bit according to ETH FlushReceivedFrame value */
  364. /* Set the TSF bit according to ETH TransmitStoreForward value */
  365. /* Set the TTC bit according to ETH TransmitThresholdControl value */
  366. /* Set the FEF bit according to ETH ForwardErrorFrames value */
  367. /* Set the FUF bit according to ETH ForwardUndersizedGoodFrames value */
  368. /* Set the RTC bit according to ETH ReceiveThresholdControl value */
  369. /* Set the OSF bit according to ETH SecondFrameOperate value */
  370. reg_val = FGMAC_READ_REG32(base_addr, FGMAC_DMA_OP_OFFSET);
  371. reg_val &= FGMAC_DMA_OP_CLEAR_MASK;
  372. /* 丢弃 TCP / IP 校验和错误帧 DT */
  373. reg_val &= ~FGMAC_DMA_OP_DT;
  374. /* 接收存储转发 RSF */
  375. reg_val |= FGMAC_DMA_OP_RSF;
  376. /* 刷新正在接收的帧 DFF */
  377. reg_val &= ~FGMAC_DMA_OP_DFF;
  378. /* 发送存储和转发 TSF */
  379. reg_val |= FGMAC_DMA_OP_TSF;
  380. /* 传输阈值控制 TTC */
  381. reg_val |= FGMAC_DMA_OP_TTC(7);
  382. /* 在第二帧上操作 OSF */
  383. reg_val |= FGMAC_DMA_OP_OSF;
  384. FGMAC_WRITE_REG32(base_addr, FGMAC_DMA_OP_OFFSET, reg_val);
  385. /* 刷新DMA发送FIFO FTF */
  386. ret = FGmacFlushTxFifo(base_addr, FGMAC_RETRY_TIMES);
  387. if (FGMAC_SUCCESS != ret)
  388. {
  389. printf("FGmac Flush Failed\r\n");
  390. }
  391. /* AXI 突发长度 BLEN 16,8,4 */
  392. reg_val = (FGMAC_DMA_AXI_BUS_MOD_BLEN16 | FGMAC_DMA_AXI_BUS_MOD_BLEN8 | FGMAC_DMA_AXI_BUS_MOD_BLEN4);
  393. FGMAC_WRITE_REG32(base_addr, FGMAC_DMA_AXI_BUS_MOD_OFFSET, reg_val);
  394. return ret;
  395. }