lantiq: add VLAN handling fixes to xrx200 ethernet driver
Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
parent
172eebbd28
commit
c536da365b
@ -209,7 +209,7 @@ Subject: [PATCH 25/36] NET: MIPS: lantiq: adds xrx200-net
|
|||||||
+};
|
+};
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/drivers/net/ethernet/lantiq_xrx200.c
|
+++ b/drivers/net/ethernet/lantiq_xrx200.c
|
||||||
@@ -0,0 +1,1810 @@
|
@@ -0,0 +1,1830 @@
|
||||||
+/*
|
+/*
|
||||||
+ * This program is free software; you can redistribute it and/or modify it
|
+ * This program is free software; you can redistribute it and/or modify it
|
||||||
+ * under the terms of the GNU General Public License version 2 as published
|
+ * under the terms of the GNU General Public License version 2 as published
|
||||||
@ -234,6 +234,7 @@ Subject: [PATCH 25/36] NET: MIPS: lantiq: adds xrx200-net
|
|||||||
+#include <linux/platform_device.h>
|
+#include <linux/platform_device.h>
|
||||||
+#include <linux/interrupt.h>
|
+#include <linux/interrupt.h>
|
||||||
+#include <linux/clk.h>
|
+#include <linux/clk.h>
|
||||||
|
+#include <linux/if_vlan.h>
|
||||||
+#include <asm/delay.h>
|
+#include <asm/delay.h>
|
||||||
+
|
+
|
||||||
+#include <linux/of_net.h>
|
+#include <linux/of_net.h>
|
||||||
@ -248,14 +249,9 @@ Subject: [PATCH 25/36] NET: MIPS: lantiq: adds xrx200-net
|
|||||||
+
|
+
|
||||||
+#define SW_POLLING
|
+#define SW_POLLING
|
||||||
+#define SW_ROUTING
|
+#define SW_ROUTING
|
||||||
+/* #define SW_PORTMAP */
|
|
||||||
+
|
+
|
||||||
+#ifdef SW_ROUTING
|
+#ifdef SW_ROUTING
|
||||||
+ #ifdef SW_PORTMAP
|
|
||||||
+#define XRX200_MAX_DEV 2
|
+#define XRX200_MAX_DEV 2
|
||||||
+ #else
|
|
||||||
+#define XRX200_MAX_DEV 2
|
|
||||||
+ #endif
|
|
||||||
+#else
|
+#else
|
||||||
+#define XRX200_MAX_DEV 1
|
+#define XRX200_MAX_DEV 1
|
||||||
+#endif
|
+#endif
|
||||||
@ -435,6 +431,8 @@ Subject: [PATCH 25/36] NET: MIPS: lantiq: adds xrx200-net
|
|||||||
+ struct mii_bus *mii_bus;
|
+ struct mii_bus *mii_bus;
|
||||||
+
|
+
|
||||||
+ struct xrx200_chan chan[XRX200_MAX_DMA];
|
+ struct xrx200_chan chan[XRX200_MAX_DMA];
|
||||||
|
+ u16 vlan_vid[XRX200_MAX_VLAN];
|
||||||
|
+ u16 vlan_port_map[XRX200_MAX_VLAN];
|
||||||
+
|
+
|
||||||
+ struct net_device *devs[XRX200_MAX_DEV];
|
+ struct net_device *devs[XRX200_MAX_DEV];
|
||||||
+ int num_devs;
|
+ int num_devs;
|
||||||
@ -735,6 +733,7 @@ Subject: [PATCH 25/36] NET: MIPS: lantiq: adds xrx200-net
|
|||||||
+static int xrx200sw_set_vlan_vid(struct switch_dev *dev, const struct switch_attr *attr,
|
+static int xrx200sw_set_vlan_vid(struct switch_dev *dev, const struct switch_attr *attr,
|
||||||
+ struct switch_val *val)
|
+ struct switch_val *val)
|
||||||
+{
|
+{
|
||||||
|
+ struct xrx200_hw *hw = container_of(dev, struct xrx200_hw, swdev);
|
||||||
+ int i;
|
+ int i;
|
||||||
+ struct xrx200_pce_table_entry tev;
|
+ struct xrx200_pce_table_entry tev;
|
||||||
+ struct xrx200_pce_table_entry tem;
|
+ struct xrx200_pce_table_entry tem;
|
||||||
@ -749,6 +748,8 @@ Subject: [PATCH 25/36] NET: MIPS: lantiq: adds xrx200-net
|
|||||||
+ return -EINVAL;
|
+ return -EINVAL;
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
|
+ hw->vlan_vid[val->port_vlan] = val->value.i;
|
||||||
|
+
|
||||||
+ tev.index = val->port_vlan;
|
+ tev.index = val->port_vlan;
|
||||||
+ xrx200_pce_table_entry_read(&tev);
|
+ xrx200_pce_table_entry_read(&tev);
|
||||||
+ tev.key[0] = val->value.i;
|
+ tev.key[0] = val->value.i;
|
||||||
@ -780,6 +781,7 @@ Subject: [PATCH 25/36] NET: MIPS: lantiq: adds xrx200-net
|
|||||||
+
|
+
|
||||||
+static int xrx200sw_set_vlan_ports(struct switch_dev *dev, struct switch_val *val)
|
+static int xrx200sw_set_vlan_ports(struct switch_dev *dev, struct switch_val *val)
|
||||||
+{
|
+{
|
||||||
|
+ struct xrx200_hw *hw = container_of(dev, struct xrx200_hw, swdev);
|
||||||
+ int i, portmap, tagmap, untagged;
|
+ int i, portmap, tagmap, untagged;
|
||||||
+ struct xrx200_pce_table_entry tem;
|
+ struct xrx200_pce_table_entry tem;
|
||||||
+
|
+
|
||||||
@ -830,6 +832,10 @@ Subject: [PATCH 25/36] NET: MIPS: lantiq: adds xrx200-net
|
|||||||
+ tem.val[2] = tagmap;
|
+ tem.val[2] = tagmap;
|
||||||
+ xrx200_pce_table_entry_write(&tem);
|
+ xrx200_pce_table_entry_write(&tem);
|
||||||
+
|
+
|
||||||
|
+ ltq_switch_w32_mask(0, portmap, PCE_PMAP2);
|
||||||
|
+ ltq_switch_w32_mask(0, portmap, PCE_PMAP3);
|
||||||
|
+ hw->vlan_port_map[val->port_vlan] = portmap;
|
||||||
|
+
|
||||||
+ xrx200sw_fixup_pvids();
|
+ xrx200sw_fixup_pvids();
|
||||||
+
|
+
|
||||||
+ return 0;
|
+ return 0;
|
||||||
@ -1156,7 +1162,7 @@ Subject: [PATCH 25/36] NET: MIPS: lantiq: adds xrx200-net
|
|||||||
+ if (ret) {
|
+ if (ret) {
|
||||||
+ netdev_err(dev,
|
+ netdev_err(dev,
|
||||||
+ "failed to allocate new rx buffer\n");
|
+ "failed to allocate new rx buffer\n");
|
||||||
+ return 0;
|
+ return;
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ skb_put(skb, len);
|
+ skb_put(skb, len);
|
||||||
@ -1258,11 +1264,7 @@ Subject: [PATCH 25/36] NET: MIPS: lantiq: adds xrx200-net
|
|||||||
+ u32 byte_offset;
|
+ u32 byte_offset;
|
||||||
+ int len;
|
+ int len;
|
||||||
+#ifdef SW_ROUTING
|
+#ifdef SW_ROUTING
|
||||||
+ #ifdef SW_PORTMAP
|
|
||||||
+ u32 special_tag = (SPID_CPU_PORT << SPID_SHIFT) | PORT_MAP_SEL | PORT_MAP_EN | DPID_ENABLE;
|
|
||||||
+ #else
|
|
||||||
+ u32 special_tag = (SPID_CPU_PORT << SPID_SHIFT) | DPID_ENABLE;
|
+ u32 special_tag = (SPID_CPU_PORT << SPID_SHIFT) | DPID_ENABLE;
|
||||||
+ #endif
|
|
||||||
+#endif
|
+#endif
|
||||||
+
|
+
|
||||||
+ skb->dev = dev;
|
+ skb->dev = dev;
|
||||||
@ -1274,12 +1276,27 @@ Subject: [PATCH 25/36] NET: MIPS: lantiq: adds xrx200-net
|
|||||||
+ return NETDEV_TX_BUSY;
|
+ return NETDEV_TX_BUSY;
|
||||||
+ }
|
+ }
|
||||||
+#ifdef SW_ROUTING
|
+#ifdef SW_ROUTING
|
||||||
+ #ifdef SW_PORTMAP
|
+ if (is_multicast_ether_addr(eth_hdr(skb)->h_dest)) {
|
||||||
|
+ u16 port_map = priv->port_map;
|
||||||
|
+ special_tag |= PORT_MAP_SEL | PORT_MAP_EN;
|
||||||
|
+ if (skb->protocol == htons(ETH_P_8021Q)) {
|
||||||
|
+ u16 vid;
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ if (!__vlan_get_tag(skb, &vid)) {
|
||||||
|
+ for (i = 0; i < XRX200_MAX_VLAN; i++) {
|
||||||
|
+ if (priv->hw->vlan_vid[i] != vid)
|
||||||
|
+ continue;
|
||||||
|
+ port_map = priv->hw->vlan_port_map[i];
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ special_tag |= port_map << PORT_MAP_SHIFT;
|
||||||
|
+ }
|
||||||
+ special_tag |= priv->port_map << PORT_MAP_SHIFT;
|
+ special_tag |= priv->port_map << PORT_MAP_SHIFT;
|
||||||
+ #else
|
|
||||||
+ if(priv->id)
|
+ if(priv->id)
|
||||||
+ special_tag |= (1 << DPID_SHIFT);
|
+ special_tag |= (1 << DPID_SHIFT);
|
||||||
+ #endif
|
|
||||||
+ if(skb_headroom(skb) < 4) {
|
+ if(skb_headroom(skb) < 4) {
|
||||||
+ struct sk_buff *tmp = skb_realloc_headroom(skb, 4);
|
+ struct sk_buff *tmp = skb_realloc_headroom(skb, 4);
|
||||||
+ dev_kfree_skb_any(skb);
|
+ dev_kfree_skb_any(skb);
|
||||||
@ -1702,9 +1719,9 @@ Subject: [PATCH 25/36] NET: MIPS: lantiq: adds xrx200-net
|
|||||||
+ xrx200_pci_microcode();
|
+ xrx200_pci_microcode();
|
||||||
+
|
+
|
||||||
+ /* Default unknown Broadcat/Multicast/Unicast port maps */
|
+ /* Default unknown Broadcat/Multicast/Unicast port maps */
|
||||||
+ ltq_switch_w32(0x7f, PCE_PMAP1);
|
+ ltq_switch_w32(0x40, PCE_PMAP1);
|
||||||
+ ltq_switch_w32(0x7f, PCE_PMAP2);
|
+ ltq_switch_w32(0x40, PCE_PMAP2);
|
||||||
+ ltq_switch_w32(0x7f, PCE_PMAP3);
|
+ ltq_switch_w32(0x40, PCE_PMAP3);
|
||||||
+
|
+
|
||||||
+ /* RMON Counter Enable for all physical ports */
|
+ /* RMON Counter Enable for all physical ports */
|
||||||
+ for (i = 0; i < 7; i++)
|
+ for (i = 0; i < 7; i++)
|
||||||
@ -1745,6 +1762,9 @@ Subject: [PATCH 25/36] NET: MIPS: lantiq: adds xrx200-net
|
|||||||
+ ltq_switch_w32_mask(0, BIT(3), MAC_CTRL_REG(6, 2));
|
+ ltq_switch_w32_mask(0, BIT(3), MAC_CTRL_REG(6, 2));
|
||||||
+ ltq_switch_w32(1518 + 8 + 4 * 2, MAC_FLEN_REG);
|
+ ltq_switch_w32(1518 + 8 + 4 * 2, MAC_FLEN_REG);
|
||||||
+ xrx200sw_write_x(1, XRX200_BM_QUEUE_GCTRL_GL_MOD, 0);
|
+ xrx200sw_write_x(1, XRX200_BM_QUEUE_GCTRL_GL_MOD, 0);
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < XRX200_MAX_VLAN; i++)
|
||||||
|
+ hw->vlan_vid[i] = i;
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static void xrx200_hw_cleanup(struct xrx200_hw *hw)
|
+static void xrx200_hw_cleanup(struct xrx200_hw *hw)
|
||||||
|
Loading…
Reference in New Issue
Block a user