Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
lan9303.c
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
Generated on Tue Jul 12 2022 17:10:14 by
1.7.2