lan9303_driver.c
Go to the documentation of this file.
1 /**
2  * @file lan9303_driver.c
3  * @brief LAN9303 Ethernet switch
4  *
5  * @section License
6  *
7  * Copyright (C) 2010-2018 Oryx Embedded SARL. All rights reserved.
8  *
9  * This file is part of CycloneTCP Open.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software Foundation,
23  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24  *
25  * @author Oryx Embedded SARL (www.oryx-embedded.com)
26  * @version 1.9.0
27  **/
28 
29 //Switch to the appropriate trace level
30 #define TRACE_LEVEL NIC_TRACE_LEVEL
31 
32 //Dependencies
33 #include "core/net.h"
35 #include "debug.h"
36 
37 
38 /**
39  * @brief LAN9303 Ethernet switch driver
40  **/
41 
43 {
49 };
50 
51 
52 /**
53  * @brief LAN9303 Ethernet switch initialization
54  * @param[in] interface Underlying network interface
55  * @return Error code
56  **/
57 
59 {
60  uint_t port;
61 
62  //Debug message
63  TRACE_INFO("Initializing LAN9303...\r\n");
64 
65  //Loop through ports
67  {
68  //Debug message
69  TRACE_INFO("Port %u:\r\n", port);
70  //Dump PHY registers for debugging purpose
71  lan9303DumpPhyReg(interface, port);
72  }
73 
74  //Force the TCP/IP stack to poll the link state at startup
75  interface->phyEvent = TRUE;
76  //Notify the TCP/IP stack of the event
78 
79  //Successful initialization
80  return NO_ERROR;
81 }
82 
83 
84 /**
85  * @brief Get link state
86  * @param[in] interface Underlying network interface
87  * @param[in] port Port number
88  * @return Link state
89  **/
90 
92 {
93  uint16_t status;
94  bool_t linkState;
95 
96  //Check port number
98  {
99  //Get exclusive access
101  //Read status register
102  status = lan9303ReadPhyReg(interface, port, LAN9303_PHY_REG_BMSR);
103  //Release exclusive access
105 
106  //Retrieve current link state
107  linkState = (status & BMSR_LINK_STATUS) ? TRUE : FALSE;
108  }
109  else
110  {
111  //The specified port number is not valid
112  linkState = FALSE;
113  }
114 
115  //Return link status
116  return linkState;
117 }
118 
119 
120 /**
121  * @brief LAN9303 timer handler
122  * @param[in] interface Underlying network interface
123  **/
124 
125 void lan9303Tick(NetInterface *interface)
126 {
127  uint_t port;
128  uint16_t status;
129  bool_t linkState;
130 
131  //Initialize link state
132  linkState = FALSE;
133 
134  //Loop through ports
136  {
137  //Read status register
138  status = lan9303ReadPhyReg(interface, port, LAN9303_PHY_REG_BMSR);
139 
140  //Retrieve current link state
141  if(status & BMSR_LINK_STATUS)
142  linkState = TRUE;
143  }
144 
145  //Link up event?
146  if(linkState)
147  {
148  if(!interface->linkState)
149  {
150  //Set event flag
151  interface->phyEvent = TRUE;
152  //Notify the TCP/IP stack of the event
154  }
155  }
156  //Link down event?
157  else
158  {
159  if(interface->linkState)
160  {
161  //Set event flag
162  interface->phyEvent = TRUE;
163  //Notify the TCP/IP stack of the event
165  }
166  }
167 }
168 
169 
170 /**
171  * @brief Enable interrupts
172  * @param[in] interface Underlying network interface
173  **/
174 
176 {
177 }
178 
179 
180 /**
181  * @brief Disable interrupts
182  * @param[in] interface Underlying network interface
183  **/
184 
186 {
187 }
188 
189 
190 /**
191  * @brief LAN9303 event handler
192  * @param[in] interface Underlying network interface
193  **/
194 
196 {
197  uint_t port;
198  uint16_t status;
199  bool_t linkState;
200 
201  //Initialize link state
202  linkState = FALSE;
203 
204  //Loop through ports
206  {
207  //Read status register
208  status = lan9303ReadPhyReg(interface, port, LAN9303_PHY_REG_BMSR);
209 
210  //Retrieve current link state
211  if(status & BMSR_LINK_STATUS)
212  linkState = TRUE;
213  }
214 
215  //Link up event?
216  if(linkState)
217  {
218  //Set current speed
219  interface->linkSpeed = NIC_LINK_SPEED_100MBPS;
220  //Set duplex mode
221  interface->duplexMode = NIC_FULL_DUPLEX_MODE;
222 
223  //Update link state
224  interface->linkState = TRUE;
225 
226  //Adjust MAC configuration parameters for proper operation
227  interface->nicDriver->updateMacConfig(interface);
228  }
229  else
230  {
231  //Update link state
232  interface->linkState = FALSE;
233  }
234 
235  //Process link state change event
236  nicNotifyLinkChange(interface);
237 }
238 
239 
240 /**
241  * @brief Write PHY register
242  * @param[in] interface Underlying network interface
243  * @param[in] port Port number
244  * @param[in] address PHY register address
245  * @param[in] data Register value
246  **/
247 
249  uint8_t port, uint8_t address, uint16_t data)
250 {
251  //Write the specified PHY register
252  interface->nicDriver->writePhyReg(port, address, data);
253 }
254 
255 
256 /**
257  * @brief Read PHY register
258  * @param[in] interface Underlying network interface
259  * @param[in] port Port number
260  * @param[in] address PHY register address
261  * @return Register value
262  **/
263 
264 uint16_t lan9303ReadPhyReg(NetInterface *interface,
265  uint8_t port, uint8_t address)
266 {
267  //Read the specified PHY register
268  return interface->nicDriver->readPhyReg(port, address);
269 }
270 
271 
272 /**
273  * @brief Dump PHY registers for debugging purpose
274  * @param[in] interface Underlying network interface
275  * @param[in] port Port number
276  **/
277 
278 void lan9303DumpPhyReg(NetInterface *interface, uint8_t port)
279 {
280  uint8_t i;
281 
282  //Loop through PHY registers
283  for(i = 0; i < 32; i++)
284  {
285  //Display current PHY register
286  TRACE_DEBUG("%02" PRIu8 ": 0x%04" PRIX16 "\r\n", i,
287  lan9303ReadPhyReg(interface, port, i));
288  }
289 
290  //Terminate with a line feed
291  TRACE_DEBUG("\r\n");
292 }
293 
294 
295 /**
296  * @brief Write SMI register
297  * @param[in] interface Underlying network interface
298  * @param[in] address System register address
299  * @param[in] data Register value
300  **/
301 
302 void lan9303WriteSmiReg(NetInterface *interface, uint16_t address,
303  uint32_t data)
304 {
305  uint8_t phyAddr;
306  uint8_t regAddr;
307 
308  //PHY address bit 4 is 1 for SMI commands. PHY address 3:0 form
309  //system register address bits 9:6
310  phyAddr = 0x10 | ((address >> 6) & 0x0F);
311 
312  //Register address field forms register address bits 5:1
313  regAddr = (address >> 1) & 0x1F;
314 
315  //Get exclusive access
317 
318  //Write the low word of the SMI register
319  interface->nicDriver->writePhyReg(phyAddr, regAddr, data & 0xFFFF);
320  //Write the high word of the SMI register
321  interface->nicDriver->writePhyReg(phyAddr, regAddr + 1, (data >> 16) & 0xFFFF);
322 
323  //Release exclusive access
325 }
326 
327 
328 /**
329  * @brief Read SMI register
330  * @param[in] interface Underlying network interface
331  * @param[in] address System register address
332  * @return Register value
333  **/
334 
335 uint32_t lan9303ReadSmiReg(NetInterface *interface, uint16_t address)
336 {
337  uint8_t phyAddr;
338  uint8_t regAddr;
339  uint32_t data;
340 
341  //PHY address bit 4 is 1 for SMI commands. PHY address 3:0 form
342  //system register address bits 9:6
343  phyAddr = 0x10 | ((address >> 6) & 0x0F);
344 
345  //Register address field forms register address bits 5:1
346  regAddr = (address >> 1) & 0x1F;
347 
348  //Get exclusive access
350 
351  //Read the low word of the SMI register
352  data = interface->nicDriver->readPhyReg(phyAddr, regAddr);
353  //Read the high word of the SMI register
354  data |= interface->nicDriver->readPhyReg(phyAddr, regAddr + 1) << 16;
355 
356  //Release exclusive access
358 
359  //Return register value
360  return data;
361 }
362 
363 
364 /**
365  * @brief Dump SMI registers for debugging purpose
366  * @param[in] interface Underlying network interface
367  **/
368 
370 {
371  uint16_t i;
372 
373  //Loop through SMI registers
374  for(i = 80; i < 512; i += 4)
375  {
376  //Display current SMI register
377  TRACE_DEBUG("0x%03" PRIX16 ": 0x%08" PRIX32 "\r\n", i,
378  lan9303ReadSmiReg(interface, i));
379  }
380 
381  //Terminate with a line feed
382  TRACE_DEBUG("\r\n");
383 }
void nicNotifyLinkChange(NetInterface *interface)
Process link state change event.
Definition: nic.c:298
void lan9303DisableIrq(NetInterface *interface)
Disable interrupts.
TCP/IP stack core.
Debugging facilities.
#define LAN9303_PORT2
const PhyDriver lan9303PhyDriver
LAN9303 Ethernet switch driver.
#define LAN9303_PORT1
#define BMSR_LINK_STATUS
Definition: ar8031_driver.h:95
void lan9303WriteSmiReg(NetInterface *interface, uint16_t address, uint32_t data)
Write SMI register.
void lan9303DumpPhyReg(NetInterface *interface, uint8_t port)
Dump PHY registers for debugging purpose.
void lan9303WritePhyReg(NetInterface *interface, uint8_t port, uint8_t address, uint16_t data)
Write PHY register.
uint32_t lan9303ReadSmiReg(NetInterface *interface, uint16_t address)
Read SMI register.
#define TRUE
Definition: os_port.h:48
uint16_t lan9303ReadPhyReg(NetInterface *interface, uint8_t port, uint8_t address)
Read PHY register.
bool_t lan9303GetLinkState(NetInterface *interface, uint8_t port)
Get link state.
PHY driver.
Definition: nic.h:196
void lan9303DumpSmiReg(NetInterface *interface)
Dump SMI registers for debugging purpose.
#define LAN9303_PHY_REG_BMSR
void lan9303EnableIrq(NetInterface *interface)
Enable interrupts.
LAN9303 Ethernet switch.
#define TRACE_INFO(...)
Definition: debug.h:86
uint16_t regAddr
Success.
Definition: error.h:42
Ipv6Addr address
OsEvent netEvent
Definition: net.c:72
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
error_t
Error codes.
Definition: error.h:40
unsigned int uint_t
Definition: compiler_port.h:43
void osReleaseMutex(OsMutex *mutex)
Release ownership of the specified mutex object.
uint8_t data[]
Definition: dtls_misc.h:167
#define NetInterface
Definition: net.h:34
void lan9303Tick(NetInterface *interface)
LAN9303 timer handler.
uint16_t port
Definition: dns_common.h:221
void lan9303EventHandler(NetInterface *interface)
LAN9303 event handler.
OsMutex netMutex
Definition: net.c:70
error_t lan9303Init(NetInterface *interface)
LAN9303 Ethernet switch initialization.
#define FALSE
Definition: os_port.h:44
int bool_t
Definition: compiler_port.h:47
void osAcquireMutex(OsMutex *mutex)
Acquire ownership of the specified mutex object.
#define TRACE_DEBUG(...)
Definition: debug.h:98