Skip to content

Commit 02ee365

Browse files
jukkarAnas Nashif
authored andcommitted
drivers: eth: gmac: Adding VLAN support to Atmel E70 board
This enables VLAN support in gmac ethernet driver. Signed-off-by: Jukka Rissanen <[email protected]>
1 parent 7385e38 commit 02ee365

File tree

1 file changed

+77
-4
lines changed

1 file changed

+77
-4
lines changed

drivers/ethernet/eth_sam_gmac.c

Lines changed: 77 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -580,10 +580,30 @@ static struct net_pkt *frame_get(struct gmac_queue *queue)
580580
return rx_frame;
581581
}
582582

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+
583602
static void eth_rx(struct gmac_queue *queue)
584603
{
585604
struct eth_sam_dev_data *dev_data =
586605
CONTAINER_OF(queue, struct eth_sam_dev_data, queue_list);
606+
u16_t vlan_tag = NET_VLAN_TAG_UNSPEC;
587607
struct net_pkt *rx_frame;
588608

589609
/* More than one frame could have been received by GMAC, get all
@@ -593,7 +613,36 @@ static void eth_rx(struct gmac_queue *queue)
593613
while (rx_frame) {
594614
SYS_LOG_DBG("ETH rx");
595615

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) {
597646
net_pkt_unref(rx_frame);
598647
}
599648

@@ -776,12 +825,21 @@ static void eth0_iface_init(struct net_if *iface)
776825
struct device *const dev = net_if_get_device(iface);
777826
struct eth_sam_dev_data *const dev_data = DEV_DATA(dev);
778827
const struct eth_sam_dev_cfg *const cfg = DEV_CFG(dev);
828+
static bool init_done;
779829
u32_t gmac_ncfgr_val;
780830
u32_t link_status;
781831
int result;
782832

833+
/* For VLAN, this value is only used to get the correct L2 driver */
783834
dev_data->iface = iface;
784835

836+
ethernet_init(iface);
837+
838+
/* The rest of initialization should only be done once */
839+
if (init_done) {
840+
return;
841+
}
842+
785843
/* Initialize GMAC driver, maximum frame length is 1518 bytes */
786844
gmac_ncfgr_val =
787845
GMAC_NCFGR_MTIHEN /* Multicast Hash Enable */
@@ -837,11 +895,26 @@ static void eth0_iface_init(struct net_if *iface)
837895

838896
/* Set up link parameters */
839897
link_configure(cfg->regs, link_status);
898+
899+
init_done = true;
840900
}
841901

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+
842911
static const struct ethernet_api eth0_api = {
843912
.iface_api.init = eth0_iface_init,
844913
.iface_api.send = eth_tx,
914+
915+
#if defined(CONFIG_NET_VLAN)
916+
.get_capabilities = eth_capabilities,
917+
#endif
845918
};
846919

847920
static struct device DEVICE_NAME_GET(eth0_sam_gmac);
@@ -917,6 +990,6 @@ static struct eth_sam_dev_data eth0_data = {
917990
},
918991
};
919992

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

Comments
 (0)