Webserver+3d print

Dependents:   Nucleo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ksz8873.c Source File

ksz8873.c

Go to the documentation of this file.
00001 /**
00002  * @file ksz8873.c
00003  * @brief KSZ8873 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/ksz8873.h"
00035 #include "debug.h"
00036 
00037 
00038 /**
00039  * @brief KSZ8873 Ethernet switch driver
00040  **/
00041 
00042 const PhyDriver ksz8873PhyDriver =
00043 {
00044    ksz8873Init,
00045    ksz8873Tick,
00046    ksz8873EnableIrq,
00047    ksz8873DisableIrq,
00048    ksz8873EventHandler,
00049 };
00050 
00051 
00052 /**
00053  * @brief KSZ8873 Ethernet switch initialization
00054  * @param[in] interface Underlying network interface
00055  * @return Error code
00056  **/
00057 
00058 error_t ksz8873Init(NetInterface *interface)
00059 {
00060    uint_t port;
00061 
00062    //Debug message
00063    TRACE_INFO("Initializing KSZ8873...\r\n");
00064 
00065    //Loop through ports
00066    for(port = KSZ8873_PORT1; port <= KSZ8873_PORT2; port++)
00067    {
00068       //Debug message
00069       TRACE_INFO("Port %u:\r\n", port);
00070       //Dump PHY registers for debugging purpose
00071       ksz8873DumpPhyReg(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 ksz8873GetLinkState(NetInterface *interface, uint8_t port)
00092 {
00093    uint16_t status;
00094    bool_t linkState;
00095 
00096    //Check port number
00097    if(port >= KSZ8873_PORT1 && port <= KSZ8873_PORT2)
00098    {
00099       //Get exclusive access
00100       osAcquireMutex(&netMutex);
00101       //Read status register
00102       status = ksz8873ReadPhyReg(interface, port, KSZ8873_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 KSZ8873 timer handler
00122  * @param[in] interface Underlying network interface
00123  **/
00124 
00125 void ksz8873Tick(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 = KSZ8873_PORT1; port <= KSZ8873_PORT2; port++)
00136    {
00137       //Read status register
00138       status = ksz8873ReadPhyReg(interface, port, KSZ8873_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 ksz8873EnableIrq(NetInterface *interface)
00176 {
00177 }
00178 
00179 
00180 /**
00181  * @brief Disable interrupts
00182  * @param[in] interface Underlying network interface
00183  **/
00184 
00185 void ksz8873DisableIrq(NetInterface *interface)
00186 {
00187 }
00188 
00189 
00190 /**
00191  * @brief KSZ8873 event handler
00192  * @param[in] interface Underlying network interface
00193  **/
00194 
00195 void ksz8873EventHandler(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 = KSZ8873_PORT1; port <= KSZ8873_PORT2; port++)
00206    {
00207       //Read status register
00208       status = ksz8873ReadPhyReg(interface, port, KSZ8873_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 ksz8873WritePhyReg(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 ksz8873ReadPhyReg(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 ksz8873DumpPhyReg(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, ksz8873ReadPhyReg(interface, port, i));
00287    }
00288 
00289    //Terminate with a line feed
00290    TRACE_DEBUG("\r\n");
00291 }
00292