halmac_pcie_88xx.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537
  1. /******************************************************************************
  2. *
  3. * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms of version 2 of the GNU General Public License as
  7. * published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12. * more details.
  13. *
  14. ******************************************************************************/
  15. #include "halmac_pcie_88xx.h"
  16. #if (HALMAC_88XX_SUPPORT && HALMAC_PCIE_SUPPORT)
  17. /**
  18. * init_pcie_cfg_88xx() - init PCIe
  19. * @adapter : the adapter of halmac
  20. * Author : KaiYuan Chang
  21. * Return : enum halmac_ret_status
  22. * More details of status code can be found in prototype document
  23. */
  24. enum halmac_ret_status
  25. init_pcie_cfg_88xx(struct halmac_adapter *adapter)
  26. {
  27. return HALMAC_RET_SUCCESS;
  28. }
  29. /**
  30. * deinit_pcie_cfg_88xx() - deinit PCIE
  31. * @adapter : the adapter of halmac
  32. * Author : KaiYuan Chang
  33. * Return : enum halmac_ret_status
  34. * More details of status code can be found in prototype document
  35. */
  36. enum halmac_ret_status
  37. deinit_pcie_cfg_88xx(struct halmac_adapter *adapter)
  38. {
  39. return HALMAC_RET_SUCCESS;
  40. }
  41. /**
  42. * cfg_pcie_rx_agg_88xx() - config rx aggregation
  43. * @adapter : the adapter of halmac
  44. * @halmac_rx_agg_mode
  45. * Author : KaiYuan Chang/Ivan Lin
  46. * Return : enum halmac_ret_status
  47. * More details of status code can be found in prototype document
  48. */
  49. enum halmac_ret_status
  50. cfg_pcie_rx_agg_88xx(struct halmac_adapter *adapter,
  51. struct halmac_rxagg_cfg *cfg)
  52. {
  53. return HALMAC_RET_SUCCESS;
  54. }
  55. /**
  56. * reg_r8_pcie_88xx() - read 1byte register
  57. * @adapter : the adapter of halmac
  58. * @offset : register offset
  59. * Author : KaiYuan Chang/Ivan Lin
  60. * Return : enum halmac_ret_status
  61. * More details of status code can be found in prototype document
  62. */
  63. u8
  64. reg_r8_pcie_88xx(struct halmac_adapter *adapter, u32 offset)
  65. {
  66. return PLTFM_REG_R8(offset);
  67. }
  68. /**
  69. * reg_w8_pcie_88xx() - write 1byte register
  70. * @adapter : the adapter of halmac
  71. * @offset : register offset
  72. * @value : register value
  73. * Author : KaiYuan Chang/Ivan Lin
  74. * Return : enum halmac_ret_status
  75. * More details of status code can be found in prototype document
  76. */
  77. enum halmac_ret_status
  78. reg_w8_pcie_88xx(struct halmac_adapter *adapter, u32 offset, u8 value)
  79. {
  80. PLTFM_REG_W8(offset, value);
  81. return HALMAC_RET_SUCCESS;
  82. }
  83. /**
  84. * reg_r16_pcie_88xx() - read 2byte register
  85. * @adapter : the adapter of halmac
  86. * @offset : register offset
  87. * Author : KaiYuan Chang/Ivan Lin
  88. * Return : enum halmac_ret_status
  89. * More details of status code can be found in prototype document
  90. */
  91. u16
  92. reg_r16_pcie_88xx(struct halmac_adapter *adapter, u32 offset)
  93. {
  94. return PLTFM_REG_R16(offset);
  95. }
  96. /**
  97. * reg_w16_pcie_88xx() - write 2byte register
  98. * @adapter : the adapter of halmac
  99. * @offset : register offset
  100. * @value : register value
  101. * Author : KaiYuan Chang/Ivan Lin
  102. * Return : enum halmac_ret_status
  103. * More details of status code can be found in prototype document
  104. */
  105. enum halmac_ret_status
  106. reg_w16_pcie_88xx(struct halmac_adapter *adapter, u32 offset, u16 value)
  107. {
  108. PLTFM_REG_W16(offset, value);
  109. return HALMAC_RET_SUCCESS;
  110. }
  111. /**
  112. * reg_r32_pcie_88xx() - read 4byte register
  113. * @adapter : the adapter of halmac
  114. * @offset : register offset
  115. * Author : KaiYuan Chang/Ivan Lin
  116. * Return : enum halmac_ret_status
  117. * More details of status code can be found in prototype document
  118. */
  119. u32
  120. reg_r32_pcie_88xx(struct halmac_adapter *adapter, u32 offset)
  121. {
  122. return PLTFM_REG_R32(offset);
  123. }
  124. /**
  125. * reg_w32_pcie_88xx() - write 4byte register
  126. * @adapter : the adapter of halmac
  127. * @offset : register offset
  128. * @value : register value
  129. * Author : KaiYuan Chang/Ivan Lin
  130. * Return : enum halmac_ret_status
  131. * More details of status code can be found in prototype document
  132. */
  133. enum halmac_ret_status
  134. reg_w32_pcie_88xx(struct halmac_adapter *adapter, u32 offset, u32 value)
  135. {
  136. PLTFM_REG_W32(offset, value);
  137. return HALMAC_RET_SUCCESS;
  138. }
  139. /**
  140. * cfg_txagg_pcie_align_88xx() -config sdio bus tx agg alignment
  141. * @adapter : the adapter of halmac
  142. * @enable : function enable(1)/disable(0)
  143. * @align_size : sdio bus tx agg alignment size (2^n, n = 3~11)
  144. * Author : Soar Tu
  145. * Return : enum halmac_ret_status
  146. * More details of status code can be found in prototype document
  147. */
  148. enum halmac_ret_status
  149. cfg_txagg_pcie_align_88xx(struct halmac_adapter *adapter, u8 enable,
  150. u16 align_size)
  151. {
  152. return HALMAC_RET_NOT_SUPPORT;
  153. }
  154. /**
  155. * tx_allowed_pcie_88xx() - check tx status
  156. * @adapter : the adapter of halmac
  157. * @buf : tx packet, include txdesc
  158. * @size : tx packet size, include txdesc
  159. * Author : Ivan Lin
  160. * Return : enum halmac_ret_status
  161. * More details of status code can be found in prototype document
  162. */
  163. enum halmac_ret_status
  164. tx_allowed_pcie_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
  165. {
  166. return HALMAC_RET_NOT_SUPPORT;
  167. }
  168. /**
  169. * pcie_indirect_reg_r32_88xx() - read MAC reg by SDIO reg
  170. * @adapter : the adapter of halmac
  171. * @offset : register offset
  172. * Author : Soar
  173. * Return : enum halmac_ret_status
  174. * More details of status code can be found in prototype document
  175. */
  176. u32
  177. pcie_indirect_reg_r32_88xx(struct halmac_adapter *adapter, u32 offset)
  178. {
  179. return 0xFFFFFFFF;
  180. }
  181. /**
  182. * pcie_reg_rn_88xx() - read n byte register
  183. * @adapter : the adapter of halmac
  184. * @offset : register offset
  185. * @size : register value size
  186. * @value : register value
  187. * Author : Soar
  188. * Return : enum halmac_ret_status
  189. * More details of status code can be found in prototype document
  190. */
  191. enum halmac_ret_status
  192. pcie_reg_rn_88xx(struct halmac_adapter *adapter, u32 offset, u32 size,
  193. u8 *value)
  194. {
  195. return HALMAC_RET_NOT_SUPPORT;
  196. }
  197. /**
  198. * set_pcie_bulkout_num_88xx() - inform bulk-out num
  199. * @adapter : the adapter of halmac
  200. * @num : usb bulk-out number
  201. * Author : KaiYuan Chang
  202. * Return : enum halmac_ret_status
  203. * More details of status code can be found in prototype document
  204. */
  205. enum halmac_ret_status
  206. set_pcie_bulkout_num_88xx(struct halmac_adapter *adapter, u8 num)
  207. {
  208. return HALMAC_RET_NOT_SUPPORT;
  209. }
  210. /**
  211. * get_pcie_tx_addr_88xx() - get CMD53 addr for the TX packet
  212. * @adapter : the adapter of halmac
  213. * @buf : tx packet, include txdesc
  214. * @size : tx packet size
  215. * @cmd53_addr : cmd53 addr value
  216. * Author : KaiYuan Chang/Ivan Lin
  217. * Return : enum halmac_ret_status
  218. * More details of status code can be found in prototype document
  219. */
  220. enum halmac_ret_status
  221. get_pcie_tx_addr_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size,
  222. u32 *cmd53_addr)
  223. {
  224. return HALMAC_RET_NOT_SUPPORT;
  225. }
  226. /**
  227. * get_pcie_bulkout_id_88xx() - get bulk out id for the TX packet
  228. * @adapter : the adapter of halmac
  229. * @buf : tx packet, include txdesc
  230. * @size : tx packet size
  231. * @id : usb bulk-out id
  232. * Author : KaiYuan Chang
  233. * Return : enum halmac_ret_status
  234. * More details of status code can be found in prototype document
  235. */
  236. enum halmac_ret_status
  237. get_pcie_bulkout_id_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size,
  238. u8 *id)
  239. {
  240. return HALMAC_RET_NOT_SUPPORT;
  241. }
  242. enum halmac_ret_status
  243. mdio_write_88xx(struct halmac_adapter *adapter, u8 addr, u16 data, u8 speed)
  244. {
  245. u8 tmp_u1b = 0;
  246. u32 cnt = 0;
  247. struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
  248. u8 real_addr = 0;
  249. HALMAC_REG_W16(REG_MDIO_V1, data);
  250. real_addr = (addr & 0x1F);
  251. HALMAC_REG_W8(REG_PCIE_MIX_CFG, real_addr);
  252. if (speed == HAL_INTF_PHY_PCIE_GEN1) {
  253. if (addr < 0x20)
  254. HALMAC_REG_W8(REG_PCIE_MIX_CFG + 3, 0x00);
  255. else
  256. HALMAC_REG_W8(REG_PCIE_MIX_CFG + 3, 0x01);
  257. } else if (speed == HAL_INTF_PHY_PCIE_GEN2) {
  258. if (addr < 0x20)
  259. HALMAC_REG_W8(REG_PCIE_MIX_CFG + 3, 0x02);
  260. else
  261. HALMAC_REG_W8(REG_PCIE_MIX_CFG + 3, 0x03);
  262. } else {
  263. PLTFM_MSG_ERR("[ERR]Error Speed !\n");
  264. }
  265. HALMAC_REG_W8_SET(REG_PCIE_MIX_CFG, BIT_MDIO_WFLAG_V1);
  266. tmp_u1b = HALMAC_REG_R8(REG_PCIE_MIX_CFG) & BIT_MDIO_WFLAG_V1;
  267. cnt = 20;
  268. while (tmp_u1b && (cnt != 0)) {
  269. PLTFM_DELAY_US(10);
  270. tmp_u1b = HALMAC_REG_R8(REG_PCIE_MIX_CFG) & BIT_MDIO_WFLAG_V1;
  271. cnt--;
  272. }
  273. if (tmp_u1b) {
  274. PLTFM_MSG_ERR("[ERR]MDIO write fail!\n");
  275. return HALMAC_RET_FAIL;
  276. }
  277. return HALMAC_RET_SUCCESS;
  278. }
  279. u16
  280. mdio_read_88xx(struct halmac_adapter *adapter, u8 addr, u8 speed)
  281. {
  282. u16 ret = 0;
  283. u8 tmp_u1b = 0;
  284. u32 cnt = 0;
  285. struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
  286. u8 real_addr = 0;
  287. real_addr = (addr & 0x1F);
  288. HALMAC_REG_W8(REG_PCIE_MIX_CFG, real_addr);
  289. if (speed == HAL_INTF_PHY_PCIE_GEN1) {
  290. if (addr < 0x20)
  291. HALMAC_REG_W8(REG_PCIE_MIX_CFG + 3, 0x00);
  292. else
  293. HALMAC_REG_W8(REG_PCIE_MIX_CFG + 3, 0x01);
  294. } else if (speed == HAL_INTF_PHY_PCIE_GEN2) {
  295. if (addr < 0x20)
  296. HALMAC_REG_W8(REG_PCIE_MIX_CFG + 3, 0x02);
  297. else
  298. HALMAC_REG_W8(REG_PCIE_MIX_CFG + 3, 0x03);
  299. } else {
  300. PLTFM_MSG_ERR("[ERR]Error Speed !\n");
  301. }
  302. HALMAC_REG_W8_SET(REG_PCIE_MIX_CFG, BIT_MDIO_RFLAG_V1);
  303. tmp_u1b = HALMAC_REG_R8(REG_PCIE_MIX_CFG) & BIT_MDIO_RFLAG_V1;
  304. cnt = 20;
  305. while (tmp_u1b && (cnt != 0)) {
  306. PLTFM_DELAY_US(10);
  307. tmp_u1b = HALMAC_REG_R8(REG_PCIE_MIX_CFG) & BIT_MDIO_RFLAG_V1;
  308. cnt--;
  309. }
  310. if (tmp_u1b) {
  311. ret = 0xFFFF;
  312. PLTFM_MSG_ERR("[ERR]MDIO read fail!\n");
  313. } else {
  314. ret = HALMAC_REG_R16(REG_MDIO_V1 + 2);
  315. PLTFM_MSG_TRACE("[TRACE]Value-R = %x\n", ret);
  316. }
  317. return ret;
  318. }
  319. enum halmac_ret_status
  320. dbi_w32_88xx(struct halmac_adapter *adapter, u16 addr, u32 data)
  321. {
  322. u8 tmp_u1b = 0;
  323. u32 cnt = 0;
  324. u16 write_addr = 0;
  325. struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
  326. HALMAC_REG_W32(REG_DBI_WDATA_V1, data);
  327. write_addr = ((addr & 0x0ffc) | (0x000F << 12));
  328. HALMAC_REG_W16(REG_DBI_FLAG_V1, write_addr);
  329. PLTFM_MSG_TRACE("[TRACE]Addr-W = %x\n", write_addr);
  330. HALMAC_REG_W8(REG_DBI_FLAG_V1 + 2, 0x01);
  331. tmp_u1b = HALMAC_REG_R8(REG_DBI_FLAG_V1 + 2);
  332. cnt = 20;
  333. while (tmp_u1b && (cnt != 0)) {
  334. PLTFM_DELAY_US(10);
  335. tmp_u1b = HALMAC_REG_R8(REG_DBI_FLAG_V1 + 2);
  336. cnt--;
  337. }
  338. if (tmp_u1b) {
  339. PLTFM_MSG_ERR("[ERR]DBI write fail!\n");
  340. return HALMAC_RET_FAIL;
  341. }
  342. return HALMAC_RET_SUCCESS;
  343. }
  344. u32
  345. dbi_r32_88xx(struct halmac_adapter *adapter, u16 addr)
  346. {
  347. u16 read_addr = addr & 0x0ffc;
  348. u8 tmp_u1b = 0;
  349. u32 cnt = 0;
  350. u32 ret = 0;
  351. struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
  352. HALMAC_REG_W16(REG_DBI_FLAG_V1, read_addr);
  353. HALMAC_REG_W8(REG_DBI_FLAG_V1 + 2, 0x2);
  354. tmp_u1b = HALMAC_REG_R8(REG_DBI_FLAG_V1 + 2);
  355. cnt = 20;
  356. while (tmp_u1b && (cnt != 0)) {
  357. PLTFM_DELAY_US(10);
  358. tmp_u1b = HALMAC_REG_R8(REG_DBI_FLAG_V1 + 2);
  359. cnt--;
  360. }
  361. if (tmp_u1b) {
  362. ret = 0xFFFF;
  363. PLTFM_MSG_ERR("[ERR]DBI read fail!\n");
  364. } else {
  365. ret = HALMAC_REG_R32(REG_DBI_RDATA_V1);
  366. PLTFM_MSG_TRACE("[TRACE]Value-R = %x\n", ret);
  367. }
  368. return ret;
  369. }
  370. enum halmac_ret_status
  371. dbi_w8_88xx(struct halmac_adapter *adapter, u16 addr, u8 data)
  372. {
  373. u8 tmp_u1b = 0;
  374. u32 cnt = 0;
  375. u16 write_addr = 0;
  376. u16 remainder = addr & (4 - 1);
  377. struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
  378. HALMAC_REG_W8(REG_DBI_WDATA_V1 + remainder, data);
  379. write_addr = ((addr & 0x0ffc) | (BIT(0) << (remainder + 12)));
  380. HALMAC_REG_W16(REG_DBI_FLAG_V1, write_addr);
  381. PLTFM_MSG_TRACE("[TRACE]Addr-W = %x\n", write_addr);
  382. HALMAC_REG_W8(REG_DBI_FLAG_V1 + 2, 0x01);
  383. tmp_u1b = HALMAC_REG_R8(REG_DBI_FLAG_V1 + 2);
  384. cnt = 20;
  385. while (tmp_u1b && (cnt != 0)) {
  386. PLTFM_DELAY_US(10);
  387. tmp_u1b = HALMAC_REG_R8(REG_DBI_FLAG_V1 + 2);
  388. cnt--;
  389. }
  390. if (tmp_u1b) {
  391. PLTFM_MSG_ERR("[ERR]DBI write fail!\n");
  392. return HALMAC_RET_FAIL;
  393. }
  394. return HALMAC_RET_SUCCESS;
  395. }
  396. u8
  397. dbi_r8_88xx(struct halmac_adapter *adapter, u16 addr)
  398. {
  399. u16 read_addr = addr & 0x0ffc;
  400. u8 tmp_u1b = 0;
  401. u32 cnt = 0;
  402. u8 ret = 0;
  403. struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
  404. HALMAC_REG_W16(REG_DBI_FLAG_V1, read_addr);
  405. HALMAC_REG_W8(REG_DBI_FLAG_V1 + 2, 0x2);
  406. tmp_u1b = HALMAC_REG_R8(REG_DBI_FLAG_V1 + 2);
  407. cnt = 20;
  408. while (tmp_u1b && (cnt != 0)) {
  409. PLTFM_DELAY_US(10);
  410. tmp_u1b = HALMAC_REG_R8(REG_DBI_FLAG_V1 + 2);
  411. cnt--;
  412. }
  413. if (tmp_u1b) {
  414. ret = 0xFF;
  415. PLTFM_MSG_ERR("[ERR]DBI read fail!\n");
  416. } else {
  417. ret = HALMAC_REG_R8(REG_DBI_RDATA_V1 + (addr & (4 - 1)));
  418. PLTFM_MSG_TRACE("[TRACE]Value-R = %x\n", ret);
  419. }
  420. return ret;
  421. }
  422. enum halmac_ret_status
  423. trxdma_check_idle_88xx(struct halmac_adapter *adapter)
  424. {
  425. u32 cnt = 0;
  426. struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
  427. /* Stop Tx & Rx DMA */
  428. HALMAC_REG_W32_SET(REG_RXPKT_NUM, BIT(18));
  429. HALMAC_REG_W16_SET(REG_PCIE_CTRL, ~(BIT(15) | BIT(8)));
  430. /* Stop FW */
  431. HALMAC_REG_W16_CLR(REG_SYS_FUNC_EN, BIT(10));
  432. /* Check Tx DMA is idle */
  433. cnt = 20;
  434. while ((HALMAC_REG_R8(REG_SYS_CFG5) & BIT(2)) == BIT(2)) {
  435. PLTFM_DELAY_US(10);
  436. cnt--;
  437. if (cnt == 0) {
  438. PLTFM_MSG_ERR("[ERR]Chk tx idle\n");
  439. return HALMAC_RET_POWER_OFF_FAIL;
  440. }
  441. }
  442. /* Check Rx DMA is idle */
  443. cnt = 20;
  444. while ((HALMAC_REG_R32(REG_RXPKT_NUM) & BIT(17)) != BIT(17)) {
  445. PLTFM_DELAY_US(10);
  446. cnt--;
  447. if (cnt == 0) {
  448. PLTFM_MSG_ERR("[ERR]Chk rx idle\n");
  449. return HALMAC_RET_POWER_OFF_FAIL;
  450. }
  451. }
  452. return HALMAC_RET_SUCCESS;
  453. }
  454. void
  455. en_ref_autok_88xx(struct halmac_adapter *adapter, u8 en)
  456. {
  457. if (en == 1)
  458. adapter->pcie_refautok_en = 1;
  459. else
  460. adapter->pcie_refautok_en = 0;
  461. }
  462. #endif /* HALMAC_88XX_SUPPORT */