Merge branch 'autoload-dsa-tagging-driver-when-dynamically-changing-protocol'
Vladimir Oltean says: ==================== Autoload DSA tagging driver when dynamically changing protocol This patch set solves the issue reported by Michael and Heiko here: https://lore.kernel.org/lkml/20221027113248.420216-1-michael@walle.cc/ making full use of Michael's suggestion of having two modaliases: one gets used for loading the tagging protocol when it's the default one reported by the switch driver, the other gets loaded at user's request, by name. # modinfo tag_ocelot filename: /lib/modules/6.1.0-rc4+/kernel/net/dsa/tag_ocelot.ko license: GPL v2 alias: dsa_tag:seville alias: dsa_tag:id-21 alias: dsa_tag:ocelot alias: dsa_tag:id-15 depends: dsa_core intree: Y name: tag_ocelot vermagic: 6.1.0-rc4+ SMP preempt mod_unload modversions aarch64 Tested on NXP LS1028A-RDB with the following device tree addition: &mscc_felix_port4 { dsa-tag-protocol = "ocelot-8021q"; }; &mscc_felix_port5 { dsa-tag-protocol = "ocelot-8021q"; }; CONFIG_NET_DSA and everything that depends on it is built as module. Everything auto-loads, and "cat /sys/class/net/eno2/dsa/tagging" shows "ocelot-8021q". Traffic works as well. Furthermore, "echo ocelot-8021q" into the aforementioned sysfs file now auto-loads the driver for it. ==================== Link: https://lore.kernel.org/r/20221115011847.2843127-1-vladimir.oltean@nxp.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
4ab45e973c
@ -118,10 +118,6 @@ struct dsa_netdevice_ops {
|
||||
int cmd);
|
||||
};
|
||||
|
||||
#define DSA_TAG_DRIVER_ALIAS "dsa_tag-"
|
||||
#define MODULE_ALIAS_DSA_TAG_DRIVER(__proto) \
|
||||
MODULE_ALIAS(DSA_TAG_DRIVER_ALIAS __stringify(__proto##_VALUE))
|
||||
|
||||
struct dsa_lag {
|
||||
struct net_device *dev;
|
||||
unsigned int id;
|
||||
@ -1400,70 +1396,4 @@ static inline bool dsa_slave_dev_check(const struct net_device *dev)
|
||||
netdev_tx_t dsa_enqueue_skb(struct sk_buff *skb, struct net_device *dev);
|
||||
void dsa_port_phylink_mac_change(struct dsa_switch *ds, int port, bool up);
|
||||
|
||||
struct dsa_tag_driver {
|
||||
const struct dsa_device_ops *ops;
|
||||
struct list_head list;
|
||||
struct module *owner;
|
||||
};
|
||||
|
||||
void dsa_tag_drivers_register(struct dsa_tag_driver *dsa_tag_driver_array[],
|
||||
unsigned int count,
|
||||
struct module *owner);
|
||||
void dsa_tag_drivers_unregister(struct dsa_tag_driver *dsa_tag_driver_array[],
|
||||
unsigned int count);
|
||||
|
||||
#define dsa_tag_driver_module_drivers(__dsa_tag_drivers_array, __count) \
|
||||
static int __init dsa_tag_driver_module_init(void) \
|
||||
{ \
|
||||
dsa_tag_drivers_register(__dsa_tag_drivers_array, __count, \
|
||||
THIS_MODULE); \
|
||||
return 0; \
|
||||
} \
|
||||
module_init(dsa_tag_driver_module_init); \
|
||||
\
|
||||
static void __exit dsa_tag_driver_module_exit(void) \
|
||||
{ \
|
||||
dsa_tag_drivers_unregister(__dsa_tag_drivers_array, __count); \
|
||||
} \
|
||||
module_exit(dsa_tag_driver_module_exit)
|
||||
|
||||
/**
|
||||
* module_dsa_tag_drivers() - Helper macro for registering DSA tag
|
||||
* drivers
|
||||
* @__ops_array: Array of tag driver structures
|
||||
*
|
||||
* Helper macro for DSA tag drivers which do not do anything special
|
||||
* in module init/exit. Each module may only use this macro once, and
|
||||
* calling it replaces module_init() and module_exit().
|
||||
*/
|
||||
#define module_dsa_tag_drivers(__ops_array) \
|
||||
dsa_tag_driver_module_drivers(__ops_array, ARRAY_SIZE(__ops_array))
|
||||
|
||||
#define DSA_TAG_DRIVER_NAME(__ops) dsa_tag_driver ## _ ## __ops
|
||||
|
||||
/* Create a static structure we can build a linked list of dsa_tag
|
||||
* drivers
|
||||
*/
|
||||
#define DSA_TAG_DRIVER(__ops) \
|
||||
static struct dsa_tag_driver DSA_TAG_DRIVER_NAME(__ops) = { \
|
||||
.ops = &__ops, \
|
||||
}
|
||||
|
||||
/**
|
||||
* module_dsa_tag_driver() - Helper macro for registering a single DSA tag
|
||||
* driver
|
||||
* @__ops: Single tag driver structures
|
||||
*
|
||||
* Helper macro for DSA tag drivers which do not do anything special
|
||||
* in module init/exit. Each module may only use this macro once, and
|
||||
* calling it replaces module_init() and module_exit().
|
||||
*/
|
||||
#define module_dsa_tag_driver(__ops) \
|
||||
DSA_TAG_DRIVER(__ops); \
|
||||
\
|
||||
static struct dsa_tag_driver *dsa_tag_driver_array[] = { \
|
||||
&DSA_TAG_DRIVER_NAME(__ops) \
|
||||
}; \
|
||||
module_dsa_tag_drivers(dsa_tag_driver_array)
|
||||
#endif
|
||||
|
||||
|
@ -79,16 +79,18 @@ const char *dsa_tag_protocol_to_str(const struct dsa_device_ops *ops)
|
||||
/* Function takes a reference on the module owning the tagger,
|
||||
* so dsa_tag_driver_put must be called afterwards.
|
||||
*/
|
||||
const struct dsa_device_ops *dsa_find_tagger_by_name(const char *buf)
|
||||
const struct dsa_device_ops *dsa_tag_driver_get_by_name(const char *name)
|
||||
{
|
||||
const struct dsa_device_ops *ops = ERR_PTR(-ENOPROTOOPT);
|
||||
struct dsa_tag_driver *dsa_tag_driver;
|
||||
|
||||
request_module("%s%s", DSA_TAG_DRIVER_ALIAS, name);
|
||||
|
||||
mutex_lock(&dsa_tag_drivers_lock);
|
||||
list_for_each_entry(dsa_tag_driver, &dsa_tag_drivers_list, list) {
|
||||
const struct dsa_device_ops *tmp = dsa_tag_driver->ops;
|
||||
|
||||
if (!sysfs_streq(buf, tmp->name))
|
||||
if (strcmp(name, tmp->name))
|
||||
continue;
|
||||
|
||||
if (!try_module_get(dsa_tag_driver->owner))
|
||||
@ -102,13 +104,13 @@ const struct dsa_device_ops *dsa_find_tagger_by_name(const char *buf)
|
||||
return ops;
|
||||
}
|
||||
|
||||
const struct dsa_device_ops *dsa_tag_driver_get(int tag_protocol)
|
||||
const struct dsa_device_ops *dsa_tag_driver_get_by_id(int tag_protocol)
|
||||
{
|
||||
struct dsa_tag_driver *dsa_tag_driver;
|
||||
const struct dsa_device_ops *ops;
|
||||
bool found = false;
|
||||
|
||||
request_module("%s%d", DSA_TAG_DRIVER_ALIAS, tag_protocol);
|
||||
request_module("%sid-%d", DSA_TAG_DRIVER_ALIAS, tag_protocol);
|
||||
|
||||
mutex_lock(&dsa_tag_drivers_lock);
|
||||
list_for_each_entry(dsa_tag_driver, &dsa_tag_drivers_list, list) {
|
||||
|
@ -1431,7 +1431,7 @@ static int dsa_port_parse_cpu(struct dsa_port *dp, struct net_device *master,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
tag_ops = dsa_find_tagger_by_name(user_protocol);
|
||||
tag_ops = dsa_tag_driver_get_by_name(user_protocol);
|
||||
if (IS_ERR(tag_ops)) {
|
||||
dev_warn(ds->dev,
|
||||
"Failed to find a tagging driver for protocol %s, using default\n",
|
||||
@ -1441,7 +1441,7 @@ static int dsa_port_parse_cpu(struct dsa_port *dp, struct net_device *master,
|
||||
}
|
||||
|
||||
if (!tag_ops)
|
||||
tag_ops = dsa_tag_driver_get(default_proto);
|
||||
tag_ops = dsa_tag_driver_get_by_id(default_proto);
|
||||
|
||||
if (IS_ERR(tag_ops)) {
|
||||
if (PTR_ERR(tag_ops) == -ENOPROTOOPT)
|
||||
|
@ -17,6 +17,81 @@
|
||||
|
||||
#define DSA_MAX_NUM_OFFLOADING_BRIDGES BITS_PER_LONG
|
||||
|
||||
/* Create 2 modaliases per tagging protocol, one to auto-load the module
|
||||
* given the ID reported by get_tag_protocol(), and the other by name.
|
||||
*/
|
||||
#define DSA_TAG_DRIVER_ALIAS "dsa_tag:"
|
||||
#define MODULE_ALIAS_DSA_TAG_DRIVER(__proto, __name) \
|
||||
MODULE_ALIAS(DSA_TAG_DRIVER_ALIAS __name); \
|
||||
MODULE_ALIAS(DSA_TAG_DRIVER_ALIAS "id-" \
|
||||
__stringify(__proto##_VALUE))
|
||||
|
||||
struct dsa_tag_driver {
|
||||
const struct dsa_device_ops *ops;
|
||||
struct list_head list;
|
||||
struct module *owner;
|
||||
};
|
||||
|
||||
void dsa_tag_drivers_register(struct dsa_tag_driver *dsa_tag_driver_array[],
|
||||
unsigned int count,
|
||||
struct module *owner);
|
||||
void dsa_tag_drivers_unregister(struct dsa_tag_driver *dsa_tag_driver_array[],
|
||||
unsigned int count);
|
||||
|
||||
#define dsa_tag_driver_module_drivers(__dsa_tag_drivers_array, __count) \
|
||||
static int __init dsa_tag_driver_module_init(void) \
|
||||
{ \
|
||||
dsa_tag_drivers_register(__dsa_tag_drivers_array, __count, \
|
||||
THIS_MODULE); \
|
||||
return 0; \
|
||||
} \
|
||||
module_init(dsa_tag_driver_module_init); \
|
||||
\
|
||||
static void __exit dsa_tag_driver_module_exit(void) \
|
||||
{ \
|
||||
dsa_tag_drivers_unregister(__dsa_tag_drivers_array, __count); \
|
||||
} \
|
||||
module_exit(dsa_tag_driver_module_exit)
|
||||
|
||||
/**
|
||||
* module_dsa_tag_drivers() - Helper macro for registering DSA tag
|
||||
* drivers
|
||||
* @__ops_array: Array of tag driver structures
|
||||
*
|
||||
* Helper macro for DSA tag drivers which do not do anything special
|
||||
* in module init/exit. Each module may only use this macro once, and
|
||||
* calling it replaces module_init() and module_exit().
|
||||
*/
|
||||
#define module_dsa_tag_drivers(__ops_array) \
|
||||
dsa_tag_driver_module_drivers(__ops_array, ARRAY_SIZE(__ops_array))
|
||||
|
||||
#define DSA_TAG_DRIVER_NAME(__ops) dsa_tag_driver ## _ ## __ops
|
||||
|
||||
/* Create a static structure we can build a linked list of dsa_tag
|
||||
* drivers
|
||||
*/
|
||||
#define DSA_TAG_DRIVER(__ops) \
|
||||
static struct dsa_tag_driver DSA_TAG_DRIVER_NAME(__ops) = { \
|
||||
.ops = &__ops, \
|
||||
}
|
||||
|
||||
/**
|
||||
* module_dsa_tag_driver() - Helper macro for registering a single DSA tag
|
||||
* driver
|
||||
* @__ops: Single tag driver structures
|
||||
*
|
||||
* Helper macro for DSA tag drivers which do not do anything special
|
||||
* in module init/exit. Each module may only use this macro once, and
|
||||
* calling it replaces module_init() and module_exit().
|
||||
*/
|
||||
#define module_dsa_tag_driver(__ops) \
|
||||
DSA_TAG_DRIVER(__ops); \
|
||||
\
|
||||
static struct dsa_tag_driver *dsa_tag_driver_array[] = { \
|
||||
&DSA_TAG_DRIVER_NAME(__ops) \
|
||||
}; \
|
||||
module_dsa_tag_drivers(dsa_tag_driver_array)
|
||||
|
||||
enum {
|
||||
DSA_NOTIFIER_AGEING_TIME,
|
||||
DSA_NOTIFIER_BRIDGE_JOIN,
|
||||
@ -168,9 +243,9 @@ struct dsa_slave_priv {
|
||||
};
|
||||
|
||||
/* dsa.c */
|
||||
const struct dsa_device_ops *dsa_tag_driver_get(int tag_protocol);
|
||||
const struct dsa_device_ops *dsa_tag_driver_get_by_id(int tag_protocol);
|
||||
const struct dsa_device_ops *dsa_tag_driver_get_by_name(const char *name);
|
||||
void dsa_tag_driver_put(const struct dsa_device_ops *ops);
|
||||
const struct dsa_device_ops *dsa_find_tagger_by_name(const char *buf);
|
||||
|
||||
bool dsa_db_equal(const struct dsa_db *a, const struct dsa_db *b);
|
||||
|
||||
|
@ -299,13 +299,24 @@ static ssize_t tagging_store(struct device *d, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
const struct dsa_device_ops *new_tag_ops, *old_tag_ops;
|
||||
const char *end = strchrnul(buf, '\n'), *name;
|
||||
struct net_device *dev = to_net_dev(d);
|
||||
struct dsa_port *cpu_dp = dev->dsa_ptr;
|
||||
size_t len = end - buf;
|
||||
int err;
|
||||
|
||||
/* Empty string passed */
|
||||
if (!len)
|
||||
return -ENOPROTOOPT;
|
||||
|
||||
name = kstrndup(buf, len, GFP_KERNEL);
|
||||
if (!name)
|
||||
return -ENOMEM;
|
||||
|
||||
old_tag_ops = cpu_dp->tag_ops;
|
||||
new_tag_ops = dsa_find_tagger_by_name(buf);
|
||||
/* Bad tagger name, or module is not loaded? */
|
||||
new_tag_ops = dsa_tag_driver_get_by_name(name);
|
||||
kfree(name);
|
||||
/* Bad tagger name? */
|
||||
if (IS_ERR(new_tag_ops))
|
||||
return PTR_ERR(new_tag_ops);
|
||||
|
||||
|
@ -9,6 +9,8 @@
|
||||
|
||||
#include "dsa_priv.h"
|
||||
|
||||
#define AR9331_NAME "ar9331"
|
||||
|
||||
#define AR9331_HDR_LEN 2
|
||||
#define AR9331_HDR_VERSION 1
|
||||
|
||||
@ -80,7 +82,7 @@ static struct sk_buff *ar9331_tag_rcv(struct sk_buff *skb,
|
||||
}
|
||||
|
||||
static const struct dsa_device_ops ar9331_netdev_ops = {
|
||||
.name = "ar9331",
|
||||
.name = AR9331_NAME,
|
||||
.proto = DSA_TAG_PROTO_AR9331,
|
||||
.xmit = ar9331_tag_xmit,
|
||||
.rcv = ar9331_tag_rcv,
|
||||
@ -88,5 +90,5 @@ static const struct dsa_device_ops ar9331_netdev_ops = {
|
||||
};
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_AR9331);
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_AR9331, AR9331_NAME);
|
||||
module_dsa_tag_driver(ar9331_netdev_ops);
|
||||
|
@ -12,6 +12,10 @@
|
||||
|
||||
#include "dsa_priv.h"
|
||||
|
||||
#define BRCM_NAME "brcm"
|
||||
#define BRCM_LEGACY_NAME "brcm-legacy"
|
||||
#define BRCM_PREPEND_NAME "brcm-prepend"
|
||||
|
||||
/* Legacy Broadcom tag (6 bytes) */
|
||||
#define BRCM_LEG_TAG_LEN 6
|
||||
|
||||
@ -196,7 +200,7 @@ static struct sk_buff *brcm_tag_rcv(struct sk_buff *skb, struct net_device *dev)
|
||||
}
|
||||
|
||||
static const struct dsa_device_ops brcm_netdev_ops = {
|
||||
.name = "brcm",
|
||||
.name = BRCM_NAME,
|
||||
.proto = DSA_TAG_PROTO_BRCM,
|
||||
.xmit = brcm_tag_xmit,
|
||||
.rcv = brcm_tag_rcv,
|
||||
@ -204,7 +208,7 @@ static const struct dsa_device_ops brcm_netdev_ops = {
|
||||
};
|
||||
|
||||
DSA_TAG_DRIVER(brcm_netdev_ops);
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_BRCM);
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_BRCM, BRCM_NAME);
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_LEGACY)
|
||||
@ -273,7 +277,7 @@ static struct sk_buff *brcm_leg_tag_rcv(struct sk_buff *skb,
|
||||
}
|
||||
|
||||
static const struct dsa_device_ops brcm_legacy_netdev_ops = {
|
||||
.name = "brcm-legacy",
|
||||
.name = BRCM_LEGACY_NAME,
|
||||
.proto = DSA_TAG_PROTO_BRCM_LEGACY,
|
||||
.xmit = brcm_leg_tag_xmit,
|
||||
.rcv = brcm_leg_tag_rcv,
|
||||
@ -281,7 +285,7 @@ static const struct dsa_device_ops brcm_legacy_netdev_ops = {
|
||||
};
|
||||
|
||||
DSA_TAG_DRIVER(brcm_legacy_netdev_ops);
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_BRCM_LEGACY);
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_BRCM_LEGACY, BRCM_LEGACY_NAME);
|
||||
#endif /* CONFIG_NET_DSA_TAG_BRCM_LEGACY */
|
||||
|
||||
#if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_PREPEND)
|
||||
@ -300,7 +304,7 @@ static struct sk_buff *brcm_tag_rcv_prepend(struct sk_buff *skb,
|
||||
}
|
||||
|
||||
static const struct dsa_device_ops brcm_prepend_netdev_ops = {
|
||||
.name = "brcm-prepend",
|
||||
.name = BRCM_PREPEND_NAME,
|
||||
.proto = DSA_TAG_PROTO_BRCM_PREPEND,
|
||||
.xmit = brcm_tag_xmit_prepend,
|
||||
.rcv = brcm_tag_rcv_prepend,
|
||||
@ -308,7 +312,7 @@ static const struct dsa_device_ops brcm_prepend_netdev_ops = {
|
||||
};
|
||||
|
||||
DSA_TAG_DRIVER(brcm_prepend_netdev_ops);
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_BRCM_PREPEND);
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_BRCM_PREPEND, BRCM_PREPEND_NAME);
|
||||
#endif
|
||||
|
||||
static struct dsa_tag_driver *dsa_tag_driver_array[] = {
|
||||
|
@ -52,6 +52,9 @@
|
||||
|
||||
#include "dsa_priv.h"
|
||||
|
||||
#define DSA_NAME "dsa"
|
||||
#define EDSA_NAME "edsa"
|
||||
|
||||
#define DSA_HLEN 4
|
||||
|
||||
/**
|
||||
@ -339,7 +342,7 @@ static struct sk_buff *dsa_rcv(struct sk_buff *skb, struct net_device *dev)
|
||||
}
|
||||
|
||||
static const struct dsa_device_ops dsa_netdev_ops = {
|
||||
.name = "dsa",
|
||||
.name = DSA_NAME,
|
||||
.proto = DSA_TAG_PROTO_DSA,
|
||||
.xmit = dsa_xmit,
|
||||
.rcv = dsa_rcv,
|
||||
@ -347,7 +350,7 @@ static const struct dsa_device_ops dsa_netdev_ops = {
|
||||
};
|
||||
|
||||
DSA_TAG_DRIVER(dsa_netdev_ops);
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_DSA);
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_DSA, DSA_NAME);
|
||||
#endif /* CONFIG_NET_DSA_TAG_DSA */
|
||||
|
||||
#if IS_ENABLED(CONFIG_NET_DSA_TAG_EDSA)
|
||||
@ -381,7 +384,7 @@ static struct sk_buff *edsa_rcv(struct sk_buff *skb, struct net_device *dev)
|
||||
}
|
||||
|
||||
static const struct dsa_device_ops edsa_netdev_ops = {
|
||||
.name = "edsa",
|
||||
.name = EDSA_NAME,
|
||||
.proto = DSA_TAG_PROTO_EDSA,
|
||||
.xmit = edsa_xmit,
|
||||
.rcv = edsa_rcv,
|
||||
@ -389,7 +392,7 @@ static const struct dsa_device_ops edsa_netdev_ops = {
|
||||
};
|
||||
|
||||
DSA_TAG_DRIVER(edsa_netdev_ops);
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_EDSA);
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_EDSA, EDSA_NAME);
|
||||
#endif /* CONFIG_NET_DSA_TAG_EDSA */
|
||||
|
||||
static struct dsa_tag_driver *dsa_tag_drivers[] = {
|
||||
|
@ -12,6 +12,8 @@
|
||||
|
||||
#include "dsa_priv.h"
|
||||
|
||||
#define GSWIP_NAME "gswip"
|
||||
|
||||
#define GSWIP_TX_HEADER_LEN 4
|
||||
|
||||
/* special tag in TX path header */
|
||||
@ -98,7 +100,7 @@ static struct sk_buff *gswip_tag_rcv(struct sk_buff *skb,
|
||||
}
|
||||
|
||||
static const struct dsa_device_ops gswip_netdev_ops = {
|
||||
.name = "gswip",
|
||||
.name = GSWIP_NAME,
|
||||
.proto = DSA_TAG_PROTO_GSWIP,
|
||||
.xmit = gswip_tag_xmit,
|
||||
.rcv = gswip_tag_rcv,
|
||||
@ -106,6 +108,6 @@ static const struct dsa_device_ops gswip_netdev_ops = {
|
||||
};
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_GSWIP);
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_GSWIP, GSWIP_NAME);
|
||||
|
||||
module_dsa_tag_driver(gswip_netdev_ops);
|
||||
|
@ -13,6 +13,8 @@
|
||||
|
||||
#include "dsa_priv.h"
|
||||
|
||||
#define HELLCREEK_NAME "hellcreek"
|
||||
|
||||
#define HELLCREEK_TAG_LEN 1
|
||||
|
||||
static struct sk_buff *hellcreek_xmit(struct sk_buff *skb,
|
||||
@ -57,7 +59,7 @@ static struct sk_buff *hellcreek_rcv(struct sk_buff *skb,
|
||||
}
|
||||
|
||||
static const struct dsa_device_ops hellcreek_netdev_ops = {
|
||||
.name = "hellcreek",
|
||||
.name = HELLCREEK_NAME,
|
||||
.proto = DSA_TAG_PROTO_HELLCREEK,
|
||||
.xmit = hellcreek_xmit,
|
||||
.rcv = hellcreek_rcv,
|
||||
@ -65,6 +67,6 @@ static const struct dsa_device_ops hellcreek_netdev_ops = {
|
||||
};
|
||||
|
||||
MODULE_LICENSE("Dual MIT/GPL");
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_HELLCREEK);
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_HELLCREEK, HELLCREEK_NAME);
|
||||
|
||||
module_dsa_tag_driver(hellcreek_netdev_ops);
|
||||
|
@ -9,6 +9,11 @@
|
||||
#include <net/dsa.h>
|
||||
#include "dsa_priv.h"
|
||||
|
||||
#define KSZ8795_NAME "ksz8795"
|
||||
#define KSZ9477_NAME "ksz9477"
|
||||
#define KSZ9893_NAME "ksz9893"
|
||||
#define LAN937X_NAME "lan937x"
|
||||
|
||||
/* Typically only one byte is used for tail tag. */
|
||||
#define KSZ_EGRESS_TAG_LEN 1
|
||||
#define KSZ_INGRESS_TAG_LEN 1
|
||||
@ -74,7 +79,7 @@ static struct sk_buff *ksz8795_rcv(struct sk_buff *skb, struct net_device *dev)
|
||||
}
|
||||
|
||||
static const struct dsa_device_ops ksz8795_netdev_ops = {
|
||||
.name = "ksz8795",
|
||||
.name = KSZ8795_NAME,
|
||||
.proto = DSA_TAG_PROTO_KSZ8795,
|
||||
.xmit = ksz8795_xmit,
|
||||
.rcv = ksz8795_rcv,
|
||||
@ -82,7 +87,7 @@ static const struct dsa_device_ops ksz8795_netdev_ops = {
|
||||
};
|
||||
|
||||
DSA_TAG_DRIVER(ksz8795_netdev_ops);
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_KSZ8795);
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_KSZ8795, KSZ8795_NAME);
|
||||
|
||||
/*
|
||||
* For Ingress (Host -> KSZ9477), 2 bytes are added before FCS.
|
||||
@ -147,7 +152,7 @@ static struct sk_buff *ksz9477_rcv(struct sk_buff *skb, struct net_device *dev)
|
||||
}
|
||||
|
||||
static const struct dsa_device_ops ksz9477_netdev_ops = {
|
||||
.name = "ksz9477",
|
||||
.name = KSZ9477_NAME,
|
||||
.proto = DSA_TAG_PROTO_KSZ9477,
|
||||
.xmit = ksz9477_xmit,
|
||||
.rcv = ksz9477_rcv,
|
||||
@ -155,7 +160,7 @@ static const struct dsa_device_ops ksz9477_netdev_ops = {
|
||||
};
|
||||
|
||||
DSA_TAG_DRIVER(ksz9477_netdev_ops);
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_KSZ9477);
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_KSZ9477, KSZ9477_NAME);
|
||||
|
||||
#define KSZ9893_TAIL_TAG_OVERRIDE BIT(5)
|
||||
#define KSZ9893_TAIL_TAG_LOOKUP BIT(6)
|
||||
@ -183,7 +188,7 @@ static struct sk_buff *ksz9893_xmit(struct sk_buff *skb,
|
||||
}
|
||||
|
||||
static const struct dsa_device_ops ksz9893_netdev_ops = {
|
||||
.name = "ksz9893",
|
||||
.name = KSZ9893_NAME,
|
||||
.proto = DSA_TAG_PROTO_KSZ9893,
|
||||
.xmit = ksz9893_xmit,
|
||||
.rcv = ksz9477_rcv,
|
||||
@ -191,7 +196,7 @@ static const struct dsa_device_ops ksz9893_netdev_ops = {
|
||||
};
|
||||
|
||||
DSA_TAG_DRIVER(ksz9893_netdev_ops);
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_KSZ9893);
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_KSZ9893, KSZ9893_NAME);
|
||||
|
||||
/* For xmit, 2 bytes are added before FCS.
|
||||
* ---------------------------------------------------------------------------
|
||||
@ -241,7 +246,7 @@ static struct sk_buff *lan937x_xmit(struct sk_buff *skb,
|
||||
}
|
||||
|
||||
static const struct dsa_device_ops lan937x_netdev_ops = {
|
||||
.name = "lan937x",
|
||||
.name = LAN937X_NAME,
|
||||
.proto = DSA_TAG_PROTO_LAN937X,
|
||||
.xmit = lan937x_xmit,
|
||||
.rcv = ksz9477_rcv,
|
||||
@ -249,7 +254,7 @@ static const struct dsa_device_ops lan937x_netdev_ops = {
|
||||
};
|
||||
|
||||
DSA_TAG_DRIVER(lan937x_netdev_ops);
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_LAN937X);
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_LAN937X, LAN937X_NAME);
|
||||
|
||||
static struct dsa_tag_driver *dsa_tag_driver_array[] = {
|
||||
&DSA_TAG_DRIVER_NAME(ksz8795_netdev_ops),
|
||||
|
@ -30,6 +30,8 @@
|
||||
* Required when no forwarding between the external ports should happen.
|
||||
*/
|
||||
|
||||
#define LAN9303_NAME "lan9303"
|
||||
|
||||
#define LAN9303_TAG_LEN 4
|
||||
# define LAN9303_TAG_TX_USE_ALR BIT(3)
|
||||
# define LAN9303_TAG_TX_STP_OVERRIDE BIT(4)
|
||||
@ -110,7 +112,7 @@ static struct sk_buff *lan9303_rcv(struct sk_buff *skb, struct net_device *dev)
|
||||
}
|
||||
|
||||
static const struct dsa_device_ops lan9303_netdev_ops = {
|
||||
.name = "lan9303",
|
||||
.name = LAN9303_NAME,
|
||||
.proto = DSA_TAG_PROTO_LAN9303,
|
||||
.xmit = lan9303_xmit,
|
||||
.rcv = lan9303_rcv,
|
||||
@ -118,6 +120,6 @@ static const struct dsa_device_ops lan9303_netdev_ops = {
|
||||
};
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_LAN9303);
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_LAN9303, LAN9303_NAME);
|
||||
|
||||
module_dsa_tag_driver(lan9303_netdev_ops);
|
||||
|
@ -10,6 +10,8 @@
|
||||
|
||||
#include "dsa_priv.h"
|
||||
|
||||
#define MTK_NAME "mtk"
|
||||
|
||||
#define MTK_HDR_LEN 4
|
||||
#define MTK_HDR_XMIT_UNTAGGED 0
|
||||
#define MTK_HDR_XMIT_TAGGED_TPID_8100 1
|
||||
@ -91,7 +93,7 @@ static struct sk_buff *mtk_tag_rcv(struct sk_buff *skb, struct net_device *dev)
|
||||
}
|
||||
|
||||
static const struct dsa_device_ops mtk_netdev_ops = {
|
||||
.name = "mtk",
|
||||
.name = MTK_NAME,
|
||||
.proto = DSA_TAG_PROTO_MTK,
|
||||
.xmit = mtk_tag_xmit,
|
||||
.rcv = mtk_tag_rcv,
|
||||
@ -99,6 +101,6 @@ static const struct dsa_device_ops mtk_netdev_ops = {
|
||||
};
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_MTK);
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_MTK, MTK_NAME);
|
||||
|
||||
module_dsa_tag_driver(mtk_netdev_ops);
|
||||
|
@ -4,6 +4,9 @@
|
||||
#include <linux/dsa/ocelot.h>
|
||||
#include "dsa_priv.h"
|
||||
|
||||
#define OCELOT_NAME "ocelot"
|
||||
#define SEVILLE_NAME "seville"
|
||||
|
||||
/* If the port is under a VLAN-aware bridge, remove the VLAN header from the
|
||||
* payload and move it into the DSA tag, which will make the switch classify
|
||||
* the packet to the bridge VLAN. Otherwise, leave the classified VLAN at zero,
|
||||
@ -183,7 +186,7 @@ static struct sk_buff *ocelot_rcv(struct sk_buff *skb,
|
||||
}
|
||||
|
||||
static const struct dsa_device_ops ocelot_netdev_ops = {
|
||||
.name = "ocelot",
|
||||
.name = OCELOT_NAME,
|
||||
.proto = DSA_TAG_PROTO_OCELOT,
|
||||
.xmit = ocelot_xmit,
|
||||
.rcv = ocelot_rcv,
|
||||
@ -192,10 +195,10 @@ static const struct dsa_device_ops ocelot_netdev_ops = {
|
||||
};
|
||||
|
||||
DSA_TAG_DRIVER(ocelot_netdev_ops);
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_OCELOT);
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_OCELOT, OCELOT_NAME);
|
||||
|
||||
static const struct dsa_device_ops seville_netdev_ops = {
|
||||
.name = "seville",
|
||||
.name = SEVILLE_NAME,
|
||||
.proto = DSA_TAG_PROTO_SEVILLE,
|
||||
.xmit = seville_xmit,
|
||||
.rcv = ocelot_rcv,
|
||||
@ -204,7 +207,7 @@ static const struct dsa_device_ops seville_netdev_ops = {
|
||||
};
|
||||
|
||||
DSA_TAG_DRIVER(seville_netdev_ops);
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_SEVILLE);
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_SEVILLE, SEVILLE_NAME);
|
||||
|
||||
static struct dsa_tag_driver *ocelot_tag_driver_array[] = {
|
||||
&DSA_TAG_DRIVER_NAME(ocelot_netdev_ops),
|
||||
|
@ -12,6 +12,8 @@
|
||||
#include <linux/dsa/ocelot.h>
|
||||
#include "dsa_priv.h"
|
||||
|
||||
#define OCELOT_8021Q_NAME "ocelot-8021q"
|
||||
|
||||
struct ocelot_8021q_tagger_private {
|
||||
struct ocelot_8021q_tagger_data data; /* Must be first */
|
||||
struct kthread_worker *xmit_worker;
|
||||
@ -119,7 +121,7 @@ static int ocelot_connect(struct dsa_switch *ds)
|
||||
}
|
||||
|
||||
static const struct dsa_device_ops ocelot_8021q_netdev_ops = {
|
||||
.name = "ocelot-8021q",
|
||||
.name = OCELOT_8021Q_NAME,
|
||||
.proto = DSA_TAG_PROTO_OCELOT_8021Q,
|
||||
.xmit = ocelot_xmit,
|
||||
.rcv = ocelot_rcv,
|
||||
@ -130,6 +132,6 @@ static const struct dsa_device_ops ocelot_8021q_netdev_ops = {
|
||||
};
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_OCELOT_8021Q);
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_OCELOT_8021Q, OCELOT_8021Q_NAME);
|
||||
|
||||
module_dsa_tag_driver(ocelot_8021q_netdev_ops);
|
||||
|
@ -10,6 +10,8 @@
|
||||
|
||||
#include "dsa_priv.h"
|
||||
|
||||
#define QCA_NAME "qca"
|
||||
|
||||
static struct sk_buff *qca_tag_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
{
|
||||
struct dsa_port *dp = dsa_slave_to_port(dev);
|
||||
@ -107,7 +109,7 @@ static void qca_tag_disconnect(struct dsa_switch *ds)
|
||||
}
|
||||
|
||||
static const struct dsa_device_ops qca_netdev_ops = {
|
||||
.name = "qca",
|
||||
.name = QCA_NAME,
|
||||
.proto = DSA_TAG_PROTO_QCA,
|
||||
.connect = qca_tag_connect,
|
||||
.disconnect = qca_tag_disconnect,
|
||||
@ -118,6 +120,6 @@ static const struct dsa_device_ops qca_netdev_ops = {
|
||||
};
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_QCA);
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_QCA, QCA_NAME);
|
||||
|
||||
module_dsa_tag_driver(qca_netdev_ops);
|
||||
|
@ -20,6 +20,8 @@
|
||||
|
||||
#include "dsa_priv.h"
|
||||
|
||||
#define RTL4_A_NAME "rtl4a"
|
||||
|
||||
#define RTL4_A_HDR_LEN 4
|
||||
#define RTL4_A_ETHERTYPE 0x8899
|
||||
#define RTL4_A_PROTOCOL_SHIFT 12
|
||||
@ -112,7 +114,7 @@ static struct sk_buff *rtl4a_tag_rcv(struct sk_buff *skb,
|
||||
}
|
||||
|
||||
static const struct dsa_device_ops rtl4a_netdev_ops = {
|
||||
.name = "rtl4a",
|
||||
.name = RTL4_A_NAME,
|
||||
.proto = DSA_TAG_PROTO_RTL4_A,
|
||||
.xmit = rtl4a_tag_xmit,
|
||||
.rcv = rtl4a_tag_rcv,
|
||||
@ -121,4 +123,4 @@ static const struct dsa_device_ops rtl4a_netdev_ops = {
|
||||
module_dsa_tag_driver(rtl4a_netdev_ops);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_RTL4_A);
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_RTL4_A, RTL4_A_NAME);
|
||||
|
@ -84,6 +84,9 @@
|
||||
* 0x04 = RTL8365MB DSA protocol
|
||||
*/
|
||||
|
||||
#define RTL8_4_NAME "rtl8_4"
|
||||
#define RTL8_4T_NAME "rtl8_4t"
|
||||
|
||||
#define RTL8_4_TAG_LEN 8
|
||||
|
||||
#define RTL8_4_PROTOCOL GENMASK(15, 8)
|
||||
@ -234,7 +237,7 @@ static const struct dsa_device_ops rtl8_4_netdev_ops = {
|
||||
|
||||
DSA_TAG_DRIVER(rtl8_4_netdev_ops);
|
||||
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_RTL8_4);
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_RTL8_4, RTL8_4_NAME);
|
||||
|
||||
/* Tail version */
|
||||
static const struct dsa_device_ops rtl8_4t_netdev_ops = {
|
||||
@ -247,7 +250,7 @@ static const struct dsa_device_ops rtl8_4t_netdev_ops = {
|
||||
|
||||
DSA_TAG_DRIVER(rtl8_4t_netdev_ops);
|
||||
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_RTL8_4T);
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_RTL8_4T, RTL8_4T_NAME);
|
||||
|
||||
static struct dsa_tag_driver *dsa_tag_drivers[] = {
|
||||
&DSA_TAG_DRIVER_NAME(rtl8_4_netdev_ops),
|
||||
|
@ -22,6 +22,8 @@
|
||||
* See struct a5psw_tag for layout
|
||||
*/
|
||||
|
||||
#define A5PSW_NAME "a5psw"
|
||||
|
||||
#define ETH_P_DSA_A5PSW 0xE001
|
||||
#define A5PSW_TAG_LEN 8
|
||||
#define A5PSW_CTRL_DATA_FORCE_FORWARD BIT(0)
|
||||
@ -101,7 +103,7 @@ static struct sk_buff *a5psw_tag_rcv(struct sk_buff *skb,
|
||||
}
|
||||
|
||||
static const struct dsa_device_ops a5psw_netdev_ops = {
|
||||
.name = "a5psw",
|
||||
.name = A5PSW_NAME,
|
||||
.proto = DSA_TAG_PROTO_RZN1_A5PSW,
|
||||
.xmit = a5psw_tag_xmit,
|
||||
.rcv = a5psw_tag_rcv,
|
||||
@ -109,5 +111,5 @@ static const struct dsa_device_ops a5psw_netdev_ops = {
|
||||
};
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_A5PSW);
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_A5PSW, A5PSW_NAME);
|
||||
module_dsa_tag_driver(a5psw_netdev_ops);
|
||||
|
@ -7,6 +7,9 @@
|
||||
#include <linux/packing.h>
|
||||
#include "dsa_priv.h"
|
||||
|
||||
#define SJA1105_NAME "sja1105"
|
||||
#define SJA1110_NAME "sja1110"
|
||||
|
||||
/* Is this a TX or an RX header? */
|
||||
#define SJA1110_HEADER_HOST_TO_SWITCH BIT(15)
|
||||
|
||||
@ -786,7 +789,7 @@ static int sja1105_connect(struct dsa_switch *ds)
|
||||
}
|
||||
|
||||
static const struct dsa_device_ops sja1105_netdev_ops = {
|
||||
.name = "sja1105",
|
||||
.name = SJA1105_NAME,
|
||||
.proto = DSA_TAG_PROTO_SJA1105,
|
||||
.xmit = sja1105_xmit,
|
||||
.rcv = sja1105_rcv,
|
||||
@ -798,10 +801,10 @@ static const struct dsa_device_ops sja1105_netdev_ops = {
|
||||
};
|
||||
|
||||
DSA_TAG_DRIVER(sja1105_netdev_ops);
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_SJA1105);
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_SJA1105, SJA1105_NAME);
|
||||
|
||||
static const struct dsa_device_ops sja1110_netdev_ops = {
|
||||
.name = "sja1110",
|
||||
.name = SJA1110_NAME,
|
||||
.proto = DSA_TAG_PROTO_SJA1110,
|
||||
.xmit = sja1110_xmit,
|
||||
.rcv = sja1110_rcv,
|
||||
@ -813,7 +816,7 @@ static const struct dsa_device_ops sja1110_netdev_ops = {
|
||||
};
|
||||
|
||||
DSA_TAG_DRIVER(sja1110_netdev_ops);
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_SJA1110);
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_SJA1110, SJA1110_NAME);
|
||||
|
||||
static struct dsa_tag_driver *sja1105_tag_driver_array[] = {
|
||||
&DSA_TAG_DRIVER_NAME(sja1105_netdev_ops),
|
||||
|
@ -10,6 +10,8 @@
|
||||
|
||||
#include "dsa_priv.h"
|
||||
|
||||
#define TRAILER_NAME "trailer"
|
||||
|
||||
static struct sk_buff *trailer_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
{
|
||||
struct dsa_port *dp = dsa_slave_to_port(dev);
|
||||
@ -50,7 +52,7 @@ static struct sk_buff *trailer_rcv(struct sk_buff *skb, struct net_device *dev)
|
||||
}
|
||||
|
||||
static const struct dsa_device_ops trailer_netdev_ops = {
|
||||
.name = "trailer",
|
||||
.name = TRAILER_NAME,
|
||||
.proto = DSA_TAG_PROTO_TRAILER,
|
||||
.xmit = trailer_xmit,
|
||||
.rcv = trailer_rcv,
|
||||
@ -58,6 +60,6 @@ static const struct dsa_device_ops trailer_netdev_ops = {
|
||||
};
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_TRAILER);
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_TRAILER, TRAILER_NAME);
|
||||
|
||||
module_dsa_tag_driver(trailer_netdev_ops);
|
||||
|
@ -9,6 +9,8 @@
|
||||
|
||||
#include "dsa_priv.h"
|
||||
|
||||
#define XRS700X_NAME "xrs700x"
|
||||
|
||||
static struct sk_buff *xrs700x_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
{
|
||||
struct dsa_port *partner, *dp = dsa_slave_to_port(dev);
|
||||
@ -51,7 +53,7 @@ static struct sk_buff *xrs700x_rcv(struct sk_buff *skb, struct net_device *dev)
|
||||
}
|
||||
|
||||
static const struct dsa_device_ops xrs700x_netdev_ops = {
|
||||
.name = "xrs700x",
|
||||
.name = XRS700X_NAME,
|
||||
.proto = DSA_TAG_PROTO_XRS700X,
|
||||
.xmit = xrs700x_xmit,
|
||||
.rcv = xrs700x_rcv,
|
||||
@ -59,6 +61,6 @@ static const struct dsa_device_ops xrs700x_netdev_ops = {
|
||||
};
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_XRS700X);
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_XRS700X, XRS700X_NAME);
|
||||
|
||||
module_dsa_tag_driver(xrs700x_netdev_ops);
|
||||
|
Loading…
x
Reference in New Issue
Block a user