mirror of
https://github.com/VIKINGYFY/immortalwrt.git
synced 2025-12-16 17:15:26 +00:00
The RTL930x mdio functions are scattered around the code. Relocate
them to the bus (still inside the ethernet driver). With this change
the phy identification looks into the proper registers. The SerDes
phy identifier (register 2/3) must be changed.
Additionally provide a consistent SerDes register access through the
mdio bus. Until now when a SerDes directly drives a SFP module there
is no clear rule of how to handle its register set that consists of
two parts:
- c22 phy registers 0-15 live in the fiber page (2) of the SerDes
- other SerDes specific registers exist in pages before and after
The mdio bus and other SerDes functions are a wild mix of directly
looking into page 2 or just using self defined methods to access
data.
Adapt the bus to the new consistent phy interface that mixes the
SerDes register set like classic Realtek phys do it.
- Use register 31 as page select (already in the bus)
- Always keep the common registers 0-15 in place and read fiber page
- Map the SerDes internal registers into the upper vendor specific
registers 16-23 according to the page select register (31).
That gives a register mapping as follows:
+-----------------------+-----------------------+---------------+-------------+
| reg 0x00-0x0f | reg 0x10-0x17 | reg 0x18-0x1e | reg 0x1f |
+-----------------------+-----------------------+---------------+-------------+
| SerDes fiber page (3) | real SerDes registers | zero | SerDes page |
| registers 0 - 15 | in packages of 8 | | select reg |
+-----------------------+-----------------------+---------------+-------------+
Example to make it as clear as possible.
SerDes registers on a RTL930x show
Page / Reg | 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B ...
-------------+----------------------------------------------------------------
0 - SDS | 0C03 0F00 7060 7106 074D 0EBF 0F0F 0359 5248 0000 0F80 0000 ...
1 - SDS_EXT | 0000 0000 85FA 8C6D 5CCC 0000 20D8 0003 79AA 8C64 00C3 1482 ...
2 - FIB | 1140 6189 001C CA40 01A0 0000 0000 0004 0000 0000 0000 0000 ...
3 - FIB_EXT | 1140 6109 001C CA40 01A0 0000 0000 0004 0000 0000 0000 0000 ...
This translates to this phy layout
| SerDes fiber registers normal SerDes registers zero p.sel
Page / Reg | 0x00 0x01 0x02 0x03 ... 0x10 0x11 0x12 0x13 ... 0x18 ... 0x1f
-------------+---------------------------------------------------------------
0 | 1140 6189 001C CA40 ... 0C03 0F00 7060 7106 ... 0000 ... 0000
1 | 1140 6189 001C CA40 ... 5248 0000 0F80 0000 ... 0000 ... 0001
...
4 | 1140 6189 001C CA40 ... 0000 0000 85FA 8C6D ... 0000 ... 0004
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/19692
Signed-off-by: Robert Marko <robimarko@gmail.com>
91 lines
3.1 KiB
C
91 lines
3.1 KiB
C
// SPDX-License-Identifier: GPL-2.0-only
|
|
|
|
struct rtl83xx_shared_private {
|
|
char *name;
|
|
};
|
|
|
|
struct __attribute__ ((__packed__)) part {
|
|
uint16_t start;
|
|
uint8_t wordsize;
|
|
uint8_t words;
|
|
};
|
|
|
|
struct __attribute__ ((__packed__)) fw_header {
|
|
uint32_t magic;
|
|
uint32_t phy;
|
|
uint32_t checksum;
|
|
uint32_t version;
|
|
struct part parts[10];
|
|
};
|
|
|
|
/* TODO: fixed path? */
|
|
#define FIRMWARE_838X_8380_1 "rtl838x_phy/rtl838x_8380.fw"
|
|
#define FIRMWARE_838X_8214FC_1 "rtl838x_phy/rtl838x_8214fc.fw"
|
|
#define FIRMWARE_838X_8218b_1 "rtl838x_phy/rtl838x_8218b.fw"
|
|
|
|
#define PHY_ID_RTL8214C 0x001cc942
|
|
#define PHY_ID_RTL8218B_E 0x001cc980
|
|
#define PHY_ID_RTL8214_OR_8218 0x001cc981
|
|
#define PHY_ID_RTL8218D 0x001cc983
|
|
#define PHY_ID_RTL8218B_I 0x001cca40
|
|
#define PHY_ID_RTL8221B 0x001cc849
|
|
#define PHY_ID_RTL8226 0x001cc838
|
|
#define PHY_ID_RTL8390_GENERIC 0x001ccab0
|
|
#define PHY_ID_RTL8393_I 0x001c8393
|
|
#define PHY_ID_RTL9300_I 0x338002a0
|
|
|
|
/* These PHYs share the same id (0x001cc981) */
|
|
#define PHY_IS_NOT_RTL821X 0
|
|
#define PHY_IS_RTL8214FC 1
|
|
#define PHY_IS_RTL8214FB 2
|
|
#define PHY_IS_RTL8218B_E 3
|
|
|
|
/* Registers of the internal Serdes of the 8380 */
|
|
#define RTL838X_SDS_MODE_SEL (0x0028)
|
|
#define RTL838X_SDS_CFG_REG (0x0034)
|
|
#define RTL838X_INT_MODE_CTRL (0x005c)
|
|
#define RTL838X_DMY_REG31 (0x3b28)
|
|
|
|
#define RTL8380_SDS4_FIB_REG0 (0xF800)
|
|
#define RTL838X_SDS4_REG28 (0xef80)
|
|
#define RTL838X_SDS4_DUMMY0 (0xef8c)
|
|
#define RTL838X_SDS5_EXT_REG6 (0xf18c)
|
|
#define RTL838X_SDS4_FIB_REG0 (RTL838X_SDS4_REG28 + 0x880)
|
|
#define RTL838X_SDS5_FIB_REG0 (RTL838X_SDS4_REG28 + 0x980)
|
|
|
|
/* Registers of the internal SerDes of the RTL8390 */
|
|
#define RTL839X_SDS12_13_XSG0 (0xB800)
|
|
|
|
/* Registers of the internal Serdes of the 9300 */
|
|
#define RTL930X_MAC_FORCE_MODE_CTRL (0xCA1C)
|
|
|
|
/* Registers of the internal SerDes of the 9310 */
|
|
#define RTL931X_SERDES_INDRT_ACCESS_CTRL (0x5638)
|
|
#define RTL931X_SERDES_INDRT_DATA_CTRL (0x563C)
|
|
#define RTL931X_SERDES_MODE_CTRL (0x13cc)
|
|
#define RTL931X_PS_SERDES_OFF_MODE_CTRL_ADDR (0x13F4)
|
|
#define RTL931X_MAC_SERDES_MODE_CTRL(sds) (0x136C + (((sds) << 2)))
|
|
|
|
int rtl9300_serdes_setup(int port, int sds_num, phy_interface_t phy_mode);
|
|
|
|
int rtl931x_read_sds_phy(int phy_addr, int page, int phy_reg);
|
|
int rtl931x_write_sds_phy(int phy_addr, int page, int phy_reg, u16 v);
|
|
int rtl931x_sds_cmu_band_get(int sds, phy_interface_t mode);
|
|
void rtl931x_sds_init(u32 sds, phy_interface_t mode);
|
|
|
|
/*
|
|
* TODO: The following functions are currently not in use. So compiler will complain if
|
|
* they are static and not made available externally. Collect them in this section to
|
|
* preserve for future use.
|
|
*/
|
|
|
|
void rtl9300_do_rx_calibration_3(int sds_num, phy_interface_t phy_mode);
|
|
int rtl9300_sds_clock_wait(int timeout);
|
|
int rtl9300_sds_cmu_band_get(int sds);
|
|
void rtl9300_sds_rxcal_dcvs_get(u32 sds_num, u32 dcvs_id, u32 dcvs_list[]);
|
|
void rtl9300_sds_rxcal_dcvs_manual(u32 sds_num, u32 dcvs_id, bool manual, u32 dvcs_list[]);
|
|
void rtl9300_sds_set(int sds_num, u32 mode);
|
|
|
|
int rtl931x_link_sts_get(u32 sds);
|
|
void rtl931x_sds_fiber_disable(u32 sds);
|
|
int rtl931x_sds_cmu_band_set(int sds, bool enable, u32 band, phy_interface_t mode); |