"Introduction to the Chip"
AR8033 is Atheros's 4th generation 10/100/1000mbps rate Ethernet PHY chip, which can be used for home gateways, enterprise switches, mobile base stations, optical modules and other devices. The chip uses the RGMII protocol or the SGMII protocol to communicate with the MAC chip, only need a single 3.3V power supply, can self-rectifier to transform out of the chip circuit required other power supplies. The AR8033 also incorporates a SerDes interface with a working frequency of 1.25GHz, which can be connected directly to the optical transceiver module, converting the light signal into an electrical signal suitable for 1000base-x/100 BASE-FX transmission mode or a SGMII protocol signal for communication with the MAC chip.
The PHY chip belongs to the lowest physical layer in the OSI protocol stack.
From the hardware, the general PHY chip is a analog-to-digital hybrid circuit, which is responsible for receiving the analog signal such as electricity and light, after demodulation and A/D conversion, the signal is sent to the MAC chip for processing via the Mii interface. The general Mac Chip is a pure digital circuit.
"SerDes Interface"
The SerDes is the abbreviation for the Serializer (serializer)/deserializer (Deserializer). It is a mainstream time division Multiplexing (TDM), peer-to-peer serial communication technology, that is, at the transmitting end of the multi-speed parallel signal is converted to high-speed serial signal, through the transmission medium (optical cable or copper wire), and finally at the receiving end of the high-speed serial signal re-conversion to low-speed parallel signal.
"Rgmii Interface"
Rgmii, reduced GMII, is a simplified version of GMII. Its interface signal line number is 14 (Col/crs port status indication signal, here is not drawn), the clock frequency is 125mhz,tx/rx data width of 4 bits, in order to maintain the transmission rate of 1000Mbps, RGMII interface in the rising edge of the clock and the falling edge are sampled data. On the rising edge of the reference clock, send the txd[3:0]/rxd[3:0] in the Gmii interface, sending txd[7:4]/rxd[7:4 in the Gmii interface on the falling edge of the reference clock]. The RGMII is compatible with two rates of 100Mbps and 10Mbps, at which point the reference clock rate is 25MHz and 2.5MHz respectively.
Tx_en Signal Line transmits tx_en and tx_er two kinds of information, sends tx_en along the rising edge of the TX_CLK, sends tx_er along the descending edge; Likewise, RX_DV and RX_DV Two kinds of information are also transmitted on the rx_er signal line, sending RX_CLK on the rising edge of RX_DV, The falling edge sends Rx_er.
"Sgmii Interface"
Sgmii is serial GMII, is the interface between PHY and Mac, clock frequency 625MHz, send and receive each pair of differential signal line, so the total data rate is 1.25Gbps = 625mbps* 2. Gmii and Rgmii are both parallel, and need to follow the clock, PCB cabling is relatively troublesome, not suitable for backplane applications, and the SGMII is serial, do not need to provide additional clocks, Mac and PHY use CDR to restore the clock. The reference clock RX_CLK is provided by the PHY and is optional, sampled on both the rising and falling edges of the clock signal, primarily for cases where there is no clock on the Mac side, in general, the RX_CLK is not used, and the transceiver can recover the clock from the data.
In the serial data sent by TXD, each 8bits data will be inserted into the Tx_en/tx_er 2bits control information, similarly, in the RXD receive data, each 8bits data will be inserted rx_dv/rx_er 2bits control information, called 8B/10B encoding.
"Mdc/mdio Interface"
The interface has MDC and Mdio two lines. The MDC is a reference clock signal provided by the Mac, and the Mdio is a two-way configurable data line that can be transmitted asynchronously with the MDC clock. The Mdio interface of the AR8033 is an open-drain output, so an external pull-up 1.5k resistor is required for use.
The meanings of each field are as follows:
The PRE's response to the MDC clock signal is used to calibrate the asynchronous transmit clock with a content of 32 digits of 1.
The ST data frame begins to be identified.
OP opcode, 10 for read data, 01 for write data.
The physical address of the Phyad PHY chip, a total of 5 bits, of which 3 bits can be configured inside the AR8033.
The Regad register address, a total of 5 bits, is used to select one of the 32 registers in the PHY chip.
TA is used to prevent the creation of a new connection during data transfer, a total of 2 bits. The 1th bit in the read operation is a high impedance state, the 2nd bit is 0, the 1th bit is 1 during the write operation, and the 2nd bit is 0.
Data represents a total of 16 bits from the register read or write to the register. Start transmission from high.
Idle signal between the idle frames, high impedance state. An idle signal of at least 1 clocks between adjacent two data frames.
"Working mode Configuration"
AR8033 can operate in 3 mode categories: Electrical outlet mode, optical port mode, and photoelectric converter mode. The AR8033 can be configured to a different operating mode depending on the level of the pin on the 4 mode selection.
when we want the AR8033 to work in 1000Mbps light-port mode, the RX_DV, RXD2, RX_CLK, RXD3 4-pin levels are pulled down and pulled up to 0010. Similarly, to work in 100Mbps light mode, you can set the level to 0110 or 1110.
"Application Example"
We can use AR8033 to manage the optical port. As described in the official data sheet.
As can be seen from the block diagram, when the AR8033 chip is used for fiber module management, it needs to be configured as 100BASE-FX mode or 1000base-x mode, and the RGMII protocol is used for data transmission between switch chips. In practical application, the AR8033 operation mode is directly configured by the main control chip via the Mdc/mdio bus, and the data transmission path is AR8033 transmitted to the switching chip, which is transmitted by the switching chip to the main control chip.
As can be seen in the optical module chip AR8033 and switching between the data transmission using the RGMII protocol, the exchange between the chip and the master chip data transmission between the use of Sgmii protocol.
"Code Analysis"
To use AR8033 on Linux requires 2 parts, one is to write device drivers and register the device driver to the kernel, and the other is to create the Mdio bus to use for device communication and register the device on the bus.
A) driver registration process:
The file mdio_gpio.c is where the code for the Mdio_gpio module resides. The Mdio driver is registered as a "platform device driver" in the module load function Mdio_gpio_init () via the statement ret = Platform_driver_register (&mdio_gpio_driver), where Mdio_gpio_ Driver is a platform_driver struct, the initialization code is as follows:
static struct Platform_driver mdio_gpio_driver= {
. probe= Mdio_gpio_probe,//Probe function of the associated device
. remove= __devexit_p (Mdio_gpio_remove),//The Remove function of the associated device
. Driver = {
. Name = "Mdio-gpio",//driver name
. Owner = This_module,
},
};
In the Platform_driver_register () function, the drive bus type is further set to Platform_bus_type, along with the associated-driven probe () function, the Remove () function, and the shutdown () function. The code details are as follows:
int Platform_driver_register (Structplatform_driver *drv)
{
drv->driver.bus= &platform_bus_type;
if (drv->probe)
drv->driver.probe = Platform_drv_probe; Note that this is drv->driver.probe
if (Drv->remove)
Drv->driver.remove= Platform_drv_remove; Association Drv->driver.remove
if (Drv->shutdown)
Drv->driver.shutdown= Platform_drv_shutdown; Association Drv->driver.shutdown
Returndriver_register (&drv->driver);
}
As you can see, the initialization to this step for all drivers will point to the 3 functions of Probe (), remove (), shutdown (), which are used to return the probe (), remove (), shutdown () functions of the Platform device driver, respectively. The code is as follows:
static int platform_drv_probe (struct Device*_dev)
{
Structplatform_driver *drv = To_platform_driver (_dev->driver);
Structplatform_device *dev = To_platform_device (_dev);
Returndrv->probe (Dev);
}
In the return statement at the end of the Platform_driver_register () function, call Driver_register (&drv->driver) to register the driver further. Through the statement driver_find (Drv->name, Drv->bus) Find out if the driver has been registered on the bus, and if not, use statement bus_add_driver (DRV) to add the driver to the bus. At this point, the driver registration process is complete. The code is as follows:
int Driver_register (struct device_driver*drv)
{
intret;
Structdevice_driver *other;
BUG_ON (!DRV->BUS->P); Turn on debugging
Do some testing.
if ((drv->bus->probe && drv->probe) | |
(Drv->bus->remove &&drv->remove) | |
(Drv->bus->shutdown &&drv->shutdown))
PRINTK (kern_warning "Driver '%s ' needs updating-please use"
"Bus_typemethods\n", drv->name);
Other = Driver_find (Drv->name, Drv->bus); Find out if the driver has been registered in the bus
if (other) {
PRINTK (kern_err "Error:driver '%s ' is already registered,"
"aborting...\n", drv->name);
Return-ebusy;
}
ret = Bus_add_driver (DRV); Adding drivers to the bus
if (ret)
Returnret;
Ret= driver_add_groups (DRV, drv->groups);
if (ret)
Bus_remove_driver (DRV);
Returnret;
}
b) Device registration process:
The driver's probe () function, the Mdio_gpio_probe () function, is called at the end of the driver registration process. In this function, a Mdio bus device is initialized with the statement New_bus = Mdio_gpio_bus_init (&pdev->dev, Pdata,pdev->id), in the use of the statement mdiobus_register ( New_bus) to register the device bus. The code is as follows:
static int __devinit mdio_gpio_probe (structplatform_device *pdev)
{
Structmdio_gpio_platform_data *pdata = pdev->dev.platform_data;
Structmii_bus *new_bus;
intret;
if (!pdata)
Return-enodev;
New_bus = Mdio_gpio_bus_init (&pdev->dev, pdata,pdev->id);
if (!new_bus)
Return-enodev;
ret = Mdiobus_register (New_bus);
if (ret)
Mdio_gpio_bus_deinit (&pdev->dev);
Returnret;
}
Enter function Mdiobus_register () to see the code, which can be divided into 2 sections. First, the Mdio bus device for real registration, the second is the successful registration, on the bus based on Phy_mask search PHY device. The code is as follows:
int Mdiobus_register (struct Mii_bus *bus)
{
Inti, err;
if (NULL = = Bus | | NULL = = Bus->name | |
null== Bus->read | |
null== bus->write)
Return-einval;
bug_on (bus->state!= mdiobus_allocated &&
Bus->state! = mdiobus_unregistered);
Bus->dev.parent= bus->parent;
bus->dev.class= &mdio_bus_class;
Bus->dev.groups= NULL;
Dev_set_name (&bus->dev, "%s", Bus->id);
err = Device_register (&bus->dev); registering mdio bus devices
if (err) {
PRINTK (kern_err "Mii_bus%s failed to register\n", bus->id);
Return-einval;
}
Mutex_init (&bus->mdio_lock);
if (Bus->reset)
Bus->reset (bus);
for (i = 0; i < phy_max_addr; i++) {
if ((Bus->phy_mask & (1 << i) = = 0) {
Structphy_device *phydev;
Phydev = Mdiobus_scan (bus, i); searching for PHY devices on the bus
if (Is_err (Phydev)) {
Err= Ptr_err (Phydev);
Gotoerror;
}
}
}
Bus->state= mdiobus_registered;
...//omitted below
}
Enter the function Mdiobus_scan () to see the code, and you can see that the function uses the Phydev = Get_phy_device (bus, addr) statement to obtain the PHY device from the bus device, and then through the statement Phy_device_register ( Phydev) to register the PHY device. At this point, the device registration process is complete. The code is as follows:
struct Phy_device *mdiobus_scan (structmii_bus *bus, int addr)
{
Structphy_device *phydev;
Structmdio_board_entry *be;
Interr;
Phydev = Get_phy_device (bus, addr); getting the PHY device from the bus device
if (Is_err (Phydev) | | phydev = = NULL)
Returnphydev;
Mutex_lock (&__mdio_board_lock);
List_for_each_entry (be,&__mdio_board_list, list)
Mdiobus_setup_phydev_from_boardinfo (Bus,phydev,
&be->board_info);
Mutex_unlock (&__mdio_board_lock);
err = Phy_device_register (Phydev); registering the PHY device with the kernel
if (err) {
Phy_device_free (Phydev);
Returnnull;
}
Returnphydev;
}
PHY Chip AR8033 Learning Notes