Author: blogic Date: 2014-11-19 10:19:43 +0100 (Wed, 19 Nov 2014) New Revision: 43301
Modified: trunk/target/linux/ramips/files/drivers/net/ethernet/ralink/ralink_soc_eth.c trunk/target/linux/ramips/files/drivers/net/ethernet/ralink/ralink_soc_eth.h Log: ralink: improve tx vlan offload hardware tx vlan offload only support max 16 vids now use add/delete vlan interface to update vlan id table when duplicate vlan id index detect. disable hardware tx vlan offload support. Signed-off-by: michael lee <[email protected]> Modified: trunk/target/linux/ramips/files/drivers/net/ethernet/ralink/ralink_soc_eth.c =================================================================== --- trunk/target/linux/ramips/files/drivers/net/ethernet/ralink/ralink_soc_eth.c 2014-11-19 09:19:38 UTC (rev 43300) +++ trunk/target/linux/ramips/files/drivers/net/ethernet/ralink/ralink_soc_eth.c 2014-11-19 09:19:43 UTC (rev 43301) @@ -418,6 +418,54 @@ return storage; } +static int fe_vlan_rx_add_vid(struct net_device *dev, + __be16 proto, u16 vid) +{ + struct fe_priv *priv = netdev_priv(dev); + u32 idx = (vid & 0xf); + u32 vlan_cfg; + + if (!((fe_reg_table[FE_REG_FE_DMA_VID_BASE]) && + (dev->features | NETIF_F_HW_VLAN_CTAG_TX))) + return 0; + + if (test_bit(idx, &priv->vlan_map)) { + netdev_warn(dev, "disable tx vlan offload\n"); + dev->wanted_features &= ~NETIF_F_HW_VLAN_CTAG_TX; + netdev_update_features(dev); + } else { + vlan_cfg = fe_r32(fe_reg_table[FE_REG_FE_DMA_VID_BASE] + + ((idx >> 1) << 2)); + if (idx & 0x1) { + vlan_cfg &= 0xffff; + vlan_cfg |= (vid << 16); + } else { + vlan_cfg &= 0xffff0000; + vlan_cfg |= vid; + } + fe_w32(vlan_cfg, fe_reg_table[FE_REG_FE_DMA_VID_BASE] + + ((idx >> 1) << 2)); + set_bit(idx, &priv->vlan_map); + } + + return 0; +} + +static int fe_vlan_rx_kill_vid(struct net_device *dev, + __be16 proto, u16 vid) +{ + struct fe_priv *priv = netdev_priv(dev); + u32 idx = (vid & 0xf); + + if (!((fe_reg_table[FE_REG_FE_DMA_VID_BASE]) && + (dev->features | NETIF_F_HW_VLAN_CTAG_TX))) + return 0; + + clear_bit(idx, &priv->vlan_map); + + return 0; +} + static int fe_tx_map_dma(struct sk_buff *skb, struct net_device *dev, int idx) { @@ -1182,6 +1230,8 @@ .ndo_change_mtu = fe_change_mtu, .ndo_tx_timeout = fe_tx_timeout, .ndo_get_stats64 = fe_get_stats64, + .ndo_vlan_rx_add_vid = fe_vlan_rx_add_vid, + .ndo_vlan_rx_kill_vid = fe_vlan_rx_kill_vid, }; static int fe_probe(struct platform_device *pdev) @@ -1237,6 +1287,10 @@ ~(NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX); netdev->features |= netdev->hw_features; + /* fake rx vlan filter func. to support tx vlan offload func */ + if (fe_reg_table[FE_REG_FE_DMA_VID_BASE]) + netdev->features |= NETIF_F_HW_VLAN_CTAG_FILTER; + priv = netdev_priv(netdev); spin_lock_init(&priv->page_lock); if (fe_reg_table[FE_REG_FE_COUNTER_BASE]) { Modified: trunk/target/linux/ramips/files/drivers/net/ethernet/ralink/ralink_soc_eth.h =================================================================== --- trunk/target/linux/ramips/files/drivers/net/ethernet/ralink/ralink_soc_eth.h 2014-11-19 09:19:38 UTC (rev 43300) +++ trunk/target/linux/ramips/files/drivers/net/ethernet/ralink/ralink_soc_eth.h 2014-11-19 09:19:43 UTC (rev 43301) @@ -432,6 +432,7 @@ int link[8]; struct fe_hw_stats *hw_stats; + unsigned long vlan_map; }; extern const struct of_device_id of_fe_match[]; _______________________________________________ openwrt-commits mailing list [email protected] https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-commits
