lan9303_driver.c
Go to the documentation of this file.
1 /**
2  * @file lan9303_driver.c
3  * @brief LAN9303 3-port Ethernet switch driver
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2024 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneTCP Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.4.4
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL NIC_TRACE_LEVEL
33 
34 //Dependencies
35 #include "core/net.h"
37 #include "debug.h"
38 
39 
40 /**
41  * @brief LAN9303 Ethernet switch driver
42  **/
43 
45 {
69 };
70 
71 
72 /**
73  * @brief LAN9303 Ethernet switch initialization
74  * @param[in] interface Underlying network interface
75  * @return Error code
76  **/
77 
79 {
80  uint_t port;
81  uint32_t value;
82 
83  //Debug message
84  TRACE_INFO("Initializing LAN9303...\r\n");
85 
86  //Initialize serial management interface
87  if(interface->smiDriver != NULL)
88  {
89  interface->smiDriver->init();
90  }
91 
92  //Chip-level reset/configuration completion can be determined by first
93  //polling the BYTE_TEST register
94  do
95  {
96  //Read BYTE_TEST register
98 
99  //The returned data is invalid until the serial interface reset is
100  //complete
101  } while(value != LAN9303_BYTE_TEST_DEFAULT);
102 
103  //The completion of the entire chip-level reset must then be determined
104  //by polling the READY bit of the HW_CFG register
105  do
106  {
107  //Read HW_CFG register
108  value = lan9303ReadSysReg(interface, LAN9303_HW_CFG);
109 
110  //When set, the READY bit indicates that the reset has completed and
111  //the device is ready to be accessed
112  } while((value & LAN9303_HW_CFG_DEVICE_READY) == 0);
113 
114 #if (ETH_PORT_TAGGING_SUPPORT == ENABLED)
115  //Enable special VLAN tagging mode
118 
119  //Configure egress VLAN tagging rules
122 #else
123  //Disable special VLAN tagging mode
125 
126  //Revert to default configuration
128 #endif
129 
130 #if (ETH_PORT_TAGGING_SUPPORT == ENABLED)
131  //Port separation mode?
132  if(interface->port != 0)
133  {
134  //Enable port mirroring
141 
142  //Configure port state
147  }
148  else
149 #endif
150  {
151  //Disable port mirroring
153 
154  //Configure port state
159  }
160 
161  //Configure port 0 receive parameters
164 
165  //Configure port 0 transmit parameters
169 
170  //Loop through the ports
172  {
173  //Debug message
174  TRACE_DEBUG("Port %u:\r\n", port);
175  //Dump PHY registers for debugging purpose
176  lan9303DumpPhyReg(interface, port);
177  }
178 
179  //Perform custom configuration
180  lan9303InitHook(interface);
181 
182  //Force the TCP/IP stack to poll the link state at startup
183  interface->phyEvent = TRUE;
184  //Notify the TCP/IP stack of the event
186 
187  //Successful initialization
188  return NO_ERROR;
189 }
190 
191 
192 /**
193  * @brief LAN9303 custom configuration
194  * @param[in] interface Underlying network interface
195  **/
196 
197 __weak_func void lan9303InitHook(NetInterface *interface)
198 {
199 }
200 
201 
202 /**
203  * @brief LAN9303 timer handler
204  * @param[in] interface Underlying network interface
205  **/
206 
207 void lan9303Tick(NetInterface *interface)
208 {
209  uint_t port;
210  bool_t linkState;
211 
212 #if (ETH_PORT_TAGGING_SUPPORT == ENABLED)
213  //Port separation mode?
214  if(interface->port != 0)
215  {
216  uint_t i;
217  NetInterface *virtualInterface;
218 
219  //Loop through network interfaces
220  for(i = 0; i < NET_INTERFACE_COUNT; i++)
221  {
222  //Point to the current interface
223  virtualInterface = &netInterface[i];
224 
225  //Check whether the current virtual interface is attached to the
226  //physical interface
227  if(virtualInterface == interface ||
228  virtualInterface->parent == interface)
229  {
230  //Retrieve current link state
231  linkState = lan9303GetLinkState(interface, virtualInterface->port);
232 
233  //Link up or link down event?
234  if(linkState != virtualInterface->linkState)
235  {
236  //Set event flag
237  interface->phyEvent = TRUE;
238  //Notify the TCP/IP stack of the event
240  }
241  }
242  }
243  }
244  else
245 #endif
246  {
247  //Initialize link state
248  linkState = FALSE;
249 
250  //Loop through the ports
252  {
253  //Retrieve current link state
254  if(lan9303GetLinkState(interface, port))
255  {
256  linkState = TRUE;
257  }
258  }
259 
260  //Link up or link down event?
261  if(linkState != interface->linkState)
262  {
263  //Set event flag
264  interface->phyEvent = TRUE;
265  //Notify the TCP/IP stack of the event
267  }
268  }
269 }
270 
271 
272 /**
273  * @brief Enable interrupts
274  * @param[in] interface Underlying network interface
275  **/
276 
278 {
279 }
280 
281 
282 /**
283  * @brief Disable interrupts
284  * @param[in] interface Underlying network interface
285  **/
286 
288 {
289 }
290 
291 
292 /**
293  * @brief LAN9303 event handler
294  * @param[in] interface Underlying network interface
295  **/
296 
298 {
299  uint_t port;
300  bool_t linkState;
301 
302 #if (ETH_PORT_TAGGING_SUPPORT == ENABLED)
303  //Port separation mode?
304  if(interface->port != 0)
305  {
306  uint_t i;
307  uint16_t status;
308  NetInterface *virtualInterface;
309 
310  //Loop through network interfaces
311  for(i = 0; i < NET_INTERFACE_COUNT; i++)
312  {
313  //Point to the current interface
314  virtualInterface = &netInterface[i];
315 
316  //Check whether the current virtual interface is attached to the
317  //physical interface
318  if(virtualInterface == interface ||
319  virtualInterface->parent == interface)
320  {
321  //Get the port number associated with the current interface
322  port = virtualInterface->port;
323 
324  //Valid port?
325  if(port >= LAN9303_PORT1 && port <= LAN9303_PORT2)
326  {
327  //Retrieve current link state
328  linkState = lan9303GetLinkState(interface, port);
329 
330  //Link up event?
331  if(linkState && !virtualInterface->linkState)
332  {
333  //Adjust MAC configuration parameters for proper operation
334  interface->linkSpeed = NIC_LINK_SPEED_100MBPS;
335  interface->duplexMode = NIC_FULL_DUPLEX_MODE;
336  interface->nicDriver->updateMacConfig(interface);
337 
338  //Read PHY special control/status register
339  status = lan9303ReadPhyReg(interface, port, LAN9303_PSCSR);
340 
341  //Check current operation mode
342  switch(status & LAN9303_PSCSR_SPEED)
343  {
344  //10BASE-T half-duplex
346  virtualInterface->linkSpeed = NIC_LINK_SPEED_10MBPS;
347  virtualInterface->duplexMode = NIC_HALF_DUPLEX_MODE;
348  break;
349 
350  //10BASE-T full-duplex
352  virtualInterface->linkSpeed = NIC_LINK_SPEED_10MBPS;
353  virtualInterface->duplexMode = NIC_FULL_DUPLEX_MODE;
354  break;
355 
356  //100BASE-TX half-duplex
358  virtualInterface->linkSpeed = NIC_LINK_SPEED_100MBPS;
359  virtualInterface->duplexMode = NIC_HALF_DUPLEX_MODE;
360  break;
361 
362  //100BASE-TX full-duplex
364  virtualInterface->linkSpeed = NIC_LINK_SPEED_100MBPS;
365  virtualInterface->duplexMode = NIC_FULL_DUPLEX_MODE;
366  break;
367 
368  //Unknown operation mode
369  default:
370  //Debug message
371  TRACE_WARNING("Invalid operation mode!\r\n");
372  break;
373  }
374 
375  //Update link state
376  virtualInterface->linkState = TRUE;
377 
378  //Process link state change event
379  nicNotifyLinkChange(virtualInterface);
380  }
381  //Link down event
382  else if(!linkState && virtualInterface->linkState)
383  {
384  //Update link state
385  virtualInterface->linkState = FALSE;
386 
387  //Process link state change event
388  nicNotifyLinkChange(virtualInterface);
389  }
390  }
391  }
392  }
393  }
394  else
395 #endif
396  {
397  //Initialize link state
398  linkState = FALSE;
399 
400  //Loop through the ports
402  {
403  //Retrieve current link state
404  if(lan9303GetLinkState(interface, port))
405  {
406  linkState = TRUE;
407  }
408  }
409 
410  //Link up event?
411  if(linkState)
412  {
413  //Adjust MAC configuration parameters for proper operation
414  interface->linkSpeed = NIC_LINK_SPEED_100MBPS;
415  interface->duplexMode = NIC_FULL_DUPLEX_MODE;
416  interface->nicDriver->updateMacConfig(interface);
417 
418  //Update link state
419  interface->linkState = TRUE;
420  }
421  else
422  {
423  //Update link state
424  interface->linkState = FALSE;
425  }
426 
427  //Process link state change event
428  nicNotifyLinkChange(interface);
429  }
430 }
431 
432 
433 /**
434  * @brief Add special VLAN tag to Ethernet frame
435  * @param[in] interface Underlying network interface
436  * @param[in] buffer Multi-part buffer containing the payload
437  * @param[in,out] offset Offset to the first payload byte
438  * @param[in] ancillary Additional options passed to the stack along with
439  * the packet
440  * @return Error code
441  **/
442 
444  size_t *offset, NetTxAncillary *ancillary)
445 {
446  error_t error;
447 
448  //Initialize status code
449  error = NO_ERROR;
450 
451 #if (ETH_PORT_TAGGING_SUPPORT == ENABLED)
452  //Valid port?
453  if(ancillary->port <= LAN9303_PORT2)
454  {
455  //Is there enough space for the VLAN tag?
456  if(*offset >= sizeof(VlanTag))
457  {
458  EthHeader *header;
459  VlanTag *vlanTag;
460 
461  //Make room for the special VLAN tag
462  *offset -= sizeof(VlanTag);
463  //Point to the beginning of the frame
464  header = netBufferAt(buffer, *offset, 0);
465 
466  //Move the Ethernet header to make room for the special VLAN tag
467  osMemmove(header, (uint8_t *) header + sizeof(VlanTag),
468  sizeof(EthHeader));
469 
470  //The special VLAN tag is a normal VLAN tag where the VID field is
471  //used as the destination port indicator
472  vlanTag = (VlanTag *) header->data;
473 
474  //Default port number?
475  if(ancillary->port == 0)
476  {
477  //If VID bit 3 is one, then the normal ALR lookup is performed
478  vlanTag->tci = htons(LAN9303_VID_ALR_LOOKUP);
479  }
480  else
481  {
482  //VID bits 0 and 1 specify the destination port
483  vlanTag->tci = htons(LAN9303_VID_STP_OVERRIDE | ancillary->port);
484  }
485 
486  //The EtherType field indicates which protocol is encapsulated in
487  //the payload
488  vlanTag->type = header->type;
489 
490  //A distinct Ethertype has been allocated for use in the TPID field
491  header->type = HTONS(ETH_TYPE_VLAN);
492  }
493  else
494  {
495  //Report an error
496  error = ERROR_INVALID_PARAMETER;
497  }
498  }
499  else
500  {
501  //The port number is not valid
502  error = ERROR_INVALID_PORT;
503  }
504 #endif
505 
506  //Return status code
507  return error;
508 }
509 
510 
511 /**
512  * @brief Decode special VLAN tag from incoming Ethernet frame
513  * @param[in] interface Underlying network interface
514  * @param[in,out] frame Pointer to the received Ethernet frame
515  * @param[in,out] length Length of the frame, in bytes
516  * @param[in,out] ancillary Additional options passed to the stack along with
517  * the packet
518  * @return Error code
519  **/
520 
521 error_t lan9303UntagFrame(NetInterface *interface, uint8_t **frame,
522  size_t *length, NetRxAncillary *ancillary)
523 {
524  error_t error;
525 #if (ETH_PORT_TAGGING_SUPPORT == ENABLED)
526  EthHeader *header;
527  VlanTag *vlanTag;
528 #endif
529 
530  //Initialize status code
531  error = NO_ERROR;
532 
533 #if (ETH_PORT_TAGGING_SUPPORT == ENABLED)
534  //Point to the beginning of the frame
535  header = (EthHeader *) *frame;
536 
537  //Check whether VLAN tagging is used
538  if(ntohs(header->type) == ETH_TYPE_VLAN)
539  {
540  //Valid Ethernet frame received?
541  if(*length >= (sizeof(EthHeader) + sizeof(VlanTag)))
542  {
543  //The special VLAN tag is a normal VLAN tag where the VID field is
544  //used as a source port indicator
545  vlanTag = (VlanTag *) header->data;
546 
547  //VID bits 0 and 1 specify the source port
548  ancillary->port = ntohs(vlanTag->tci) & LAN9303_VID_SRC_PORT;
549  //Fix the value of the EtherType field
550  header->type = vlanTag->type;
551 
552  //Strip the VLAN tag from the Ethernet frame
553  osMemmove(*frame + sizeof(VlanTag), *frame, sizeof(EthHeader));
554 
555  //Point to the Ethernet frame header
556  *frame += sizeof(VlanTag);
557  //Retrieve the length of the original frame
558  *length -= sizeof(VlanTag);
559 
560  //Successful processing
561  error = NO_ERROR;
562  }
563  else
564  {
565  //Drop the received frame
566  error = ERROR_INVALID_LENGTH;
567  }
568  }
569  else
570  {
571  //If the interface is configured to accept VLAN-tagged frames, then
572  //drop the incoming Ethernet frame
573  error = ERROR_WRONG_IDENTIFIER;
574  }
575 #endif
576 
577  //Return status code
578  return error;
579 }
580 
581 
582 /**
583  * @brief Get link state
584  * @param[in] interface Underlying network interface
585  * @param[in] port Port number
586  * @return Link state
587  **/
588 
590 {
591  uint16_t status;
592  bool_t linkState;
593 
594  //Check port number
595  if(port >= LAN9303_PORT1 && port <= LAN9303_PORT2)
596  {
597  //Read status register
598  status = lan9303ReadPhyReg(interface, port, LAN9303_BMSR);
599 
600  //Retrieve current link state
601  linkState = (status & LAN9303_BMSR_LINK_STATUS) ? TRUE : FALSE;
602  }
603  else
604  {
605  //The specified port number is not valid
606  linkState = FALSE;
607  }
608 
609  //Return link status
610  return linkState;
611 }
612 
613 
614 /**
615  * @brief Get link speed
616  * @param[in] interface Underlying network interface
617  * @param[in] port Port number
618  * @return Link speed
619  **/
620 
621 uint32_t lan9303GetLinkSpeed(NetInterface *interface, uint8_t port)
622 {
623  uint16_t status;
624  uint32_t linkSpeed;
625 
626  //Check port number
627  if(port >= LAN9303_PORT1 && port <= LAN9303_PORT2)
628  {
629  //Read PHY special control/status register
630  status = lan9303ReadPhyReg(interface, port, LAN9303_PSCSR);
631 
632  //Check current operation mode
633  switch(status & LAN9303_PSCSR_SPEED)
634  {
635  //10BASE-T
638  linkSpeed = NIC_LINK_SPEED_10MBPS;
639  break;
640 
641  //100BASE-TX
644  linkSpeed = NIC_LINK_SPEED_100MBPS;
645  break;
646 
647  //Unknown operation mode
648  default:
649  linkSpeed = NIC_LINK_SPEED_UNKNOWN;
650  break;
651  }
652  }
653  else
654  {
655  //The specified port number is not valid
656  linkSpeed = NIC_LINK_SPEED_UNKNOWN;
657  }
658 
659  //Return link status
660  return linkSpeed;
661 }
662 
663 
664 /**
665  * @brief Get duplex mode
666  * @param[in] interface Underlying network interface
667  * @param[in] port Port number
668  * @return Duplex mode
669  **/
670 
672 {
673  uint16_t status;
674  NicDuplexMode duplexMode;
675 
676  //Check port number
677  if(port >= LAN9303_PORT1 && port <= LAN9303_PORT2)
678  {
679  //Read PHY special control/status register
680  status = lan9303ReadPhyReg(interface, port, LAN9303_PSCSR);
681 
682  //Check current operation mode
683  switch(status & LAN9303_PSCSR_SPEED)
684  {
685  //10BASE-T or 100BASE-TX half-duplex
688  duplexMode = NIC_HALF_DUPLEX_MODE;
689  break;
690 
691  //10BASE-T or 100BASE-TX full-duplex
694  duplexMode = NIC_FULL_DUPLEX_MODE;
695  break;
696 
697  //Unknown operation mode
698  default:
699  duplexMode = NIC_UNKNOWN_DUPLEX_MODE;
700  break;
701  }
702  }
703  else
704  {
705  //The specified port number is not valid
706  duplexMode = NIC_UNKNOWN_DUPLEX_MODE;
707  }
708 
709  //Return duplex mode
710  return duplexMode;
711 }
712 
713 
714 /**
715  * @brief Set port state
716  * @param[in] interface Underlying network interface
717  * @param[in] port Port number
718  * @param[in] state Port state
719  **/
720 
721 void lan9303SetPortState(NetInterface *interface, uint8_t port,
722  SwitchPortState state)
723 {
724  uint32_t temp;
725 
726  //Read port state register
727  temp = lan9303ReadSwitchReg(interface, LAN9303_SWE_PORT_STATE);
728 
729  //Check port number
730  if(port == LAN9303_PORT1)
731  {
732  //Clear current configuration
734 
735  //Update port 1 state
736  switch(state)
737  {
740  break;
743  break;
746  break;
747  default:
749  break;
750  }
751  }
752  else if(port == LAN9303_PORT2)
753  {
754  //Clear current configuration
756 
757  //Update port 2 state
758  switch(state)
759  {
762  break;
765  break;
768  break;
769  default:
771  break;
772  }
773  }
774  else
775  {
776  //The specified port number is not valid
777  }
778 
779  //Write the value back to port state register
781 }
782 
783 
784 /**
785  * @brief Get port state
786  * @param[in] interface Underlying network interface
787  * @param[in] port Port number
788  * @return Port state
789  **/
790 
792 {
793  uint32_t temp;
794  SwitchPortState state;
795 
796  //Read port state register
797  temp = lan9303ReadSwitchReg(interface, LAN9303_SWE_PORT_STATE);
798 
799  //Check port number
800  if(port == LAN9303_PORT1)
801  {
802  //Check port 1 state
803  switch(temp & LAN9303_SWE_PORT_STATE_PORT1)
804  {
807  break;
810  break;
813  break;
814  default:
816  break;
817  }
818  }
819  else if(port == LAN9303_PORT2)
820  {
821  //Check port 2 state
822  switch(temp & LAN9303_SWE_PORT_STATE_PORT2)
823  {
826  break;
829  break;
832  break;
833  default:
835  break;
836  }
837  }
838  else
839  {
840  //The specified port number is not valid
842  }
843 
844  //Return port state
845  return state;
846 }
847 
848 
849 /**
850  * @brief Set aging time for dynamic filtering entries
851  * @param[in] interface Underlying network interface
852  * @param[in] agingTime Aging time, in seconds
853  **/
854 
855 void lan9303SetAgingTime(NetInterface *interface, uint32_t agingTime)
856 {
857  //The aging period is fixed to 5 minutes
858 }
859 
860 
861 /**
862  * @brief Enable IGMP snooping
863  * @param[in] interface Underlying network interface
864  * @param[in] enable Enable or disable IGMP snooping
865  **/
866 
868 {
869  uint32_t temp;
870 
871  //Read the Switch Engine Global Ingress Configuration register
873 
874  //Enable or disable IGMP monitoring
875  if(enable)
876  {
878  }
879  else
880  {
882  }
883 
884  //Set the port bit map where IGMP packets are sent
887 
888  //Write the value back to Switch Engine Global Ingress Configuration register
890 }
891 
892 
893 /**
894  * @brief Enable MLD snooping
895  * @param[in] interface Underlying network interface
896  * @param[in] enable Enable or disable MLD snooping
897  **/
898 
900 {
901  //Not implemented
902 }
903 
904 
905 /**
906  * @brief Enable reserved multicast table
907  * @param[in] interface Underlying network interface
908  * @param[in] enable Enable or disable reserved group addresses
909  **/
910 
912 {
913  uint_t i;
914  SwitchFdbEntry entry;
915 
916  //The reserved group addresses are in the range of 01-80-C2-00-00-00 to
917  //01-80-C2-00-00-0F
918  for(i = 0; i <= 15; i++)
919  {
920  //Specify the reserved group address to be added or removed
921  entry.macAddr.b[0] = 0x01;
922  entry.macAddr.b[1] = 0x80;
923  entry.macAddr.b[2] = 0xC2;
924  entry.macAddr.b[3] = 0x00;
925  entry.macAddr.b[4] = 0x00;
926  entry.macAddr.b[5] = i;
927 
928  //Format forwarding database entry
929  entry.srcPort = 0;
931  entry.override = TRUE;
932 
933  //Update the static MAC table
934  if(enable)
935  {
936  lan9303AddStaticFdbEntry(interface, &entry);
937  }
938  else
939  {
940  lan9303DeleteStaticFdbEntry(interface, &entry);
941  }
942  }
943 }
944 
945 
946 /**
947  * @brief Add a new entry to the static MAC table
948  * @param[in] interface Underlying network interface
949  * @param[in] entry Pointer to the forwarding database entry
950  * @return Error code
951  **/
952 
954  const SwitchFdbEntry *entry)
955 {
956  uint32_t value;
957  uint32_t ports;
958 
959  //Check whether the forward port is the CPU port
960  if(entry->destPorts == SWITCH_CPU_PORT_MASK)
961  {
962  ports = LAN9303_PORT0_MASK;
963  }
964  else
965  {
966  ports = entry->destPorts & LAN9303_PORT_MASK;
967  }
968 
969  //Valid forward ports?
970  if(ports != 0)
971  {
972  //Write SWE_ALR_WR_DAT_0 and SWE_ALR_WR_DAT_1 with the desired MAC
973  //address and control bits
975 
976  //When the Override bit set, packets received with a destination
977  //address that matches the MAC address in the SWE_ALR_WR_DAT_1 and
978  //SWE_ALR_WR_DAT_0 registers will be forwarded regardless of the port
979  //state
980  if(entry->override)
981  {
983  }
984 
985  //Set the ports associated with this MAC address
986  switch(ports)
987  {
988  case LAN9303_PORT0_MASK:
990  break;
991  case LAN9303_PORT1_MASK:
993  break;
994  case LAN9303_PORT2_MASK:
996  break;
999  break;
1000  case LAN9303_PORT0_2_MASK:
1002  break;
1003  case LAN9303_PORT1_2_MASK:
1005  break;
1006  default:
1008  break;
1009  }
1010  }
1011  else
1012  {
1013  //An entry can be deleted by setting the Valid bit to 0
1015  }
1016 
1017  //Copy MAC address (last 16 bits)
1018  value |= entry->macAddr.b[4] | (entry->macAddr.b[5] << 8);
1019  //Write SWE_ALR_WR_DAT_1 register
1021 
1022  //Copy MAC address (first 32 bits)
1023  value = entry->macAddr.b[0] | (entry->macAddr.b[1] << 8) |
1024  (entry->macAddr.b[2] << 16) | (entry->macAddr.b[3] << 24);
1025 
1026  //Write SWE_ALR_WR_DAT_0 register
1028 
1029  //Write the SWE_ALR_CMD register
1032 
1033  //Poll the Make Pending bit in the SWE_ALR_CMD_STS register until it is
1034  //cleared
1035  do
1036  {
1037  //Read the SWE_ALR_CMD_STS register
1039 
1040  //Check the Make Pending bit
1041  } while((value & LAN9303_SWE_ALR_CMD_STS_MAKE_PENDING) != 0);
1042 
1043  //Clear the SWE_ALR_CMD register
1045 
1046  //Successful processing
1047  return NO_ERROR;
1048 }
1049 
1050 
1051 /**
1052  * @brief Remove an entry from the static MAC table
1053  * @param[in] interface Underlying network interface
1054  * @param[in] entry Forwarding database entry to remove from the table
1055  * @return Error code
1056  **/
1057 
1059  const SwitchFdbEntry *entry)
1060 {
1061  uint32_t value;
1062 
1063  //An entry can be deleted by setting the Valid bit to 0
1065 
1066  //Specify the MAC address to remove (last 16 bits)
1067  value |= entry->macAddr.b[4] | (entry->macAddr.b[5] << 8);
1068  //Write SWE_ALR_WR_DAT_1 register
1070 
1071  //Specify the MAC address to remove (first 32 bits)
1072  value = entry->macAddr.b[0] | (entry->macAddr.b[1] << 8) |
1073  (entry->macAddr.b[2] << 16) | (entry->macAddr.b[3] << 24);
1074 
1075  //Write SWE_ALR_WR_DAT_0 register
1077 
1078  //Write the SWE_ALR_CMD register
1081 
1082  //Poll the Make Pending bit in the SWE_ALR_CMD_STS register until it is
1083  //cleared
1084  do
1085  {
1086  //Read the SWE_ALR_CMD_STS register
1088 
1089  //Check the Make Pending bit
1090  } while((value & LAN9303_SWE_ALR_CMD_STS_MAKE_PENDING) != 0);
1091 
1092  //Clear the SWE_ALR_CMD register
1094 
1095  //Successful processing
1096  return NO_ERROR;
1097 }
1098 
1099 
1100 /**
1101  * @brief Read an entry from the static MAC table
1102  * @param[in] interface Underlying network interface
1103  * @param[in] index Zero-based index of the entry to read
1104  * @param[out] entry Pointer to the forwarding database entry
1105  * @return Error code
1106  **/
1107 
1109  SwitchFdbEntry *entry)
1110 {
1111  uint32_t value;
1112 
1113  //Loop through the ALR table
1114  while(1)
1115  {
1116  //Out of bound index?
1117  if(index >= LAN9303_ALR_TABLE_SIZE)
1118  return ERROR_END_OF_TABLE;
1119 
1120  //First entry?
1121  if(index == 0)
1122  {
1124  }
1125  else
1126  {
1128  }
1129 
1130  //Write the SWE_ALR_CMD register
1132  //Clear the SWE_ALR_CMD register
1134 
1135  //Poll the Valid and End of Table bits in the SWE_ALR_RD_DAT_1 register
1136  //until either is set
1137  while(1)
1138  {
1139  //Read SWE_ALR_RD_DAT_1 register
1141 
1142  //If the End of Table bit is set, then exit
1144  {
1145  return ERROR_END_OF_TABLE;
1146  }
1147 
1148  //If the Valid bit is set, then the entry is valid
1150  {
1151  break;
1152  }
1153  }
1154 
1155  //Static entry?
1157  {
1158  break;
1159  }
1160 
1161  //Skip dynamic entries
1162  index++;
1163  }
1164 
1165  //Store the data from SWE_ALR_RD_DAT_0 and SWE_ALR_RD_DAT_1 registers
1166  entry->srcPort = 0;
1167  entry->override = FALSE;
1168 
1169  //Retrieve the ports associated with this MAC address
1171  {
1173  entry->destPorts = LAN9303_PORT0_MASK;
1174  break;
1176  entry->destPorts = LAN9303_PORT1_MASK;
1177  break;
1179  entry->destPorts = LAN9303_PORT2_MASK;
1180  break;
1183  break;
1186  break;
1189  break;
1192  break;
1193  default:
1194  entry->destPorts = 0;
1195  break;
1196  }
1197 
1198  //Copy MAC address (last 16 bits)
1199  entry->macAddr.b[4] = value & 0xFF;
1200  entry->macAddr.b[5] = (value >> 8) & 0xFF;
1201 
1202  //Read SWE_ALR_RD_DAT_0 register
1204 
1205  //Copy MAC address (first 32 bits)
1206  entry->macAddr.b[0] = value & 0xFF;
1207  entry->macAddr.b[1] = (value >> 8) & 0xFF;
1208  entry->macAddr.b[2] = (value >> 16) & 0xFF;
1209  entry->macAddr.b[3] = (value >> 24) & 0xFF;
1210 
1211  //Successful processing
1212  return NO_ERROR;
1213 }
1214 
1215 
1216 /**
1217  * @brief Flush static MAC table
1218  * @param[in] interface Underlying network interface
1219  **/
1220 
1222 {
1223  error_t error;
1224  uint_t i;
1225  SwitchFdbEntry entry;
1226 
1227  //Loop through the ALR table
1228  for(i = 0; i < LAN9303_ALR_TABLE_SIZE; i++)
1229  {
1230  //Read current entry
1231  error = lan9303GetStaticFdbEntry(interface, i, &entry);
1232 
1233  //Valid entry?
1234  if(!error)
1235  {
1236  //An entry can be deleted by setting the Valid bit to 0
1237  lan9303DeleteStaticFdbEntry(interface, &entry);
1238  }
1239  else
1240  {
1241  //The end of the table has been reached
1242  break;
1243  }
1244  }
1245 }
1246 
1247 
1248 /**
1249  * @brief Read an entry from the dynamic MAC table
1250  * @param[in] interface Underlying network interface
1251  * @param[in] index Zero-based index of the entry to read
1252  * @param[out] entry Pointer to the forwarding database entry
1253  * @return Error code
1254  **/
1255 
1257  SwitchFdbEntry *entry)
1258 {
1259  uint32_t value;
1260 
1261  //Loop through the ALR table
1262  while(1)
1263  {
1264  //Out of bound index?
1265  if(index >= LAN9303_ALR_TABLE_SIZE)
1266  return ERROR_END_OF_TABLE;
1267 
1268  //First entry?
1269  if(index == 0)
1270  {
1272  }
1273  else
1274  {
1276  }
1277 
1278  //Write the SWE_ALR_CMD register
1280  //Clear the SWE_ALR_CMD register
1282 
1283  //Poll the Valid and End of Table bits in the SWE_ALR_RD_DAT_1 register
1284  //until either is set
1285  while(1)
1286  {
1287  //Read SWE_ALR_RD_DAT_1 register
1289 
1290  //If the End of Table bit is set, then exit
1292  {
1293  return ERROR_END_OF_TABLE;
1294  }
1295 
1296  //If the Valid bit is set, then the entry is valid
1298  {
1299  break;
1300  }
1301  }
1302 
1303  //Dynamic entry?
1305  {
1306  break;
1307  }
1308 
1309  //Skip static entries
1310  index++;
1311  }
1312 
1313  //Store the data from SWE_ALR_RD_DAT_0 and SWE_ALR_RD_DAT_1 registers
1314  entry->destPorts = 0;
1315  entry->override = FALSE;
1316 
1317  //Retrieve the port associated with this MAC address
1319  {
1321  entry->srcPort = LAN9303_PORT0;
1322  break;
1324  entry->srcPort = LAN9303_PORT1;
1325  break;
1327  entry->srcPort = LAN9303_PORT2;
1328  break;
1329  default:
1330  entry->srcPort = 0;
1331  break;
1332  }
1333 
1334  //Copy MAC address (last 16 bits)
1335  entry->macAddr.b[4] = value & 0xFF;
1336  entry->macAddr.b[5] = (value >> 8) & 0xFF;
1337 
1338  //Read SWE_ALR_RD_DAT_0 register
1340 
1341  //Copy MAC address (first 32 bits)
1342  entry->macAddr.b[0] = value & 0xFF;
1343  entry->macAddr.b[1] = (value >> 8) & 0xFF;
1344  entry->macAddr.b[2] = (value >> 16) & 0xFF;
1345  entry->macAddr.b[3] = (value >> 24) & 0xFF;
1346 
1347  //Successful processing
1348  return NO_ERROR;
1349 }
1350 
1351 
1352 /**
1353  * @brief Flush dynamic MAC table
1354  * @param[in] interface Underlying network interface
1355  * @param[in] port Port number
1356  **/
1357 
1359 {
1360  error_t error;
1361  uint_t i;
1362  uint32_t value;
1363  SwitchFdbEntry entry;
1364 
1365  //Loop through the ALR table
1366  for(i = 0; i < LAN9303_ALR_TABLE_SIZE; i++)
1367  {
1368  //Read current entry
1369  error = lan9303GetDynamicFdbEntry(interface, i, &entry);
1370 
1371  //Valid entry?
1372  if(!error)
1373  {
1374  //Matching port number?
1375  if(entry.srcPort == port || port == 0)
1376  {
1377  //Specify the MAC address to remove (last 16 bits)
1378  value = entry.macAddr.b[4] | (entry.macAddr.b[5] << 8);
1379  //Write SWE_ALR_WR_DAT_1 register
1381 
1382  //Specify the MAC address to remove (first 32 bits)
1383  value = entry.macAddr.b[0] | (entry.macAddr.b[1] << 8) |
1384  (entry.macAddr.b[2] << 16) | (entry.macAddr.b[3] << 24);
1385 
1386  //Write SWE_ALR_WR_DAT_0 register
1388 
1389  //Write the SWE_ALR_CMD register
1392 
1393  //Poll the Make Pending bit in the SWE_ALR_CMD_STS register until
1394  //it is cleared
1395  do
1396  {
1397  //Read the SWE_ALR_CMD_STS register
1399 
1400  //Check the Make Pending bit
1401  } while((value & LAN9303_SWE_ALR_CMD_STS_MAKE_PENDING) != 0);
1402 
1403  //Clear the SWE_ALR_CMD register
1405  }
1406  }
1407  else
1408  {
1409  //The end of the table has been reached
1410  break;
1411  }
1412  }
1413 }
1414 
1415 
1416 /**
1417  * @brief Set forward ports for unknown multicast packets
1418  * @param[in] interface Underlying network interface
1419  * @param[in] enable Enable or disable forwarding of unknown multicast packets
1420  * @param[in] forwardPorts Port map
1421  **/
1422 
1424  bool_t enable, uint32_t forwardPorts)
1425 {
1426  //Not implemented
1427 }
1428 
1429 
1430 /**
1431  * @brief Write PHY register
1432  * @param[in] interface Underlying network interface
1433  * @param[in] port Port number
1434  * @param[in] address PHY register address
1435  * @param[in] data Register value
1436  **/
1437 
1438 void lan9303WritePhyReg(NetInterface *interface, uint8_t port,
1439  uint8_t address, uint16_t data)
1440 {
1441  //Write the specified PHY register
1442  if(interface->smiDriver != NULL)
1443  {
1444  interface->smiDriver->writePhyReg(SMI_OPCODE_WRITE, port, address, data);
1445  }
1446  else
1447  {
1448  interface->nicDriver->writePhyReg(SMI_OPCODE_WRITE, port, address, data);
1449  }
1450 }
1451 
1452 
1453 /**
1454  * @brief Read PHY register
1455  * @param[in] interface Underlying network interface
1456  * @param[in] port Port number
1457  * @param[in] address PHY register address
1458  * @return Register value
1459  **/
1460 
1461 uint16_t lan9303ReadPhyReg(NetInterface *interface, uint8_t port,
1462  uint8_t address)
1463 {
1464  uint16_t data;
1465 
1466  //Read the specified PHY register
1467  if(interface->smiDriver != NULL)
1468  {
1469  data = interface->smiDriver->readPhyReg(SMI_OPCODE_READ, port, address);
1470  }
1471  else
1472  {
1473  data = interface->nicDriver->readPhyReg(SMI_OPCODE_READ, port, address);
1474  }
1475 
1476  //Return the value of the PHY register
1477  return data;
1478 }
1479 
1480 
1481 /**
1482  * @brief Dump PHY registers for debugging purpose
1483  * @param[in] interface Underlying network interface
1484  * @param[in] port Port number
1485  **/
1486 
1487 void lan9303DumpPhyReg(NetInterface *interface, uint8_t port)
1488 {
1489  uint8_t i;
1490 
1491  //Loop through PHY registers
1492  for(i = 0; i < 32; i++)
1493  {
1494  //Display current PHY register
1495  TRACE_DEBUG("%02" PRIu8 ": 0x%04" PRIX16 "\r\n", i,
1496  lan9303ReadPhyReg(interface, port, i));
1497  }
1498 
1499  //Terminate with a line feed
1500  TRACE_DEBUG("\r\n");
1501 }
1502 
1503 
1504 /**
1505  * @brief Write system CSR register
1506  * @param[in] interface Underlying network interface
1507  * @param[in] address System register address
1508  * @param[in] data Register value
1509  **/
1510 
1511 void lan9303WriteSysReg(NetInterface *interface, uint16_t address,
1512  uint32_t data)
1513 {
1514  uint8_t phyAddr;
1515  uint8_t regAddr;
1516 
1517  //PHY address bit 4 is 1 for SMI commands. PHY address 3:0 form system
1518  //register address bits 9:6
1519  phyAddr = 0x10 | ((address >> 6) & 0x0F);
1520 
1521  //Register address field forms register address bits 5:1
1522  regAddr = (address >> 1) & 0x1F;
1523 
1524  //Write system CSR register
1525  if(interface->smiDriver != NULL)
1526  {
1527  //Write the low word of the SMI register
1528  interface->smiDriver->writePhyReg(SMI_OPCODE_WRITE, phyAddr, regAddr,
1529  data & 0xFFFF);
1530 
1531  //Write the high word of the SMI register
1532  interface->smiDriver->writePhyReg(SMI_OPCODE_WRITE, phyAddr, regAddr + 1,
1533  (data >> 16) & 0xFFFF);
1534  }
1535  else
1536  {
1537  //Write the low word of the SMI register
1538  interface->nicDriver->writePhyReg(SMI_OPCODE_WRITE, phyAddr, regAddr,
1539  data & 0xFFFF);
1540 
1541  //Write the high word of the SMI register
1542  interface->nicDriver->writePhyReg(SMI_OPCODE_WRITE, phyAddr, regAddr + 1,
1543  (data >> 16) & 0xFFFF);
1544  }
1545 }
1546 
1547 
1548 /**
1549  * @brief Read system CSR register
1550  * @param[in] interface Underlying network interface
1551  * @param[in] address System register address
1552  * @return Register value
1553  **/
1554 
1555 uint32_t lan9303ReadSysReg(NetInterface *interface, uint16_t address)
1556 {
1557  uint8_t phyAddr;
1558  uint8_t regAddr;
1559  uint32_t data;
1560 
1561  //PHY address bit 4 is 1 for SMI commands. PHY address 3:0 form system
1562  //register address bits 9:6
1563  phyAddr = 0x10 | ((address >> 6) & 0x0F);
1564 
1565  //Register address field forms register address bits 5:1
1566  regAddr = (address >> 1) & 0x1F;
1567 
1568  //Read system CSR register
1569  if(interface->smiDriver != NULL)
1570  {
1571  //Read the low word of the SMI register
1572  data = interface->smiDriver->readPhyReg(SMI_OPCODE_READ, phyAddr,
1573  regAddr);
1574 
1575  //Read the high word of the SMI register
1576  data |= interface->smiDriver->readPhyReg(SMI_OPCODE_READ, phyAddr,
1577  regAddr + 1) << 16;
1578  }
1579  else
1580  {
1581  //Read the low word of the SMI register
1582  data = interface->nicDriver->readPhyReg(SMI_OPCODE_READ, phyAddr,
1583  regAddr);
1584 
1585  //Read the high word of the SMI register
1586  data |= interface->nicDriver->readPhyReg(SMI_OPCODE_READ, phyAddr,
1587  regAddr + 1) << 16;
1588  }
1589 
1590  //Return register value
1591  return data;
1592 }
1593 
1594 
1595 /**
1596  * @brief Dump system CSR registers for debugging purpose
1597  * @param[in] interface Underlying network interface
1598  **/
1599 
1601 {
1602  uint16_t i;
1603 
1604  //Loop through system registers
1605  for(i = 80; i < 512; i += 4)
1606  {
1607  //Display current system register
1608  TRACE_DEBUG("0x%03" PRIX16 ": 0x%08" PRIX32 "\r\n", i,
1609  lan9303ReadSysReg(interface, i));
1610  }
1611 
1612  //Terminate with a line feed
1613  TRACE_DEBUG("\r\n");
1614 }
1615 
1616 
1617 /**
1618  * @brief Write switch fabric CSR register
1619  * @param[in] interface Underlying network interface
1620  * @param[in] address Switch fabric register address
1621  * @param[in] data Register value
1622  **/
1623 
1624 void lan9303WriteSwitchReg(NetInterface *interface, uint16_t address,
1625  uint32_t data)
1626 {
1627  uint32_t value;
1628 
1629  //To perform a write to an individual switch fabric register, the desired
1630  //data must first be written into the SWITCH_CSR_DATA register
1632 
1633  //Set up a write operation
1636 
1637  //Set register address
1639 
1640  //The write cycle is initiated by performing a single write to the
1641  //SWITCH_CSR_CMD register
1643 
1644  //The completion of the write cycle is indicated by the clearing of the
1645  //CSR_BUSY bit
1646  do
1647  {
1648  //Read SWITCH_CSR_CMD register
1650 
1651  //Poll CSR_BUSY bit
1652  } while((value & LAN9303_SWITCH_CSR_CMD_BUSY) != 0);
1653 }
1654 
1655 
1656 /**
1657  * @brief Read switch fabric CSR register
1658  * @param[in] interface Underlying network interface
1659  * @param[in] address Switch fabric register address
1660  * @return Register value
1661  **/
1662 
1663 uint32_t lan9303ReadSwitchReg(NetInterface *interface, uint16_t address)
1664 {
1665  uint32_t value;
1666 
1667  //Set up a read operation
1670 
1671  //Set register address
1673 
1674  //To perform a read of an individual switch fabric register, the read cycle
1675  //must be initiated by performing a single write to the SWITCH_CSR_CMD
1676  //register
1678 
1679  //Valid data is available for reading when the CSR_BUSY bit is cleared
1680  do
1681  {
1682  //Read SWITCH_CSR_CMD register
1684 
1685  //Poll CSR_BUSY bit
1686  } while((value & LAN9303_SWITCH_CSR_CMD_BUSY) != 0);
1687 
1688  //Read data from the SWITCH_CSR_DATA register
1689  return lan9303ReadSysReg(interface, LAN9303_SWITCH_CSR_DATA);
1690 }
void nicNotifyLinkChange(NetInterface *interface)
Process link state change notification.
Definition: nic.c:559
#define htons(value)
Definition: cpu_endian.h:413
void lan9303Tick(NetInterface *interface)
LAN9303 timer handler.
#define LAN9303_BYTE_TEST
#define LAN9303_SWE_ALR_WR_DAT_1_AGE_OVERRIDE
int bool_t
Definition: compiler_port.h:53
#define LAN9303_PSCSR_SPEED_100BTX_FD
void lan9303EventHandler(NetInterface *interface)
LAN9303 event handler.
@ NIC_LINK_SPEED_UNKNOWN
Definition: nic.h:110
uint32_t destPorts
Definition: nic.h:152
#define netEvent
Definition: net_legacy.h:196
#define LAN9303_BM_EGRSS_PORT_TYPE_PORT0_TYPE_CPU
#define LAN9303_SWE_GLOBAL_INGRSS_CFG_IGMP_MONITOR_PORT
@ NIC_FULL_DUPLEX_MODE
Definition: nic.h:125
#define LAN9303_PORT0_1_MASK
#define LAN9303_SWE_PORT_STATE_PORT0_FORWARDING
#define LAN9303_SWE_ALR_WR_DAT_1_PORT_0_1
const SwitchDriver lan9303SwitchDriver
LAN9303 Ethernet switch driver.
#define LAN9303_SWE_ALR_RD_DAT_1_STATIC
#define LAN9303_SWE_ALR_WR_DAT_1_PORT_2
SwitchPortState lan9303GetPortState(NetInterface *interface, uint8_t port)
Get port state.
error_t lan9303AddStaticFdbEntry(NetInterface *interface, const SwitchFdbEntry *entry)
Add a new entry to the static MAC table.
#define LAN9303_SWE_ALR_WR_DAT_1_PORT_0_2
#define LAN9303_BYTE_TEST_DEFAULT
@ ERROR_END_OF_TABLE
Definition: error.h:291
@ SWITCH_PORT_STATE_DISABLED
Definition: nic.h:136
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:89
#define LAN9303_SWITCH_CSR_CMD_WRITE
error_t lan9303Init(NetInterface *interface)
LAN9303 Ethernet switch initialization.
#define TRUE
Definition: os_port.h:50
uint8_t data[]
Definition: ethernet.h:222
#define LAN9303_PORT0_2_MASK
@ SWITCH_PORT_STATE_LEARNING
Definition: nic.h:139
#define LAN9303_SWE_GLOBAL_INGRSS_CFG_IGMP_MONITORING_EN
#define NET_INTERFACE_COUNT
Definition: net.h:114
void lan9303SetPortState(NetInterface *interface, uint8_t port, SwitchPortState state)
Set port state.
#define LAN9303_MAC_TX_CFG_IFG_CONFIG_DEFAULT
#define LAN9303_VID_STP_OVERRIDE
@ ERROR_INVALID_PORT
Definition: error.h:104
#define LAN9303_SWE_ALR_CMD
#define LAN9303_PSCSR_SPEED_100BTX_HD
bool_t lan9303GetLinkState(NetInterface *interface, uint8_t port)
Get link state.
#define LAN9303_SWE_PORT_STATE_PORT2_DISABLED
#define LAN9303_SWITCH_CSR_CMD_READ
EthHeader
Definition: ethernet.h:223
#define LAN9303_SWE_PORT_STATE_PORT2_FORWARDING
#define LAN9303_PORT2_MASK
#define LAN9303_SWE_ALR_CMD_GET_NEXT_ENTRY
void lan9303DisableIrq(NetInterface *interface)
Disable interrupts.
void lan9303EnableIgmpSnooping(NetInterface *interface, bool_t enable)
Enable IGMP snooping.
#define LAN9303_SWE_ALR_CMD_STS_MAKE_PENDING
#define LAN9303_PORT0
#define LAN9303_PSCSR_SPEED_10BT_HD
VlanTag
Definition: ethernet.h:246
#define SMI_OPCODE_WRITE
Definition: nic.h:66
void lan9303WriteSysReg(NetInterface *interface, uint16_t address, uint32_t data)
Write system CSR register.
#define LAN9303_SWE_GLOBAL_INGRSS_CFG
#define LAN9303_SWE_PORT_MIRROR_SNIFFER_PORT_0
#define LAN9303_SWITCH_CSR_CMD
#define LAN9303_SWE_INGRSS_PORT_TYP
#define LAN9303_SWE_PORT_MIRROR_RX_MIRRORING_EN
#define LAN9303_PORT0_1_2_MASK
#define LAN9303_HW_CFG_DEVICE_READY
#define FALSE
Definition: os_port.h:46
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
error_t
Error codes.
Definition: error.h:43
uint16_t lan9303ReadPhyReg(NetInterface *interface, uint8_t port, uint8_t address)
Read PHY register.
#define netInterface
Definition: net_legacy.h:199
#define LAN9303_SWE_ALR_RD_DAT_0
#define LAN9303_SWE_ALR_RD_DAT_1_VALID
#define LAN9303_PORT0_MASK
void lan9303WriteSwitchReg(NetInterface *interface, uint16_t address, uint32_t data)
Write switch fabric CSR register.
#define LAN9303_PSCSR
#define LAN9303_PORT1_2_MASK
void lan9303EnableMldSnooping(NetInterface *interface, bool_t enable)
Enable MLD snooping.
#define NetRxAncillary
Definition: net_misc.h:40
#define NetInterface
Definition: net.h:36
@ NIC_LINK_SPEED_10MBPS
Definition: nic.h:111
#define LAN9303_MAC_RX_CFG_REJECT_MAC_TYPES
#define LAN9303_SWE_ALR_WR_DAT_0
@ ERROR_INVALID_LENGTH
Definition: error.h:111
#define LAN9303_SWE_ALR_RD_DAT_1_PORT_1
#define LAN9303_VID_ALR_LOOKUP
#define LAN9303_BMSR
#define LAN9303_SWE_PORT_STATE_PORT1_LISTENING
#define LAN9303_MAC_TX_CFG_TX_EN
#define LAN9303_SWITCH_CSR_CMD_ADDR
void lan9303DumpSysReg(NetInterface *interface)
Dump system CSR registers for debugging purpose.
#define LAN9303_PSCSR_SPEED
#define NetTxAncillary
Definition: net_misc.h:36
#define LAN9303_HW_CFG
#define LAN9303_SWE_ALR_WR_DAT_1_PORT_1
#define SMI_OPCODE_READ
Definition: nic.h:67
SwitchPortState
Switch port state.
Definition: nic.h:134
#define LAN9303_SWE_PORT_STATE_PORT1
#define TRACE_INFO(...)
Definition: debug.h:95
uint8_t length
Definition: tcp.h:368
#define LAN9303_BMSR_LINK_STATUS
LAN9303 3-port Ethernet switch driver.
#define LAN9303_SWE_PORT_STATE_PORT1_FORWARDING
#define LAN9303_SWE_ALR_RD_DAT_1_PORT_0_2
@ SWITCH_PORT_STATE_BLOCKING
Definition: nic.h:137
uint32_t lan9303ReadSwitchReg(NetInterface *interface, uint16_t address)
Read switch fabric CSR register.
#define LAN9303_SWE_ALR_WR_DAT_1_PORT_0_1_2
error_t lan9303UntagFrame(NetInterface *interface, uint8_t **frame, size_t *length, NetRxAncillary *ancillary)
Decode special VLAN tag from incoming Ethernet frame.
void lan9303SetUnknownMcastFwdPorts(NetInterface *interface, bool_t enable, uint32_t forwardPorts)
Set forward ports for unknown multicast packets.
@ SWITCH_PORT_STATE_FORWARDING
Definition: nic.h:140
#define LAN9303_SWE_ALR_RD_DAT_1_PORT_2
#define LAN9303_SWE_INGRSS_PORT_TYP_PORT0
uint16_t port
Definition: dns_common.h:267
#define ntohs(value)
Definition: cpu_endian.h:421
__weak_func void lan9303InitHook(NetInterface *interface)
LAN9303 custom configuration.
#define TRACE_WARNING(...)
Definition: debug.h:85
@ ETH_TYPE_VLAN
Definition: ethernet.h:167
#define TRACE_DEBUG(...)
Definition: debug.h:107
#define LAN9303_SWITCH_CSR_CMD_BE
error_t lan9303GetDynamicFdbEntry(NetInterface *interface, uint_t index, SwitchFdbEntry *entry)
Read an entry from the dynamic MAC table.
#define LAN9303_MAC_TX_CFG_TX_PAD_EN
uint16_t regAddr
#define LAN9303_SWE_PORT_STATE_PORT1_DISABLED
#define LAN9303_MAC_RX_CFG_RX_EN
uint32_t lan9303GetLinkSpeed(NetInterface *interface, uint8_t port)
Get link speed.
#define LAN9303_SWE_PORT_STATE_PORT2
error_t lan9303GetStaticFdbEntry(NetInterface *interface, uint_t index, SwitchFdbEntry *entry)
Read an entry from the static MAC table.
Ethernet switch driver.
Definition: nic.h:325
#define LAN9303_SWE_ALR_RD_DAT_1_PORT_0_1_2
#define HTONS(value)
Definition: cpu_endian.h:410
void lan9303WritePhyReg(NetInterface *interface, uint8_t port, uint8_t address, uint16_t data)
Write PHY register.
#define LAN9303_SWE_ALR_RD_DAT_1_PORT_0_1
Ipv6Addr address[]
Definition: ipv6.h:325
NicDuplexMode
Duplex mode.
Definition: nic.h:122
#define LAN9303_BM_EGRSS_PORT_TYPE
MacAddr macAddr
Definition: nic.h:150
error_t lan9303DeleteStaticFdbEntry(NetInterface *interface, const SwitchFdbEntry *entry)
Remove an entry from the static MAC table.
#define LAN9303_PORT2
uint8_t srcPort
Definition: nic.h:151
#define LAN9303_SWITCH_CSR_CMD_BUSY
@ NIC_HALF_DUPLEX_MODE
Definition: nic.h:124
uint8_t value[]
Definition: tcp.h:369
#define LAN9303_SWE_ALR_RD_DAT_1_END_OF_TABLE
#define LAN9303_SWE_ALR_WR_DAT_1_VALID
#define LAN9303_PORT_MASK
#define LAN9303_SWE_PORT_MIRROR_MIRRORED_PORT_2
#define LAN9303_SWE_ALR_WR_DAT_1_PORT_1_2
#define LAN9303_SWE_PORT_STATE_PORT1_LEARNING
#define LAN9303_PORT1
uint32_t lan9303ReadSysReg(NetInterface *interface, uint16_t address)
Read system CSR register.
@ ERROR_WRONG_IDENTIFIER
Definition: error.h:89
void lan9303FlushStaticFdbTable(NetInterface *interface)
Flush static MAC table.
#define LAN9303_PORT1_MASK
@ NIC_UNKNOWN_DUPLEX_MODE
Definition: nic.h:123
#define LAN9303_SWE_ALR_RD_DAT_1_PORT
void lan9303EnableIrq(NetInterface *interface)
Enable interrupts.
#define LAN9303_MAC_RX_CFG(port)
#define LAN9303_SWE_PORT_MIRROR_MIRRORED_PORT_1
void lan9303DumpPhyReg(NetInterface *interface, uint8_t port)
Dump PHY registers for debugging purpose.
#define LAN9303_SWE_PORT_MIRROR_RX_MIRRORING_FILT_EN
#define LAN9303_SWE_ALR_RD_DAT_1
#define LAN9303_ALR_TABLE_SIZE
NicDuplexMode lan9303GetDuplexMode(NetInterface *interface, uint8_t port)
Get duplex mode.
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
void * netBufferAt(const NetBuffer *buffer, size_t offset, size_t length)
Returns a pointer to a data segment.
Definition: net_mem.c:418
#define LAN9303_SWE_PORT_MIRROR
#define LAN9303_MAC_TX_CFG(port)
#define LAN9303_SWE_ALR_CMD_GET_FIRST_ENTRY
#define SWITCH_CPU_PORT_MASK
Definition: nic.h:60
#define LAN9303_SWE_ALR_WR_DAT_1_PORT_0
@ NIC_LINK_SPEED_100MBPS
Definition: nic.h:112
#define LAN9303_PSCSR_SPEED_10BT_FD
#define LAN9303_SWE_ALR_CMD_STS
#define LAN9303_SWE_PORT_STATE
unsigned int uint_t
Definition: compiler_port.h:50
TCP/IP stack core.
#define LAN9303_SWE_ALR_RD_DAT_1_PORT_0
#define LAN9303_SWE_PORT_STATE_PORT2_LEARNING
#define LAN9303_SWE_GLOBAL_INGRSS_CFG_IGMP_MONITOR_PORT_0
#define LAN9303_SWITCH_CSR_DATA
void lan9303FlushDynamicFdbTable(NetInterface *interface, uint8_t port)
Flush dynamic MAC table.
void lan9303EnableRsvdMcastTable(NetInterface *interface, bool_t enable)
Enable reserved multicast table.
#define LAN9303_SWE_ALR_RD_DAT_1_PORT_1_2
error_t lan9303TagFrame(NetInterface *interface, NetBuffer *buffer, size_t *offset, NetTxAncillary *ancillary)
Add special VLAN tag to Ethernet frame.
#define LAN9303_SWE_ALR_WR_DAT_1_STATIC
@ NO_ERROR
Success.
Definition: error.h:44
bool_t override
Definition: nic.h:153
void lan9303SetAgingTime(NetInterface *interface, uint32_t agingTime)
Set aging time for dynamic filtering entries.
Debugging facilities.
#define osMemmove(dest, src, length)
Definition: os_port.h:147
Forwarding database entry.
Definition: nic.h:149
#define LAN9303_VID_SRC_PORT
#define LAN9303_SWE_ALR_WR_DAT_1
#define LAN9303_SWE_PORT_STATE_PORT2_LISTENING
#define LAN9303_SWE_ALR_CMD_MAKE_ENTRY