phy_patch.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. /*
  2. * SPDX-License-Identifier: GPL-2.0-only
  3. *
  4. * Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved.
  5. */
  6. /*
  7. * Include Files
  8. */
  9. #if defined(RTK_PHYDRV_IN_LINUX)
  10. #include "rtk_osal.h"
  11. #else
  12. #include <common/rt_type.h>
  13. #include <common/rt_error.h>
  14. #include <common/debug/rt_log.h>
  15. #include <hal/common/halctrl.h>
  16. #include <hal/phy/phy_patch.h>
  17. #endif
  18. /*
  19. * Function Declaration
  20. */
  21. uint8 phy_patch_op_translate(uint8 patch_mode, uint8 patch_op, uint8 compare_op)
  22. {
  23. if (patch_mode != PHY_PATCH_MODE_CMP)
  24. {
  25. return patch_op;
  26. }
  27. else
  28. {
  29. switch (compare_op)
  30. {
  31. case RTK_PATCH_CMP_WS:
  32. return RTK_PATCH_OP_SKIP;
  33. case RTK_PATCH_CMP_W:
  34. case RTK_PATCH_CMP_WC:
  35. case RTK_PATCH_CMP_SWC:
  36. default:
  37. return RTK_PATCH_OP_TO_CMP(patch_op, compare_op);
  38. }
  39. }
  40. }
  41. int32 phy_patch_op(rt_phy_patch_db_t *pPhy_patchDb, uint32 unit, rtk_port_t port, uint8 portOffset, uint8 patch_op, uint16 portmask, uint16 pagemmd, uint16 addr, uint8 msb, uint8 lsb, uint16 data, uint8 patch_mode)
  42. {
  43. rtk_hwpatch_t op;
  44. op.patch_op = patch_op;
  45. op.portmask = portmask;
  46. op.pagemmd = pagemmd;
  47. op.addr = addr;
  48. op.msb = msb;
  49. op.lsb = lsb;
  50. op.data = data;
  51. op.compare_op = RTK_PATCH_CMP_W;
  52. return pPhy_patchDb->fPatch_op(unit, port, portOffset, &op, patch_mode);
  53. }
  54. static int32 _phy_patch_process(uint32 unit, rtk_port_t port, uint8 portOffset, rtk_hwpatch_t *pPatch, int32 size, uint8 patch_mode)
  55. {
  56. int32 i = 0;
  57. int32 ret = 0;
  58. int32 chk_ret = RT_ERR_OK;
  59. int32 n;
  60. rtk_hwpatch_t *patch = pPatch;
  61. rt_phy_patch_db_t *pPatchDb = NULL;
  62. PHYPATCH_DB_GET(unit, port, pPatchDb);
  63. if (size <= 0)
  64. {
  65. return RT_ERR_OK;
  66. }
  67. n = size / sizeof(rtk_hwpatch_t);
  68. for (i = 0; i < n; i++)
  69. {
  70. ret = pPatchDb->fPatch_op(unit, port, portOffset, &patch[i], patch_mode);
  71. if ((ret != RT_ERR_ABORT) && (ret != RT_ERR_OK))
  72. {
  73. if ((ret == RT_ERR_CHECK_FAILED) && (patch_mode == PHY_PATCH_MODE_CMP))
  74. {
  75. osal_printf("PATCH CHECK: Failed entry:%u|%u|0x%X|0x%X|%u|%u|0x%X\n",
  76. i + 1, patch[i].patch_op, patch[i].pagemmd, patch[i].addr, patch[i].msb, patch[i].lsb, patch[i].data);
  77. chk_ret = RT_ERR_CHECK_FAILED;
  78. continue;
  79. }
  80. else
  81. {
  82. RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u %s failed! %u[%u][0x%X][0x%X][0x%X] ret=0x%X\n", unit, port, __FUNCTION__,
  83. i+1, patch[i].patch_op, patch[i].pagemmd, patch[i].addr, patch[i].data, ret);
  84. return ret;
  85. }
  86. }
  87. }
  88. return (chk_ret == RT_ERR_CHECK_FAILED) ? chk_ret : RT_ERR_OK;
  89. }
  90. rtk_hwpatch_t rtl826XB_patch_rtk_conf[] = {
  91. {RTK_PATCH_OP_PSDS0 , 0xff , 0x07 , 0x10 , 15, 0, 0x80aa, RTK_PATCH_CMP_WC , 0, 0, 0, 0},
  92. {RTK_PATCH_OP_PSDS0 , 0xff , 0x06 , 0x12 , 15, 0, 0x5078, RTK_PATCH_CMP_WC , 0, 0, 0, 0},
  93. };
  94. /* Function Name:
  95. * phy_patch
  96. * Description:
  97. * apply initial patch data to PHY
  98. * Input:
  99. * unit - unit id
  100. * port - port id
  101. * portOffset - the index offset of port based the base port in the PHY chip
  102. * Output:
  103. * None
  104. * Return:
  105. * RT_ERR_OK
  106. * RT_ERR_FAILED
  107. * RT_ERR_CHECK_FAILED
  108. * RT_ERR_NOT_SUPPORTED
  109. * Note:
  110. * None
  111. */
  112. int32 phy_patch(uint32 unit, rtk_port_t port, uint8 portOffset, uint8 patch_mode)
  113. {
  114. int32 ret = RT_ERR_OK;
  115. int32 chk_ret = RT_ERR_OK;
  116. uint32 i = 0;
  117. uint8 patch_type = 0;
  118. rt_phy_patch_db_t *pPatchDb = NULL;
  119. rtk_hwpatch_seq_t *table = NULL;
  120. PHYPATCH_DB_GET(unit, port, pPatchDb);
  121. if ((pPatchDb == NULL) || (pPatchDb->fPatch_op == NULL) || (pPatchDb->fPatch_flow == NULL))
  122. {
  123. RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u phy_patch, db is NULL\n", unit, port);
  124. return RT_ERR_DRIVER_NOT_SUPPORTED;
  125. }
  126. if (patch_mode == PHY_PATCH_MODE_CMP)
  127. {
  128. table = pPatchDb->cmp_table;
  129. }
  130. else
  131. {
  132. table = pPatchDb->seq_table;
  133. }
  134. RT_LOG(LOG_INFO, (MOD_HAL | MOD_PHY), "phy_patch: U%u P%u portOffset:%u patch_mode:%u\n", unit, port, portOffset, patch_mode);
  135. for (i = 0; i < RTK_PATCH_SEQ_MAX; i++)
  136. {
  137. patch_type = table[i].patch_type;
  138. RT_LOG(LOG_INFO, (MOD_HAL | MOD_PHY), "phy_patch: table[%u] patch_type:%u\n", i, patch_type);
  139. if (RTK_PATCH_TYPE_IS_DATA(patch_type))
  140. {
  141. ret = _phy_patch_process(unit, port, portOffset, table[i].patch.data.conf, table[i].patch.data.size, patch_mode);
  142. if (ret == RT_ERR_CHECK_FAILED)
  143. chk_ret = ret;
  144. else if (ret != RT_ERR_OK)
  145. {
  146. RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u patch_mode:%u id:%u patch-%u failed. ret:0x%X\n", unit, port, patch_mode, i, patch_type, ret);
  147. return ret;
  148. }
  149. }
  150. else if (RTK_PATCH_TYPE_IS_FLOW(patch_type))
  151. {
  152. RT_ERR_CHK_EHDL(pPatchDb->fPatch_flow(unit, port, portOffset, table[i].patch.flow_id, patch_mode),
  153. ret, RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u patch_mode:%u id:%u patch-%u failed. ret:0x%X\n", unit, port, patch_mode, i, patch_type, ret););
  154. }
  155. else
  156. {
  157. break;
  158. }
  159. }
  160. ret = _phy_patch_process(unit, port, portOffset, rtl826XB_patch_rtk_conf, sizeof(rtl826XB_patch_rtk_conf), patch_mode);
  161. if (ret == RT_ERR_CHECK_FAILED)
  162. chk_ret = ret;
  163. else if (ret != RT_ERR_OK)
  164. {
  165. RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u patch_mode:%u id:%u patch-%u failed. ret:0x%X\n", unit, port, patch_mode, i, patch_type, ret);
  166. return ret;
  167. }
  168. return (chk_ret == RT_ERR_CHECK_FAILED) ? chk_ret : RT_ERR_OK;
  169. }