fxmac_options.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745
  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: fxmac_options.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 "fxmac_hw.h"
  24. #include "fxmac.h"
  25. #include "fassert.h"
  26. /**
  27. * @name: FXmacSetMacAddress
  28. *
  29. * @msg: Set the MAC address for this driver/device. The address is a 48-bit value.
  30. * The device must be stopped before calling this function.
  31. *
  32. * @param {FXmac *}: instance_p is a pointer to the instance to be worked on.
  33. * @param address_ptr is a pointer to a 6-byte MAC address.
  34. * @param index plus 1 is a index to which MAC (1-4) address.
  35. *
  36. * @return
  37. * - FT_SUCCESS if the MAC address was set successfully
  38. * - FXMAC_ERR_MAC_IS_PROCESSING if the device has not yet been stopped
  39. *
  40. */
  41. FError FXmacSetMacAddress(FXmac *instance_p, u8 *address_ptr, u8 index)
  42. {
  43. u32 mac_addr;
  44. u8 *aptr = (u8 *)(void *)address_ptr;
  45. u8 index_loc = index;
  46. FError status;
  47. FASSERT(instance_p != NULL);
  48. FASSERT(aptr != NULL);
  49. FASSERT(instance_p->is_ready == (u32)FT_COMPONENT_IS_READY);
  50. FASSERT((index_loc < (u8)FXMAC_MAX_MAC_ADDR));
  51. /* Be sure device has been stopped */
  52. if (instance_p->is_started == (u32)FT_COMPONENT_IS_STARTED)
  53. {
  54. status = (FError)(FXMAC_ERR_MAC_IS_PROCESSING);
  55. }
  56. else
  57. {
  58. /* Set the MAC bits [31:0] in BOT */
  59. mac_addr = *(aptr);
  60. mac_addr |= ((u32)(*(aptr + 1)) << 8U);
  61. mac_addr |= ((u32)(*(aptr + 2)) << 16U);
  62. mac_addr |= ((u32)(*(aptr + 3)) << 24U);
  63. FXMAC_WRITEREG32(instance_p->config.base_address,
  64. ((u32)FXMAC_GEM_SA1B + ((u32)index_loc * (u32)8)), mac_addr);
  65. /* There are reserved bits in TOP so don't affect them */
  66. mac_addr = FXMAC_READREG32(instance_p->config.base_address,
  67. ((u32)FXMAC_GEM_SA1T + ((u32)index_loc * (u32)8)));
  68. mac_addr &= (u32)(~FXMAC_GEM_SAB_MASK);
  69. /* Set MAC bits [47:32] in TOP */
  70. mac_addr |= (u32)(*(aptr + 4));
  71. mac_addr |= (u32)(*(aptr + 5)) << 8U;
  72. FXMAC_WRITEREG32(instance_p->config.base_address,
  73. ((u32)FXMAC_GEM_SA1T + ((u32)index_loc * (u32)8)), mac_addr);
  74. status = (FError)(FT_SUCCESS);
  75. }
  76. return status;
  77. }
  78. /**
  79. * @name: FXmacGetMacAddress
  80. * @msg: Set the MAC address according to index
  81. * @param {FXmac} *mac is a pointer to the instance to be worked on.
  82. * @param {void} *address_ptr is an output parameter, and is a pointer to a buffer into
  83. * which the current MAC address will be copied.
  84. * @param {u8} index is a index to which MAC (0-3) address.
  85. */
  86. void FXmacGetMacAddress(FXmac *instance_p, u8 *address_ptr, u8 index)
  87. {
  88. u32 reg_value;
  89. u8 *ptr = (u8 *)address_ptr;
  90. FASSERT(instance_p != NULL);
  91. FASSERT(ptr != NULL);
  92. FASSERT(instance_p->is_ready == FT_COMPONENT_IS_READY);
  93. FASSERT((index < FXMAC_MAX_MAC_ADDR));
  94. reg_value = FXMAC_READREG32(instance_p->config.base_address, FXMAC_GEM_SA1B + ((u32)index * (u32)8));
  95. *ptr = (u8)reg_value;
  96. *(ptr + 1) = (u8)(reg_value >> 8U);
  97. *(ptr + 2) = (u8)(reg_value >> 16U);
  98. *(ptr + 3) = (u8)(reg_value >> 24U);
  99. reg_value = FXMAC_READREG32(instance_p->config.base_address, FXMAC_GEM_SA1T + ((u32)index * (u32)8));
  100. *(ptr + 4) = (u8)(reg_value);
  101. *(ptr + 5) = (u8)(reg_value >> 8U);
  102. }
  103. /**
  104. * Set the Type ID match for this driver/device. The register is a 32-bit
  105. * value. The device must be stopped before calling this function.
  106. *
  107. * @param instance_p is a pointer to the instance to be worked on.
  108. * @param id_check is type ID to be configured.
  109. * @param index plus 1 is a index to which Type ID (1-4).
  110. *
  111. * @return
  112. * - FT_SUCCESS if the MAC address was set successfully
  113. * - FXMAC_ERR_MAC_IS_PROCESSING if the device has not yet been stopped
  114. *
  115. */
  116. FError FXmacSetTypeIdCheck(FXmac *instance_p, u32 id_check, u8 index)
  117. {
  118. u8 index_loc = index;
  119. FError status;
  120. FASSERT(instance_p != NULL);
  121. FASSERT(instance_p->is_ready == FT_COMPONENT_IS_READY);
  122. FASSERT((index_loc < (u8)FXMAC_MAX_TYPE_ID));
  123. /* Be sure device has been stopped */
  124. if (instance_p->is_started == (u32)FT_COMPONENT_IS_STARTED)
  125. {
  126. status = (FError)(FXMAC_ERR_MAC_IS_PROCESSING);
  127. }
  128. else
  129. {
  130. /* Set the ID bits in MATCHx register */
  131. FXMAC_WRITEREG32(instance_p->config.base_address,
  132. ((u32)FXMAC_MATCH1_OFFSET + ((u32)index_loc * (u32)4)), id_check);
  133. status = (FError)(FT_SUCCESS);
  134. }
  135. return status;
  136. }
  137. /**
  138. * Set options for the driver/device. The driver should be stopped with
  139. * FXmacStop() before changing options.
  140. *
  141. * @param instance_p is a pointer to the instance to be worked on.
  142. * @param options are the options to set. Multiple options can be set by OR'ing
  143. * FXMAC_*_OPTIONS constants together. options not specified are not
  144. * affected.
  145. * @param queue_num is the Buffer Queue Index ,Used for jumbo frames only
  146. *
  147. * @return
  148. * - FT_SUCCESS if the options were set successfully
  149. * - FXMAC_ERR_MAC_IS_PROCESSING if the device has not yet been stopped
  150. *
  151. * @note
  152. * See fxmac.h for a description of the available options.
  153. *
  154. */
  155. FError FXmacSetOptions(FXmac *instance_p, u32 options, u32 queue_num)
  156. {
  157. u32 reg; /* Generic register contents */
  158. u32 reg_netcfg; /* Reflects original contents of NET_CONFIG */
  159. u32 reg_new_netcfg; /* Reflects new contents of NET_CONFIG */
  160. FError status;
  161. FXmacConfig *config_p;
  162. FASSERT(instance_p != NULL);
  163. FASSERT(instance_p->is_ready == (u32)FT_COMPONENT_IS_READY);
  164. config_p = &instance_p->config;
  165. /* Be sure device has been stopped */
  166. if (instance_p->is_started == (u32)FT_COMPONENT_IS_STARTED)
  167. {
  168. status = (FError)(FXMAC_ERR_MAC_IS_PROCESSING);
  169. }
  170. else
  171. {
  172. /* Many of these options will change the NET_CONFIG registers.
  173. * To reduce the amount of IO to the device, group these options here
  174. * and change them all at once.
  175. */
  176. /* Grab current register contents */
  177. reg_netcfg = FXMAC_READREG32(config_p->base_address,
  178. FXMAC_NWCFG_OFFSET);
  179. reg_new_netcfg = reg_netcfg;
  180. /*
  181. * It is configured to max 1536.
  182. */
  183. if ((options & FXMAC_FRAME1536_OPTION) != 0x00000000U)
  184. {
  185. reg_new_netcfg |= (FXMAC_NWCFG_1536RXEN_MASK);
  186. }
  187. /* Turn on VLAN packet only, only VLAN tagged will be accepted */
  188. if ((options & FXMAC_VLAN_OPTION) != 0x00000000U)
  189. {
  190. reg_new_netcfg |= FXMAC_NWCFG_NVLANDISC_MASK;
  191. }
  192. /* Turn on FCS stripping on receive packets */
  193. if ((options & FXMAC_FCS_STRIP_OPTION) != 0x00000000U)
  194. {
  195. reg_new_netcfg |= FXMAC_NWCFG_FCSREM_MASK;
  196. }
  197. /* Turn on length/type field checking on receive packets */
  198. if ((options & FXMAC_LENTYPE_ERR_OPTION) != 0x00000000U)
  199. {
  200. reg_new_netcfg |= FXMAC_NWCFG_LENERRDSCRD_MASK;
  201. }
  202. /* Turn on flow control */
  203. if ((options & FXMAC_FLOW_CONTROL_OPTION) != 0x00000000U)
  204. {
  205. reg_new_netcfg |= FXMAC_NWCFG_PAUSEEN_MASK;
  206. }
  207. /* Turn on promiscuous frame filtering (all frames are received) */
  208. if ((options & FXMAC_PROMISC_OPTION) != 0x00000000U)
  209. {
  210. reg_new_netcfg |= FXMAC_NWCFG_COPYALLEN_MASK;
  211. }
  212. /* Allow broadcast address reception */
  213. if ((options & FXMAC_BROADCAST_OPTION) != 0x00000000U)
  214. {
  215. reg_new_netcfg &= (u32)(~FXMAC_NWCFG_BCASTDI_MASK);
  216. }
  217. /* Allow multicast address filtering */
  218. if ((options & FXMAC_MULTICAST_OPTION) != 0x00000000U)
  219. {
  220. reg_new_netcfg |= FXMAC_NWCFG_MCASTHASHEN_MASK;
  221. }
  222. /* enable RX checksum offload */
  223. if ((options & FXMAC_RX_CHKSUM_ENABLE_OPTION) != 0x00000000U)
  224. {
  225. reg_new_netcfg |= FXMAC_NWCFG_RXCHKSUMEN_MASK;
  226. }
  227. /* Enable jumbo frames */
  228. if ((options & FXMAC_JUMBO_ENABLE_OPTION) != 0x00000000U)
  229. {
  230. instance_p->max_mtu_size = FXMAC_MTU_JUMBO;
  231. instance_p->max_frame_size = FXMAC_MTU_JUMBO +
  232. FXMAC_HDR_SIZE + FXMAC_TRL_SIZE;
  233. reg_new_netcfg |= FXMAC_NWCFG_JUMBO_MASK;
  234. FXMAC_WRITEREG32(config_p->base_address,
  235. FXMAC_JUMBOMAXLEN_OFFSET, FXMAC_MTU_JUMBO);
  236. if (queue_num == 0)
  237. {
  238. u32 rx_buf_size = 0;
  239. reg = FXMAC_READREG32(config_p->base_address,
  240. FXMAC_DMACR_OFFSET);
  241. reg &= ~FXMAC_DMACR_RXBUF_MASK;
  242. rx_buf_size = ((u32)instance_p->max_mtu_size / (u32)FXMAC_RX_BUF_UNIT);
  243. rx_buf_size += (((u32)instance_p->max_mtu_size % (u32)FXMAC_RX_BUF_UNIT) != (u32)0) ? 1U : 0U;
  244. reg |= ((rx_buf_size << (u32)(FXMAC_DMACR_RXBUF_SHIFT)) &
  245. (u32)(FXMAC_DMACR_RXBUF_MASK));
  246. FXMAC_WRITEREG32(config_p->base_address,
  247. FXMAC_DMACR_OFFSET, reg);
  248. }
  249. else if (queue_num < instance_p->config.max_queue_num)
  250. {
  251. u32 rx_buf_size = 0;
  252. rx_buf_size = ((u32)instance_p->max_mtu_size / (u32)FXMAC_RX_BUF_UNIT);
  253. rx_buf_size += (((u32)instance_p->max_mtu_size % (u32)FXMAC_RX_BUF_UNIT) != (u32)0) ? 1U : 0U;
  254. FXMAC_WRITEREG32(config_p->base_address, FXMAC_RXBUFQX_SIZE_OFFSET(queue_num), rx_buf_size & FXMAC_RXBUFQX_SIZE_MASK);
  255. }
  256. }
  257. if (((options & FXMAC_SGMII_ENABLE_OPTION) != 0x00000000U))
  258. {
  259. reg_new_netcfg |= (FXMAC_NWCFG_SGMIIEN_MASK |
  260. FXMAC_NWCFG_PCSSEL_MASK);
  261. }
  262. if ((options & FXMAC_LOOPBACK_NO_MII_OPTION) != 0x00000000U)
  263. {
  264. reg = FXMAC_READREG32(config_p->base_address, FXMAC_NWCTRL_OFFSET);
  265. reg |= FXMAC_NWCFG_LOOPBACK_LOCAL_MASK;
  266. FXMAC_WRITEREG32(config_p->base_address, FXMAC_NWCTRL_OFFSET, reg);
  267. }
  268. if ((options & FXMAC_LOOPBACK_USXGMII_OPTION) != 0x00000000U)
  269. {
  270. FXMAC_WRITEREG32(config_p->base_address, FXMAC_TEST_CONTROL_OFFSET, 2);
  271. }
  272. /* Officially change the NET_CONFIG registers if it needs to be
  273. * modified.
  274. */
  275. if (reg_netcfg != reg_new_netcfg)
  276. {
  277. FXMAC_WRITEREG32(config_p->base_address,
  278. FXMAC_NWCFG_OFFSET, reg_new_netcfg);
  279. }
  280. /* Enable TX checksum offload */
  281. if ((options & FXMAC_TX_CHKSUM_ENABLE_OPTION) != 0x00000000U)
  282. {
  283. reg = FXMAC_READREG32(config_p->base_address,
  284. FXMAC_DMACR_OFFSET);
  285. reg |= FXMAC_DMACR_TCPCKSUM_MASK;
  286. FXMAC_WRITEREG32(config_p->base_address,
  287. FXMAC_DMACR_OFFSET, reg);
  288. }
  289. /* Enable transmitter */
  290. if ((options & FXMAC_TRANSMITTER_ENABLE_OPTION) != 0x00000000U)
  291. {
  292. reg = FXMAC_READREG32(config_p->base_address,
  293. FXMAC_NWCTRL_OFFSET);
  294. reg |= FXMAC_NWCTRL_TXEN_MASK;
  295. FXMAC_WRITEREG32(config_p->base_address,
  296. FXMAC_NWCTRL_OFFSET, reg);
  297. }
  298. /* Enable receiver */
  299. if ((options & FXMAC_RECEIVER_ENABLE_OPTION) != 0x00000000U)
  300. {
  301. reg = FXMAC_READREG32(config_p->base_address,
  302. FXMAC_NWCTRL_OFFSET);
  303. reg |= FXMAC_NWCTRL_RXEN_MASK;
  304. FXMAC_WRITEREG32(config_p->base_address,
  305. FXMAC_NWCTRL_OFFSET, reg);
  306. }
  307. /* The remaining options not handled here are managed elsewhere in the
  308. * driver. No register modifications are needed at this time. Reflecting
  309. * the option in instance_p->options is good enough for now.
  310. */
  311. /* Set options word to its new value */
  312. instance_p->options |= options;
  313. status = (FError)(FT_SUCCESS);
  314. }
  315. return status;
  316. }
  317. /**
  318. * Clear options for the driver/device
  319. *
  320. * @param instance_p is a pointer to the instance to be worked on.
  321. * @param options are the options to clear. Multiple options can be cleared by
  322. * OR'ing FXMAC_*_options constants together. options not specified
  323. * are not affected.
  324. * @param queue_num is the Buffer Queue Index ,Used for jumbo frames only
  325. * @return
  326. * - FT_SUCCESS if the options were set successfully
  327. * - FXMAC_ERR_MAC_IS_PROCESSING if the device has not yet been stopped
  328. *
  329. * @note
  330. * See fxmac.h for a description of the available options.
  331. */
  332. FError FXmacClearOptions(FXmac *instance_p, u32 options, u32 queue_num)
  333. {
  334. u32 reg; /* Generic */
  335. u32 reg_net_cfg; /* Reflects original contents of NET_CONFIG */
  336. u32 reg_new_net_cfg; /* Reflects new contents of NET_CONFIG */
  337. FError status;
  338. FXmacConfig *config_p;
  339. FASSERT(instance_p != NULL);
  340. FASSERT(instance_p->is_ready == (u32)FT_COMPONENT_IS_READY);
  341. config_p = &instance_p->config;
  342. /* Be sure device has been stopped */
  343. if (instance_p->is_started == (u32)FT_COMPONENT_IS_STARTED)
  344. {
  345. status = (FError)(FXMAC_ERR_MAC_IS_PROCESSING);
  346. }
  347. else
  348. {
  349. /* Many of these options will change the NET_CONFIG registers.
  350. * To reduce the amount of IO to the device, group these options here
  351. * and change them all at once.
  352. */
  353. /* Grab current register contents */
  354. reg_net_cfg = FXMAC_READREG32(instance_p->config.base_address,
  355. FXMAC_NWCFG_OFFSET);
  356. reg_new_net_cfg = reg_net_cfg;
  357. /* There is only RX configuration!?
  358. * It is configured in two different length, up to 1536 and 10240 bytes
  359. */
  360. if ((options & FXMAC_FRAME1536_OPTION) != 0x00000000U)
  361. {
  362. reg_new_net_cfg &= (u32)(~FXMAC_NWCFG_1536RXEN_MASK);
  363. }
  364. /* Turn off VLAN packet only */
  365. if ((options & FXMAC_VLAN_OPTION) != 0x00000000U)
  366. {
  367. reg_new_net_cfg &= (u32)(~FXMAC_NWCFG_NVLANDISC_MASK);
  368. }
  369. /* Turn off FCS stripping on receive packets */
  370. if ((options & FXMAC_FCS_STRIP_OPTION) != 0x00000000U)
  371. {
  372. reg_new_net_cfg &= (u32)(~FXMAC_NWCFG_FCSREM_MASK);
  373. }
  374. /* Turn off length/type field checking on receive packets */
  375. if ((options & FXMAC_LENTYPE_ERR_OPTION) != 0x00000000U)
  376. {
  377. reg_new_net_cfg &= (u32)(~FXMAC_NWCFG_LENERRDSCRD_MASK);
  378. }
  379. /* Turn off flow control */
  380. if ((options & FXMAC_FLOW_CONTROL_OPTION) != 0x00000000U)
  381. {
  382. reg_new_net_cfg &= (u32)(~FXMAC_NWCFG_PAUSEEN_MASK);
  383. }
  384. /* Turn off promiscuous frame filtering (all frames are received) */
  385. if ((options & FXMAC_PROMISC_OPTION) != 0x00000000U)
  386. {
  387. reg_new_net_cfg &= (u32)(~FXMAC_NWCFG_COPYALLEN_MASK);
  388. }
  389. /* Disallow broadcast address filtering => broadcast reception */
  390. if ((options & FXMAC_BROADCAST_OPTION) != 0x00000000U)
  391. {
  392. reg_new_net_cfg |= FXMAC_NWCFG_BCASTDI_MASK;
  393. }
  394. /* Disallow multicast address filtering */
  395. if ((options & FXMAC_MULTICAST_OPTION) != 0x00000000U)
  396. {
  397. reg_new_net_cfg &= (u32)(~FXMAC_NWCFG_MCASTHASHEN_MASK);
  398. }
  399. /* Disable RX checksum offload */
  400. if ((options & FXMAC_RX_CHKSUM_ENABLE_OPTION) != 0x00000000U)
  401. {
  402. reg_new_net_cfg &= (u32)(~FXMAC_NWCFG_RXCHKSUMEN_MASK);
  403. }
  404. /* Disable jumbo frames */
  405. if (((options & FXMAC_JUMBO_ENABLE_OPTION) != 0x00000000U)) /* 恢复之前buffer 容量 */
  406. {
  407. instance_p->max_mtu_size = FXMAC_MTU;
  408. instance_p->max_frame_size = FXMAC_MTU + FXMAC_HDR_SIZE + FXMAC_TRL_SIZE;
  409. reg_new_net_cfg &= (u32)(~FXMAC_NWCFG_JUMBO_MASK);
  410. reg = FXMAC_READREG32(instance_p->config.base_address,
  411. FXMAC_DMACR_OFFSET);
  412. reg &= ~FXMAC_DMACR_RXBUF_MASK;
  413. if (queue_num == 0)
  414. {
  415. u32 rx_buf_size = 0;
  416. reg = FXMAC_READREG32(instance_p->config.base_address, FXMAC_DMACR_OFFSET);
  417. reg &= ~FXMAC_DMACR_RXBUF_MASK;
  418. rx_buf_size = ((u32)instance_p->max_mtu_size / (u32)FXMAC_RX_BUF_UNIT);
  419. rx_buf_size += ((u32)instance_p->max_mtu_size % ((u32)FXMAC_RX_BUF_UNIT) != (u32)0) ? 1U : 0U;
  420. reg |= ((rx_buf_size << (u32)(FXMAC_DMACR_RXBUF_SHIFT)) & (u32)(FXMAC_DMACR_RXBUF_MASK));
  421. FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_DMACR_OFFSET, reg);
  422. }
  423. else if (queue_num < instance_p->config.max_queue_num)
  424. {
  425. u32 rx_buf_size = 0;
  426. rx_buf_size = ((u32)instance_p->max_mtu_size / (u32)FXMAC_RX_BUF_UNIT);
  427. rx_buf_size += (((u32)instance_p->max_mtu_size % (u32)FXMAC_RX_BUF_UNIT) != (u32)0) ? 1U : 0U;
  428. FXMAC_WRITEREG32(config_p->base_address, FXMAC_RXBUFQX_SIZE_OFFSET(queue_num), rx_buf_size & FXMAC_RXBUFQX_SIZE_MASK);
  429. }
  430. }
  431. if (((options & FXMAC_SGMII_ENABLE_OPTION) != 0x00000000U))
  432. {
  433. reg_new_net_cfg &= (u32)(~(FXMAC_NWCFG_SGMIIEN_MASK |
  434. FXMAC_NWCFG_PCSSEL_MASK));
  435. }
  436. if ((options & FXMAC_LOOPBACK_NO_MII_OPTION) != 0x00000000U)
  437. {
  438. reg = FXMAC_READREG32(config_p->base_address, FXMAC_NWCTRL_OFFSET);
  439. reg &= (u32)(~FXMAC_NWCFG_LOOPBACK_LOCAL_MASK);
  440. FXMAC_WRITEREG32(config_p->base_address, FXMAC_NWCTRL_OFFSET, reg);
  441. }
  442. if ((options & FXMAC_LOOPBACK_USXGMII_OPTION) != 0x00000000U)
  443. {
  444. FXMAC_WRITEREG32(config_p->base_address, FXMAC_TEST_CONTROL_OFFSET, (FXMAC_READREG32(config_p->base_address, FXMAC_TEST_CONTROL_OFFSET) & ~2));
  445. }
  446. /* Officially change the NET_CONFIG registers if it needs to be
  447. * modified.
  448. */
  449. if (reg_net_cfg != reg_new_net_cfg)
  450. {
  451. FXMAC_WRITEREG32(instance_p->config.base_address,
  452. FXMAC_NWCFG_OFFSET, reg_new_net_cfg);
  453. }
  454. /* Disable TX checksum offload */
  455. if ((options & FXMAC_TX_CHKSUM_ENABLE_OPTION) != 0x00000000U)
  456. {
  457. reg = FXMAC_READREG32(instance_p->config.base_address,
  458. FXMAC_DMACR_OFFSET);
  459. reg &= (u32)(~FXMAC_DMACR_TCPCKSUM_MASK);
  460. FXMAC_WRITEREG32(instance_p->config.base_address,
  461. FXMAC_DMACR_OFFSET, reg);
  462. }
  463. /* Disable transmitter */
  464. if ((options & FXMAC_TRANSMITTER_ENABLE_OPTION) != 0x00000000U)
  465. {
  466. reg = FXMAC_READREG32(instance_p->config.base_address,
  467. FXMAC_NWCTRL_OFFSET);
  468. reg &= (u32)(~FXMAC_NWCTRL_TXEN_MASK);
  469. FXMAC_WRITEREG32(instance_p->config.base_address,
  470. FXMAC_NWCTRL_OFFSET, reg);
  471. }
  472. /* Disable receiver */
  473. if ((options & FXMAC_RECEIVER_ENABLE_OPTION) != 0x00000000U)
  474. {
  475. reg = FXMAC_READREG32(instance_p->config.base_address,
  476. FXMAC_NWCTRL_OFFSET);
  477. reg &= (u32)(~FXMAC_NWCTRL_RXEN_MASK);
  478. FXMAC_WRITEREG32(instance_p->config.base_address,
  479. FXMAC_NWCTRL_OFFSET, reg);
  480. }
  481. /* The remaining options not handled here are managed elsewhere in the
  482. * driver. No register modifications are needed at this time. Reflecting
  483. * option in instance_p->options is good enough for now.
  484. */
  485. /* Set options word to its new value */
  486. instance_p->options &= ~options;
  487. status = (FError)(FT_SUCCESS);
  488. }
  489. return status;
  490. }
  491. /**
  492. * Clear the Hash registers for the mac address pointed by address_ptr.
  493. *
  494. * @param instance_p is a pointer to the instance to be worked on.
  495. *
  496. */
  497. void FXmacClearHash(FXmac *instance_p)
  498. {
  499. FASSERT(instance_p != NULL);
  500. FASSERT(instance_p->is_ready == (u32)FT_COMPONENT_IS_READY);
  501. FXMAC_WRITEREG32(instance_p->config.base_address,
  502. FXMAC_HASHL_OFFSET, 0x0U);
  503. /* write bits [63:32] in TOP */
  504. FXMAC_WRITEREG32(instance_p->config.base_address,
  505. FXMAC_HASHH_OFFSET, 0x0U);
  506. }
  507. /**
  508. * Write data to the specified PHY register. The Ethernet driver does not
  509. * require the device to be stopped before writing to the PHY. Although it is
  510. * probably a good idea to stop the device, it is the responsibility of the
  511. * application to deem this necessary. The MAC provides the driver with the
  512. * ability to talk to a PHY that adheres to the Media Independent Interface
  513. * (MII) as defined in the IEEE 802.3 standard.
  514. *
  515. * Prior to PHY access with this function, the user should have setup the MDIO
  516. * clock with FXmacSetMdioDivisor().
  517. *
  518. * @param instance_p is a pointer to the FXmac instance to be worked on.
  519. * @param phy_address is the address of the PHY to be written (supports multiple
  520. * PHYs)
  521. * @param register_num is the register number, 0-31, of the specific PHY register
  522. * to write
  523. * @param phy_data is the 16-bit value that will be written to the register
  524. *
  525. * @return
  526. *
  527. * - FT_SUCCESS if the PHY was written to successfully. Since there is no error
  528. * status from the MAC on a write, the user should read the PHY to verify the
  529. * write was successful.
  530. * - FXMAC_ERR_PHY_BUSY if there is another PHY operation in progress
  531. *
  532. * @note
  533. *
  534. * This function is not thread-safe. The user must provide mutually exclusive
  535. * access to this function if there are to be multiple threads that can call it.
  536. *
  537. * There is the possibility that this function will not return if the hardware
  538. * is broken (i.e., it never sets the status bit indicating that the write is
  539. * done). If this is of concern to the user, the user should provide a mechanism
  540. * suitable to their needs for recovery.
  541. *
  542. * For the duration of this function, all host interface reads and writes are
  543. * blocked to the current FXmac instance.
  544. *
  545. ******************************************************************************/
  546. FError FXmacPhyWrite(FXmac *instance_p, u32 phy_address,
  547. u32 register_num, u16 phy_data)
  548. {
  549. u32 mgtcr;
  550. volatile u32 ipisr;
  551. u32 ip_write_temp;
  552. FError status;
  553. FASSERT(instance_p != NULL);
  554. /* Make sure no other PHY operation is currently in progress */
  555. if ((!(FXMAC_READREG32(instance_p->config.base_address,
  556. FXMAC_NWSR_OFFSET) &
  557. FXMAC_NWSR_MDIOIDLE_MASK)) == TRUE)
  558. {
  559. status = (FError)(FXMAC_ERR_PHY_BUSY);
  560. }
  561. else
  562. {
  563. /* Construct mgtcr mask for the operation */
  564. mgtcr = FXMAC_PHYMNTNC_OP_MASK | FXMAC_PHYMNTNC_OP_W_MASK |
  565. (phy_address << FXMAC_PHYMNTNC_PHAD_SHFT_MSK) |
  566. (register_num << FXMAC_PHYMNTNC_PREG_SHFT_MSK) | (u32)phy_data;
  567. /* Write mgtcr and wait for completion */
  568. FXMAC_WRITEREG32(instance_p->config.base_address,
  569. FXMAC_PHYMNTNC_OFFSET, mgtcr);
  570. do
  571. {
  572. ipisr = FXMAC_READREG32(instance_p->config.base_address,
  573. FXMAC_NWSR_OFFSET);
  574. ip_write_temp = ipisr;
  575. }
  576. while ((ip_write_temp & FXMAC_NWSR_MDIOIDLE_MASK) == 0x00000000U);
  577. status = (FError)(FT_SUCCESS);
  578. }
  579. return status;
  580. }
  581. /**
  582. * Read the current value of the PHY register indicated by the phy_address and
  583. * the register_num parameters. The MAC provides the driver with the ability to
  584. * talk to a PHY that adheres to the Media Independent Interface (MII) as
  585. * defined in the IEEE 802.3 standard.
  586. *
  587. *
  588. * @param instance_p is a pointer to the FXmac instance to be worked on.
  589. * @param phy_address is the address of the PHY to be read (supports multiple
  590. * PHYs)
  591. * @param register_num is the register number, 0-31, of the specific PHY register
  592. * to read
  593. * @param phydat_aptr is an output parameter, and points to a 16-bit buffer into
  594. * which the current value of the register will be copied.
  595. *
  596. * @return
  597. *
  598. * - FT_SUCCESS if the PHY was read from successfully
  599. * - FXMAC_ERR_PHY_BUSY if there is another PHY operation in progress
  600. *
  601. * @note
  602. *
  603. * This function is not thread-safe. The user must provide mutually exclusive
  604. * access to this function if there are to be multiple threads that can call it.
  605. *
  606. * There is the possibility that this function will not return if the hardware
  607. * is broken (i.e., it never sets the status bit indicating that the read is
  608. * done). If this is of concern to the user, the user should provide a mechanism
  609. * suitable to their needs for recovery.
  610. *
  611. * For the duration of this function, all host interface reads and writes are
  612. * blocked to the current FXmac instance.
  613. *
  614. ******************************************************************************/
  615. FError FXmacPhyRead(FXmac *instance_p, u32 phy_address,
  616. u32 register_num, u16 *phydat_aptr)
  617. {
  618. u32 mgtcr;
  619. volatile u32 ipisr;
  620. u32 IpReadTemp;
  621. FError status;
  622. FASSERT(instance_p != NULL);
  623. /* Make sure no other PHY operation is currently in progress */
  624. if ((!(FXMAC_READREG32(instance_p->config.base_address,
  625. FXMAC_NWSR_OFFSET) &
  626. FXMAC_NWSR_MDIOIDLE_MASK)) == TRUE)
  627. {
  628. status = (FError)(FXMAC_ERR_PHY_BUSY);
  629. }
  630. else
  631. {
  632. /* Construct mgtcr mask for the operation */
  633. mgtcr = FXMAC_PHYMNTNC_OP_MASK | FXMAC_PHYMNTNC_OP_R_MASK |
  634. (phy_address << FXMAC_PHYMNTNC_PHAD_SHFT_MSK) |
  635. (register_num << FXMAC_PHYMNTNC_PREG_SHFT_MSK);
  636. /* Write mgtcr and wait for completion */
  637. FXMAC_WRITEREG32(instance_p->config.base_address,
  638. FXMAC_PHYMNTNC_OFFSET, mgtcr);
  639. do
  640. {
  641. ipisr = FXMAC_READREG32(instance_p->config.base_address,
  642. FXMAC_NWSR_OFFSET);
  643. IpReadTemp = ipisr;
  644. }
  645. while ((IpReadTemp & FXMAC_NWSR_MDIOIDLE_MASK) == 0x00000000U);
  646. /* Read data */
  647. *phydat_aptr = (u16)FXMAC_READREG32(instance_p->config.base_address,
  648. FXMAC_PHYMNTNC_OFFSET);
  649. status = (FError)(FT_SUCCESS);
  650. }
  651. return status;
  652. }