diff options
author | Fugang Duan <b38611@freescale.com> | 2014-10-10 16:25:26 +0800 |
---|---|---|
committer | Leonard Crestez <leonard.crestez@nxp.com> | 2018-08-23 16:42:26 +0300 |
commit | af8ae01b5a1f8cbea30e1fa6db8b8d9f104e34e9 (patch) | |
tree | 9a31b90cb804298326eb7d86f5735f00e9e37d63 /drivers/net | |
parent | 8428f73229415029c76fee3eb10d583443f8fde3 (diff) |
MLK-11285-02 net:fec: add enet AVB Ubuntu Gstreamer demo support
Support Gstreamer AVB demo support.
ring1 -> ClassA, ring2 -> ClassB, ring0 -> Best Effort
For QoS: ring1 > ring2 > ring0
For bandwidth reverse:
50% bandwidth -> ClassA
33% bandwidth -> ClassB
17% bandwidth -> Best effort queue
In general, ClassA run audio, ClassB run video.
Since AVB demo use big bandwidth streaming, video cost more than
33Mbps bandwidth, and with Qos limitation: ClassA >= ClassB > Best effort,
so we have to change ring2 bandwidth equal to ring1 bandwidth (50%).
After validate on FPGA, AVB demo can work fine for audio and video.
Signed-off-by: Fugang Duan <B38611@freescale.com>
(cherry picked from commit 93d6579a7b3d2dafa721c835df5d5f7d30ed386e)
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/ethernet/freescale/fec_main.c | 35 |
1 files changed, 34 insertions, 1 deletions
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 8d94e721c47e..081887371faf 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -18,7 +18,7 @@ * Bug fixes and cleanup by Philippe De Muyter (phdm@macqel.be) * Copyright (c) 2004-2006 Macq Electronique SA. * - * Copyright (C) 2010-2011 Freescale Semiconductor, Inc. + * Copyright (C) 2010-2014 Freescale Semiconductor, Inc. */ #include <linux/module.h> @@ -72,6 +72,7 @@ static void fec_enet_itr_coal_init(struct net_device *ndev); #define DRIVER_NAME "fec" #define FEC_ENET_GET_QUQUE(_x) ((_x == 0) ? 1 : ((_x == 1) ? 2 : 0)) +static const u16 fec_enet_vlan_pri_to_queue[8] = {1, 1, 1, 1, 2, 2, 2, 2}; /* Pause frame feild and FIFO threshold */ #define FEC_ENET_FCE (1 << 5) @@ -3106,10 +3107,42 @@ static int fec_set_features(struct net_device *netdev, return 0; } +u16 fec_enet_get_raw_vlan_tci(struct sk_buff *skb) +{ + struct vlan_ethhdr *vhdr; + unsigned short vlan_TCI = 0; + + if (skb->protocol == ntohs(ETH_P_ALL)) { + vhdr = (struct vlan_ethhdr *)(skb->data); + vlan_TCI = ntohs(vhdr->h_vlan_TCI); + } + + return vlan_TCI; +} + +u16 fec_enet_select_queue(struct net_device *ndev, struct sk_buff *skb, + void *accel_priv, select_queue_fallback_t fallback) +{ + struct fec_enet_private *fep = netdev_priv(ndev); + const struct platform_device_id *id_entry = + platform_get_device_id(fep->pdev); + u16 vlan_tag; + + if (!(id_entry->driver_data & FEC_QUIRK_HAS_AVB)) + return skb_tx_hash(ndev, skb); + + vlan_tag = fec_enet_get_raw_vlan_tci(skb); + if (!vlan_tag) + return vlan_tag; + + return fec_enet_vlan_pri_to_queue[vlan_tag >> 13]; +} + static const struct net_device_ops fec_netdev_ops = { .ndo_open = fec_enet_open, .ndo_stop = fec_enet_close, .ndo_start_xmit = fec_enet_start_xmit, + .ndo_select_queue = fec_enet_select_queue, .ndo_set_rx_mode = set_multicast_list, .ndo_change_mtu = eth_change_mtu, .ndo_validate_addr = eth_validate_addr, |