From 8c19ced548538d964dcfb83bdf9ea9e8fbb7bdb1 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Wed, 13 Mar 2013 10:02:58 +0100 Subject: [PATCH 10/34] MIPS: lantiq: wifi and ethernet eeprom handling Signed-off-by: John Crispin --- arch/mips/include/asm/mach-lantiq/pci-ath-fixup.h | 6 + .../mips/include/asm/mach-lantiq/xway/lantiq_soc.h | 3 + arch/mips/lantiq/xway/Makefile | 2 + arch/mips/lantiq/xway/ath_eep.c | 237 ++++++++++++++++++++ arch/mips/lantiq/xway/pci-ath-fixup.c | 109 +++++++++ arch/mips/lantiq/xway/rt_eep.c | 60 +++++ 6 files changed, 417 insertions(+) create mode 100644 arch/mips/include/asm/mach-lantiq/pci-ath-fixup.h create mode 100644 arch/mips/lantiq/xway/ath_eep.c create mode 100644 arch/mips/lantiq/xway/pci-ath-fixup.c create mode 100644 arch/mips/lantiq/xway/rt_eep.c --- /dev/null +++ b/arch/mips/include/asm/mach-lantiq/pci-ath-fixup.h @@ -0,0 +1,6 @@ +#ifndef _PCI_ATH_FIXUP +#define _PCI_ATH_FIXUP + +void ltq_pci_ath_fixup(unsigned slot, u16 *cal_data) __init; + +#endif /* _PCI_ATH_FIXUP */ --- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h +++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h @@ -90,5 +90,8 @@ int xrx200_gphy_boot(struct device *dev, extern void ltq_pmu_enable(unsigned int module); extern void ltq_pmu_disable(unsigned int module); +/* allow the ethernet driver to load a flash mapped mac addr */ +const u8* ltq_get_eth_mac(void); + #endif /* CONFIG_SOC_TYPE_XWAY */ #endif /* _LTQ_XWAY_H__ */ --- a/arch/mips/lantiq/xway/Makefile +++ b/arch/mips/lantiq/xway/Makefile @@ -2,4 +2,6 @@ obj-y := prom.o sysctrl.o clk.o reset.o obj-y += vmmc.o +obj-$(CONFIG_PCI) += ath_eep.o rt_eep.o pci-ath-fixup.o + obj-$(CONFIG_XRX200_PHY_FW) += xrx200_phy_fw.o --- /dev/null +++ b/arch/mips/lantiq/xway/ath_eep.c @@ -0,0 +1,250 @@ +/* + * Copyright (C) 2011 Luca Olivetti + * Copyright (C) 2011 John Crispin + * Copyright (C) 2011 Andrej Vlašić + * Copyright (C) 2013 Álvaro Fernández Rojas + * Copyright (C) 2013 Daniel Gimpelevich + * + * 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 + * by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern int (*ltq_pci_plat_dev_init)(struct pci_dev *dev); +struct ath5k_platform_data ath5k_pdata; +struct ath9k_platform_data ath9k_pdata = { + .led_pin = -1, +}; +static u8 athxk_eeprom_mac[6]; + +static int ath9k_pci_plat_dev_init(struct pci_dev *dev) +{ + dev->dev.platform_data = &ath9k_pdata; + return 0; +} + +int __init of_ath9k_eeprom_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node, *mtd_np; + int mac_offset; + u32 mac_inc = 0, pci_slot = 0; + int i; + struct mtd_info *the_mtd; + size_t flash_readlen; + const __be32 *list; + const char *part; + phandle phandle; + + list = of_get_property(np, "ath,eep-flash", &i); + if (!list || (i != (2 * sizeof(*list)))) { + dev_err(&pdev->dev, "failed to find ath,eep-flash\n"); + return -ENODEV; + } + + phandle = be32_to_cpup(list++); + if (!phandle) { + dev_err(&pdev->dev, "failed to find phandle\n"); + return -ENODEV; + } + + mtd_np = of_find_node_by_phandle(phandle); + if (!mtd_np) { + dev_err(&pdev->dev, "failed to find mtd node\n"); + return -ENODEV; + } + + part = of_get_property(mtd_np, "label", NULL); + if (!part) + part = mtd_np->name; + + the_mtd = get_mtd_device_nm(part); + if (the_mtd == ERR_PTR(-ENODEV)) { + dev_err(&pdev->dev, "failed to find mtd device\n"); + return -ENODEV; + } + + i = mtd_read(the_mtd, be32_to_cpup(list), + ATH9K_PLAT_EEP_MAX_WORDS << 1, &flash_readlen, + (void *) ath9k_pdata.eeprom_data); + put_mtd_device(the_mtd); + if ((sizeof(ath9k_pdata.eeprom_data) != flash_readlen) || i) { + dev_err(&pdev->dev, "failed to load eeprom from mtd\n"); + return -ENODEV; + } + + if (of_find_property(np, "ath,eep-swap", NULL)) + for (i = 0; i < ATH9K_PLAT_EEP_MAX_WORDS; i++) + ath9k_pdata.eeprom_data[i] = swab16(ath9k_pdata.eeprom_data[i]); + + if (of_find_property(np, "ath,eep-endian", NULL)) { + ath9k_pdata.endian_check = true; + + dev_info(&pdev->dev, "endian check enabled.\n"); + } + + if (!of_property_read_u32(np, "ath,mac-offset", &mac_offset)) { + memcpy_fromio(athxk_eeprom_mac, (void*) ath9k_pdata.eeprom_data + mac_offset, 6); + } else { + random_ether_addr(athxk_eeprom_mac); + if (of_get_mac_address_mtd(np, athxk_eeprom_mac)) + dev_warn(&pdev->dev, "using random mac\n"); + } + + if (!of_property_read_u32(np, "ath,mac-increment", &mac_inc)) + athxk_eeprom_mac[5] += mac_inc; + + ath9k_pdata.macaddr = athxk_eeprom_mac; + ltq_pci_plat_dev_init = ath9k_pci_plat_dev_init; + + if (!of_property_read_u32(np, "ath,pci-slot", &pci_slot)) { + ltq_pci_ath_fixup(pci_slot, ath9k_pdata.eeprom_data); + dev_info(&pdev->dev, "pci slot: %u\n", pci_slot); + } + + dev_info(&pdev->dev, "loaded ath9k eeprom\n"); + + return 0; +} + +static struct of_device_id ath9k_eeprom_ids[] = { + { .compatible = "ath9k,eeprom" }, + { } +}; + +static struct platform_driver ath9k_eeprom_driver = { + .driver = { + .name = "ath9k,eeprom", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(ath9k_eeprom_ids), + }, +}; + +static int ath9k_eep_loaded; +static int __init of_ath9k_eeprom_init(void) +{ + int ret = platform_driver_probe(&ath9k_eeprom_driver, of_ath9k_eeprom_probe); + + if (!ret) + ath9k_eep_loaded = 1; + + return ret; +} + +static int __init of_ath9k_eeprom_init_late(void) +{ + if (ath9k_eep_loaded) + return 0; + return platform_driver_probe(&ath9k_eeprom_driver, of_ath9k_eeprom_probe); +} +late_initcall(of_ath9k_eeprom_init_late); +subsys_initcall(of_ath9k_eeprom_init); + +static int ath5k_pci_plat_dev_init(struct pci_dev *dev) +{ + dev->dev.platform_data = &ath5k_pdata; + return 0; +} + +int __init of_ath5k_eeprom_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node, *mtd_np; + int mac_offset; + u32 mac_inc = 0; + int i; + struct mtd_info *the_mtd; + size_t flash_readlen; + const __be32 *list; + const char *p
From: Felix Fietkau <nbd@nbd.name>
Date: Thu, 15 Mar 2018 20:50:37 +0100
Subject: [PATCH] net: bridge: support hardware flow table offload

