Marvell 88E1111 linux driver
The Alaska? Ultra 88E1111 Gigabit Ethernet Transceiver is a physical layer device for Ethernet 1000BASE-T, 100BASE-TX, and 10BASE-T applications.
?
1. FEATURES
? 10/100/1000BASE-T IEEE 802.3 compliant
? Supports GMII, TBI, reduced pin count GMII (RGMII), reduced pin count TBI (RTBI), and serial GMII (SGMII) interfaces
? Integrated 1.25 GHz SERDES for 1000BASE-X fiber applications
? Four RGMII timing modes
? Energy Detect and Energy Detect+ low power modes
? Three loopback modes for diagnostics
? "Downshift" mode for two-pair cable installations
? Fully integrated digital adaptive equalizers, echo cancellers, and crosstalk cancellers
? Advanced digital baseline wander correction
? Automatic MDI/MDIX crossover at all speeds of operation
? Automatic polarity correction
? IEEE 802.3u compliant Auto-Negotiation
? Software programmable LED modes including LED testing
? Automatic detection of fiber or copper operation
? Supports IEEE 1149.1 JTAG
? Two-Wire Serial Interface (TWSI) and MDC/MDIO
? CRC checker, packet counter
? Packet generation
? Virtual Cable Tester (VCT)
? Auto-Calibration for MAC Interface outputs
? Requires only two supplies: 2.5V and 1.0V (with 1.2V option for the 1.0V supply)
? I/Os are 3.3V tolerant
? Low power dissipation Pave = 0.75W
? 0.13 μm digital CMOS process
? 117-Pin TFBGA, 96-Pin BCC, and 128 PQFP package options
? 117-Pin TFBGA and 96-Pin BCC packages available in Commercial or Industrial grade
? RoHS 6/6 compliant packages available
?
?
?
2. driver:
-
drivers/net/phy/marvell.c
-
drivers/net/phy/phy_device.c
-
include/uapi/linux/mii.h (register)
?
?
3. kernel config:
Device Drivers??--->[*] Network device support??--->-*-???PHY Device support and infrastructure??---><*>???Marvell PHYs?
4. dts config:
mdio {#address-cells = <1>;#size-cells = <0>;compatible = "snps,dwmac-mdio";phy0: phy@0 {device_tpye = "ethernet-phy";compatible = "ethernet-phy-id0141.0cc0", "ethernet-phy-ieee802.3-c22";reg = <0>;};};pay attention to reg(phy_addr), it will be used in?of_mdiobus_register().
the reg(phy_addr) need to be the same as address in PHY configuration, see 6.1
if there is no reg property in dts, of_mdiobus_register() will auto scan for PHYs with empty reg property.
?
?
5. PHY driver
-
first, we need get and register all PHY device into bus.
-
second,?register PHY driver by?module_phy_driver().?
-
third,?when we excute "ifconfig eth0 up",? kernel will call stmmac_init_phy() to init a PHY.
?
5.1 register PHY device
bring up all the PHYs on a given bus and attach them to bus(register them)
stmmac_dvr_probe ->? stmmac_mdio_register ->? of_mdiobus_register ->? mdiobus_register ->? __mdiobus_register ->? mdiobus_scan ->? get_phy_device &? phy_device_register
for (i = 0; i < PHY_MAX_ADDR; i++) {if ((bus->phy_mask & (1 << i)) == 0) {struct phy_device *phydev;phydev = mdiobus_scan(bus, i);if (IS_ERR(phydev) && (PTR_ERR(phydev) != -ENODEV)) {err = PTR_ERR(phydev);goto error;}} }struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr) {struct phy_device *phydev;int err;phydev = get_phy_device(bus, addr, false);if (IS_ERR(phydev))return phydev;/** For DT, see if the auto-probed phy has a correspoding child* in the bus node, and set the of_node pointer in this case.*/of_mdiobus_link_mdiodev(bus, &phydev->mdio);err = phy_device_register(phydev);if (err) {phy_device_free(phydev);return ERR_PTR(-ENODEV);}return phydev; }?
if get_phy_id() is ok, there is a valid PHY device on given addr(PHY addr, also var i). then we create phy device using this addr.
struct phy_device *get_phy_device(struct mii_bus *bus, int addr, bool is_c45) {struct phy_c45_device_ids c45_ids = {0};u32 phy_id = 0;int r;r = get_phy_id(bus, addr, &phy_id, is_c45, &c45_ids);if (r)return ERR_PTR(r);/* If the phy_id is mostly Fs, there is no device there */if ((phy_id & 0x1fffffff) == 0x1fffffff)return ERR_PTR(-ENODEV);return phy_device_create(bus, addr, phy_id, is_c45, &c45_ids); }5.2 register PHY driver
register PHY driver by?module_phy_driver(). PHY device and PHY driver will be matched by phy_id.?kernel will excute phy_probe() once match is successful.
module_phy_driver(marvell_drivers) ->? phy_module_driver ->? phy_module_init ->? phy_drivers_register ->? phy_driver_register ->? driver_register(&new_driver->mdiodrv.driver)
?
5.3 init PHY(register)
when we excute "ifconfig eth0 up",? kernel will call stmmac_init_phy() to init a PHY.
stmmac_open ->? stmmac_init_phy ->? phy_connect ->? bus_find_device_by_name &? phy_connect_direct()
snprintf(bus_id, MII_BUS_ID_SIZE, "stmmac-%x",priv->plat->bus_id);snprintf(phy_id_fmt, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id,priv->plat->phy_addr);phydev = phy_connect(dev, phy_id_fmt, &stmmac_adjust_link,interface);we can find a specified PHY device(the name is phy_id_fmt which contain phy_addr ) by? bus_find_device_by_name().
in __mdiobus_register(), if get a PHY device, it call? dev_set_name(&mdiodev->dev, PHY_ID_FMT, bus->id, addr) set device name in phy_device_create.?
so we can init a PHY that have been registed in bus.
總結
以上是生活随笔為你收集整理的Marvell 88E1111 linux driver的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 刺客信条中主角康纳的父亲是谁(中国古代十
- 下一篇: painless语法入门[通俗易懂]