mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-25 00:11:13 +00:00
mediatek: add support for Realtek RTL8261n 10G PHYs
There is no upstream driver yet. Merge the RTL SDK driver for now. Signed-off-by: John Crispin <john@phrozen.org>
This commit is contained in:
parent
7c8bfc0be5
commit
0f6aafcc24
@ -0,0 +1,5 @@
|
||||
|
||||
config RTL8261N_PHY
|
||||
tristate "Driver for Realtek RTL8261N PHYs"
|
||||
help
|
||||
Currently supports the RTL8261N,RTL8264B PHYs.
|
@ -0,0 +1,11 @@
|
||||
|
||||
obj-$(CONFIG_RTL8261N_PHY) += rtl8621n.o
|
||||
|
||||
rtl8621n-objs += phy_patch.o
|
||||
rtl8621n-objs += phy_rtl826xb_patch.o
|
||||
rtl8621n-objs += rtk_osal.o
|
||||
rtl8621n-objs += rtk_phy.o
|
||||
rtl8621n-objs += rtk_phylib.o
|
||||
rtl8621n-objs += rtk_phylib_rtl826xb.o
|
||||
|
||||
ccflags-y += -Werror -DRTK_PHYDRV_IN_LINUX
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
165
target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/error.h
Normal file
165
target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/error.h
Normal file
@ -0,0 +1,165 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: GPL-2.0-only
|
||||
*
|
||||
* Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __COMMON_ERROR_H__
|
||||
#define __COMMON_ERROR_H__
|
||||
|
||||
/*
|
||||
* Include Files
|
||||
*/
|
||||
#if defined(RTK_PHYDRV_IN_LINUX)
|
||||
#include "type.h"
|
||||
#else
|
||||
#include <common/type.h>
|
||||
#endif
|
||||
/*
|
||||
* Data Type Declaration
|
||||
*/
|
||||
typedef enum rt_error_common_e
|
||||
{
|
||||
RT_ERR_FAILED = -1, /* General Error */
|
||||
|
||||
/* 0x0000xxxx for common error code */
|
||||
RT_ERR_OK = 0, /* 0x00000000, OK */
|
||||
RT_ERR_INPUT = 0xF001, /* 0x0000F001, invalid input parameter */
|
||||
RT_ERR_UNIT_ID, /* 0x0000F002, invalid unit id */
|
||||
RT_ERR_PORT_ID, /* 0x0000F003, invalid port id */
|
||||
RT_ERR_PORT_MASK, /* 0x0000F004, invalid port mask */
|
||||
RT_ERR_PORT_LINKDOWN, /* 0x0000F005, link down port status */
|
||||
RT_ERR_ENTRY_INDEX, /* 0x0000F006, invalid entry index */
|
||||
RT_ERR_NULL_POINTER, /* 0x0000F007, input parameter is null pointer */
|
||||
RT_ERR_QUEUE_ID, /* 0x0000F008, invalid queue id */
|
||||
RT_ERR_QUEUE_NUM, /* 0x0000F009, invalid queue number */
|
||||
RT_ERR_BUSYWAIT_TIMEOUT, /* 0x0000F00a, busy watting time out */
|
||||
RT_ERR_MAC, /* 0x0000F00b, invalid mac address */
|
||||
RT_ERR_OUT_OF_RANGE, /* 0x0000F00c, input parameter out of range */
|
||||
RT_ERR_CHIP_NOT_SUPPORTED, /* 0x0000F00d, functions not supported by this chip model */
|
||||
RT_ERR_SMI, /* 0x0000F00e, SMI error */
|
||||
RT_ERR_NOT_INIT, /* 0x0000F00f, The module is not initial */
|
||||
RT_ERR_CHIP_NOT_FOUND, /* 0x0000F010, The chip can not found */
|
||||
RT_ERR_NOT_ALLOWED, /* 0x0000F011, actions not allowed by the function */
|
||||
RT_ERR_DRIVER_NOT_FOUND, /* 0x0000F012, The driver can not found */
|
||||
RT_ERR_SEM_LOCK_FAILED, /* 0x0000F013, Failed to lock semaphore */
|
||||
RT_ERR_SEM_UNLOCK_FAILED, /* 0x0000F014, Failed to unlock semaphore */
|
||||
RT_ERR_THREAD_EXIST, /* 0x0000F015, Thread exist */
|
||||
RT_ERR_THREAD_CREATE_FAILED, /* 0x0000F016, Thread create fail */
|
||||
RT_ERR_FWD_ACTION, /* 0x0000F017, Invalid forwarding Action */
|
||||
RT_ERR_IPV4_ADDRESS, /* 0x0000F018, Invalid IPv4 address */
|
||||
RT_ERR_IPV6_ADDRESS, /* 0x0000F019, Invalid IPv6 address */
|
||||
RT_ERR_PRIORITY, /* 0x0000F01a, Invalid Priority value */
|
||||
RT_ERR_FID, /* 0x0000F01b, invalid fid */
|
||||
RT_ERR_ENTRY_NOTFOUND, /* 0x0000F01c, specified entry not found */
|
||||
RT_ERR_DROP_PRECEDENCE, /* 0x0000F01d, invalid drop precedence */
|
||||
RT_ERR_NOT_FINISH, /* 0x0000F01e, Action not finish, still need to wait */
|
||||
RT_ERR_TIMEOUT, /* 0x0000F01f, Time out */
|
||||
RT_ERR_REG_ARRAY_INDEX_1, /* 0x0000F020, invalid index 1 of register array */
|
||||
RT_ERR_REG_ARRAY_INDEX_2, /* 0x0000F021, invalid index 2 of register array */
|
||||
RT_ERR_ETHER_TYPE, /* 0x0000F022, invalid ether type */
|
||||
RT_ERR_MBUF_PKT_NOT_AVAILABLE, /* 0x0000F023, mbuf->packet is not available */
|
||||
RT_ERR_QOS_INVLD_RSN, /* 0x0000F024, invalid pkt to CPU reason */
|
||||
RT_ERR_CB_FUNCTION_EXIST, /* 0x0000F025, Callback function exist */
|
||||
RT_ERR_CB_FUNCTION_FULL, /* 0x0000F026, Callback function number is full */
|
||||
RT_ERR_CB_FUNCTION_NOT_FOUND, /* 0x0000F027, Callback function can not found */
|
||||
RT_ERR_TBL_FULL, /* 0x0000F028, The table is full */
|
||||
RT_ERR_TRUNK_ID, /* 0x0000F029, invalid trunk id */
|
||||
RT_ERR_TYPE, /* 0x0000F02a, invalid type */
|
||||
RT_ERR_ENTRY_EXIST, /* 0x0000F02b, entry exists */
|
||||
RT_ERR_CHIP_UNDEFINED_VALUE, /* 0x0000F02c, chip returned an undefined value */
|
||||
RT_ERR_EXCEEDS_CAPACITY, /* 0x0000F02d, exceeds the capacity of hardware */
|
||||
RT_ERR_ENTRY_REFERRED, /* 0x0000F02e, entry is still being referred */
|
||||
RT_ERR_OPER_DENIED, /* 0x0000F02f, operation denied */
|
||||
RT_ERR_PORT_NOT_SUPPORTED, /* 0x0000F030, functions not supported by this port */
|
||||
RT_ERR_SOCKET, /* 0x0000F031, socket error */
|
||||
RT_ERR_MEM_ALLOC, /* 0x0000F032, insufficient memory resource */
|
||||
RT_ERR_ABORT, /* 0x0000F033, operation aborted */
|
||||
RT_ERR_DEV_ID, /* 0x0000F034, invalid device id */
|
||||
RT_ERR_DRIVER_NOT_SUPPORTED, /* 0x0000F035, functions not supported by this driver */
|
||||
RT_ERR_NOT_SUPPORTED, /* 0x0000F036, functions not supported */
|
||||
RT_ERR_SER, /* 0x0000F037, ECC or parity error */
|
||||
RT_ERR_MEM_NOT_ALIGN, /* 0x0000F038, memory address is not aligned */
|
||||
RT_ERR_SEM_FAKELOCK_OK, /* 0x0000F039, attach thread lock a semaphore which was already locked */
|
||||
RT_ERR_CHECK_FAILED, /* 0x0000F03a, check result is failed */
|
||||
|
||||
RT_ERR_COMMON_END = 0xFFFF /* The symbol is the latest symbol of common error */
|
||||
} rt_error_common_t;
|
||||
|
||||
/*
|
||||
* Macro Definition
|
||||
*/
|
||||
#define RT_PARAM_CHK(expr, errCode)\
|
||||
do {\
|
||||
if ((int32)(expr)) {\
|
||||
return errCode; \
|
||||
}\
|
||||
} while (0)
|
||||
|
||||
#define RT_PARAM_CHK_EHDL(expr, errCode, err_hdl)\
|
||||
do {\
|
||||
if ((int32)(expr)) {\
|
||||
{err_hdl}\
|
||||
return errCode; \
|
||||
}\
|
||||
} while (0)
|
||||
|
||||
#define RT_INIT_CHK(state)\
|
||||
do {\
|
||||
if (INIT_COMPLETED != (state)) {\
|
||||
return RT_ERR_NOT_INIT;\
|
||||
}\
|
||||
} while (0)
|
||||
|
||||
#define RT_INIT_REENTRY_CHK(state)\
|
||||
do {\
|
||||
if (INIT_COMPLETED == (state)) {\
|
||||
osal_printf(" %s had already been initialized!\n", __FUNCTION__);\
|
||||
return RT_ERR_OK;\
|
||||
}\
|
||||
} while (0)
|
||||
|
||||
#define RT_INIT_REENTRY_CHK_NO_WARNING(state)\
|
||||
do {\
|
||||
if (INIT_COMPLETED == (state)) {\
|
||||
return RT_ERR_OK;\
|
||||
}\
|
||||
} while (0)
|
||||
|
||||
#define RT_ERR_CHK(op, ret)\
|
||||
do {\
|
||||
if ((ret = (op)) != RT_ERR_OK)\
|
||||
return ret;\
|
||||
} while(0)
|
||||
|
||||
#define RT_ERR_HDL(op, errHandle, ret)\
|
||||
do {\
|
||||
if ((ret = (op)) != RT_ERR_OK)\
|
||||
goto errHandle;\
|
||||
} while(0)
|
||||
|
||||
#define RT_ERR_CHK_EHDL(op, ret, err_hdl)\
|
||||
do {\
|
||||
if ((ret = (op)) != RT_ERR_OK)\
|
||||
{\
|
||||
{err_hdl}\
|
||||
return ret;\
|
||||
}\
|
||||
} while(0)
|
||||
|
||||
#define RT_NULL_HDL(pointer, err_label)\
|
||||
do {\
|
||||
if (NULL == (pointer)) {\
|
||||
goto err_label;\
|
||||
}\
|
||||
} while (0)
|
||||
|
||||
#define RT_ERR_VOID_CHK(op, ret)\
|
||||
do {\
|
||||
if ((ret = (op)) != RT_ERR_OK) {\
|
||||
osal_printf("Fail in %s %d, ret %x!\n", __FUNCTION__, __LINE__, ret);\
|
||||
return ;}\
|
||||
} while(0)
|
||||
|
||||
#endif /* __COMMON_ERROR_H__ */
|
||||
|
@ -0,0 +1,179 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
||||
return (chk_ret == RT_ERR_CHECK_FAILED) ? chk_ret : RT_ERR_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,174 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: GPL-2.0-only
|
||||
*
|
||||
* Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __HAL_PHY_PATCH_H__
|
||||
#define __HAL_PHY_PATCH_H__
|
||||
|
||||
/*
|
||||
* Include Files
|
||||
*/
|
||||
#if defined(RTK_PHYDRV_IN_LINUX)
|
||||
#include "rtk_phylib_def.h"
|
||||
#else
|
||||
#include <common/rt_type.h>
|
||||
#include <common/rt_autoconf.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Symbol Definition
|
||||
*/
|
||||
#define PHYPATCH_PHYCTRL_IN_HALCTRL 0 /* 3.6.x: 1 ,4.0.x: 1, 4.1.x+: 0 */
|
||||
#define PHYPATCH_FMAILY_IN_HWP 0 /* 3.6.x: 1 ,4.0.x: 0, 4.1.x+: 0 */
|
||||
#define PHY_PATCH_MODE_BCAST_DEFAULT PHY_PATCH_MODE_BCAST /* 3.6.x: PHY_PATCH_MODE_BCAST_BUS ,4.0.x+: PHY_PATCH_MODE_BCAST */
|
||||
|
||||
#define PHY_PATCH_MODE_NORMAL 0
|
||||
#define PHY_PATCH_MODE_CMP 1
|
||||
#define PHY_PATCH_MODE_BCAST 2
|
||||
#define PHY_PATCH_MODE_BCAST_BUS 3
|
||||
|
||||
#define RTK_PATCH_CMP_W 0 /* write */
|
||||
#define RTK_PATCH_CMP_WC 1 /* compare */
|
||||
#define RTK_PATCH_CMP_SWC 2 /* sram compare */
|
||||
#define RTK_PATCH_CMP_WS 3 /* skip */
|
||||
|
||||
#define RTK_PATCH_OP_SECTION_SIZE 50
|
||||
#define RTK_PATCH_OP_TO_CMP(_op, _cmp) (_op + (RTK_PATCH_OP_SECTION_SIZE * _cmp))
|
||||
/* 0~49 normal op */
|
||||
#define RTK_PATCH_OP_PHY 0
|
||||
#define RTK_PATCH_OP_PHYOCP 1
|
||||
#define RTK_PATCH_OP_TOP 2
|
||||
#define RTK_PATCH_OP_TOPOCP 3
|
||||
#define RTK_PATCH_OP_PSDS0 4
|
||||
#define RTK_PATCH_OP_PSDS1 5
|
||||
#define RTK_PATCH_OP_MSDS 6
|
||||
#define RTK_PATCH_OP_MAC 7
|
||||
|
||||
/* 50~99 normal op for compare */
|
||||
#define RTK_PATCH_OP_CMP_PHY RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_PHY , RTK_PATCH_CMP_WC)
|
||||
#define RTK_PATCH_OP_CMP_PHYOCP RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_PHYOCP , RTK_PATCH_CMP_WC)
|
||||
#define RTK_PATCH_OP_CMP_TOP RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_TOP , RTK_PATCH_CMP_WC)
|
||||
#define RTK_PATCH_OP_CMP_TOPOCP RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_TOPOCP , RTK_PATCH_CMP_WC)
|
||||
#define RTK_PATCH_OP_CMP_PSDS0 RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_PSDS0 , RTK_PATCH_CMP_WC)
|
||||
#define RTK_PATCH_OP_CMP_PSDS1 RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_PSDS1 , RTK_PATCH_CMP_WC)
|
||||
#define RTK_PATCH_OP_CMP_MSDS RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_MSDS , RTK_PATCH_CMP_WC)
|
||||
#define RTK_PATCH_OP_CMP_MAC RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_MAC , RTK_PATCH_CMP_WC)
|
||||
|
||||
/* 100~149 normal op for sram compare */
|
||||
#define RTK_PATCH_OP_CMP_SRAM_PHY RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_PHY , RTK_PATCH_CMP_SWC)
|
||||
#define RTK_PATCH_OP_CMP_SRAM_PHYOCP RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_PHYOCP , RTK_PATCH_CMP_SWC)
|
||||
#define RTK_PATCH_OP_CMP_SRAM_TOP RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_TOP , RTK_PATCH_CMP_SWC)
|
||||
#define RTK_PATCH_OP_CMP_SRAM_TOPOCP RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_TOPOCP , RTK_PATCH_CMP_SWC)
|
||||
#define RTK_PATCH_OP_CMP_SRAM_PSDS0 RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_PSDS0 , RTK_PATCH_CMP_SWC)
|
||||
#define RTK_PATCH_OP_CMP_SRAM_PSDS1 RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_PSDS1 , RTK_PATCH_CMP_SWC)
|
||||
#define RTK_PATCH_OP_CMP_SRAM_MSDS RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_MSDS , RTK_PATCH_CMP_SWC)
|
||||
#define RTK_PATCH_OP_CMP_SRAM_MAC RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_MAC , RTK_PATCH_CMP_SWC)
|
||||
|
||||
/* 200~255 control op */
|
||||
#define RTK_PATCH_OP_DELAY_MS 200
|
||||
#define RTK_PATCH_OP_SKIP 255
|
||||
|
||||
|
||||
/*
|
||||
patch type PHY_PATCH_TYPE_NONE => empty
|
||||
patch type: PHY_PATCH_TYPE_TOP ~ (PHY_PATCH_TYPE_END-1) => data array
|
||||
patch type: PHY_PATCH_TYPE_END ~ (PHY_PATCH_TYPE_END + RTK_PATCH_TYPE_FLOW_MAX) => flow
|
||||
*/
|
||||
#define RTK_PATCH_TYPE_IS_DATA(_patch_type) (_patch_type > PHY_PATCH_TYPE_NONE && _patch_type < PHY_PATCH_TYPE_END)
|
||||
#define RTK_PATCH_TYPE_IS_FLOW(_patch_type) (_patch_type >= PHY_PATCH_TYPE_END && _patch_type <= (PHY_PATCH_TYPE_END + RTK_PATCH_TYPE_FLOWID_MAX))
|
||||
|
||||
|
||||
/*
|
||||
* Macro Definition
|
||||
*/
|
||||
#if PHYPATCH_PHYCTRL_IN_HALCTRL
|
||||
#define PHYPATCH_DB_GET(_unit, _port, _pPatchDb) \
|
||||
do {\
|
||||
hal_control_t *pHalCtrl = NULL;\
|
||||
if ((pHalCtrl = hal_ctrlInfo_get(_unit)) == NULL)\
|
||||
return RT_ERR_FAILED;\
|
||||
_pPatchDb = (pHalCtrl->pPhy_ctrl[_port]->pPhy_patchDb);\
|
||||
} while(0)
|
||||
#else
|
||||
#if defined(RTK_PHYDRV_IN_LINUX)
|
||||
#else
|
||||
#include <hal/phy/phydef.h>
|
||||
#include <hal/phy/phy_probe.h>
|
||||
#endif
|
||||
#define PHYPATCH_DB_GET(_unit, _port, _pPatchDb) \
|
||||
do {\
|
||||
rt_phyctrl_t *pPhyCtrl = NULL;\
|
||||
if ((pPhyCtrl = phy_phyctrl_get(_unit, _port)) == NULL)\
|
||||
return RT_ERR_FAILED;\
|
||||
_pPatchDb = (pPhyCtrl->pPhy_patchDb);\
|
||||
} while(0)
|
||||
#endif
|
||||
|
||||
#if PHYPATCH_FMAILY_IN_HWP
|
||||
#define PHYPATCH_IS_RTKSDS(_unit) (HWP_9300_FAMILY_ID(_unit) || HWP_9310_FAMILY_ID(_unit))
|
||||
#else
|
||||
#define PHYPATCH_IS_RTKSDS(_unit) (RTK_9300_FAMILY_ID(_unit) || RTK_9310_FAMILY_ID(_unit) || RTK_9311B_FAMILY_ID(_unit) || RTK_9330_FAMILY_ID(_unit))
|
||||
#endif
|
||||
|
||||
#define PHYPATCH_TABLE_ASSIGN(_pPatchDb, _table, _idx, _patch_type, _para) \
|
||||
do {\
|
||||
if (RTK_PATCH_TYPE_IS_DATA(_patch_type)) {\
|
||||
_pPatchDb->_table[_idx].patch_type = _patch_type;\
|
||||
_pPatchDb->_table[_idx].patch.data.conf = _para;\
|
||||
_pPatchDb->_table[_idx].patch.data.size = sizeof(_para);\
|
||||
}\
|
||||
else if (RTK_PATCH_TYPE_IS_FLOW(_patch_type)) {\
|
||||
_pPatchDb->_table[_idx].patch_type = _patch_type;\
|
||||
_pPatchDb->_table[_idx].patch.flow_id = _patch_type;\
|
||||
}\
|
||||
else {\
|
||||
_pPatchDb->_table[_idx].patch_type = PHY_PATCH_TYPE_NONE;\
|
||||
}\
|
||||
} while(0)
|
||||
#define PHYPATCH_SEQ_TABLE_ASSIGN(_pPatchDb, _idx, _patch_type, _para) PHYPATCH_TABLE_ASSIGN(_pPatchDb, seq_table, _idx, _patch_type, _para)
|
||||
#define PHYPATCH_CMP_TABLE_ASSIGN(_pPatchDb, _idx, _patch_type, _para) PHYPATCH_TABLE_ASSIGN(_pPatchDb, cmp_table, _idx, _patch_type, _para)
|
||||
|
||||
#define PHYPATCH_COMPARE(_mmdpage, _reg, _msb, _lsb, _exp, _real, _mask) \
|
||||
do {\
|
||||
uint32 _rData = REG32_FIELD_GET(_real, _lsb, _mask);\
|
||||
if (_exp != _rData) {\
|
||||
osal_printf("PATCH CHECK: %u(0x%X).%u(0x%X)[%u:%u] = 0x%X (!= 0x%X)\n", _mmdpage, _mmdpage, _reg, _reg, _msb, _lsb, _rData, _exp);\
|
||||
return RT_ERR_CHECK_FAILED;\
|
||||
}\
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Function Declaration
|
||||
*/
|
||||
|
||||
extern uint8 phy_patch_op_translate(uint8 patch_mode, uint8 patch_op, uint8 compare_op);
|
||||
extern 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);
|
||||
|
||||
|
||||
/* 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
|
||||
*/
|
||||
extern int32 phy_patch(uint32 unit, rtk_port_t port, uint8 portOffset, uint8 patch_mode);
|
||||
|
||||
|
||||
|
||||
#endif /* __HAL_PHY_PATCH_H__ */
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: GPL-2.0-only
|
||||
*
|
||||
* Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __HAL_PHY_PHY_RTL826XB_PATCH_H__
|
||||
#define __HAL_PHY_PHY_RTL826XB_PATCH_H__
|
||||
|
||||
/*
|
||||
* Include Files
|
||||
*/
|
||||
#if defined(RTK_PHYDRV_IN_LINUX)
|
||||
#include "rtk_osal.h"
|
||||
#include "rtk_phylib_def.h"
|
||||
#else
|
||||
#include <common/rt_type.h>
|
||||
#include <rtk/port.h>
|
||||
#endif
|
||||
|
||||
/* Function Name:
|
||||
* phy_rtl826xb_patch
|
||||
* Description:
|
||||
* apply patch data to PHY
|
||||
* Input:
|
||||
* unit - unit id
|
||||
* baseport - base port id on the PHY chip
|
||||
* portOffset - the index offset base on baseport for the port to patch
|
||||
* Output:
|
||||
* None
|
||||
* Return:
|
||||
* RT_ERR_OK
|
||||
* RT_ERR_FAILED
|
||||
* RT_ERR_NOT_SUPPORTED
|
||||
* RT_ERR_ABORT
|
||||
* Note:
|
||||
* None
|
||||
*/
|
||||
extern int32 phy_rtl826xb_patch(uint32 unit, rtk_port_t baseport, uint8 portOffset);
|
||||
|
||||
/* Function Name:
|
||||
* phy_rtl826xb_broadcast_patch
|
||||
* Description:
|
||||
* apply patch data to PHY
|
||||
* Input:
|
||||
* unit - unit id
|
||||
* baseport - base port id on the PHY chip
|
||||
* portOffset - the index offset base on baseport for the port to patch
|
||||
* perChip - 1 for per-chip mode, 0 for per-bus mode
|
||||
* Output:
|
||||
* None
|
||||
* Return:
|
||||
* RT_ERR_OK
|
||||
* RT_ERR_FAILED
|
||||
* RT_ERR_NOT_SUPPORTED
|
||||
* RT_ERR_ABORT
|
||||
* Note:
|
||||
* None
|
||||
*/
|
||||
extern int32 phy_rtl826xb_broadcast_patch(uint32 unit, rtk_port_t port, uint8 portOffset, uint8 perChip);
|
||||
|
||||
extern int32 phy_rtl826xb_patch_db_init(uint32 unit, rtk_port_t port, rt_phy_patch_db_t **pPhy_patchDb);
|
||||
#endif /* __HAL_PHY_PHY_RTL826XB_PATCH_H__ */
|
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: GPL-2.0-only
|
||||
*
|
||||
* Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "type.h"
|
||||
#include "error.h"
|
||||
#include "rtk_phylib_def.h"
|
||||
|
||||
#include <linux/version.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/sched/signal.h>
|
||||
#include <linux/phy.h>
|
||||
|
||||
int32
|
||||
osal_time_usecs_get(osal_usecs_t *pUsec)
|
||||
{
|
||||
struct timespec64 ts;
|
||||
|
||||
RT_PARAM_CHK((NULL == pUsec), RT_ERR_NULL_POINTER);
|
||||
|
||||
ktime_get_ts64(&ts);
|
||||
*pUsec = (osal_usecs_t)((ts.tv_sec * USEC_PER_SEC) + (ts.tv_nsec / NSEC_PER_USEC));
|
||||
return RT_ERR_OK;
|
||||
}
|
||||
|
||||
void *
|
||||
osal_alloc(uint32 size)
|
||||
{
|
||||
void *p;
|
||||
p = kmalloc((size_t)size, GFP_ATOMIC);
|
||||
return p;
|
||||
}
|
||||
|
||||
int32
|
||||
phy_common_general_reg_mmd_get(uint32 unit, rtk_port_t port, uint32 mmdAddr, uint32 mmdReg, uint32 *pData)
|
||||
{
|
||||
int32 rData = 0;
|
||||
rData = phy_read_mmd(port, mmdAddr, mmdReg);
|
||||
if (rData < 0)
|
||||
return RT_ERR_FAILED;
|
||||
*pData = (uint32)rData;
|
||||
return RT_ERR_OK;
|
||||
}
|
||||
|
||||
int32
|
||||
phy_common_general_reg_mmd_set(uint32 unit, rtk_port_t port, uint32 mmdAddr, uint32 mmdReg, uint32 data)
|
||||
{
|
||||
int ret = phy_write_mmd(port, mmdAddr, mmdReg, data);
|
||||
return (ret < 0) ? RT_ERR_FAILED : RT_ERR_OK;
|
||||
}
|
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: GPL-2.0-only
|
||||
*
|
||||
* Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __RTK_PHY_OSAL_H
|
||||
#define __RTK_PHY_OSAL_H
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/phy.h>
|
||||
#include "type.h"
|
||||
#include "error.h"
|
||||
#include "phy_patch.h"
|
||||
#include "rtk_phylib.h"
|
||||
|
||||
#ifdef PHYPATCH_DB_GET
|
||||
#undef PHYPATCH_DB_GET
|
||||
#endif
|
||||
|
||||
#define PHYPATCH_DB_GET(_unit, _pPhy_device, _pPatchDb) \
|
||||
do { \
|
||||
struct rtk_phy_priv *_pPriv = (_pPhy_device)->priv; \
|
||||
rt_phy_patch_db_t *_pDb = _pPriv->patch; _pPatchDb = _pDb; \
|
||||
/*printk("[PHYPATCH_DB_GET] ? [%s]\n", (_pDb != NULL) ? "E":"N");*/ \
|
||||
} while(0)
|
||||
|
||||
#define HWP_9300_FAMILY_ID(_unit) 0
|
||||
#define HWP_9310_FAMILY_ID(_unit) 0
|
||||
#define RTK_9300_FAMILY_ID(_unit) 0
|
||||
#define RTK_9310_FAMILY_ID(_unit) 0
|
||||
#define RTK_9311B_FAMILY_ID(_unit) 0
|
||||
#define RTK_9330_FAMILY_ID(_unit) 0
|
||||
|
||||
#ifndef WAIT_COMPLETE_VAR
|
||||
#define WAIT_COMPLETE_VAR() \
|
||||
osal_usecs_t _t, _now, _t_wait=0, _timeout; \
|
||||
int32 _chkCnt=0;
|
||||
|
||||
#define WAIT_COMPLETE(_timeout_us) \
|
||||
_timeout = _timeout_us; \
|
||||
for(osal_time_usecs_get(&_t),osal_time_usecs_get(&_now),_t_wait=0,_chkCnt=0 ; \
|
||||
(_t_wait <= _timeout); \
|
||||
osal_time_usecs_get(&_now), _chkCnt++, _t_wait += ((_now >= _t) ? (_now - _t) : (0xFFFFFFFF - _t + _now)),_t = _now \
|
||||
)
|
||||
|
||||
#define WAIT_COMPLETE_IS_TIMEOUT() (_t_wait > _timeout)
|
||||
#endif
|
||||
|
||||
/* OSAL */
|
||||
#include <linux/slab.h>
|
||||
int32 osal_time_usecs_get(osal_usecs_t *pUsec);
|
||||
void *osal_alloc(uint32 size);
|
||||
#define osal_time_mdelay mdelay
|
||||
|
||||
#include <linux/ctype.h> /* for Kernel Space */
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/string.h>
|
||||
#define osal_strlen strlen
|
||||
#define osal_strcmp strcmp
|
||||
#define osal_strcpy strcpy
|
||||
#define osal_strncpy strncpy
|
||||
#define osal_strcat strcat
|
||||
#define osal_strchr strchr
|
||||
#define osal_memset memset
|
||||
#define osal_memcpy memcpy
|
||||
#define osal_memcmp memcmp
|
||||
#define osal_strdup strdup
|
||||
#define osal_strncmp strncmp
|
||||
#define osal_strstr strstr
|
||||
#define osal_strtok strtok
|
||||
#define osal_strtok_r strtok_r
|
||||
#define osal_toupper toupper
|
||||
|
||||
#define osal_printf printk
|
||||
|
||||
/* HWP */
|
||||
#define HWP_PORT_SMI(unit, port) 0
|
||||
#define HWP_PHY_MODEL_BY_PORT(unit, port) 0
|
||||
#define HWP_PHY_ADDR(unit, port) 0
|
||||
#define HWP_PHY_BASE_MACID(unit, p) 0
|
||||
#define HWP_PORT_TRAVS_EXCEPT_CPU(unit, p) if (bcast_phyad < 0x1F && p != NULL)
|
||||
|
||||
|
||||
/* RT_LOG */
|
||||
//#define RT_LOG(level, module, fmt, args...) do { printk("RT_LOG:"fmt, ## args); } while(0)
|
||||
#define RT_LOG(level, module, fmt, args...) do {} while(0)
|
||||
#define RT_ERR(error_code, module, fmt, args...) do {} while(0)
|
||||
#define RT_INIT_ERR(error_code, module, fmt, args...) do {} while(0)
|
||||
#define RT_INIT_MSG(fmt, args...) do {} while(0)
|
||||
|
||||
#define phy_826xb_ctrl_set(unit, p, RTK_PHY_CTRL_MIIM_BCAST_PHYAD, bcast_phyad) 0
|
||||
|
||||
/* reg access */
|
||||
int32 phy_common_general_reg_mmd_get(uint32 unit, rtk_port_t port, uint32 mmdAddr, uint32 mmdReg, uint32 *pData);
|
||||
int32 phy_common_general_reg_mmd_set(uint32 unit, rtk_port_t port, uint32 mmdAddr, uint32 mmdReg, uint32 data);
|
||||
|
||||
|
||||
#endif /* __RTK_PHY_OSAL_H */
|
@ -0,0 +1,282 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: GPL-2.0-only
|
||||
*
|
||||
* Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/phy.h>
|
||||
|
||||
#include "phy_rtl826xb_patch.h"
|
||||
#include "rtk_phylib_rtl826xb.h"
|
||||
#include "rtk_phylib.h"
|
||||
|
||||
#define REALTEK_PHY_ID_RTL8261N 0x001CCAF3
|
||||
#define REALTEK_PHY_ID_RTL8264B 0x001CC813
|
||||
|
||||
static int rtl826xb_get_features(struct phy_device *phydev)
|
||||
{
|
||||
int ret;
|
||||
ret = genphy_c45_pma_read_abilities(phydev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
linkmode_or(phydev->supported, phydev->supported, PHY_BASIC_FEATURES);
|
||||
|
||||
|
||||
linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
|
||||
phydev->supported);
|
||||
linkmode_set_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
|
||||
phydev->supported);
|
||||
|
||||
/* not support 10M modes */
|
||||
linkmode_clear_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT,
|
||||
phydev->supported);
|
||||
linkmode_clear_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT,
|
||||
phydev->supported);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtl826xb_probe(struct phy_device *phydev)
|
||||
{
|
||||
struct rtk_phy_priv *priv = NULL;
|
||||
|
||||
priv = devm_kzalloc(&phydev->mdio.dev, sizeof(struct rtk_phy_priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(priv, 0, sizeof(struct rtk_phy_priv));
|
||||
|
||||
if (phy_rtl826xb_patch_db_init(0, phydev, &(priv->patch)) != RT_ERR_OK)
|
||||
return -ENOMEM;
|
||||
|
||||
priv->phytype = (phydev->drv->phy_id == REALTEK_PHY_ID_RTL8261N) ? (RTK_PHYLIB_RTL8261N) : (RTK_PHYLIB_RTL8264B);
|
||||
priv->isBasePort = (phydev->drv->phy_id == REALTEK_PHY_ID_RTL8261N) ? (1) : (((phydev->mdio.addr % 4) == 0) ? (1) : (0));
|
||||
phydev->priv = priv;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtkphy_config_init(struct phy_device *phydev)
|
||||
{
|
||||
int ret = 0;
|
||||
switch (phydev->drv->phy_id)
|
||||
{
|
||||
case REALTEK_PHY_ID_RTL8261N:
|
||||
case REALTEK_PHY_ID_RTL8264B:
|
||||
phydev_info(phydev, "%s:%u [RTL8261N/RTL826XB] phy_id: 0x%X PHYAD:%d\n", __FUNCTION__, __LINE__, phydev->drv->phy_id, phydev->mdio.addr);
|
||||
|
||||
|
||||
#if 1 /* toggle reset */
|
||||
phy_modify_mmd_changed(phydev, 30, 0x145, BIT(0) , 1);
|
||||
phy_modify_mmd_changed(phydev, 30, 0x145, BIT(0) , 0);
|
||||
mdelay(30);
|
||||
#endif
|
||||
|
||||
ret = phy_patch(0, phydev, 0, PHY_PATCH_MODE_NORMAL);
|
||||
if (ret)
|
||||
{
|
||||
phydev_err(phydev, "%s:%u [RTL8261N/RTL826XB] patch failed!! 0x%X\n", __FUNCTION__, __LINE__, ret);
|
||||
return ret;
|
||||
}
|
||||
#if 0 /* Debug: patch check */
|
||||
ret = phy_patch(0, phydev, 0, PHY_PATCH_MODE_CMP);
|
||||
if (ret)
|
||||
{
|
||||
phydev_err(phydev, "%s:%u [RTL8261N/RTL826XB] phy_patch failed!! 0x%X\n", __FUNCTION__, __LINE__, ret);
|
||||
return ret;
|
||||
}
|
||||
printk("[%s,%u] patch chk %s\n", __FUNCTION__, __LINE__, (ret == 0) ? "PASS" : "FAIL");
|
||||
#endif
|
||||
#if 0 /* Debug: USXGMII*/
|
||||
{
|
||||
uint32 data = 0;
|
||||
rtk_phylib_826xb_sds_read(phydev, 0x07, 0x10, 15, 0, &data);
|
||||
printk("[%s,%u] SDS 0x07, 0x10 : 0x%X\n", __FUNCTION__, __LINE__, data);
|
||||
rtk_phylib_826xb_sds_read(phydev, 0x06, 0x12, 15, 0, &data);
|
||||
printk("[%s,%u] SDS 0x06, 0x12 : 0x%X\n", __FUNCTION__, __LINE__, data);
|
||||
}
|
||||
{
|
||||
u16 sdspage = 0x5, sdsreg = 0x0;
|
||||
u16 regData = (sdspage & 0x3f) | ((sdsreg & 0x1f) << 6) | BIT(15);
|
||||
u16 readData = 0;
|
||||
phy_write_mmd(phydev, 30, 323, regData);
|
||||
do
|
||||
{
|
||||
udelay(10);
|
||||
readData = phy_read_mmd(phydev, 30, 323);
|
||||
} while ((readData & BIT(15)) != 0);
|
||||
readData = phy_read_mmd(phydev, 30, 322);
|
||||
printk("[%s,%d] sds link [%s] (0x%X)\n", __FUNCTION__, __LINE__, (readData & BIT(12)) ? "UP" : "DOWN", readData);
|
||||
}
|
||||
#endif
|
||||
|
||||
break;
|
||||
default:
|
||||
phydev_err(phydev, "%s:%u Unknow phy_id: 0x%X\n", __FUNCTION__, __LINE__, phydev->drv->phy_id);
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rtkphy_c45_suspend(struct phy_device *phydev)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = rtk_phylib_c45_power_low(phydev);
|
||||
|
||||
phydev->speed = SPEED_UNKNOWN;
|
||||
phydev->duplex = DUPLEX_UNKNOWN;
|
||||
phydev->pause = 0;
|
||||
phydev->asym_pause = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rtkphy_c45_resume(struct phy_device *phydev)
|
||||
{
|
||||
return rtk_phylib_c45_power_normal(phydev);
|
||||
}
|
||||
|
||||
static int rtkphy_c45_config_aneg(struct phy_device *phydev)
|
||||
{
|
||||
bool changed = false;
|
||||
u16 reg = 0;
|
||||
int ret = 0;
|
||||
|
||||
phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
|
||||
if (phydev->autoneg == AUTONEG_DISABLE)
|
||||
return genphy_c45_pma_setup_forced(phydev);
|
||||
|
||||
ret = genphy_c45_an_config_aneg(phydev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (ret > 0)
|
||||
changed = true;
|
||||
|
||||
reg = 0;
|
||||
if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
|
||||
phydev->advertising))
|
||||
reg |= BIT(9);
|
||||
|
||||
if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
|
||||
phydev->advertising))
|
||||
reg |= BIT(8);
|
||||
|
||||
ret = phy_modify_mmd_changed(phydev, MDIO_MMD_VEND2, 0xA412,
|
||||
BIT(9) | BIT(8) , reg);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (ret > 0)
|
||||
changed = true;
|
||||
|
||||
return genphy_c45_check_and_restart_aneg(phydev, changed);
|
||||
}
|
||||
|
||||
static int rtkphy_c45_aneg_done(struct phy_device *phydev)
|
||||
{
|
||||
return genphy_c45_aneg_done(phydev);
|
||||
}
|
||||
|
||||
static int rtkphy_c45_read_status(struct phy_device *phydev)
|
||||
{
|
||||
int ret = 0, status = 0;
|
||||
phydev->speed = SPEED_UNKNOWN;
|
||||
phydev->duplex = DUPLEX_UNKNOWN;
|
||||
phydev->pause = 0;
|
||||
phydev->asym_pause = 0;
|
||||
|
||||
ret = genphy_c45_read_link(phydev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (phydev->autoneg == AUTONEG_ENABLE)
|
||||
{
|
||||
linkmode_clear_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
|
||||
phydev->lp_advertising);
|
||||
|
||||
ret = genphy_c45_read_lpa(phydev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
status = phy_read_mmd(phydev, 31, 0xA414);
|
||||
if (status < 0)
|
||||
return status;
|
||||
linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
|
||||
phydev->lp_advertising, status & BIT(11));
|
||||
|
||||
phy_resolve_aneg_linkmode(phydev);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = genphy_c45_read_pma(phydev);
|
||||
}
|
||||
|
||||
/* mdix*/
|
||||
status = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_10GBT_SWAPPOL);
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
||||
switch (status & 0x3)
|
||||
{
|
||||
case MDIO_PMA_10GBT_SWAPPOL_ABNX | MDIO_PMA_10GBT_SWAPPOL_CDNX:
|
||||
phydev->mdix = ETH_TP_MDI;
|
||||
break;
|
||||
|
||||
case 0:
|
||||
phydev->mdix = ETH_TP_MDI_X;
|
||||
break;
|
||||
|
||||
default:
|
||||
phydev->mdix = ETH_TP_MDI_INVALID;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static struct phy_driver rtk_phy_drivers[] = {
|
||||
{
|
||||
PHY_ID_MATCH_EXACT(REALTEK_PHY_ID_RTL8261N),
|
||||
.name = "Realtek RTL8261N",
|
||||
.get_features = rtl826xb_get_features,
|
||||
.config_init = rtkphy_config_init,
|
||||
.probe = rtl826xb_probe,
|
||||
.suspend = rtkphy_c45_suspend,
|
||||
.resume = rtkphy_c45_resume,
|
||||
.config_aneg = rtkphy_c45_config_aneg,
|
||||
.aneg_done = rtkphy_c45_aneg_done,
|
||||
.read_status = rtkphy_c45_read_status,
|
||||
},
|
||||
{
|
||||
PHY_ID_MATCH_EXACT(REALTEK_PHY_ID_RTL8264B),
|
||||
.name = "Realtek RTL8264B",
|
||||
.get_features = rtl826xb_get_features,
|
||||
.config_init = rtkphy_config_init,
|
||||
.probe = rtl826xb_probe,
|
||||
.suspend = rtkphy_c45_suspend,
|
||||
.resume = rtkphy_c45_resume,
|
||||
.config_aneg = rtkphy_c45_config_aneg,
|
||||
.aneg_done = rtkphy_c45_aneg_done,
|
||||
.read_status = rtkphy_c45_read_status,
|
||||
},
|
||||
};
|
||||
|
||||
module_phy_driver(rtk_phy_drivers);
|
||||
|
||||
|
||||
static struct mdio_device_id __maybe_unused rtk_phy_tbl[] = {
|
||||
{ PHY_ID_MATCH_EXACT(REALTEK_PHY_ID_RTL8261N) },
|
||||
{ PHY_ID_MATCH_EXACT(REALTEK_PHY_ID_RTL8264B) },
|
||||
{ },
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(mdio, rtk_phy_tbl);
|
||||
|
||||
MODULE_AUTHOR("Realtek");
|
||||
MODULE_DESCRIPTION("Realtek PHY drivers");
|
||||
MODULE_LICENSE("GPL");
|
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: GPL-2.0-only
|
||||
*
|
||||
* Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "rtk_phylib.h"
|
||||
#include <linux/phy.h>
|
||||
|
||||
|
||||
/* OSAL */
|
||||
|
||||
void rtk_phylib_mdelay(uint32 msec)
|
||||
{
|
||||
#if defined(RTK_PHYDRV_IN_LINUX)
|
||||
mdelay(msec);
|
||||
#else
|
||||
osal_time_mdelay(msec);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void rtk_phylib_udelay(uint32 usec)
|
||||
{
|
||||
#if defined(RTK_PHYDRV_IN_LINUX)
|
||||
if (1000 <= usec)
|
||||
{
|
||||
mdelay(usec/1000);
|
||||
usec = usec % 1000;
|
||||
}
|
||||
udelay(usec);
|
||||
#else
|
||||
osal_time_udelay(usec);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Register Access APIs */
|
||||
int32 rtk_phylib_mmd_write(rtk_phydev *phydev, uint32 mmd, uint32 reg, uint8 msb, uint8 lsb, uint32 data)
|
||||
{
|
||||
int32 ret = 0;
|
||||
uint32 mask = 0;
|
||||
mask = UINT32_BITS_MASK(msb,lsb);
|
||||
|
||||
#if defined(RTK_PHYDRV_IN_LINUX)
|
||||
ret = phy_modify_mmd(phydev, mmd, reg, mask, data);
|
||||
#else
|
||||
{
|
||||
uint32 rData = 0, wData = 0;
|
||||
if ((msb != 15) || (lsb != 0))
|
||||
{
|
||||
if ((ret = phy_common_general_reg_mmd_get(phydev->unit, phydev->port, page, reg, &rData)) != RT_ERR_OK)
|
||||
return ret;
|
||||
}
|
||||
wData = REG32_FIELD_SET(rData, data, lsb, mask);
|
||||
ret = phy_common_general_reg_mmd_set(phydev->unit, phydev->port, page, reg, wData);
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32 rtk_phylib_mmd_read(rtk_phydev *phydev, uint32 mmd, uint32 reg, uint8 msb, uint8 lsb, uint32 *pData)
|
||||
{
|
||||
int32 ret = 0;
|
||||
uint32 rData = 0;
|
||||
uint32 mask = 0;
|
||||
mask = UINT32_BITS_MASK(msb,lsb);
|
||||
|
||||
#if defined(RTK_PHYDRV_IN_LINUX)
|
||||
rData = phy_read_mmd(phydev, mmd, reg);
|
||||
#else
|
||||
{
|
||||
ret = phy_common_general_reg_mmd_get(phydev->unit, phydev->port, page, reg, &rData);
|
||||
}
|
||||
#endif
|
||||
|
||||
*pData = REG32_FIELD_GET(rData, lsb, mask);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Function Driver */
|
||||
|
||||
int32 rtk_phylib_c45_power_normal(rtk_phydev *phydev)
|
||||
{
|
||||
int32 ret = 0;
|
||||
RTK_PHYLIB_ERR_CHK(rtk_phylib_mmd_write(phydev, 1, 0, 11, 11, 0));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 rtk_phylib_c45_power_low(rtk_phydev *phydev)
|
||||
{
|
||||
int32 ret = 0;
|
||||
RTK_PHYLIB_ERR_CHK(rtk_phylib_mmd_write(phydev, 1, 0, 11, 11, 1));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 rtk_phylib_c45_pcs_loopback(rtk_phydev *phydev, uint32 enable)
|
||||
{
|
||||
int32 ret = 0;
|
||||
RTK_PHYLIB_ERR_CHK(rtk_phylib_mmd_write(phydev, 3, 0, 14, 14, (enable == 0) ? 0 : 1));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,101 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: GPL-2.0-only
|
||||
*
|
||||
* Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __RTK_PHYLIB_H
|
||||
#define __RTK_PHYLIB_H
|
||||
|
||||
#if defined(RTK_PHYDRV_IN_LINUX)
|
||||
#include "type.h"
|
||||
#include "rtk_phylib_def.h"
|
||||
#else
|
||||
//#include SDK headers
|
||||
#endif
|
||||
|
||||
#if defined(RTK_PHYDRV_IN_LINUX)
|
||||
#define PR_INFO(_fmt, _args...) pr_info(_fmt, ##_args)
|
||||
#define PR_DBG(_fmt, _args...) pr_debug(_fmt, ##_args)
|
||||
#define PR_ERR(_fmt, _args...) pr_err("ERROR: "_fmt, ##_args)
|
||||
|
||||
#define RTK_PHYLIB_ERR_FAILED (-EPERM)
|
||||
#define RTK_PHYLIB_ERR_INPUT (-EINVAL)
|
||||
#define RTK_PHYLIB_ERR_EXCEEDS_CAPACITY (-ENOSPC)
|
||||
#define RTK_PHYLIB_ERR_TIMEOUT (-ETIME)
|
||||
#define RTK_PHYLIB_ERR_ENTRY_NOTFOUND (-ENODATA)
|
||||
#else
|
||||
#define PR_INFO(_fmt, _args...) RT_LOG(LOG_INFO, (MOD_HAL|MOD_PHY), _fmt, ##_args)
|
||||
#define PR_DBG(_fmt, _args...) RT_LOG(LOG_DEBUG, (MOD_HAL|MOD_PHY), _fmt, ##_args)
|
||||
#define PR_ERR(_fmt, _args...) RT_LOG(LOG_MAJOR_ERR, (MOD_HAL|MOD_PHY), _fmt, ##_args)
|
||||
|
||||
#define RTK_PHYLIB_ERR_FAILED (RT_ERR_FAILED)
|
||||
#define RTK_PHYLIB_ERR_INPUT (RT_ERR_INPUT)
|
||||
#define RTK_PHYLIB_ERR_EXCEEDS_CAPACITY (RT_ERR_EXCEEDS_CAPACITY)
|
||||
#define RTK_PHYLIB_ERR_TIMEOUT (RT_ERR_BUSYWAIT_TIMEOUT)
|
||||
#define RTK_PHYLIB_ERR_ENTRY_NOTFOUND (RT_ERR_ENTRY_NOTFOUND)
|
||||
#endif
|
||||
|
||||
typedef enum rtk_phylib_phy_e
|
||||
{
|
||||
RTK_PHYLIB_NONE,
|
||||
RTK_PHYLIB_RTL8261N,
|
||||
RTK_PHYLIB_RTL8264B,
|
||||
RTK_PHYLIB_END
|
||||
} rtk_phylib_phy_t;
|
||||
|
||||
struct rtk_phy_priv {
|
||||
rtk_phylib_phy_t phytype;
|
||||
uint8 isBasePort;
|
||||
rt_phy_patch_db_t *patch;
|
||||
};
|
||||
|
||||
#if defined(RTK_PHYDRV_IN_LINUX)
|
||||
typedef struct phy_device rtk_phydev;
|
||||
#else
|
||||
struct rtk_phy_dev_s
|
||||
{
|
||||
uint32 unit;
|
||||
rtk_port_t port;
|
||||
|
||||
struct rtk_phy_priv *priv;
|
||||
};
|
||||
typedef struct rtk_phy_dev_s rtk_phydev;
|
||||
#endif
|
||||
|
||||
#define RTK_PHYLIB_ERR_CHK(op)\
|
||||
do {\
|
||||
if ((ret = (op)) != 0)\
|
||||
return ret;\
|
||||
} while(0)
|
||||
|
||||
#define RTK_PHYLIB_VAL_TO_BYTE_ARRAY(_val, _valbytes, _array, _start, _bytes)\
|
||||
do{\
|
||||
uint32 _i = 0;\
|
||||
for (_i = 0; _i < _bytes; _i++)\
|
||||
_array[_start+_i] = (_val >> (8* (_valbytes - _i - 1)));\
|
||||
}while(0)
|
||||
|
||||
#define RTK_PHYLIB_BYTE_ARRAY_TO_VAL(_val, _array, _start, _bytes)\
|
||||
do{\
|
||||
uint32 _i = 0;\
|
||||
for (_i = 0; _i < _bytes; _i++)\
|
||||
_val = (_val << 8) | _array[_start + _i];\
|
||||
}while(0)
|
||||
|
||||
|
||||
/* OSAL */
|
||||
void rtk_phylib_mdelay(uint32 msec);
|
||||
void rtk_phylib_udelay(uint32 usec);
|
||||
|
||||
/* Register Access APIs */
|
||||
int32 rtk_phylib_mmd_write(rtk_phydev *phydev, uint32 mmd, uint32 reg, uint8 msb, uint8 lsb, uint32 data);
|
||||
int32 rtk_phylib_mmd_read(rtk_phydev *phydev, uint32 mmd, uint32 reg, uint8 msb, uint8 lsb, uint32 *pData);
|
||||
|
||||
/* Function Driver */
|
||||
int32 rtk_phylib_c45_power_normal(rtk_phydev *phydev);
|
||||
int32 rtk_phylib_c45_power_low(rtk_phydev *phydev);
|
||||
int32 rtk_phylib_c45_pcs_loopback(rtk_phydev *phydev, uint32 enable);
|
||||
|
||||
|
||||
#endif /* __RTK_PHYLIB_H */
|
@ -0,0 +1,166 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: GPL-2.0-only
|
||||
*
|
||||
* Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved.
|
||||
*/
|
||||
#ifndef __RTK_PHYLIB_DEF_H
|
||||
#define __RTK_PHYLIB_DEF_H
|
||||
|
||||
#include "type.h"
|
||||
|
||||
//#define PHY_C22_MMD_PAGE 0
|
||||
#define PHY_C22_MMD_PAGE 0x0A41
|
||||
#define PHY_C22_MMD_DEV_REG 13
|
||||
#define PHY_C22_MMD_ADD_REG 14
|
||||
|
||||
/* MDIO Manageable Device(MDD) address*/
|
||||
#define PHY_MMD_PMAPMD 1
|
||||
#define PHY_MMD_PCS 3
|
||||
#define PHY_MMD_AN 7
|
||||
#define PHY_MMD_VEND1 30 /* Vendor specific 1 */
|
||||
#define PHY_MMD_VEND2 31 /* Vendor specific 2 */
|
||||
|
||||
#define BIT_0 0x00000001U
|
||||
#define BIT_1 0x00000002U
|
||||
#define BIT_2 0x00000004U
|
||||
#define BIT_3 0x00000008U
|
||||
#define BIT_4 0x00000010U
|
||||
#define BIT_5 0x00000020U
|
||||
#define BIT_6 0x00000040U
|
||||
#define BIT_7 0x00000080U
|
||||
#define BIT_8 0x00000100U
|
||||
#define BIT_9 0x00000200U
|
||||
#define BIT_10 0x00000400U
|
||||
#define BIT_11 0x00000800U
|
||||
#define BIT_12 0x00001000U
|
||||
#define BIT_13 0x00002000U
|
||||
#define BIT_14 0x00004000U
|
||||
#define BIT_15 0x00008000U
|
||||
#define BIT_16 0x00010000U
|
||||
#define BIT_17 0x00020000U
|
||||
#define BIT_18 0x00040000U
|
||||
#define BIT_19 0x00080000U
|
||||
#define BIT_20 0x00100000U
|
||||
#define BIT_21 0x00200000U
|
||||
#define BIT_22 0x00400000U
|
||||
#define BIT_23 0x00800000U
|
||||
#define BIT_24 0x01000000U
|
||||
#define BIT_25 0x02000000U
|
||||
#define BIT_26 0x04000000U
|
||||
#define BIT_27 0x08000000U
|
||||
#define BIT_28 0x10000000U
|
||||
#define BIT_29 0x20000000U
|
||||
#define BIT_30 0x40000000U
|
||||
#define BIT_31 0x80000000U
|
||||
|
||||
#define MASK_1_BITS (BIT_1 - 1)
|
||||
#define MASK_2_BITS (BIT_2 - 1)
|
||||
#define MASK_3_BITS (BIT_3 - 1)
|
||||
#define MASK_4_BITS (BIT_4 - 1)
|
||||
#define MASK_5_BITS (BIT_5 - 1)
|
||||
#define MASK_6_BITS (BIT_6 - 1)
|
||||
#define MASK_7_BITS (BIT_7 - 1)
|
||||
#define MASK_8_BITS (BIT_8 - 1)
|
||||
#define MASK_9_BITS (BIT_9 - 1)
|
||||
#define MASK_10_BITS (BIT_10 - 1)
|
||||
#define MASK_11_BITS (BIT_11 - 1)
|
||||
#define MASK_12_BITS (BIT_12 - 1)
|
||||
#define MASK_13_BITS (BIT_13 - 1)
|
||||
#define MASK_14_BITS (BIT_14 - 1)
|
||||
#define MASK_15_BITS (BIT_15 - 1)
|
||||
#define MASK_16_BITS (BIT_16 - 1)
|
||||
#define MASK_17_BITS (BIT_17 - 1)
|
||||
#define MASK_18_BITS (BIT_18 - 1)
|
||||
#define MASK_19_BITS (BIT_19 - 1)
|
||||
#define MASK_20_BITS (BIT_20 - 1)
|
||||
#define MASK_21_BITS (BIT_21 - 1)
|
||||
#define MASK_22_BITS (BIT_22 - 1)
|
||||
#define MASK_23_BITS (BIT_23 - 1)
|
||||
#define MASK_24_BITS (BIT_24 - 1)
|
||||
#define MASK_25_BITS (BIT_25 - 1)
|
||||
#define MASK_26_BITS (BIT_26 - 1)
|
||||
#define MASK_27_BITS (BIT_27 - 1)
|
||||
#define MASK_28_BITS (BIT_28 - 1)
|
||||
#define MASK_29_BITS (BIT_29 - 1)
|
||||
#define MASK_30_BITS (BIT_30 - 1)
|
||||
#define MASK_31_BITS (BIT_31 - 1)
|
||||
|
||||
#define REG32_FIELD_SET(_data, _val, _fOffset, _fMask) ((_data & ~(_fMask)) | ((_val << (_fOffset)) & (_fMask)))
|
||||
#define REG32_FIELD_GET(_data, _fOffset, _fMask) ((_data & (_fMask)) >> (_fOffset))
|
||||
#define UINT32_BITS_MASK(_mBit, _lBit) ((0xFFFFFFFF >> (31 - _mBit)) ^ ((1 << _lBit) - 1))
|
||||
|
||||
typedef struct phy_device * rtk_port_t;
|
||||
|
||||
#if 1 /* ss\sdk\include\hal\phy\phydef.h */
|
||||
/* unified patch format */
|
||||
typedef enum rtk_phypatch_type_e
|
||||
{
|
||||
PHY_PATCH_TYPE_NONE = 0,
|
||||
PHY_PATCH_TYPE_TOP = 1,
|
||||
PHY_PATCH_TYPE_SDS,
|
||||
PHY_PATCH_TYPE_AFE,
|
||||
PHY_PATCH_TYPE_UC,
|
||||
PHY_PATCH_TYPE_UC2,
|
||||
PHY_PATCH_TYPE_NCTL0,
|
||||
PHY_PATCH_TYPE_NCTL1,
|
||||
PHY_PATCH_TYPE_NCTL2,
|
||||
PHY_PATCH_TYPE_ALGXG,
|
||||
PHY_PATCH_TYPE_ALG1G,
|
||||
PHY_PATCH_TYPE_NORMAL,
|
||||
PHY_PATCH_TYPE_DATARAM,
|
||||
PHY_PATCH_TYPE_RTCT,
|
||||
PHY_PATCH_TYPE_END
|
||||
} rtk_phypatch_type_t;
|
||||
|
||||
#define RTK_PATCH_TYPE_FLOW(_id) (PHY_PATCH_TYPE_END + _id)
|
||||
#define RTK_PATCH_TYPE_FLOWID_MAX PHY_PATCH_TYPE_END
|
||||
#define RTK_PATCH_SEQ_MAX ( PHY_PATCH_TYPE_END + RTK_PATCH_TYPE_FLOWID_MAX -1)
|
||||
|
||||
typedef struct rtk_hwpatch_s
|
||||
{
|
||||
uint8 patch_op;
|
||||
uint8 portmask;
|
||||
uint16 pagemmd;
|
||||
uint16 addr;
|
||||
uint8 msb;
|
||||
uint8 lsb;
|
||||
uint16 data;
|
||||
uint8 compare_op;
|
||||
uint16 sram_p;
|
||||
uint16 sram_rr;
|
||||
uint16 sram_rw;
|
||||
uint16 sram_a;
|
||||
} rtk_hwpatch_t;
|
||||
|
||||
typedef struct rtk_hwpatch_data_s
|
||||
{
|
||||
rtk_hwpatch_t *conf;
|
||||
uint32 size;
|
||||
} rtk_hwpatch_data_t;
|
||||
|
||||
typedef struct rtk_hwpatch_seq_s
|
||||
{
|
||||
uint8 patch_type;
|
||||
union
|
||||
{
|
||||
rtk_hwpatch_data_t data;
|
||||
uint8 flow_id;
|
||||
} patch;
|
||||
} rtk_hwpatch_seq_t;
|
||||
|
||||
typedef struct rt_phy_patch_db_s
|
||||
{
|
||||
/* patch operation */
|
||||
int32 (*fPatch_op)(uint32 unit, rtk_port_t port, uint8 portOffset, rtk_hwpatch_t *pPatch_data, uint8 patch_mode);
|
||||
int32 (*fPatch_flow)(uint32 unit, rtk_port_t port, uint8 portOffset, uint8 patch_flow, uint8 patch_mode);
|
||||
|
||||
/* patch data */
|
||||
rtk_hwpatch_seq_t seq_table[RTK_PATCH_SEQ_MAX];
|
||||
rtk_hwpatch_seq_t cmp_table[RTK_PATCH_SEQ_MAX];
|
||||
|
||||
} rt_phy_patch_db_t;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif /* __RTK_PHYLIB_DEF_H */
|
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: GPL-2.0-only
|
||||
*
|
||||
* Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "rtk_phylib_rtl826xb.h"
|
||||
|
||||
/* Indirect Register Access APIs */
|
||||
int rtk_phylib_826xb_sds_read(rtk_phydev *phydev, uint32 page, uint32 reg, uint8 msb, uint8 lsb, uint32 *pData)
|
||||
{
|
||||
int32 ret = 0;
|
||||
uint32 rData = 0;
|
||||
uint32 op = (page & 0x3f) | ((reg & 0x1f) << 6) | (0x8000);
|
||||
uint32 i = 0;
|
||||
uint32 mask = 0;
|
||||
mask = UINT32_BITS_MASK(msb,lsb);
|
||||
|
||||
RTK_PHYLIB_ERR_CHK(rtk_phylib_mmd_write(phydev, 30, 323, 15, 0, op));
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
RTK_PHYLIB_ERR_CHK(rtk_phylib_mmd_read(phydev, 30, 323, 15, 15, &rData));
|
||||
if (rData == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
rtk_phylib_udelay(10);
|
||||
}
|
||||
if (i == 10)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
RTK_PHYLIB_ERR_CHK(rtk_phylib_mmd_read(phydev, 30, 322, 15, 0, &rData));
|
||||
*pData = REG32_FIELD_GET(rData, lsb, mask);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int rtk_phylib_826xb_sds_write(rtk_phydev *phydev, uint32 page, uint32 reg, uint8 msb, uint8 lsb, uint32 data)
|
||||
{
|
||||
int32 ret = 0;
|
||||
uint32 wData = 0, rData = 0;
|
||||
uint32 op = (page & 0x3f) | ((reg & 0x1f) << 6) | (0x8800);
|
||||
uint32 mask = 0;
|
||||
mask = UINT32_BITS_MASK(msb,lsb);
|
||||
|
||||
RTK_PHYLIB_ERR_CHK(rtk_phylib_826xb_sds_read(phydev, page, reg, 15, 0, &rData));
|
||||
|
||||
wData = REG32_FIELD_SET(rData, data, lsb, mask);
|
||||
|
||||
RTK_PHYLIB_ERR_CHK(rtk_phylib_mmd_write(phydev, 30, 321, 15, 0, wData));
|
||||
RTK_PHYLIB_ERR_CHK(rtk_phylib_mmd_write(phydev, 30, 323, 15, 0, op));
|
||||
|
||||
return ret;
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: GPL-2.0-only
|
||||
*
|
||||
* Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __RTK_PHYLIB_RTL826XB_H
|
||||
#define __RTK_PHYLIB_RTL826XB_H
|
||||
|
||||
#if defined(RTK_PHYDRV_IN_LINUX)
|
||||
#include "rtk_phylib.h"
|
||||
#else
|
||||
//#include SDK headers
|
||||
#endif
|
||||
|
||||
int rtk_phylib_826xb_sds_read(rtk_phydev *phydev, uint32 page, uint32 reg, uint8 msb, uint8 lsb, uint32 *pData);
|
||||
int rtk_phylib_826xb_sds_write(rtk_phydev *phydev, uint32 page, uint32 reg, uint8 msb, uint8 lsb, uint32 data);
|
||||
|
||||
#endif /* __RTK_PHYLIB_RTL826XB_H */
|
117
target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/type.h
Normal file
117
target/linux/mediatek/files-6.6/drivers/net/phy/rtl8261n/type.h
Normal file
@ -0,0 +1,117 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: GPL-2.0-only
|
||||
*
|
||||
* Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __COMMON_TYPE_H__
|
||||
#define __COMMON_TYPE_H__
|
||||
|
||||
/*
|
||||
* Symbol Definition
|
||||
*/
|
||||
|
||||
#define USING_RTSTK_PKT_AS_RAIL
|
||||
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#ifndef ETHER_ADDR_LEN
|
||||
#define ETHER_ADDR_LEN 6
|
||||
#endif
|
||||
|
||||
#ifndef IP6_ADDR_LEN
|
||||
#define IP6_ADDR_LEN 16
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Data Type Declaration
|
||||
*/
|
||||
#ifndef uint64
|
||||
typedef unsigned long long uint64;
|
||||
#endif
|
||||
|
||||
#ifndef int64
|
||||
typedef signed long long int64;
|
||||
#endif
|
||||
|
||||
#ifndef uint32
|
||||
typedef unsigned int uint32;
|
||||
#endif
|
||||
|
||||
#ifndef int32
|
||||
typedef signed int int32;
|
||||
#endif
|
||||
|
||||
#ifndef uint16
|
||||
typedef unsigned short uint16;
|
||||
#endif
|
||||
|
||||
#ifndef int16
|
||||
typedef signed short int16;
|
||||
#endif
|
||||
|
||||
#ifndef uint8
|
||||
typedef unsigned char uint8;
|
||||
#endif
|
||||
|
||||
#ifndef int8
|
||||
typedef signed char int8;
|
||||
#endif
|
||||
|
||||
//#define CONFIG_SDK_WORDSIZE_64 /* not ready */
|
||||
#ifdef CONFIG_SDK_WORDSIZE_64
|
||||
typedef long int intptr;
|
||||
typedef unsigned long int uintptr;
|
||||
#else
|
||||
typedef int intptr;
|
||||
typedef unsigned int uintptr;
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef ipaddr_t
|
||||
typedef uint32 ipaddr_t; /* ipv4 address type */
|
||||
#endif
|
||||
|
||||
/* configuration mode type */
|
||||
typedef enum rtk_enable_e
|
||||
{
|
||||
DISABLED = 0,
|
||||
ENABLED,
|
||||
RTK_ENABLE_END
|
||||
} rtk_enable_t;
|
||||
|
||||
/* initial state of module */
|
||||
typedef enum init_state_e
|
||||
{
|
||||
INIT_NOT_COMPLETED = 0,
|
||||
INIT_COMPLETED,
|
||||
INIT_STATE_END
|
||||
} init_state_t;
|
||||
|
||||
/* ethernet address type */
|
||||
typedef struct rtk_mac_s
|
||||
{
|
||||
uint8 octet[ETHER_ADDR_LEN];
|
||||
} rtk_mac_t;
|
||||
|
||||
typedef uint32 osal_time_t;
|
||||
typedef uint32 osal_usecs_t;
|
||||
|
||||
/*
|
||||
* Macro Definition
|
||||
*/
|
||||
|
||||
#endif /* __COMMON_TYPE_H__ */
|
||||
|
@ -428,6 +428,7 @@ CONFIG_RPS=y
|
||||
CONFIG_RTC_CLASS=y
|
||||
CONFIG_RTC_DRV_MT7622=y
|
||||
CONFIG_RTC_I2C_AND_SPI=y
|
||||
CONFIG_RTL8261N_PHY=y
|
||||
# CONFIG_RTL8367S_GSW is not set
|
||||
CONFIG_RWSEM_SPIN_ON_OWNER=y
|
||||
CONFIG_SCHED_MC=y
|
||||
|
@ -424,6 +424,7 @@ CONFIG_RPS=y
|
||||
CONFIG_RTC_CLASS=y
|
||||
CONFIG_RTC_DRV_MT7622=y
|
||||
CONFIG_RTC_I2C_AND_SPI=y
|
||||
# CONFIG_RTL8261N_PHY is not set
|
||||
CONFIG_RTL8367S_GSW=y
|
||||
CONFIG_RWSEM_SPIN_ON_OWNER=y
|
||||
CONFIG_SCHED_MC=y
|
||||
|
@ -541,6 +541,7 @@ CONFIG_RTC_CLASS=y
|
||||
# CONFIG_RTC_DRV_MT7622 is not set
|
||||
CONFIG_RTC_I2C_AND_SPI=y
|
||||
CONFIG_RTC_MC146818_LIB=y
|
||||
# CONFIG_RTL8261N_PHY is not set
|
||||
# CONFIG_RTL8367S_GSW is not set
|
||||
CONFIG_RWSEM_SPIN_ON_OWNER=y
|
||||
# CONFIG_SERIAL_8250_DMA is not set
|
||||
|
@ -301,6 +301,7 @@ CONFIG_REGMAP_MMIO=y
|
||||
CONFIG_RESET_CONTROLLER=y
|
||||
CONFIG_RFS_ACCEL=y
|
||||
CONFIG_RPS=y
|
||||
# CONFIG_RTL8261N_PHY is not set
|
||||
# CONFIG_RTL8367S_GSW is not set
|
||||
CONFIG_RWSEM_SPIN_ON_OWNER=y
|
||||
CONFIG_SCSI=y
|
||||
|
@ -0,0 +1,21 @@
|
||||
--- a/drivers/net/phy/Kconfig
|
||||
+++ b/drivers/net/phy/Kconfig
|
||||
@@ -334,6 +334,8 @@ config REALTEK_PHY
|
||||
help
|
||||
Supports the Realtek 821x PHY.
|
||||
|
||||
+source "drivers/net/phy/rtl8261n/Kconfig"
|
||||
+
|
||||
config RENESAS_PHY
|
||||
tristate "Renesas PHYs"
|
||||
help
|
||||
--- a/drivers/net/phy/Makefile
|
||||
+++ b/drivers/net/phy/Makefile
|
||||
@@ -85,6 +85,7 @@ obj-$(CONFIG_ADIN_PHY) += adin.o
|
||||
obj-y += qcom/
|
||||
obj-$(CONFIG_QSEMI_PHY) += qsemi.o
|
||||
obj-$(CONFIG_REALTEK_PHY) += realtek.o
|
||||
+obj-y += rtl8261n/
|
||||
obj-$(CONFIG_RENESAS_PHY) += uPD60620.o
|
||||
obj-$(CONFIG_ROCKCHIP_PHY) += rockchip.o
|
||||
obj-$(CONFIG_SMSC_PHY) += smsc.o
|
Loading…
Reference in New Issue
Block a user