In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Network Security >
Share
Shulou(Shulou.com)06/01 Report--
1. Overview of the principle
1.1 Overview of Network Card driver
An Ethernet network card includes two layers of the OSI model: the physical layer and the data link layer. The chip in the data link layer is referred to as the MAC controller, and the chip in the physical layer is referred to as PHY.
MAC is mainly responsible for controlling and connecting the physical media of the physical layer. When sending data, MAC first judges whether data can be sent, if it can, adds control information to the data, and finally sends the data and control information to the physical layer according to the prescribed format; when receiving data, MAC first judges whether the information has a transmission error, and if there are no errors, remove the control information and send it to the LLC layer. This layer protocol is defined by the IEEE-802.3 Ethernet standard.
PHY is a physical interface transceiver that implements the physical layer. The IEEE-802.3 standard defines Ethernet PHY. When sending data, the MAC data is received, the parallel data is converted into serial stream data, and then encoded according to the coding rules of the physical layer, and then into an analog signal to send data. When receiving data, the process is the opposite. Another important function of PHY is to implement some of the functions of CSMA/CD.
The relationship between PHY and MAC is that PCI bus connects to MAC bus and MAC connects to PHY,PHY network line.
In the Ethernet network card driver, the driver of the PHY chip can be abstracted into a general interface. IEEE802.3 defines the function of the PHY chip address 0-15 register, while the address 16-31 register is left to the chip manufacturer to define freely.
two。 Technical realization
2.1 PHY driver directory
The PHY chip driver has been given in the Base of SylixOS, as shown in figure 3.1.
Figure 3.1 PHY driver directory
The PHY chip driver provided by SylixOS can support the link capability of 10Mb, 100Mb, 1000Mb.
2.2 PHY driver framework
The general process of PHY driver is as follows:
Initialize the component library (semaphore, timer).
Select Auto find / specify to find PHY devices.
Select autonegotiation / specify link mode.
Enable the timer to query the link status at regular intervals.
As shown in figure 3.2.
Figure 3.2 PHY driver Framework
In the network card driver, first pass parameters to the program listing 3.1, and then call the API_MiiPhyInit interface to complete the initialization of the PHY chip.
Program listing 3.1 passing parameters
Pmiidrv- > MIID_phydev.PHY_pPhyDrvFunc- > PHYF_pfuncWrite = (FUNCPTR) _ miiPhyWrite; pmiidrv- > MIID_phydev.PHY_pPhyDrvFunc- > PHYF_pfuncRead = (FUNCPTR) _ miiPhyRead; pmiidrv- > MIID_phydev.PHY_pPhyDrvFunc- > PHYF_pfuncLinkDown = (FUNCPTR) _ miiLinkStatus; pmiidrv- > MIID_phydev.PHY_pvMacDrv = pmiidrv; pmiidrv- > MIID_phydev.PHY_ucPhyAddr = ENET_PHYADDR; pmiidrv- > MIID_phydev.PHY_uiPhyID = FEC_ENET_PHYID Pmiidrv- > MIID_phydev.PHY_uiPhyIDMask = 0x0000000000; / * different signal recognition of the same series of chips * / pmiidrv- > MIID_phydev.PHY_uiTryMax = 100; pmiidrv- > MIID_phydev.PHY_uiLinkDelay = 100 / * delay 100ms automatic negotiation process * / pmiidrv- > MIID_phydev.PHY_uiPhyFlags = MII_PHY_AUTO | / * automatic negotiation flag * / MII_PHY_FD | / * full-duplex mode * / MII_PHY_100 | / * 100Mbit * / MII_PHY_10 | / * 10Mbit * / MII_PHY_HD | / * half-duplex mode * / MII_PHY_MONITOR / * enable automatic monitoring * /
MAC can read and write to PHY chip (miiPhyWrite function, miiPhyRead function).
Link state change function (miiLinkStatus function, print link information and perform related operations).
Control parameters (PHY driver will perform different operations according to the passed parameters, such as whether to enable automatic negotiation, select speed / duplex mode, and enable automatic monitoring).
2.3 concrete implementation
2.3.1 API_MiiPhyInit function implementation
The API_MiiPhyInit function initializes the component library, looks for PHY devices, and sets the linking capability according to the passed parameters.
The PHY driver provides a linked list to add valid PHY devices to the MII linked list and can operate on multiple PHY chips.
As shown in listing 3.2 of the program.
Listing 3.2 implementation of the API_MiiPhyInit function
INTAPI_MiiPhyInit (PHY_DEV * pPhyDev) {. If (API_MiiLibInit () = = MII_ERROR) {return (MII_ERROR);} if (pPhyDev- > PHY_ucPhyAddr = = 0) {/ * Auto scan phydevice * / if (API_MiiPhyScan (pPhyDev) = = MII_ERROR) {_ DebugHandle (_ ERRORMESSAGE_LEVEL, "can notfind phy device.\ r\ n") Return (MII_ERROR);}} else {/ * Test specific phy device * / if (API_MiiPhyProbe (pPhyDev)! = MII_OK) {MII_DEBUG_ADDR ("can notfind phy device. Addr [x]\ r\ n ", pPhyDev- > PHY_ucPhyAddr); return (MII_ERROR);} if (API_MiiPhyDiagnostic (pPhyDev)! = MII_OK) {return (MII_ERROR);}}. If (API_MiiPhyLinkSet (pPhyDev)! = MII_OK) {MII_DEBUG_ADDR ("mii:found phy [x], but Link-Down.\ r\ n", pPhyDev- > PHY_ucPhyAddr);} usPhyStatus = pPhyDev- > PHY_usPhyStatus / * Remember Link Status * / / * Get The New Status * /. Return (iRet); / * MII_ERROR orMII_OK * /}
2.3.2 API_MiiLibInit function implementation
The API_MiiLibInit function initializes the component library. Roughly create semaphores, timers, and start timers to test link capabilities. (the _ _ miiPhyMonitor function mainly reads the PHY chip status and updates the status information).
As shown in listing 3.3 of the program.
Listing 3.3 implementation of the API_MiiLibInit function
INTAPI_MiiLibInit (VOID) {. _ G_hMiiMSem = API_SemaphoreMCreate ("mii_lock", LW_PRIO_DEF_CEILING, LW_OPTION_WAIT_PRIORITY | LW_OPTION_DELETE_SAFE | LW_OPTION_INHERIT_PRIORITY | LW_OPTION_OBJECT_GLOBAL, LW_NULL) / * Create MIIMutex Semaphore * / _ G_hMiiTimer = API_TimerCreate ("mii_timer", LW_OPTION_ITIMER | LW_OPTION_OBJECT_GLOBAL, LW_NULL); if (_ G_hMiiTimer = = 0) {/ * Create mii timer * / return (MII_ERROR);}. If (API_TimerStart (_ G_hMiiTimer, / * Start PhyMonitor * / (MII_LINK_CHK_DELAY * LW_TICK_HZ), LW_OPTION_AUTO_RESTART, (PTIMER_CALLBACK_ROUTINE) _ _ miiPhyMonitor LW_NULL)) {API_SemaphoreMDelete (& _ G_hMiiMSem) Return (MII_ERROR);}. Return (MII_OK);}
2.3.3 API_MiiPhyScan function implementation
The API_MiiPhyScan function automatically looks for PHY devices. Roughly look up the addresses of all PHY devices from 0-32, and test whether the PHY is valid if there are devices.
As shown in listing 3.4 of the program.
Listing 3.4 implementation of the API_MiiPhyScan function
INTAPI_MiiPhyScan (PHY_DEV * pPhyDev) {. For (I = 0; I)
< MII_MAX_PHY_NUM; i++, pPhyDev->PHY_ucPhyAddr++) {iRet = API_MiiPhyProbe (pPhyDev); if (iRet! = MII_OK) {continue;} if (API_MiiPhyDiagnostic (pPhyDev)! = MII_OK) {return (MII_ERROR);} return (MII_OK) / * Found aValid PHY * /} return (MII_PHY_NULL);}
2.3.4 implementation of API_MiiPhyProbe,API_MiiPhyDiagnostic function
The API_MiiPhyProbe function detects whether the PHY device exists, which is roughly reading the PHY register ID, matching it, and returning whether it is successful. As shown in listing 3.5 of the program.
Listing 3.5 implementation of the API_MiiPhyProbe function
INTAPI_MiiPhyProbe (PHY_DEV * pPhyDev) {. If (MII_READ (pPhyDev, MII_PHY_ID1_REG, & usID1) = = MII_ERROR) {return (MII_ERROR);} if (MII_READ (pPhyDev, MII_PHY_ID2_REG, & usID2) = = MII_ERROR) {return (MII_ERROR) } uiPhyID = usID1 | (usID2 PHY_uiPhyID & pPhyDev- > PHY_uiPhyIDMask)! = (uiPhyID & pPhyDev- > PHY_uiPhyIDMask) {return (MII_PHY_NULL); / * phyId mismatch * /} return (MII_OK) / * phyId match * /}
The API_MiiPhyDiagnostic function tests whether the PHY is valid, specifically whether the reset PHY is successful, and detects whether the PHY is in a physically isolated state. As shown in listing 3.6.
Listing 3.6 implementation of the API_MiiPhyDiagnostic function
INTAPI_MiiPhyDiagnostic (PHY_DEV * pPhyDev) {. IRet = MII_WRITE (pPhyDev, ucRegAddr, usData); / * Reset thePHY * / if (iRet! = MII_OK) {return (MII_ERROR);} for (I = 0; I
< pPhyDev->PHY_uiTryMax; iTunes +) {API_TimeMSleep (pPhyDev- > PHY_uiLinkDelay); if (MII_READ (pPhyDev, ucRegAddr, & usData) = = MII_ERROR) {return (MII_ERROR);}}. UsData = MII_CTRL_NORM_EN; / * re-enable the chip * / if (MII_WRITE (pPhyDev, ucRegAddr, usData) = = MII_ERROR) {return (MII_ERROR);} for (I = 0; I
< pPhyDev->PHY_uiTryMax; iTunes +) {API_TimeMSleep (pPhyDev- > PHY_uiLinkDelay); if (MII_READ (pPhyDev, ucRegAddr, & usData) = = MII_ERROR) {return (MII_ERROR);} return (MII_OK);}
2.3.5 API_MiiPhyLinkSet function implementation
The API_MiiPhyLinkSet function sets the PHY link mode. As shown in listing 3.7 of the program.
Listing 3.7 implementation of the API_MiiPhyLinkSet function
INTAPI_MiiPhyLinkSet (PHY_DEV * pPhyDev) {. If (_ _ miiAbilFlagUpdate (pPhyDev) = = MII_ERROR) {return (MII_ERROR);}. IRet = API_MiiPhyModeSet (pPhyDev); Return (MII_OK);}
The API_MiiPhyModeSet function automatically negotiates / sets manually according to the parameter selection.
As shown in listing 3.8 of the program.
Listing 3.8 implementation of the API_MiiPhyModeSet function
INTAPI_MiiPhyModeSet (PHY_DEV * pPhyDev) {if (pPhyDev- > PHY_uiPhyFlags & MII_PHY_AUTO) {/ * AutoNegotiationenabled * / if (_ _ miiAutoNegotiate (pPhyDev) = = MII_OK) {return (MII_OK) }} else {/ * autonegotiation function is not enabled * / if (_ _ miiModeForce (pPhyDev) = = MII_OK) {if (_ _ miiFlagsHandle (pPhyDev) = = MII_OK) {/ * handlesome flags * / return (MII_OK) }} return (MII_ERROR);}
The _ _ miiAutoNegotiate function performs autonegotiation and checks whether the negotiation is successful. _ _ miiBasicCheck is used to check whether it is link up/remote fault. As shown in listing 3.9.
Listing 3.9 _ _ miiAutoNegotiate function implementation
StaticINT__miiAutoNegotiate (PHY_DEV * pPhyDev) {. / * * start theauto-negotiation process: return * only in caseof fatal error. * / iRet = _ _ miiAutoNegStart (pPhyDev); / * check the negotiation was successful * / if (! (pPhyDev- > PHY_uiPhyFlags & MII_PHY_NWAIT_STAT)) {if (_ miiAnCheck (pPhyDev) = = MII_OK) {return (MII_OK);}} return (MII_ERROR);}
The _ _ miiAutoNegStart function starts auto-negotiation. Specifically, start autonegotiation and choose to wait for autonegotiation to end / return immediately according to the passed parameters. As shown in listing 3.10.
Listing 3.10 _ _ miiAutoNegStart function implementation
StaticINT__miiAutoNegStart (PHY_DEV * pPhyDev) {. / * * restart the auto-negotiation process * / ucRegAddr = MII_CTRL_REG; usData = (MII_CTRL_RESTART | MII_CTRL_AUTO_EN); if (MII_WRITE (pPhyDev, ucRegAddr, usData)! = MII_OK) {return (MII_ERROR) } / * * let's check the PHY status forcompletion * / if (! (pPhyDev- > PHY_uiPhyFlags & MII_PHY_NWAIT_STAT)) {ucRegAddr = MII_STAT_REG; do {/ * spin until it is done * / API_TimeMSleep (pPhyDev- > PHY_uiLinkDelay) If (iTunes + = = pPhyDev- > PHY_uiTryMax) break; if (MII_READ (pPhyDev, ucRegAddr, & usPhyStatus)! = MII_OK) {return (MII_ERROR);}} while ((usPhyStatus & MII_SR_AUTO_NEG)! = MII_SR_AUTO_NEG); Return (MII_OK);}
2.3.6 _ miiModeForce function implementation
The _ _ miiModeForce function sets the specified link mode based on the passed parameters (if there are multiple parameters, the highest link mode is specified). As shown in listing 3.11 of the program.
Listing 3.11 _ _ miiModeForce function implementation
StaticINT__miiModeForce (PHY_DEV * pPhyDev) {. / * 100Mb/s full * / if (MII_PHY_FLAGS_JUDGE (MII_PHY_100) & & MII_PHY_FLAGS_JUDGE (MII_PHY_FD)) {usData = MII_CTRL_NORM_EN; usData | = MII_CTRL_100; usData | = MII_CTRL_FDX; _ _ miiForceAttempt (pPhyDev, usData); MII_PHY_ABILITY_FLAGS_SET (MII_PHY_100 | MII_PHY_FD) Return (MII_OK);}. Return (MII_ERROR);}
The _ _ miiForceAttempt function sets the specified link mode and checks the PHY status. The _ _ miiBasicCheck function is used to check whether the PHY state is correct. As shown in listing 3.12 of the program.
Listing 3.12 _ _ miiForceAttempt function implementation
StaticINT__miiForceAttempt (PHY_DEV * pPhyDev, UINT16 usData) {if (MII_WRITE (pPhyDev, MII_CTRL_REG, usData)! = MII_OK) {return (MII_ERROR);} if (_ _ miiBasicCheck (pPhyDev)! = MII_OK) {return (MII_ERROR);} return (MII_OK);}
2.3.7 _ _ miiPhyMonitor function implementation
The _ _ miiPhyMonitor function continuously monitors the PHY status. Specifically, it detects the status of the PHY link and updates the status information at regular intervals, and calls the PHYF_pfuncLinkDown function (actually the previous miiLinkStatus function) when it is detected that the link is lost. As shown in listing 3.13 of the program.
Listing 3.13 _ _ miiPhyMonitor function implementation
StaticINT__miiPhyMonitor (VOID) {. IRet = MII_READ (pPhyDev, MII_STAT_REG, & usPhyStatus); if (iRet = = MII_ERROR) {goto _ _ mii_monitor_exit } / * is the PHY's status linkchanged? * / if ((pPhyDev- > PHY_usPhyStatus & MII_SR_LINK_STATUS)! = (usPhyStatus & MII_SR_LINK_STATUS)) {if (usPhyStatus & MII_SR_LINK_STATUS) { If (pPhyDev- > PHY_uiPhyFlags & MII_PHY_AUTO) {_ _ miiAbilFlagUpdate (pPhyDev) _ _ miiPhyUpdate (pPhyDev);} else {_ _ miiFlagsHandle (pPhyDev) }} if (pPhyDev- > PHY_pPhyDrvFunc- > PHYF_pfuncLinkDown! = LW_NULL) {API_NetJobAdd ((VOIDFUNCPTR) (pPhyDev- > PHY_pPhyDrvFunc- > PHYF_pfuncLinkDown), (PVOID) (pPhyDev- > PHY_pvMacDrv), 0lle 0,0); pPhyDev- > PHY_usPhyStatus = usPhyStatus }. Return (iRet);}
2.4 practical application
The _ _ phyInit function initializes the driver for the PHY chip written in the actual Nic driver. Specifically, it calls the miiDrvInit function to write parameters, and calls the API_MiiPhyInit function to initialize the PHY chip.
As shown in listing 3.14 of the program.
Listing 3.14 _ _ phyInit function implementation
StaticINT__phyInit (struct netdev * pNetDev) {. PEnet = & pEnet- > ENET_netdev; pmiidrv = miiDrvInit (); if (! pmiidrv) {return (PX_ERROR);} pEnet- > ENET_miidrv = pmiidrv; pmiidrv- > MIID_enet = pEnet; pnetdev- > priv = (PVOID) pEnet; iRet = API_MiiPhyInit (& (pEnet- > ENET_miidrv- > MIID_phydev)); if (iRet = = MII_OK) {pEnet- > ENET_iMiiInit = 1 } return (ERROR_NONE);}
The miiDrvInit function passes parameters that are needed in API_MiiPhyInit. Encapsulate the read and write function of MAC to PHY and specify the working mode. As shown in listing 3.15.
Listing 3.15 miiDrvInit function implementation
MII_DRV * miiDrvInit (VOID) {. Pmiidrv- > MIID_phydev.PHY_pPhyDrvFunc- > PHYF_pfuncWrite = (FUNCPTR) miiPhyWrite; pmiidrv- > MIID_phydev.PHY_pPhyDrvFunc- > PHYF_pfuncRead = (FUNCPTR) miiPhyRead; pmiidrv- > MIID_phydev.PHY_pPhyDrvFunc- > PHYF_pfuncLinkDown = (FUNCPTR) miiLinkStatus; pmiidrv- > MIID_phydev.PHY_pvMacDrv = pmiidrv; pmiidrv- > MIID_phydev.PHY_ucPhyAddr = ENET_PHYADDR; pmiidrv- > MIID_phydev.PHY_uiPhyID = FEC_ENET_PHYID; pmiidrv- > MIID_phydev.PHY_uiPhyIDMask = 0x00000000 / * different signal recognition of the same series of chips * / pmiidrv- > MIID_phydev.PHY_uiTryMax = 100; pmiidrv- > MIID_phydev.PHY_uiLinkDelay = 100 / * delay 100ms automatic negotiation process * / pmiidrv- > MIID_phydev.PHY_uiPhyFlags = MII_PHY_AUTO | / * automatic negotiation flag * / MII_PHY_FD | / * full-duplex mode * / MII_PHY_100 | / * 100Mbit * / MII_PHY_10 | / * 10Mbit * / MII_PHY_HD | / * half-duplex mode * / MII_PHY_MONITOR / * enable automatic monitoring * / return (pmiidrv);}
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.