@@ -580,10 +580,30 @@ static struct net_pkt *frame_get(struct gmac_queue *queue)
580
580
return rx_frame ;
581
581
}
582
582
583
+ static inline struct net_if * get_iface (struct eth_sam_dev_data * ctx ,
584
+ u16_t vlan_tag )
585
+ {
586
+ #if defined(CONFIG_NET_VLAN )
587
+ struct net_if * iface ;
588
+
589
+ iface = net_eth_get_vlan_iface (ctx -> iface , vlan_tag );
590
+ if (!iface ) {
591
+ return ctx -> iface ;
592
+ }
593
+
594
+ return iface ;
595
+ #else
596
+ ARG_UNUSED (vlan_tag );
597
+
598
+ return ctx -> iface ;
599
+ #endif
600
+ }
601
+
583
602
static void eth_rx (struct gmac_queue * queue )
584
603
{
585
604
struct eth_sam_dev_data * dev_data =
586
605
CONTAINER_OF (queue , struct eth_sam_dev_data , queue_list );
606
+ u16_t vlan_tag = NET_VLAN_TAG_UNSPEC ;
587
607
struct net_pkt * rx_frame ;
588
608
589
609
/* More than one frame could have been received by GMAC, get all
@@ -593,7 +613,36 @@ static void eth_rx(struct gmac_queue *queue)
593
613
while (rx_frame ) {
594
614
SYS_LOG_DBG ("ETH rx" );
595
615
596
- if (net_recv_data (dev_data -> iface , rx_frame ) < 0 ) {
616
+ #if defined(CONFIG_NET_VLAN )
617
+ /* FIXME: Instead of this, use the GMAC register to get
618
+ * the used VLAN tag.
619
+ */
620
+ {
621
+ struct net_eth_hdr * hdr = NET_ETH_HDR (rx_frame );
622
+
623
+ if (ntohs (hdr -> type ) == NET_ETH_PTYPE_VLAN ) {
624
+ struct net_eth_vlan_hdr * hdr_vlan =
625
+ (struct net_eth_vlan_hdr * )
626
+ NET_ETH_HDR (rx_frame );
627
+
628
+ net_pkt_set_vlan_tci (rx_frame ,
629
+ ntohs (hdr_vlan -> vlan .tci ));
630
+ vlan_tag = net_pkt_vlan_tag (rx_frame );
631
+
632
+ #if CONFIG_NET_TC_RX_COUNT > 1
633
+ {
634
+ enum net_priority prio ;
635
+
636
+ prio = net_vlan2priority (
637
+ net_pkt_vlan_priority (rx_frame ));
638
+ net_pkt_set_priority (rx_frame , prio );
639
+ }
640
+ #endif
641
+ }
642
+ }
643
+ #endif
644
+ if (net_recv_data (get_iface (dev_data , vlan_tag ),
645
+ rx_frame ) < 0 ) {
597
646
net_pkt_unref (rx_frame );
598
647
}
599
648
@@ -776,12 +825,21 @@ static void eth0_iface_init(struct net_if *iface)
776
825
struct device * const dev = net_if_get_device (iface );
777
826
struct eth_sam_dev_data * const dev_data = DEV_DATA (dev );
778
827
const struct eth_sam_dev_cfg * const cfg = DEV_CFG (dev );
828
+ static bool init_done ;
779
829
u32_t gmac_ncfgr_val ;
780
830
u32_t link_status ;
781
831
int result ;
782
832
833
+ /* For VLAN, this value is only used to get the correct L2 driver */
783
834
dev_data -> iface = iface ;
784
835
836
+ ethernet_init (iface );
837
+
838
+ /* The rest of initialization should only be done once */
839
+ if (init_done ) {
840
+ return ;
841
+ }
842
+
785
843
/* Initialize GMAC driver, maximum frame length is 1518 bytes */
786
844
gmac_ncfgr_val =
787
845
GMAC_NCFGR_MTIHEN /* Multicast Hash Enable */
@@ -837,11 +895,26 @@ static void eth0_iface_init(struct net_if *iface)
837
895
838
896
/* Set up link parameters */
839
897
link_configure (cfg -> regs , link_status );
898
+
899
+ init_done = true;
840
900
}
841
901
902
+ #if defined(CONFIG_NET_VLAN )
903
+ static enum eth_hw_caps eth_capabilities (struct device * dev )
904
+ {
905
+ ARG_UNUSED (dev );
906
+
907
+ return ETH_HW_VLAN ;
908
+ }
909
+ #endif
910
+
842
911
static const struct ethernet_api eth0_api = {
843
912
.iface_api .init = eth0_iface_init ,
844
913
.iface_api .send = eth_tx ,
914
+
915
+ #if defined(CONFIG_NET_VLAN )
916
+ .get_capabilities = eth_capabilities ,
917
+ #endif
845
918
};
846
919
847
920
static struct device DEVICE_NAME_GET (eth0_sam_gmac );
@@ -917,6 +990,6 @@ static struct eth_sam_dev_data eth0_data = {
917
990
},
918
991
};
919
992
920
- NET_DEVICE_INIT (eth0_sam_gmac , CONFIG_ETH_SAM_GMAC_NAME , eth_initialize ,
921
- & eth0_data , & eth0_config , CONFIG_ETH_INIT_PRIORITY , & eth0_api ,
922
- ETHERNET_L2 , NET_L2_GET_CTX_TYPE ( ETHERNET_L2 ) , GMAC_MTU );
993
+ ETH_NET_DEVICE_INIT (eth0_sam_gmac , CONFIG_ETH_SAM_GMAC_NAME , eth_initialize ,
994
+ & eth0_data , & eth0_config , CONFIG_ETH_INIT_PRIORITY ,
995
+ & eth0_api , GMAC_MTU );
0 commit comments