| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 |
- /*
- * SPDX-License-Identifier: GPL-2.0-only
- *
- * Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved.
- */
- /*
- * Include Files
- */
- #if defined(RTK_PHYDRV_IN_LINUX)
- #include "rtk_osal.h"
- #else
- #include <common/rt_type.h>
- #include <common/rt_error.h>
- #include <common/debug/rt_log.h>
- #include <hal/common/halctrl.h>
- #include <hal/phy/phy_patch.h>
- #endif
- /*
- * Function Declaration
- */
- uint8 phy_patch_op_translate(uint8 patch_mode, uint8 patch_op, uint8 compare_op)
- {
- if (patch_mode != PHY_PATCH_MODE_CMP)
- {
- return patch_op;
- }
- else
- {
- switch (compare_op)
- {
- case RTK_PATCH_CMP_WS:
- return RTK_PATCH_OP_SKIP;
- case RTK_PATCH_CMP_W:
- case RTK_PATCH_CMP_WC:
- case RTK_PATCH_CMP_SWC:
- default:
- return RTK_PATCH_OP_TO_CMP(patch_op, compare_op);
- }
- }
- }
- 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)
- {
- rtk_hwpatch_t op;
- op.patch_op = patch_op;
- op.portmask = portmask;
- op.pagemmd = pagemmd;
- op.addr = addr;
- op.msb = msb;
- op.lsb = lsb;
- op.data = data;
- op.compare_op = RTK_PATCH_CMP_W;
- return pPhy_patchDb->fPatch_op(unit, port, portOffset, &op, patch_mode);
- }
- static int32 _phy_patch_process(uint32 unit, rtk_port_t port, uint8 portOffset, rtk_hwpatch_t *pPatch, int32 size, uint8 patch_mode)
- {
- int32 i = 0;
- int32 ret = 0;
- int32 chk_ret = RT_ERR_OK;
- int32 n;
- rtk_hwpatch_t *patch = pPatch;
- rt_phy_patch_db_t *pPatchDb = NULL;
- PHYPATCH_DB_GET(unit, port, pPatchDb);
- if (size <= 0)
- {
- return RT_ERR_OK;
- }
- n = size / sizeof(rtk_hwpatch_t);
- for (i = 0; i < n; i++)
- {
- ret = pPatchDb->fPatch_op(unit, port, portOffset, &patch[i], patch_mode);
- if ((ret != RT_ERR_ABORT) && (ret != RT_ERR_OK))
- {
- if ((ret == RT_ERR_CHECK_FAILED) && (patch_mode == PHY_PATCH_MODE_CMP))
- {
- osal_printf("PATCH CHECK: Failed entry:%u|%u|0x%X|0x%X|%u|%u|0x%X\n",
- i + 1, patch[i].patch_op, patch[i].pagemmd, patch[i].addr, patch[i].msb, patch[i].lsb, patch[i].data);
- chk_ret = RT_ERR_CHECK_FAILED;
- continue;
- }
- else
- {
- 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__,
- i+1, patch[i].patch_op, patch[i].pagemmd, patch[i].addr, patch[i].data, ret);
- return ret;
- }
- }
- }
- return (chk_ret == RT_ERR_CHECK_FAILED) ? chk_ret : RT_ERR_OK;
- }
- rtk_hwpatch_t rtl826XB_patch_rtk_conf[] = {
- {RTK_PATCH_OP_PSDS0 , 0xff , 0x07 , 0x10 , 15, 0, 0x80aa, RTK_PATCH_CMP_WC , 0, 0, 0, 0},
- {RTK_PATCH_OP_PSDS0 , 0xff , 0x06 , 0x12 , 15, 0, 0x5078, RTK_PATCH_CMP_WC , 0, 0, 0, 0},
- };
- /* Function Name:
- * phy_patch
- * Description:
- * apply initial patch data to PHY
- * Input:
- * unit - unit id
- * port - port id
- * portOffset - the index offset of port based the base port in the PHY chip
- * Output:
- * None
- * Return:
- * RT_ERR_OK
- * RT_ERR_FAILED
- * RT_ERR_CHECK_FAILED
- * RT_ERR_NOT_SUPPORTED
- * Note:
- * None
- */
- int32 phy_patch(uint32 unit, rtk_port_t port, uint8 portOffset, uint8 patch_mode)
- {
- int32 ret = RT_ERR_OK;
- int32 chk_ret = RT_ERR_OK;
- uint32 i = 0;
- uint8 patch_type = 0;
- rt_phy_patch_db_t *pPatchDb = NULL;
- rtk_hwpatch_seq_t *table = NULL;
- PHYPATCH_DB_GET(unit, port, pPatchDb);
- if ((pPatchDb == NULL) || (pPatchDb->fPatch_op == NULL) || (pPatchDb->fPatch_flow == NULL))
- {
- RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u phy_patch, db is NULL\n", unit, port);
- return RT_ERR_DRIVER_NOT_SUPPORTED;
- }
- if (patch_mode == PHY_PATCH_MODE_CMP)
- {
- table = pPatchDb->cmp_table;
- }
- else
- {
- table = pPatchDb->seq_table;
- }
- 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);
- for (i = 0; i < RTK_PATCH_SEQ_MAX; i++)
- {
- patch_type = table[i].patch_type;
- RT_LOG(LOG_INFO, (MOD_HAL | MOD_PHY), "phy_patch: table[%u] patch_type:%u\n", i, patch_type);
- if (RTK_PATCH_TYPE_IS_DATA(patch_type))
- {
- ret = _phy_patch_process(unit, port, portOffset, table[i].patch.data.conf, table[i].patch.data.size, patch_mode);
- if (ret == RT_ERR_CHECK_FAILED)
- chk_ret = ret;
- else if (ret != RT_ERR_OK)
- {
- 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);
- return ret;
- }
- }
- else if (RTK_PATCH_TYPE_IS_FLOW(patch_type))
- {
- RT_ERR_CHK_EHDL(pPatchDb->fPatch_flow(unit, port, portOffset, table[i].patch.flow_id, patch_mode),
- 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););
- }
- else
- {
- break;
- }
- }
- ret = _phy_patch_process(unit, port, portOffset, rtl826XB_patch_rtk_conf, sizeof(rtl826XB_patch_rtk_conf), patch_mode);
- if (ret == RT_ERR_CHECK_FAILED)
- chk_ret = ret;
- else if (ret != RT_ERR_OK)
- {
- 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);
- return ret;
- }
- return (chk_ret == RT_ERR_CHECK_FAILED) ? chk_ret : RT_ERR_OK;
- }
|