Webserver+3d print

Dependents:   Nucleo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers lan9303.c Source File

lan9303.c

Go to the documentation of this file.
00001 /**
00002  * @file lan9303.c
00003  * @brief LAN9303 Ethernet switch
00004  *
00005  * @section License
00006  *
00007  * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved.
00008  *
00009  * This file is part of CycloneTCP Open.
00010  *
00011  * This program is free software; you can redistribute it and/or
00012  * modify it under the terms of the GNU General Public License
00013  * as published by the Free Software Foundation; either version 2
00014  * of the License, or (at your option) any later version.
00015  *
00016  * This program is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU General Public License
00022  * along with this program; if not, write to the Free Software Foundation,
00023  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00024  *
00025  * @author Oryx Embedded SARL (www.oryx-embedded.com)
00026  * @version 1.7.6
00027  **/
00028 
00029 //Switch to the appropriate trace level
00030 #define TRACE_LEVEL NIC_TRACE_LEVEL
00031 
00032 //Dependencies
00033 #include "core/net.h"
00034 #include "drivers/lan9303.h"
00035 #include "debug.h"
00036 
00037 
00038 /**
00039  * @brief LAN9303 Ethernet switch driver
00040  **/
00041 
00042 const PhyDriver lan9303PhyDriver =
00043 {
00044    lan9303Init,
00045    lan9303Tick,
00046    lan9303EnableIrq,
00047    lan9303DisableIrq,
00048    lan9303EventHandler,
00049 };
00050 
00051 
00052 /**
00053  * @brief LAN9303 Ethernet switch initialization
00054  * @param[in] interface Underlying network interface
00055  * @return Error code
00056  **/
00057 
00058 error_t lan9303Init(NetInterface *interface)
00059 {
00060    uint_t port;
00061 
00062    //Debug message
00063    TRACE_INFO("Initializing LAN9303...\r\n");
00064 
00065    //Loop through ports
00066    for(port = LAN9303_PORT1; port <= LAN9303_PORT2; port++)
00067    {
00068       //Debug message
00069       TRACE_INFO("Port %u:\r\n", port);
00070       //Dump PHY registers for debugging purpose
00071       lan9303DumpPhyReg(interface, port);
00072    }
00073 
00074    //Force the TCP/IP stack to poll the link state at startup
00075    interface->phyEvent = TRUE;
00076    //Notify the TCP/IP stack of the event
00077    osSetEvent(&netEvent);
00078 
00079    //Successful initialization
00080    return NO_ERROR;
00081 }
00082 
00083 
00084 /**
00085  * @brief Get link state
00086  * @param[in] interface Underlying network interface
00087  * @param[in] port Port number
00088  * @return Link state
00089  **/
00090 
00091 bool_t lan9303GetLinkState(NetInterface *interface, uint8_t port)
00092 {
00093    uint16_t status;
00094    bool_t linkState;
00095 
00096    //Check port number
00097    if(port >= LAN9303_PORT1 && port <= LAN9303_PORT2)
00098    {
00099       //Get exclusive access
00100       osAcquireMutex(&netMutex);
00101       //Read status register
00102       status = lan9303ReadPhyReg(interface, port, LAN9303_PHY_REG_BMSR);
00103       //Release exclusive access
00104       osReleaseMutex(&netMutex);
00105 
00106       //Retrieve current link state
00107       linkState = (status & BMSR_LINK_STATUS) ? TRUE : FALSE;
00108    }
00109    else
00110    {
00111       //The specified port number is not valid
00112       linkState = FALSE;
00113    }
00114 
00115    //Return link status
00116    return linkState;
00117 }
00118 
00119 
00120 /**
00121  * @brief LAN9303 timer handler
00122  * @param[in] interface Underlying network interface
00123  **/
00124 
00125 void lan9303Tick(NetInterface *interface)
00126 {
00127    uint_t port;
00128    uint16_t status;
00129    bool_t linkState;
00130 
00131    //Initialize link state
00132    linkState = FALSE;
00133 
00134    //Loop through ports
00135    for(port = LAN9303_PORT1; port <= LAN9303_PORT2; port++)
00136    {
00137       //Read status register
00138       status = lan9303ReadPhyReg(interface, port, LAN9303_PHY_REG_BMSR);
00139 
00140       //Retrieve current link state
00141       if(status & BMSR_LINK_STATUS)
00142          linkState = TRUE;
00143    }
00144 
00145    //Link up event?
00146    if(linkState)
00147    {
00148       if(!interface->linkState)
00149       {
00150          //Set event flag
00151          interface->phyEvent = TRUE;
00152          //Notify the TCP/IP stack of the event
00153          osSetEvent(&netEvent);
00154       }
00155    }
00156    //Link down event?
00157    else
00158    {
00159       if(interface->linkState)
00160       {
00161          //Set event flag
00162          interface->phyEvent = TRUE;
00163          //Notify the TCP/IP stack of the event
00164          osSetEvent(&netEvent);
00165       }
00166    }
00167 }
00168 
00169 
00170 /**
00171  * @brief Enable interrupts
00172  * @param[in] interface Underlying network interface
00173  **/
00174 
00175 void lan9303EnableIrq(NetInterface *interface)
00176 {
00177 }
00178 
00179 
00180 /**
00181  * @brief Disable interrupts
00182  * @param[in] interface Underlying network interface
00183  **/
00184 
00185 void lan9303DisableIrq(NetInterface *interface)
00186 {
00187 }
00188 
00189 
00190 /**
00191  * @brief LAN9303 event handler
00192  * @param[in] interface Underlying network interface
00193  **/
00194 
00195 void lan9303EventHandler(NetInterface *interface)
00196 {
00197    uint_t port;
00198    uint16_t status;
00199    bool_t linkState;
00200 
00201    //Initialize link state
00202    linkState = FALSE;
00203 
00204    //Loop through ports
00205    for(port = LAN9303_PORT1; port <= LAN9303_PORT2; port++)
00206    {
00207       //Read status register
00208       status = lan9303ReadPhyReg(interface, port, LAN9303_PHY_REG_BMSR);
00209 
00210       //Retrieve current link state
00211       if(status & BMSR_LINK_STATUS)
00212          linkState = TRUE;
00213    }
00214 
00215    //Link up event?
00216    if(linkState)
00217    {
00218       //Set current speed
00219       interface->linkSpeed = NIC_LINK_SPEED_100MBPS;
00220       //Set duplex mode
00221       interface->duplexMode = NIC_FULL_DUPLEX_MODE;
00222 
00223       //Update link state
00224       interface->linkState = TRUE;
00225 
00226       //Adjust MAC configuration parameters for proper operation
00227       interface->nicDriver->updateMacConfig(interface);
00228    }
00229    else
00230    {
00231       //Update link state
00232       interface->linkState = FALSE;
00233    }
00234 
00235    //Process link state change event
00236    nicNotifyLinkChange(interface);
00237 }
00238 
00239 
00240 /**
00241  * @brief Write PHY register
00242  * @param[in] interface Underlying network interface
00243  * @param[in] port Port number
00244  * @param[in] address PHY register address
00245  * @param[in] data Register value
00246  **/
00247 
00248 void lan9303WritePhyReg(NetInterface *interface,
00249    uint8_t port, uint8_t address, uint16_t data)
00250 {
00251    //Write the specified PHY register
00252    interface->nicDriver->writePhyReg(port, address, data);
00253 }
00254 
00255 
00256 /**
00257  * @brief Read PHY register
00258  * @param[in] interface Underlying network interface
00259  * @param[in] port Port number
00260  * @param[in] address PHY register address
00261  * @return Register value
00262  **/
00263 
00264 uint16_t lan9303ReadPhyReg(NetInterface *interface,
00265    uint8_t port, uint8_t address)
00266 {
00267    //Read the specified PHY register
00268    return interface->nicDriver->readPhyReg(port, address);
00269 }
00270 
00271 
00272 /**
00273  * @brief Dump PHY registers for debugging purpose
00274  * @param[in] interface Underlying network interface
00275  * @param[in] port Port number
00276  **/
00277 
00278 void lan9303DumpPhyReg(NetInterface *interface, uint8_t port)
00279 {
00280    uint8_t i;
00281 
00282    //Loop through PHY registers
00283    for(i = 0; i < 32; i++)
00284    {
00285       //Display current PHY register
00286       TRACE_DEBUG("%02" PRIu8 ": 0x%04" PRIX16 "\r\n", i,
00287          lan9303ReadPhyReg(interface, port, i));
00288    }
00289 
00290    //Terminate with a line feed
00291    TRACE_DEBUG("\r\n");
00292 }
00293 
00294 
00295 /**
00296  * @brief Write SMI register
00297  * @param[in] interface Underlying network interface
00298  * @param[in] address System register address
00299  * @param[in] data Register value
00300  **/
00301 
00302 void lan9303WriteSmiReg(NetInterface *interface, uint16_t address,
00303    uint32_t data)
00304 {
00305    uint8_t phyAddr;
00306    uint8_t regAddr;
00307 
00308    //PHY address bit 4 is 1 for SMI commands. PHY address 3:0 form
00309    //system register address bits 9:6
00310    phyAddr = 0x10 | ((address >> 6) & 0x0F);
00311 
00312    //Register address field forms register address bits 5:1
00313    regAddr = (address >> 1) & 0x1F;
00314 
00315    //Get exclusive access
00316    osAcquireMutex(&netMutex);
00317 
00318    //Write the low word of the SMI register
00319    interface->nicDriver->writePhyReg(phyAddr, regAddr, data & 0xFFFF);
00320    //Write the high word of the SMI register
00321    interface->nicDriver->writePhyReg(phyAddr, regAddr + 1, (data >> 16) & 0xFFFF);
00322 
00323    //Release exclusive access
00324    osReleaseMutex(&netMutex);
00325 }
00326 
00327 
00328 /**
00329  * @brief Read SMI register
00330  * @param[in] interface Underlying network interface
00331  * @param[in] address System register address
00332  * @return Register value
00333  **/
00334 
00335 uint32_t lan9303ReadSmiReg(NetInterface *interface, uint16_t address)
00336 {
00337    uint8_t phyAddr;
00338    uint8_t regAddr;
00339    uint32_t data;
00340 
00341    //PHY address bit 4 is 1 for SMI commands. PHY address 3:0 form
00342    //system register address bits 9:6
00343    phyAddr = 0x10 | ((address >> 6) & 0x0F);
00344 
00345    //Register address field forms register address bits 5:1
00346    regAddr = (address >> 1) & 0x1F;
00347 
00348    //Get exclusive access
00349    osAcquireMutex(&netMutex);
00350 
00351    //Read the low word of the SMI register
00352    data = interface->nicDriver->readPhyReg(phyAddr, regAddr);
00353    //Read the high word of the SMI register
00354    data |= interface->nicDriver->readPhyReg(phyAddr, regAddr + 1) << 16;
00355 
00356    //Release exclusive access
00357    osReleaseMutex(&netMutex);
00358 
00359    //Return register value
00360    return data;
00361 }
00362 
00363 
00364 /**
00365  * @brief Dump SMI registers for debugging purpose
00366  * @param[in] interface Underlying network interface
00367  **/
00368 
00369 void lan9303DumpSmiReg(NetInterface *interface)
00370 {
00371    uint16_t i;
00372 
00373    //Loop through SMI registers
00374    for(i = 80; i < 512; i += 4)
00375    {
00376       //Display current SMI register
00377       TRACE_DEBUG("0x%03" PRIX16 ": 0x%08" PRIX32 "\r\n", i,
00378          lan9303ReadSmiReg(interface, i));
00379    }
00380 
00381    //Terminate with a line feed
00382    TRACE_DEBUG("\r\n");
00383 }
00384