Look up the real device and pass it on

Signed-off-by: Felix Fietkau <nbd@nbd.name>
---

--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -18,6 +18,10 @@
 #include <linux/ethtool.h>
 #include <linux/list.h>
 #include <linux/netfilter_bridge.h>
+#if IS_ENABLED(CONFIG_NF_FLOW_TABLE)
+#include <linux/netfilter.h>
+#include <net/netfilter/nf_flow_table.h>
+#endif
 
 #include <linux/uaccess.h>
 #include "br_private.h"
@@ -376,6 +380,28 @@ static const struct ethtool_ops br_ethto
 	.get_link	= ethtool_op_get_link,
 };
 
+#if IS_ENABLED(CONFIG_NF_FLOW_TABLE)
+static int br_flow_offload_check(struct flow_offload_hw_path *path)
+{
+	struct net_device *dev = path->dev;
+	struct net_bridge *br = netdev_priv(dev);
+	struct net_bridge_fdb_entry *dst;
+
+	if (!(path->flags & FLOW_OFFLOAD_PATH_ETHERNET))
+		return -EINVAL;
+
+	dst = br_fdb_find_rcu(br, path->eth_dest, path->vlan_id);
+	if (!dst || !dst->dst)
+		return -ENOENT;
+
+	path->dev = dst->dst->dev;
+	if (path->dev->netdev_ops->ndo_flow_offload_check)
+		return path->dev->netdev_ops->ndo_flow_offload_check(path);
+
+	return 0;
+}
+#endif /* CONFIG_NF_FLOW_TABLE */
+
 static const struct net_device_ops br_netdev_ops = {
 	.ndo_open		 = br_dev_open,
 	.ndo_stop		 = br_dev_stop,
@@ -403,6 +429,9 @@ static const struct net_device_ops br_ne
 	.ndo_bridge_setlink	 = br_setlink,
 	.ndo_bridge_dellink	 = br_dellink,
 	.ndo_features_check	 = passthru_features_check,
+#if IS_ENABLED(CONFIG_NF_FLOW_TABLE)
+	.ndo_flow_offload_check	 = br_flow_offload_check,
+#endif
 };
 
 static struct device_type br_type = {