diff options
author | Zhao Qiang | 2013-09-04 10:11:27 +0800 |
---|---|---|
committer | York Sun | 2013-10-16 16:13:11 -0700 |
commit | ffee1dde3c4cb2721c56c78e0360affec1c23d3f (patch) | |
tree | fc87c859def7c217c5caca59a4a9ac3f0eae69bc /drivers/net | |
parent | d56898249c09f8264fc398dd209c293116a293c9 (diff) |
SGMII:fix PHY addresses for QSGMII Riser Card working in SGMII mode
Fix PHY addresses for QSGMII Riser Card working in
SGMII mode on board P3041/P5020/P4080/P5040/B4860.
QSGMII Riser Card can work in SGMII mode, but
having the different PHY addresses.
So the following steps should be done:
1. Confirm whether QSGMII Riser Card is used.
2. If yes, set the proper PHY address.
Generally, the function is_qsgmii_riser_card() is
for step 1, and set_sgmii_phy() for step 2.
However, there are still some special situations,
take P5040 and B4860 as examples, the PHY addresses
need to be changed when serdes protocol is changed,
so it is necessary to confirm the protocol before
setting PHY addresses.
Signed-off-by: Zhao Qiang <B45475@freescale.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/fm/fm.h | 1 | ||||
-rw-r--r-- | drivers/net/fm/init.c | 44 |
2 files changed, 45 insertions, 0 deletions
diff --git a/drivers/net/fm/fm.h b/drivers/net/fm/fm.h index 38fdbcdc421..5f197a98295 100644 --- a/drivers/net/fm/fm.h +++ b/drivers/net/fm/fm.h @@ -21,6 +21,7 @@ #define TX_PORT_1G_BASE 0x28 #define MAX_NUM_TX_PORT_1G CONFIG_SYS_NUM_FM1_DTSEC #define TX_PORT_10G_BASE 0x30 +#define MIIM_TIMEOUT 0xFFFF struct fm_muram { u32 base; diff --git a/drivers/net/fm/init.c b/drivers/net/fm/init.c index 14fa2ce59cf..2d13145f143 100644 --- a/drivers/net/fm/init.c +++ b/drivers/net/fm/init.c @@ -274,3 +274,47 @@ void fdt_fixup_fman_ethernet(void *blob) } #endif } + +/*QSGMII Riser Card can work in SGMII mode, but the PHY address is different. + *This function scans which Riser Card being used(QSGMII or SGMII Riser Card), + *then set the correct PHY address + */ +void set_sgmii_phy(struct mii_dev *bus, enum fm_port base_port, + unsigned int port_num, int phy_base_addr) +{ + unsigned int regnum = 0; + int qsgmii; + int i; + int phy_real_addr; + + qsgmii = is_qsgmii_riser_card(bus, phy_base_addr, port_num, regnum); + + if (!qsgmii) + return; + + for (i = base_port; i < base_port + port_num; i++) { + if (fm_info_get_enet_if(i) == PHY_INTERFACE_MODE_SGMII) { + phy_real_addr = phy_base_addr + i - base_port; + fm_info_set_phy_address(i, phy_real_addr); + } + } +} + +/*to check whether qsgmii riser card is used*/ +int is_qsgmii_riser_card(struct mii_dev *bus, int phy_base_addr, + unsigned int port_num, unsigned regnum) +{ + int i; + int val; + + if (!bus) + return 0; + + for (i = phy_base_addr; i < phy_base_addr + port_num; i++) { + val = bus->read(bus, i, MDIO_DEVAD_NONE, regnum); + if (val != MIIM_TIMEOUT) + return 1; + } + + return 0; +} |