lan9353_driver.c
Go to the documentation of this file.
1 /**
2  * @file lan9353_driver.c
3  * @brief LAN9353 3-port Ethernet switch driver
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2026 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.6.0
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 LAN9353 Ethernet switch driver
42  **/
43 
45 {
69 };
70 
71 
72 /**
73  * @brief LAN9353 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 LAN9353...\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 != LAN9353_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 = lan9353ReadSysReg(interface, LAN9353_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 & LAN9353_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  lan9353DumpPhyReg(interface, port);
177  }
178 
179  //Perform custom configuration
180  lan9353InitHook(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
185  osSetEvent(&interface->netContext->event);
186 
187  //Successful initialization
188  return NO_ERROR;
189 }
190 
191 
192 /**
193  * @brief LAN9353 custom configuration
194  * @param[in] interface Underlying network interface
195  **/
196 
197 __weak_func void lan9353InitHook(NetInterface *interface)
198 {
199 }
200 
201 
202 /**
203  * @brief LAN9353 timer handler
204  * @param[in] interface Underlying network interface
205  **/
206 
207 __weak_func void lan9353Tick(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  NetContext *context;
218  NetInterface *virtualInterface;
219 
220  //Point to the TCP/IP stack context
221  context = interface->netContext;
222 
223  //Loop through network interfaces
224  for(i = 0; i < context->numInterfaces; i++)
225  {
226  //Point to the current interface
227  virtualInterface = &context->interfaces[i];
228 
229  //Check whether the current virtual interface is attached to the
230  //physical interface
231  if(virtualInterface == interface ||
232  virtualInterface->parent == interface)
233  {
234  //Retrieve current link state
235  linkState = lan9353GetLinkState(interface, virtualInterface->port);
236 
237  //Link up or link down event?
238  if(linkState != virtualInterface->linkState)
239  {
240  //Set event flag
241  interface->phyEvent = TRUE;
242  //Notify the TCP/IP stack of the event
243  osSetEvent(&interface->netContext->event);
244  }
245  }
246  }
247  }
248  else
249 #endif
250  {
251  //Initialize link state
252  linkState = FALSE;
253 
254  //Loop through the ports
256  {
257  //Retrieve current link state
258  if(lan9353GetLinkState(interface, port))
259  {
260  linkState = TRUE;
261  }
262  }
263 
264  //Link up or link down event?
265  if(linkState != interface->linkState)
266  {
267  //Set event flag
268  interface->phyEvent = TRUE;
269  //Notify the TCP/IP stack of the event
270  osSetEvent(&interface->netContext->event);
271  }
272  }
273 }
274 
275 
276 /**
277  * @brief Enable interrupts
278  * @param[in] interface Underlying network interface
279  **/
280 
282 {
283 }
284 
285 
286 /**
287  * @brief Disable interrupts
288  * @param[in] interface Underlying network interface
289  **/
290 
292 {
293 }
294 
295 
296 /**
297  * @brief LAN9353 event handler
298  * @param[in] interface Underlying network interface
299  **/
300 
301 __weak_func void lan9353EventHandler(NetInterface *interface)
302 {
303  uint_t port;
304  bool_t linkState;
305 
306 #if (ETH_PORT_TAGGING_SUPPORT == ENABLED)
307  //Port separation mode?
308  if(interface->port != 0)
309  {
310  uint_t i;
311  uint16_t status;
312  NetContext *context;
313  NetInterface *virtualInterface;
314 
315  //Point to the TCP/IP stack context
316  context = interface->netContext;
317 
318  //Loop through network interfaces
319  for(i = 0; i < context->numInterfaces; i++)
320  {
321  //Point to the current interface
322  virtualInterface = &context->interfaces[i];
323 
324  //Check whether the current virtual interface is attached to the
325  //physical interface
326  if(virtualInterface == interface ||
327  virtualInterface->parent == interface)
328  {
329  //Get the port number associated with the current interface
330  port = virtualInterface->port;
331 
332  //Valid port?
333  if(port >= LAN9353_PORT1 && port <= LAN9353_PORT2)
334  {
335  //Retrieve current link state
336  linkState = lan9353GetLinkState(interface, port);
337 
338  //Link up event?
339  if(linkState && !virtualInterface->linkState)
340  {
341  //Adjust MAC configuration parameters for proper operation
342  interface->linkSpeed = NIC_LINK_SPEED_100MBPS;
343  interface->duplexMode = NIC_FULL_DUPLEX_MODE;
344  interface->nicDriver->updateMacConfig(interface);
345 
346  //Read PHY special control/status register
347  status = lan9353ReadPhyReg(interface, port, LAN9353_PSCSR);
348 
349  //Check current operation mode
350  switch(status & LAN9353_PSCSR_SPEED)
351  {
352  //10BASE-T half-duplex
354  virtualInterface->linkSpeed = NIC_LINK_SPEED_10MBPS;
355  virtualInterface->duplexMode = NIC_HALF_DUPLEX_MODE;
356  break;
357 
358  //10BASE-T full-duplex
360  virtualInterface->linkSpeed = NIC_LINK_SPEED_10MBPS;
361  virtualInterface->duplexMode = NIC_FULL_DUPLEX_MODE;
362  break;
363 
364  //100BASE-TX half-duplex
366  virtualInterface->linkSpeed = NIC_LINK_SPEED_100MBPS;
367  virtualInterface->duplexMode = NIC_HALF_DUPLEX_MODE;
368  break;
369 
370  //100BASE-TX full-duplex
372  virtualInterface->linkSpeed = NIC_LINK_SPEED_100MBPS;
373  virtualInterface->duplexMode = NIC_FULL_DUPLEX_MODE;
374  break;
375 
376  //Unknown operation mode
377  default:
378  //Debug message
379  TRACE_WARNING("Invalid operation mode!\r\n");
380  break;
381  }
382 
383  //Update link state
384  virtualInterface->linkState = TRUE;
385 
386  //Process link state change event
387  nicNotifyLinkChange(virtualInterface);
388  }
389  //Link down event
390  else if(!linkState && virtualInterface->linkState)
391  {
392  //Update link state
393  virtualInterface->linkState = FALSE;
394 
395  //Process link state change event
396  nicNotifyLinkChange(virtualInterface);
397  }
398  }
399  }
400  }
401  }
402  else
403 #endif
404  {
405  //Initialize link state
406  linkState = FALSE;
407 
408  //Loop through the ports
410  {
411  //Retrieve current link state
412  if(lan9353GetLinkState(interface, port))
413  {
414  linkState = TRUE;
415  }
416  }
417 
418  //Link up event?
419  if(linkState)
420  {
421  //Adjust MAC configuration parameters for proper operation
422  interface->linkSpeed = NIC_LINK_SPEED_100MBPS;
423  interface->duplexMode = NIC_FULL_DUPLEX_MODE;
424  interface->nicDriver->updateMacConfig(interface);
425 
426  //Update link state
427  interface->linkState = TRUE;
428  }
429  else
430  {
431  //Update link state
432  interface->linkState = FALSE;
433  }
434 
435  //Process link state change event
436  nicNotifyLinkChange(interface);
437  }
438 }
439 
440 
441 /**
442  * @brief Add special VLAN tag to Ethernet frame
443  * @param[in] interface Underlying network interface
444  * @param[in] buffer Multi-part buffer containing the payload
445  * @param[in,out] offset Offset to the first payload byte
446  * @param[in] ancillary Additional options passed to the stack along with
447  * the packet
448  * @return Error code
449  **/
450 
452  size_t *offset, NetTxAncillary *ancillary)
453 {
454  error_t error;
455 
456  //Initialize status code
457  error = NO_ERROR;
458 
459 #if (ETH_PORT_TAGGING_SUPPORT == ENABLED)
460  //Valid port?
461  if(ancillary->port <= LAN9353_PORT2)
462  {
463  //Is there enough space for the VLAN tag?
464  if(*offset >= sizeof(VlanTag))
465  {
466  EthHeader *header;
467  VlanTag *vlanTag;
468 
469  //Make room for the special VLAN tag
470  *offset -= sizeof(VlanTag);
471  //Point to the beginning of the frame
472  header = netBufferAt(buffer, *offset, 0);
473 
474  //Move the Ethernet header to make room for the special VLAN tag
475  osMemmove(header, (uint8_t *) header + sizeof(VlanTag),
476  sizeof(EthHeader));
477 
478  //The special VLAN tag is a normal VLAN tag where the VID field is
479  //used as the destination port indicator
480  vlanTag = (VlanTag *) header->data;
481 
482  //Default port number?
483  if(ancillary->port == 0)
484  {
485  //If VID bit 3 is one, then the normal ALR lookup is performed
486  vlanTag->tci = HTONS(LAN9353_VID_ALR_LOOKUP);
487  }
488  else
489  {
490  //VID bits 0 and 1 specify the destination port
491  vlanTag->tci = htons(LAN9353_VID_STP_OVERRIDE | ancillary->port);
492  }
493 
494  //The EtherType field indicates which protocol is encapsulated in
495  //the payload
496  vlanTag->type = header->type;
497 
498  //A distinct EtherType has been allocated for use in the TPID field
499  header->type = HTONS(ETH_TYPE_VLAN);
500  }
501  else
502  {
503  //Report an error
504  error = ERROR_INVALID_PARAMETER;
505  }
506  }
507  else
508  {
509  //The port number is not valid
510  error = ERROR_INVALID_PORT;
511  }
512 #endif
513 
514  //Return status code
515  return error;
516 }
517 
518 
519 /**
520  * @brief Decode special VLAN tag from incoming Ethernet frame
521  * @param[in] interface Underlying network interface
522  * @param[in,out] frame Pointer to the received Ethernet frame
523  * @param[in,out] length Length of the frame, in bytes
524  * @param[in,out] ancillary Additional options passed to the stack along with
525  * the packet
526  * @return Error code
527  **/
528 
529 error_t lan9353UntagFrame(NetInterface *interface, uint8_t **frame,
530  size_t *length, NetRxAncillary *ancillary)
531 {
532  error_t error;
533 #if (ETH_PORT_TAGGING_SUPPORT == ENABLED)
534  EthHeader *header;
535  VlanTag *vlanTag;
536 #endif
537 
538  //Initialize status code
539  error = NO_ERROR;
540 
541 #if (ETH_PORT_TAGGING_SUPPORT == ENABLED)
542  //Point to the beginning of the frame
543  header = (EthHeader *) *frame;
544 
545  //Check whether VLAN tagging is used
546  if(ntohs(header->type) == ETH_TYPE_VLAN)
547  {
548  //Valid Ethernet frame received?
549  if(*length >= (sizeof(EthHeader) + sizeof(VlanTag)))
550  {
551  //The special VLAN tag is a normal VLAN tag where the VID field is
552  //used as a source port indicator
553  vlanTag = (VlanTag *) header->data;
554 
555  //VID bits 0 and 1 specify the source port
556  ancillary->port = ntohs(vlanTag->tci) & LAN9353_VID_SRC_PORT;
557  //Fix the value of the EtherType field
558  header->type = vlanTag->type;
559 
560  //Strip the VLAN tag from the Ethernet frame
561  osMemmove(*frame + sizeof(VlanTag), *frame, sizeof(EthHeader));
562 
563  //Point to the Ethernet frame header
564  *frame += sizeof(VlanTag);
565  //Retrieve the length of the original frame
566  *length -= sizeof(VlanTag);
567  }
568  else
569  {
570  //Drop the received frame
571  error = ERROR_INVALID_LENGTH;
572  }
573  }
574  else
575  {
576  //If the interface is configured to accept VLAN-tagged frames, then
577  //drop the incoming Ethernet frame
578  error = ERROR_WRONG_IDENTIFIER;
579  }
580 #endif
581 
582  //Return status code
583  return error;
584 }
585 
586 
587 /**
588  * @brief Get link state
589  * @param[in] interface Underlying network interface
590  * @param[in] port Port number
591  * @return Link state
592  **/
593 
595 {
596  uint16_t status;
597  bool_t linkState;
598 
599  //Check port number
600  if(port >= LAN9353_PORT1 && port <= LAN9353_PORT2)
601  {
602  //Read status register
603  status = lan9353ReadPhyReg(interface, port, LAN9353_BMSR);
604 
605  //Retrieve current link state
606  linkState = (status & LAN9353_BMSR_LINK_STATUS) ? TRUE : FALSE;
607  }
608  else
609  {
610  //The specified port number is not valid
611  linkState = FALSE;
612  }
613 
614  //Return link status
615  return linkState;
616 }
617 
618 
619 /**
620  * @brief Get link speed
621  * @param[in] interface Underlying network interface
622  * @param[in] port Port number
623  * @return Link speed
624  **/
625 
626 uint32_t lan9353GetLinkSpeed(NetInterface *interface, uint8_t port)
627 {
628  uint16_t status;
629  uint32_t linkSpeed;
630 
631  //Check port number
632  if(port >= LAN9353_PORT1 && port <= LAN9353_PORT2)
633  {
634  //Read PHY special control/status register
635  status = lan9353ReadPhyReg(interface, port, LAN9353_PSCSR);
636 
637  //Check current operation mode
638  switch(status & LAN9353_PSCSR_SPEED)
639  {
640  //10BASE-T
643  linkSpeed = NIC_LINK_SPEED_10MBPS;
644  break;
645 
646  //100BASE-TX
649  linkSpeed = NIC_LINK_SPEED_100MBPS;
650  break;
651 
652  //Unknown operation mode
653  default:
654  linkSpeed = NIC_LINK_SPEED_UNKNOWN;
655  break;
656  }
657  }
658  else
659  {
660  //The specified port number is not valid
661  linkSpeed = NIC_LINK_SPEED_UNKNOWN;
662  }
663 
664  //Return link speed
665  return linkSpeed;
666 }
667 
668 
669 /**
670  * @brief Get duplex mode
671  * @param[in] interface Underlying network interface
672  * @param[in] port Port number
673  * @return Duplex mode
674  **/
675 
677 {
678  uint16_t status;
679  NicDuplexMode duplexMode;
680 
681  //Check port number
682  if(port >= LAN9353_PORT1 && port <= LAN9353_PORT2)
683  {
684  //Read PHY special control/status register
685  status = lan9353ReadPhyReg(interface, port, LAN9353_PSCSR);
686 
687  //Check current operation mode
688  switch(status & LAN9353_PSCSR_SPEED)
689  {
690  //10BASE-T or 100BASE-TX half-duplex
693  duplexMode = NIC_HALF_DUPLEX_MODE;
694  break;
695 
696  //10BASE-T or 100BASE-TX full-duplex
699  duplexMode = NIC_FULL_DUPLEX_MODE;
700  break;
701 
702  //Unknown operation mode
703  default:
704  duplexMode = NIC_UNKNOWN_DUPLEX_MODE;
705  break;
706  }
707  }
708  else
709  {
710  //The specified port number is not valid
711  duplexMode = NIC_UNKNOWN_DUPLEX_MODE;
712  }
713 
714  //Return duplex mode
715  return duplexMode;
716 }
717 
718 
719 /**
720  * @brief Set port state
721  * @param[in] interface Underlying network interface
722  * @param[in] port Port number
723  * @param[in] state Port state
724  **/
725 
726 void lan9353SetPortState(NetInterface *interface, uint8_t port,
727  SwitchPortState state)
728 {
729  uint32_t temp;
730 
731  //Read port state register
732  temp = lan9353ReadSwitchReg(interface, LAN9353_SWE_PORT_STATE);
733 
734  //Check port number
735  if(port == LAN9353_PORT1)
736  {
737  //Clear current configuration
739 
740  //Update port 1 state
741  switch(state)
742  {
745  break;
748  break;
751  break;
752  default:
754  break;
755  }
756  }
757  else if(port == LAN9353_PORT2)
758  {
759  //Clear current configuration
761 
762  //Update port 2 state
763  switch(state)
764  {
767  break;
770  break;
773  break;
774  default:
776  break;
777  }
778  }
779  else
780  {
781  //The specified port number is not valid
782  }
783 
784  //Write the value back to port state register
786 }
787 
788 
789 /**
790  * @brief Get port state
791  * @param[in] interface Underlying network interface
792  * @param[in] port Port number
793  * @return Port state
794  **/
795 
797 {
798  uint32_t temp;
799  SwitchPortState state;
800 
801  //Read port state register
802  temp = lan9353ReadSwitchReg(interface, LAN9353_SWE_PORT_STATE);
803 
804  //Check port number
805  if(port == LAN9353_PORT1)
806  {
807  //Check port 1 state
808  switch(temp & LAN9353_SWE_PORT_STATE_PORT1)
809  {
812  break;
815  break;
818  break;
819  default:
821  break;
822  }
823  }
824  else if(port == LAN9353_PORT2)
825  {
826  //Check port 2 state
827  switch(temp & LAN9353_SWE_PORT_STATE_PORT2)
828  {
831  break;
834  break;
837  break;
838  default:
840  break;
841  }
842  }
843  else
844  {
845  //The specified port number is not valid
847  }
848 
849  //Return port state
850  return state;
851 }
852 
853 
854 /**
855  * @brief Set aging time for dynamic filtering entries
856  * @param[in] interface Underlying network interface
857  * @param[in] agingTime Aging time, in seconds
858  **/
859 
860 void lan9353SetAgingTime(NetInterface *interface, uint32_t agingTime)
861 {
862  uint32_t temp;
863 
864  //The maximum value is approximately 69 minutes
865  agingTime = MAX(agingTime, 1);
866  agingTime = MIN(agingTime, 4096);
867 
868  //The time is specified in 1 second increments plus 1 second
869  temp = ((agingTime - 1) << 16) & LAN9353_SWE_ALR_CFG_AGING_TIME;
870 
871  //Write the value to the Switch Engine ALR Configuration register
872  lan9353WriteSwitchReg(interface, LAN9353_SWE_ALR_CFG, temp |
874 }
875 
876 
877 /**
878  * @brief Enable IGMP snooping
879  * @param[in] interface Underlying network interface
880  * @param[in] enable Enable or disable IGMP snooping
881  **/
882 
884 {
885  uint32_t temp;
886 
887  //Read the Switch Engine Global Ingress Configuration register
889 
890  //Enable or disable IGMP monitoring
891  if(enable)
892  {
894  }
895  else
896  {
898  }
899 
900  //Set the port bit map where IGMP packets are sent
903 
904  //Write the value back to Switch Engine Global Ingress Configuration register
906 }
907 
908 
909 /**
910  * @brief Enable MLD snooping
911  * @param[in] interface Underlying network interface
912  * @param[in] enable Enable or disable MLD snooping
913  **/
914 
916 {
917  uint32_t temp;
918 
919  //Read the Switch Engine Global Ingress Configuration register
921 
922  //Enable or disable MLD monitoring
923  if(enable)
924  {
926  }
927  else
928  {
930  }
931 
932  //Set the port bit map where MLD packets are sent
935 
936  //Write the value back to Switch Engine Global Ingress Configuration register
938 }
939 
940 
941 /**
942  * @brief Enable reserved multicast table
943  * @param[in] interface Underlying network interface
944  * @param[in] enable Enable or disable reserved group addresses
945  **/
946 
948 {
949  uint_t i;
950  SwitchFdbEntry entry;
951 
952  //The reserved group addresses are in the range of 01-80-C2-00-00-00 to
953  //01-80-C2-00-00-0F
954  for(i = 0; i <= 15; i++)
955  {
956  //Specify the reserved group address to be added or removed
957  entry.macAddr.b[0] = 0x01;
958  entry.macAddr.b[1] = 0x80;
959  entry.macAddr.b[2] = 0xC2;
960  entry.macAddr.b[3] = 0x00;
961  entry.macAddr.b[4] = 0x00;
962  entry.macAddr.b[5] = i;
963 
964  //Format forwarding database entry
965  entry.srcPort = 0;
967  entry.override = TRUE;
968 
969  //Update the static MAC table
970  if(enable)
971  {
972  lan9353AddStaticFdbEntry(interface, &entry);
973  }
974  else
975  {
976  lan9353DeleteStaticFdbEntry(interface, &entry);
977  }
978  }
979 }
980 
981 
982 /**
983  * @brief Add a new entry to the static MAC table
984  * @param[in] interface Underlying network interface
985  * @param[in] entry Pointer to the forwarding database entry
986  * @return Error code
987  **/
988 
990  const SwitchFdbEntry *entry)
991 {
992  uint32_t value;
993  uint32_t ports;
994 
995  //Check whether the forward port is the CPU port
996  if(entry->destPorts == SWITCH_CPU_PORT_MASK)
997  {
998  ports = LAN9353_PORT0_MASK;
999  }
1000  else
1001  {
1002  ports = entry->destPorts & LAN9353_PORT_MASK;
1003  }
1004 
1005  //Valid forward ports?
1006  if(ports != 0)
1007  {
1008  //Write SWE_ALR_WR_DAT_0 and SWE_ALR_WR_DAT_1 with the desired MAC
1009  //address and control bits
1011 
1012  //When the Override bit set, packets received with a destination
1013  //address that matches the MAC address in the SWE_ALR_WR_DAT_1 and
1014  //SWE_ALR_WR_DAT_0 registers will be forwarded regardless of the port
1015  //state
1016  if(entry->override)
1017  {
1019  }
1020 
1021  //Set the ports associated with this MAC address
1022  switch(ports)
1023  {
1024  case LAN9353_PORT0_MASK:
1026  break;
1027  case LAN9353_PORT1_MASK:
1029  break;
1030  case LAN9353_PORT2_MASK:
1032  break;
1033  case LAN9353_PORT0_1_MASK:
1035  break;
1036  case LAN9353_PORT0_2_MASK:
1038  break;
1039  case LAN9353_PORT1_2_MASK:
1041  break;
1042  default:
1044  break;
1045  }
1046  }
1047  else
1048  {
1049  //An entry can be deleted by setting the Valid bit to 0
1051  }
1052 
1053  //Copy MAC address (last 16 bits)
1054  value |= entry->macAddr.b[4] | (entry->macAddr.b[5] << 8);
1055  //Write SWE_ALR_WR_DAT_1 register
1057 
1058  //Copy MAC address (first 32 bits)
1059  value = entry->macAddr.b[0] | (entry->macAddr.b[1] << 8) |
1060  (entry->macAddr.b[2] << 16) | (entry->macAddr.b[3] << 24);
1061 
1062  //Write SWE_ALR_WR_DAT_0 register
1064 
1065  //Write the SWE_ALR_CMD register
1068 
1069  //Poll the Make Pending bit in the SWE_ALR_CMD_STS register until it is
1070  //cleared
1071  do
1072  {
1073  //Read the SWE_ALR_CMD_STS register
1075 
1076  //Check the Make Pending bit
1078 
1079  //Clear the SWE_ALR_CMD register
1081 
1082  //Successful processing
1083  return NO_ERROR;
1084 }
1085 
1086 
1087 /**
1088  * @brief Remove an entry from the static MAC table
1089  * @param[in] interface Underlying network interface
1090  * @param[in] entry Forwarding database entry to remove from the table
1091  * @return Error code
1092  **/
1093 
1095  const SwitchFdbEntry *entry)
1096 {
1097  uint32_t value;
1098 
1099  //An entry can be deleted by setting the Valid bit to 0
1101 
1102  //Specify the MAC address to remove (last 16 bits)
1103  value |= entry->macAddr.b[4] | (entry->macAddr.b[5] << 8);
1104  //Write SWE_ALR_WR_DAT_1 register
1106 
1107  //Specify the MAC address to remove (first 32 bits)
1108  value = entry->macAddr.b[0] | (entry->macAddr.b[1] << 8) |
1109  (entry->macAddr.b[2] << 16) | (entry->macAddr.b[3] << 24);
1110 
1111  //Write SWE_ALR_WR_DAT_0 register
1113 
1114  //Write the SWE_ALR_CMD register
1117 
1118  //Poll the Make Pending bit in the SWE_ALR_CMD_STS register until it is
1119  //cleared
1120  do
1121  {
1122  //Read the SWE_ALR_CMD_STS register
1124 
1125  //Check the Make Pending bit
1127 
1128  //Clear the SWE_ALR_CMD register
1130 
1131  //Successful processing
1132  return NO_ERROR;
1133 }
1134 
1135 
1136 /**
1137  * @brief Read an entry from the static MAC table
1138  * @param[in] interface Underlying network interface
1139  * @param[in] index Zero-based index of the entry to read
1140  * @param[out] entry Pointer to the forwarding database entry
1141  * @return Error code
1142  **/
1143 
1145  SwitchFdbEntry *entry)
1146 {
1147  uint32_t value;
1148 
1149  //Loop through the ALR table
1150  while(1)
1151  {
1152  //Out of bound index?
1153  if(index >= LAN9353_ALR_TABLE_SIZE)
1154  return ERROR_END_OF_TABLE;
1155 
1156  //First entry?
1157  if(index == 0)
1158  {
1160  }
1161  else
1162  {
1164  }
1165 
1166  //Write the SWE_ALR_CMD register
1168  //Clear the SWE_ALR_CMD register
1170 
1171  //Poll the Valid and End of Table bits in the SWE_ALR_RD_DAT_1 register
1172  //until either is set
1173  while(1)
1174  {
1175  //Read SWE_ALR_RD_DAT_1 register
1177 
1178  //If the End of Table bit is set, then exit
1180  {
1181  return ERROR_END_OF_TABLE;
1182  }
1183 
1184  //If the Valid bit is set, then the entry is valid
1186  {
1187  break;
1188  }
1189  }
1190 
1191  //Static entry?
1193  {
1194  break;
1195  }
1196 
1197  //Skip dynamic entries
1198  index++;
1199  }
1200 
1201  //Store the data from SWE_ALR_RD_DAT_0 and SWE_ALR_RD_DAT_1 registers
1202  entry->srcPort = 0;
1203  entry->override = FALSE;
1204 
1205  //Retrieve the ports associated with this MAC address
1207  {
1209  entry->destPorts = LAN9353_PORT0_MASK;
1210  break;
1212  entry->destPorts = LAN9353_PORT1_MASK;
1213  break;
1215  entry->destPorts = LAN9353_PORT2_MASK;
1216  break;
1219  break;
1222  break;
1225  break;
1228  break;
1229  default:
1230  entry->destPorts = 0;
1231  break;
1232  }
1233 
1234  //Copy MAC address (last 16 bits)
1235  entry->macAddr.b[4] = value & 0xFF;
1236  entry->macAddr.b[5] = (value >> 8) & 0xFF;
1237 
1238  //Read SWE_ALR_RD_DAT_0 register
1240 
1241  //Copy MAC address (first 32 bits)
1242  entry->macAddr.b[0] = value & 0xFF;
1243  entry->macAddr.b[1] = (value >> 8) & 0xFF;
1244  entry->macAddr.b[2] = (value >> 16) & 0xFF;
1245  entry->macAddr.b[3] = (value >> 24) & 0xFF;
1246 
1247  //Successful processing
1248  return NO_ERROR;
1249 }
1250 
1251 
1252 /**
1253  * @brief Flush static MAC table
1254  * @param[in] interface Underlying network interface
1255  **/
1256 
1258 {
1259  error_t error;
1260  uint_t i;
1261  SwitchFdbEntry entry;
1262 
1263  //Loop through the ALR table
1264  for(i = 0; i < LAN9353_ALR_TABLE_SIZE; i++)
1265  {
1266  //Read current entry
1267  error = lan9353GetStaticFdbEntry(interface, i, &entry);
1268 
1269  //Valid entry?
1270  if(!error)
1271  {
1272  //An entry can be deleted by setting the Valid bit to 0
1273  lan9353DeleteStaticFdbEntry(interface, &entry);
1274  }
1275  else
1276  {
1277  //The end of the table has been reached
1278  break;
1279  }
1280  }
1281 }
1282 
1283 
1284 /**
1285  * @brief Read an entry from the dynamic MAC table
1286  * @param[in] interface Underlying network interface
1287  * @param[in] index Zero-based index of the entry to read
1288  * @param[out] entry Pointer to the forwarding database entry
1289  * @return Error code
1290  **/
1291 
1293  SwitchFdbEntry *entry)
1294 {
1295  uint32_t value;
1296 
1297  //Loop through the ALR table
1298  while(1)
1299  {
1300  //Out of bound index?
1301  if(index >= LAN9353_ALR_TABLE_SIZE)
1302  return ERROR_END_OF_TABLE;
1303 
1304  //First entry?
1305  if(index == 0)
1306  {
1308  }
1309  else
1310  {
1312  }
1313 
1314  //Write the SWE_ALR_CMD register
1316  //Clear the SWE_ALR_CMD register
1318 
1319  //Poll the Valid and End of Table bits in the SWE_ALR_RD_DAT_1 register
1320  //until either is set
1321  while(1)
1322  {
1323  //Read SWE_ALR_RD_DAT_1 register
1325 
1326  //If the End of Table bit is set, then exit
1328  {
1329  return ERROR_END_OF_TABLE;
1330  }
1331 
1332  //If the Valid bit is set, then the entry is valid
1334  {
1335  break;
1336  }
1337  }
1338 
1339  //Dynamic entry?
1341  {
1342  break;
1343  }
1344 
1345  //Skip static entries
1346  index++;
1347  }
1348 
1349  //Store the data from SWE_ALR_RD_DAT_0 and SWE_ALR_RD_DAT_1 registers
1350  entry->destPorts = 0;
1351  entry->override = FALSE;
1352 
1353  //Retrieve the port associated with this MAC address
1355  {
1357  entry->srcPort = LAN9353_PORT0;
1358  break;
1360  entry->srcPort = LAN9353_PORT1;
1361  break;
1363  entry->srcPort = LAN9353_PORT2;
1364  break;
1365  default:
1366  entry->srcPort = 0;
1367  break;
1368  }
1369 
1370  //Copy MAC address (last 16 bits)
1371  entry->macAddr.b[4] = value & 0xFF;
1372  entry->macAddr.b[5] = (value >> 8) & 0xFF;
1373 
1374  //Read SWE_ALR_RD_DAT_0 register
1376 
1377  //Copy MAC address (first 32 bits)
1378  entry->macAddr.b[0] = value & 0xFF;
1379  entry->macAddr.b[1] = (value >> 8) & 0xFF;
1380  entry->macAddr.b[2] = (value >> 16) & 0xFF;
1381  entry->macAddr.b[3] = (value >> 24) & 0xFF;
1382 
1383  //Successful processing
1384  return NO_ERROR;
1385 }
1386 
1387 
1388 /**
1389  * @brief Flush dynamic MAC table
1390  * @param[in] interface Underlying network interface
1391  * @param[in] port Port number
1392  **/
1393 
1395 {
1396  error_t error;
1397  uint_t i;
1398  uint32_t value;
1399  SwitchFdbEntry entry;
1400 
1401  //Loop through the ALR table
1402  for(i = 0; i < LAN9353_ALR_TABLE_SIZE; i++)
1403  {
1404  //Read current entry
1405  error = lan9353GetDynamicFdbEntry(interface, i, &entry);
1406 
1407  //Valid entry?
1408  if(!error)
1409  {
1410  //Matching port number?
1411  if(entry.srcPort == port || port == 0)
1412  {
1413  //Specify the MAC address to remove (last 16 bits)
1414  value = entry.macAddr.b[4] | (entry.macAddr.b[5] << 8);
1415  //Write SWE_ALR_WR_DAT_1 register
1417 
1418  //Specify the MAC address to remove (first 32 bits)
1419  value = entry.macAddr.b[0] | (entry.macAddr.b[1] << 8) |
1420  (entry.macAddr.b[2] << 16) | (entry.macAddr.b[3] << 24);
1421 
1422  //Write SWE_ALR_WR_DAT_0 register
1424 
1425  //Write the SWE_ALR_CMD register
1428 
1429  //Poll the Make Pending bit in the SWE_ALR_CMD_STS register until
1430  //it is cleared
1431  do
1432  {
1433  //Read the SWE_ALR_CMD_STS register
1435 
1436  //Check the Make Pending bit
1438 
1439  //Clear the SWE_ALR_CMD register
1441  }
1442  }
1443  else
1444  {
1445  //The end of the table has been reached
1446  break;
1447  }
1448  }
1449 }
1450 
1451 
1452 /**
1453  * @brief Set forward ports for unknown multicast packets
1454  * @param[in] interface Underlying network interface
1455  * @param[in] enable Enable or disable forwarding of unknown multicast packets
1456  * @param[in] forwardPorts Port map
1457  **/
1458 
1460  bool_t enable, uint32_t forwardPorts)
1461 {
1462  //Not implemented
1463 }
1464 
1465 
1466 /**
1467  * @brief Write PHY register
1468  * @param[in] interface Underlying network interface
1469  * @param[in] port Port number
1470  * @param[in] address PHY register address
1471  * @param[in] data Register value
1472  **/
1473 
1474 void lan9353WritePhyReg(NetInterface *interface, uint8_t port,
1475  uint8_t address, uint16_t data)
1476 {
1477  //Write the specified PHY register
1478  if(interface->smiDriver != NULL)
1479  {
1480  interface->smiDriver->writePhyReg(SMI_OPCODE_WRITE, port, address, data);
1481  }
1482  else
1483  {
1484  interface->nicDriver->writePhyReg(SMI_OPCODE_WRITE, port, address, data);
1485  }
1486 }
1487 
1488 
1489 /**
1490  * @brief Read PHY register
1491  * @param[in] interface Underlying network interface
1492  * @param[in] port Port number
1493  * @param[in] address PHY register address
1494  * @return Register value
1495  **/
1496 
1497 uint16_t lan9353ReadPhyReg(NetInterface *interface, uint8_t port,
1498  uint8_t address)
1499 {
1500  uint16_t data;
1501 
1502  //Read the specified PHY register
1503  if(interface->smiDriver != NULL)
1504  {
1505  data = interface->smiDriver->readPhyReg(SMI_OPCODE_READ, port, address);
1506  }
1507  else
1508  {
1509  data = interface->nicDriver->readPhyReg(SMI_OPCODE_READ, port, address);
1510  }
1511 
1512  //Return the value of the PHY register
1513  return data;
1514 }
1515 
1516 
1517 /**
1518  * @brief Dump PHY registers for debugging purpose
1519  * @param[in] interface Underlying network interface
1520  * @param[in] port Port number
1521  **/
1522 
1523 void lan9353DumpPhyReg(NetInterface *interface, uint8_t port)
1524 {
1525  uint8_t i;
1526 
1527  //Loop through PHY registers
1528  for(i = 0; i < 32; i++)
1529  {
1530  //Display current PHY register
1531  TRACE_DEBUG("%02" PRIu8 ": 0x%04" PRIX16 "\r\n", i,
1532  lan9353ReadPhyReg(interface, port, i));
1533  }
1534 
1535  //Terminate with a line feed
1536  TRACE_DEBUG("\r\n");
1537 }
1538 
1539 
1540 /**
1541  * @brief Write system CSR register
1542  * @param[in] interface Underlying network interface
1543  * @param[in] address System register address
1544  * @param[in] data Register value
1545  **/
1546 
1547 void lan9353WriteSysReg(NetInterface *interface, uint16_t address,
1548  uint32_t data)
1549 {
1550  uint8_t phyAddr;
1551  uint8_t regAddr;
1552 
1553  //PHY address bit 4 is 1 for SMI commands. PHY address 3:0 form system
1554  //register address bits 9:6
1555  phyAddr = 0x10 | ((address >> 6) & 0x0F);
1556 
1557  //Register address field forms register address bits 5:1
1558  regAddr = (address >> 1) & 0x1F;
1559 
1560  //Write system CSR register
1561  if(interface->smiDriver != NULL)
1562  {
1563  //Write the low word of the SMI register
1564  interface->smiDriver->writePhyReg(SMI_OPCODE_WRITE, phyAddr, regAddr,
1565  data & 0xFFFF);
1566 
1567  //Write the high word of the SMI register
1568  interface->smiDriver->writePhyReg(SMI_OPCODE_WRITE, phyAddr, regAddr + 1,
1569  (data >> 16) & 0xFFFF);
1570  }
1571  else
1572  {
1573  //Write the low word of the SMI register
1574  interface->nicDriver->writePhyReg(SMI_OPCODE_WRITE, phyAddr, regAddr,
1575  data & 0xFFFF);
1576 
1577  //Write the high word of the SMI register
1578  interface->nicDriver->writePhyReg(SMI_OPCODE_WRITE, phyAddr, regAddr + 1,
1579  (data >> 16) & 0xFFFF);
1580  }
1581 }
1582 
1583 
1584 /**
1585  * @brief Read system CSR register
1586  * @param[in] interface Underlying network interface
1587  * @param[in] address System register address
1588  * @return Register value
1589  **/
1590 
1591 uint32_t lan9353ReadSysReg(NetInterface *interface, uint16_t address)
1592 {
1593  uint8_t phyAddr;
1594  uint8_t regAddr;
1595  uint32_t data;
1596 
1597  //PHY address bit 4 is 1 for SMI commands. PHY address 3:0 form system
1598  //register address bits 9:6
1599  phyAddr = 0x10 | ((address >> 6) & 0x0F);
1600 
1601  //Register address field forms register address bits 5:1
1602  regAddr = (address >> 1) & 0x1F;
1603 
1604  //Read system CSR register
1605  if(interface->smiDriver != NULL)
1606  {
1607  //Read the low word of the SMI register
1608  data = interface->smiDriver->readPhyReg(SMI_OPCODE_READ, phyAddr,
1609  regAddr);
1610 
1611  //Read the high word of the SMI register
1612  data |= interface->smiDriver->readPhyReg(SMI_OPCODE_READ, phyAddr,
1613  regAddr + 1) << 16;
1614  }
1615  else
1616  {
1617  //Read the low word of the SMI register
1618  data = interface->nicDriver->readPhyReg(SMI_OPCODE_READ, phyAddr,
1619  regAddr);
1620 
1621  //Read the high word of the SMI register
1622  data |= interface->nicDriver->readPhyReg(SMI_OPCODE_READ, phyAddr,
1623  regAddr + 1) << 16;
1624  }
1625 
1626  //Return register value
1627  return data;
1628 }
1629 
1630 
1631 /**
1632  * @brief Dump system CSR registers for debugging purpose
1633  * @param[in] interface Underlying network interface
1634  **/
1635 
1637 {
1638  uint16_t i;
1639 
1640  //Loop through system registers
1641  for(i = 80; i < 512; i += 4)
1642  {
1643  //Display current system register
1644  TRACE_DEBUG("0x%03" PRIX16 ": 0x%08" PRIX32 "\r\n", i,
1645  lan9353ReadSysReg(interface, i));
1646  }
1647 
1648  //Terminate with a line feed
1649  TRACE_DEBUG("\r\n");
1650 }
1651 
1652 
1653 /**
1654  * @brief Write switch fabric CSR register
1655  * @param[in] interface Underlying network interface
1656  * @param[in] address Switch fabric register address
1657  * @param[in] data Register value
1658  **/
1659 
1660 void lan9353WriteSwitchReg(NetInterface *interface, uint16_t address,
1661  uint32_t data)
1662 {
1663  uint32_t value;
1664 
1665  //To perform a write to an individual switch fabric register, the desired
1666  //data must first be written into the SWITCH_CSR_DATA register
1668 
1669  //Set up a write operation
1672 
1673  //Set register address
1675 
1676  //The write cycle is initiated by performing a single write to the
1677  //SWITCH_CSR_CMD register
1679 
1680  //The completion of the write cycle is indicated by the clearing of the
1681  //CSR_BUSY bit
1682  do
1683  {
1684  //Read SWITCH_CSR_CMD register
1686 
1687  //Poll CSR_BUSY bit
1688  } while((value & LAN9353_SWITCH_CSR_CMD_BUSY) != 0);
1689 }
1690 
1691 
1692 /**
1693  * @brief Read switch fabric CSR register
1694  * @param[in] interface Underlying network interface
1695  * @param[in] address Switch fabric register address
1696  * @return Register value
1697  **/
1698 
1699 uint32_t lan9353ReadSwitchReg(NetInterface *interface, uint16_t address)
1700 {
1701  uint32_t value;
1702 
1703  //Set up a read operation
1706 
1707  //Set register address
1709 
1710  //To perform a read of an individual switch fabric register, the read cycle
1711  //must be initiated by performing a single write to the SWITCH_CSR_CMD
1712  //register
1714 
1715  //Valid data is available for reading when the CSR_BUSY bit is cleared
1716  do
1717  {
1718  //Read SWITCH_CSR_CMD register
1720 
1721  //Poll CSR_BUSY bit
1722  } while((value & LAN9353_SWITCH_CSR_CMD_BUSY) != 0);
1723 
1724  //Read data from the SWITCH_CSR_DATA register
1725  return lan9353ReadSysReg(interface, LAN9353_SWITCH_CSR_DATA);
1726 }
void nicNotifyLinkChange(NetInterface *interface)
Process link state change notification.
Definition: nic.c:601
#define htons(value)
Definition: cpu_endian.h:413
#define LAN9353_PSCSR_SPEED_100BTX_FD
SwitchPortState lan9353GetPortState(NetInterface *interface, uint8_t port)
Get port state.
void lan9353SetUnknownMcastFwdPorts(NetInterface *interface, bool_t enable, uint32_t forwardPorts)
Set forward ports for unknown multicast packets.
#define LAN9353_SWE_PORT_MIRROR_MIRRORED_PORT_1
void lan9353EnableMldSnooping(NetInterface *interface, bool_t enable)
Enable MLD snooping.
error_t lan9353Init(NetInterface *interface)
LAN9353 Ethernet switch initialization.
#define NetContext
Definition: net.h:36
__weak_func void lan9353EventHandler(NetInterface *interface)
LAN9353 event handler.
#define LAN9353_MAC_TX_CFG_TX_EN
LAN9353 3-port Ethernet switch driver.
void lan9353FlushStaticFdbTable(NetInterface *interface)
Flush static MAC table.
int bool_t
Definition: compiler_port.h:63
@ NIC_LINK_SPEED_UNKNOWN
Definition: nic.h:110
uint32_t destPorts
Definition: nic.h:152
#define LAN9353_SWE_ALR_CMD_STS_OPERATION_PENDING
#define LAN9353_PORT2
const SwitchDriver lan9353SwitchDriver
LAN9353 Ethernet switch driver.
#define LAN9353_VID_ALR_LOOKUP
@ NIC_FULL_DUPLEX_MODE
Definition: nic.h:125
#define LAN9353_SWITCH_CSR_CMD_BUSY
void lan9353SetAgingTime(NetInterface *interface, uint32_t agingTime)
Set aging time for dynamic filtering entries.
#define LAN9353_SWE_PORT_MIRROR_RX_MIRRORING_EN
#define LAN9353_SWE_ALR_RD_DAT_1_PORT_1_2
error_t lan9353UntagFrame(NetInterface *interface, uint8_t **frame, size_t *length, NetRxAncillary *ancillary)
Decode special VLAN tag from incoming Ethernet frame.
@ ERROR_END_OF_TABLE
Definition: error.h:292
#define LAN9353_BMSR
#define LAN9353_SWE_PORT_MIRROR
@ SWITCH_PORT_STATE_DISABLED
Definition: nic.h:136
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:89
#define TRUE
Definition: os_port.h:50
#define LAN9353_PORT1_2_MASK
uint8_t data[]
Definition: ethernet.h:224
#define LAN9353_SWITCH_CSR_DATA
@ SWITCH_PORT_STATE_LEARNING
Definition: nic.h:139
bool_t lan9353GetLinkState(NetInterface *interface, uint8_t port)
Get link state.
#define LAN9353_BM_EGRSS_PORT_TYPE
#define LAN9353_PORT1
error_t lan9353GetStaticFdbEntry(NetInterface *interface, uint_t index, SwitchFdbEntry *entry)
Read an entry from the static MAC table.
#define LAN9353_SWE_ALR_CMD_GET_NEXT_ENTRY
NicDuplexMode lan9353GetDuplexMode(NetInterface *interface, uint8_t port)
Get duplex mode.
#define LAN9353_SWE_ALR_WR_DAT_1
@ ERROR_INVALID_PORT
Definition: error.h:104
error_t lan9353AddStaticFdbEntry(NetInterface *interface, const SwitchFdbEntry *entry)
Add a new entry to the static MAC table.
error_t lan9353DeleteStaticFdbEntry(NetInterface *interface, const SwitchFdbEntry *entry)
Remove an entry from the static MAC table.
#define LAN9353_SWE_PORT_STATE_PORT2_DISABLED
EthHeader
Definition: ethernet.h:225
#define LAN9353_SWE_ALR_RD_DAT_1_VALID
#define LAN9353_PORT2_MASK
void lan9353EnableIrq(NetInterface *interface)
Enable interrupts.
#define LAN9353_PORT0_1_MASK
#define LAN9353_SWE_PORT_STATE
VlanTag
Definition: ethernet.h:248
#define SMI_OPCODE_WRITE
Definition: nic.h:66
#define LAN9353_SWE_ALR_CMD_STS
#define LAN9353_PORT0_2_MASK
#define LAN9353_MAC_RX_CFG_REJECT_MAC_TYPES
#define LAN9353_HW_CFG
#define LAN9353_SWITCH_CSR_CMD_BE
#define LAN9353_SWE_ALR_WR_DAT_1_STATIC
#define LAN9353_SWE_PORT_MIRROR_SNIFFER_PORT_0
#define FALSE
Definition: os_port.h:46
#define LAN9353_SWE_ALR_RD_DAT_0
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
#define LAN9353_PORT1_MASK
#define LAN9353_PSCSR_SPEED_10BT_FD
#define LAN9353_SWE_PORT_STATE_PORT1_LEARNING
error_t
Error codes.
Definition: error.h:43
#define LAN9353_SWE_GLOBAL_INGRSS_CFG_MLD_IGMP_MONITOR_PORT_0
#define LAN9353_SWE_PORT_STATE_PORT1_DISABLED
#define LAN9353_SWE_ALR_RD_DAT_1
#define LAN9353_SWITCH_CSR_CMD_READ
#define LAN9353_SWE_ALR_WR_DAT_1_PORT_0_2
#define LAN9353_SWE_ALR_RD_DAT_1_PORT_0
#define LAN9353_SWE_ALR_WR_DAT_1_AGE1_OVERRIDE
#define LAN9353_SWE_ALR_CMD_GET_FIRST_ENTRY
#define LAN9353_SWE_ALR_WR_DAT_1_VALID
#define LAN9353_SWE_ALR_WR_DAT_1_PORT_2
#define LAN9353_SWITCH_CSR_CMD
#define LAN9353_SWE_GLOBAL_INGRSS_CFG_MLD_IGMP_MONITOR_PORT
void lan9353WritePhyReg(NetInterface *interface, uint8_t port, uint8_t address, uint16_t data)
Write PHY register.
#define NetRxAncillary
Definition: net_misc.h:40
#define NetInterface
Definition: net.h:40
#define LAN9353_SWE_ALR_WR_DAT_1_PORT_0_1_2
@ NIC_LINK_SPEED_10MBPS
Definition: nic.h:111
error_t lan9353GetDynamicFdbEntry(NetInterface *interface, uint_t index, SwitchFdbEntry *entry)
Read an entry from the dynamic MAC table.
#define LAN9353_SWE_INGRSS_PORT_TYP_PORT0
#define LAN9353_SWE_PORT_STATE_PORT0_FORWARDING
@ ERROR_INVALID_LENGTH
Definition: error.h:111
void lan9353WriteSysReg(NetInterface *interface, uint16_t address, uint32_t data)
Write system CSR register.
#define LAN9353_HW_CFG_DEVICE_READY
#define LAN9353_PSCSR
#define LAN9353_SWE_ALR_RD_DAT_1_STATIC
void lan9353FlushDynamicFdbTable(NetInterface *interface, uint8_t port)
Flush dynamic MAC table.
#define NetTxAncillary
Definition: net_misc.h:36
#define LAN9353_SWE_PORT_MIRROR_MIRRORED_PORT_2
#define LAN9353_SWITCH_CSR_CMD_WRITE
#define SMI_OPCODE_READ
Definition: nic.h:67
SwitchPortState
Switch port state.
Definition: nic.h:134
#define LAN9353_SWE_PORT_STATE_PORT1
#define LAN9353_SWE_ALR_WR_DAT_1_PORT_1_2
#define TRACE_INFO(...)
Definition: debug.h:105
uint8_t length
Definition: tcp.h:375
#define LAN9353_SWE_ALR_CFG_AGING_TIME
#define LAN9353_ALR_TABLE_SIZE
#define MIN(a, b)
Definition: os_port.h:63
#define LAN9353_SWE_ALR_RD_DAT_1_PORT_2
#define LAN9353_SWE_ALR_RD_DAT_1_END_OF_TABLE
#define LAN9353_SWE_ALR_CMD_MAKE_ENTRY
#define LAN9353_BMSR_LINK_STATUS
#define LAN9353_SWE_PORT_STATE_PORT2_LISTENING
#define LAN9353_SWE_GLOBAL_INGRSS_CFG_IGMP_MONITORING_EN
void lan9353DisableIrq(NetInterface *interface)
Disable interrupts.
@ SWITCH_PORT_STATE_BLOCKING
Definition: nic.h:137
__weak_func void lan9353Tick(NetInterface *interface)
LAN9353 timer handler.
#define LAN9353_MAC_RX_CFG_RX_EN
#define LAN9353_PORT0_1_2_MASK
#define LAN9353_SWE_ALR_CFG_ALR_AGE_EN
@ SWITCH_PORT_STATE_FORWARDING
Definition: nic.h:140
#define LAN9353_MAC_TX_CFG_TX_PAD_EN
#define LAN9353_BYTE_TEST_DEFAULT
uint16_t port
Definition: dns_common.h:270
#define LAN9353_SWE_ALR_WR_DAT_0
#define ntohs(value)
Definition: cpu_endian.h:421
#define TRACE_WARNING(...)
Definition: debug.h:93
@ ETH_TYPE_VLAN
Definition: ethernet.h:167
#define TRACE_DEBUG(...)
Definition: debug.h:119
#define MAX(a, b)
Definition: os_port.h:67
void lan9353DumpPhyReg(NetInterface *interface, uint8_t port)
Dump PHY registers for debugging purpose.
#define LAN9353_PSCSR_SPEED
#define LAN9353_PSCSR_SPEED_100BTX_HD
#define LAN9353_SWE_ALR_RD_DAT_1_PORT_0_1
#define LAN9353_PORT0_MASK
#define LAN9353_SWE_GLOBAL_INGRSS_CFG
#define LAN9353_SWITCH_CSR_CMD_ADDR
#define LAN9353_SWE_PORT_STATE_PORT2
#define LAN9353_SWE_ALR_CMD
uint16_t regAddr
#define LAN9353_PORT0
Ethernet switch driver.
Definition: nic.h:325
uint16_t lan9353ReadPhyReg(NetInterface *interface, uint8_t port, uint8_t address)
Read PHY register.
void lan9353EnableRsvdMcastTable(NetInterface *interface, bool_t enable)
Enable reserved multicast table.
#define LAN9353_SWE_ALR_WR_DAT_1_PORT_0
#define LAN9353_VID_SRC_PORT
#define HTONS(value)
Definition: cpu_endian.h:410
#define LAN9353_SWE_ALR_CFG
void lan9353EnableIgmpSnooping(NetInterface *interface, bool_t enable)
Enable IGMP snooping.
Ipv6Addr address[]
Definition: ipv6.h:345
#define LAN9353_SWE_PORT_STATE_PORT2_LEARNING
#define LAN9353_SWE_ALR_WR_DAT_1_PORT_1
void lan9353DumpSysReg(NetInterface *interface)
Dump system CSR registers for debugging purpose.
NicDuplexMode
Duplex mode.
Definition: nic.h:122
#define LAN9353_PORT_MASK
MacAddr macAddr
Definition: nic.h:150
uint32_t lan9353ReadSwitchReg(NetInterface *interface, uint16_t address)
Read switch fabric CSR register.
uint8_t srcPort
Definition: nic.h:151
#define LAN9353_SWE_ALR_RD_DAT_1_PORT
#define LAN9353_SWE_ALR_RD_DAT_1_PORT_1
@ NIC_HALF_DUPLEX_MODE
Definition: nic.h:124
#define LAN9353_SWE_ALR_RD_DAT_1_PORT_0_2
uint32_t lan9353ReadSysReg(NetInterface *interface, uint16_t address)
Read system CSR register.
uint8_t value[]
Definition: tcp.h:376
#define LAN9353_SWE_PORT_STATE_PORT1_FORWARDING
@ ERROR_WRONG_IDENTIFIER
Definition: error.h:89
@ NIC_UNKNOWN_DUPLEX_MODE
Definition: nic.h:123
#define LAN9353_BM_EGRSS_PORT_TYPE_PORT0_TYPE_CPU
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 LAN9353_MAC_RX_CFG(port)
#define LAN9353_VID_STP_OVERRIDE
#define LAN9353_MAC_TX_CFG_IFG_CONFIG_DEFAULT
#define LAN9353_SWE_GLOBAL_INGRSS_CFG_MLD_MONITORING_EN
#define SWITCH_CPU_PORT_MASK
Definition: nic.h:60
@ NIC_LINK_SPEED_100MBPS
Definition: nic.h:112
void lan9353WriteSwitchReg(NetInterface *interface, uint16_t address, uint32_t data)
Write switch fabric CSR register.
unsigned int uint_t
Definition: compiler_port.h:57
__weak_func void lan9353InitHook(NetInterface *interface)
LAN9353 custom configuration.
TCP/IP stack core.
#define LAN9353_SWE_ALR_RD_DAT_1_PORT_0_1_2
#define LAN9353_SWE_INGRSS_PORT_TYP
#define LAN9353_SWE_PORT_STATE_PORT2_FORWARDING
#define LAN9353_SWE_PORT_MIRROR_RX_MIRRORING_FILT_EN
void lan9353SetPortState(NetInterface *interface, uint8_t port, SwitchPortState state)
Set port state.
#define LAN9353_MAC_TX_CFG(port)
error_t lan9353TagFrame(NetInterface *interface, NetBuffer *buffer, size_t *offset, NetTxAncillary *ancillary)
Add special VLAN tag to Ethernet frame.
#define LAN9353_PSCSR_SPEED_10BT_HD
@ NO_ERROR
Success.
Definition: error.h:44
bool_t override
Definition: nic.h:153
Debugging facilities.
#define osMemmove(dest, src, length)
Definition: os_port.h:150
uint32_t lan9353GetLinkSpeed(NetInterface *interface, uint8_t port)
Get link speed.
#define LAN9353_BYTE_TEST
Forwarding database entry.
Definition: nic.h:149
#define LAN9353_SWE_ALR_WR_DAT_1_PORT_0_1
#define LAN9353_SWE_PORT_STATE_PORT1_LISTENING