aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/rocker/rocker.c64
-rw-r--r--include/linux/netdevice.h41
-rw-r--r--include/net/switchdev.h38
-rw-r--r--net/dsa/slave.c9
-rw-r--r--net/switchdev/switchdev.c42
5 files changed, 105 insertions, 89 deletions
diff --git a/drivers/net/ethernet/rocker/rocker.c b/drivers/net/ethernet/rocker/rocker.c
index 223348d8cc07..bc5f27aa3131 100644
--- a/drivers/net/ethernet/rocker/rocker.c
+++ b/drivers/net/ethernet/rocker/rocker.c
@@ -4131,8 +4131,26 @@ static int rocker_port_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
4131 rocker_port->brport_flags, mask); 4131 rocker_port->brport_flags, mask);
4132} 4132}
4133 4133
4134static int rocker_port_switch_parent_id_get(struct net_device *dev, 4134static const struct net_device_ops rocker_port_netdev_ops = {
4135 struct netdev_phys_item_id *psid) 4135 .ndo_open = rocker_port_open,
4136 .ndo_stop = rocker_port_stop,
4137 .ndo_start_xmit = rocker_port_xmit,
4138 .ndo_set_mac_address = rocker_port_set_mac_address,
4139 .ndo_vlan_rx_add_vid = rocker_port_vlan_rx_add_vid,
4140 .ndo_vlan_rx_kill_vid = rocker_port_vlan_rx_kill_vid,
4141 .ndo_fdb_add = rocker_port_fdb_add,
4142 .ndo_fdb_del = rocker_port_fdb_del,
4143 .ndo_fdb_dump = rocker_port_fdb_dump,
4144 .ndo_bridge_setlink = rocker_port_bridge_setlink,
4145 .ndo_bridge_getlink = rocker_port_bridge_getlink,
4146};
4147
4148/********************
4149 * swdev interface
4150 ********************/
4151
4152static int rocker_port_swdev_parent_id_get(struct net_device *dev,
4153 struct netdev_phys_item_id *psid)
4136{ 4154{
4137 struct rocker_port *rocker_port = netdev_priv(dev); 4155 struct rocker_port *rocker_port = netdev_priv(dev);
4138 struct rocker *rocker = rocker_port->rocker; 4156 struct rocker *rocker = rocker_port->rocker;
@@ -4142,18 +4160,18 @@ static int rocker_port_switch_parent_id_get(struct net_device *dev,
4142 return 0; 4160 return 0;
4143} 4161}
4144 4162
4145static int rocker_port_switch_port_stp_update(struct net_device *dev, u8 state) 4163static int rocker_port_swdev_port_stp_update(struct net_device *dev, u8 state)
4146{ 4164{
4147 struct rocker_port *rocker_port = netdev_priv(dev); 4165 struct rocker_port *rocker_port = netdev_priv(dev);
4148 4166
4149 return rocker_port_stp_update(rocker_port, state); 4167 return rocker_port_stp_update(rocker_port, state);
4150} 4168}
4151 4169
4152static int rocker_port_switch_fib_ipv4_add(struct net_device *dev, 4170static int rocker_port_swdev_fib_ipv4_add(struct net_device *dev,
4153 __be32 dst, int dst_len, 4171 __be32 dst, int dst_len,
4154 struct fib_info *fi, 4172 struct fib_info *fi,
4155 u8 tos, u8 type, 4173 u8 tos, u8 type,
4156 u32 nlflags, u32 tb_id) 4174 u32 nlflags, u32 tb_id)
4157{ 4175{
4158 struct rocker_port *rocker_port = netdev_priv(dev); 4176 struct rocker_port *rocker_port = netdev_priv(dev);
4159 int flags = 0; 4177 int flags = 0;
@@ -4162,10 +4180,10 @@ static int rocker_port_switch_fib_ipv4_add(struct net_device *dev,
4162 fi, tb_id, flags); 4180 fi, tb_id, flags);
4163} 4181}
4164 4182
4165static int rocker_port_switch_fib_ipv4_del(struct net_device *dev, 4183static int rocker_port_swdev_fib_ipv4_del(struct net_device *dev,
4166 __be32 dst, int dst_len, 4184 __be32 dst, int dst_len,
4167 struct fib_info *fi, 4185 struct fib_info *fi,
4168 u8 tos, u8 type, u32 tb_id) 4186 u8 tos, u8 type, u32 tb_id)
4169{ 4187{
4170 struct rocker_port *rocker_port = netdev_priv(dev); 4188 struct rocker_port *rocker_port = netdev_priv(dev);
4171 int flags = ROCKER_OP_FLAG_REMOVE; 4189 int flags = ROCKER_OP_FLAG_REMOVE;
@@ -4174,22 +4192,11 @@ static int rocker_port_switch_fib_ipv4_del(struct net_device *dev,
4174 fi, tb_id, flags); 4192 fi, tb_id, flags);
4175} 4193}
4176 4194
4177static const struct net_device_ops rocker_port_netdev_ops = { 4195static const struct swdev_ops rocker_port_swdev_ops = {
4178 .ndo_open = rocker_port_open, 4196 .swdev_parent_id_get = rocker_port_swdev_parent_id_get,
4179 .ndo_stop = rocker_port_stop, 4197 .swdev_port_stp_update = rocker_port_swdev_port_stp_update,
4180 .ndo_start_xmit = rocker_port_xmit, 4198 .swdev_fib_ipv4_add = rocker_port_swdev_fib_ipv4_add,
4181 .ndo_set_mac_address = rocker_port_set_mac_address, 4199 .swdev_fib_ipv4_del = rocker_port_swdev_fib_ipv4_del,
4182 .ndo_vlan_rx_add_vid = rocker_port_vlan_rx_add_vid,
4183 .ndo_vlan_rx_kill_vid = rocker_port_vlan_rx_kill_vid,
4184 .ndo_fdb_add = rocker_port_fdb_add,
4185 .ndo_fdb_del = rocker_port_fdb_del,
4186 .ndo_fdb_dump = rocker_port_fdb_dump,
4187 .ndo_bridge_setlink = rocker_port_bridge_setlink,
4188 .ndo_bridge_getlink = rocker_port_bridge_getlink,
4189 .ndo_switch_parent_id_get = rocker_port_switch_parent_id_get,
4190 .ndo_switch_port_stp_update = rocker_port_switch_port_stp_update,
4191 .ndo_switch_fib_ipv4_add = rocker_port_switch_fib_ipv4_add,
4192 .ndo_switch_fib_ipv4_del = rocker_port_switch_fib_ipv4_del,
4193}; 4200};
4194 4201
4195/******************** 4202/********************
@@ -4544,6 +4551,7 @@ static int rocker_probe_port(struct rocker *rocker, unsigned int port_number)
4544 rocker_port_dev_addr_init(rocker, rocker_port); 4551 rocker_port_dev_addr_init(rocker, rocker_port);
4545 dev->netdev_ops = &rocker_port_netdev_ops; 4552 dev->netdev_ops = &rocker_port_netdev_ops;
4546 dev->ethtool_ops = &rocker_port_ethtool_ops; 4553 dev->ethtool_ops = &rocker_port_ethtool_ops;
4554 dev->swdev_ops = &rocker_port_swdev_ops;
4547 netif_napi_add(dev, &rocker_port->napi_tx, rocker_port_poll_tx, 4555 netif_napi_add(dev, &rocker_port->napi_tx, rocker_port_poll_tx,
4548 NAPI_POLL_WEIGHT); 4556 NAPI_POLL_WEIGHT);
4549 netif_napi_add(dev, &rocker_port->napi_rx, rocker_port_poll_rx, 4557 netif_napi_add(dev, &rocker_port->napi_rx, rocker_port_poll_rx,
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index ddab1a2a07a0..dd1d069758be 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -768,8 +768,6 @@ struct netdev_phys_item_id {
768typedef u16 (*select_queue_fallback_t)(struct net_device *dev, 768typedef u16 (*select_queue_fallback_t)(struct net_device *dev,
769 struct sk_buff *skb); 769 struct sk_buff *skb);
770 770
771struct fib_info;
772
773/* 771/*
774 * This structure defines the management hooks for network devices. 772 * This structure defines the management hooks for network devices.
775 * The following hooks can be defined; unless noted otherwise, they are 773 * The following hooks can be defined; unless noted otherwise, they are
@@ -1024,23 +1022,6 @@ struct fib_info;
1024 * be otherwise expressed by feature flags. The check is called with 1022 * be otherwise expressed by feature flags. The check is called with
1025 * the set of features that the stack has calculated and it returns 1023 * the set of features that the stack has calculated and it returns
1026 * those the driver believes to be appropriate. 1024 * those the driver believes to be appropriate.
1027 *
1028 * int (*ndo_switch_parent_id_get)(struct net_device *dev,
1029 * struct netdev_phys_item_id *psid);
1030 * Called to get an ID of the switch chip this port is part of.
1031 * If driver implements this, it indicates that it represents a port
1032 * of a switch chip.
1033 * int (*ndo_switch_port_stp_update)(struct net_device *dev, u8 state);
1034 * Called to notify switch device port of bridge port STP
1035 * state change.
1036 * int (*ndo_sw_parent_fib_ipv4_add)(struct net_device *dev, __be32 dst,
1037 * int dst_len, struct fib_info *fi,
1038 * u8 tos, u8 type, u32 nlflags, u32 tb_id);
1039 * Called to add/modify IPv4 route to switch device.
1040 * int (*ndo_sw_parent_fib_ipv4_del)(struct net_device *dev, __be32 dst,
1041 * int dst_len, struct fib_info *fi,
1042 * u8 tos, u8 type, u32 tb_id);
1043 * Called to delete IPv4 route from switch device.
1044 */ 1025 */
1045struct net_device_ops { 1026struct net_device_ops {
1046 int (*ndo_init)(struct net_device *dev); 1027 int (*ndo_init)(struct net_device *dev);
@@ -1197,25 +1178,6 @@ struct net_device_ops {
1197 netdev_features_t (*ndo_features_check) (struct sk_buff *skb, 1178 netdev_features_t (*ndo_features_check) (struct sk_buff *skb,
1198 struct net_device *dev, 1179 struct net_device *dev,
1199 netdev_features_t features); 1180 netdev_features_t features);
1200#ifdef CONFIG_NET_SWITCHDEV
1201 int (*ndo_switch_parent_id_get)(struct net_device *dev,
1202 struct netdev_phys_item_id *psid);
1203 int (*ndo_switch_port_stp_update)(struct net_device *dev,
1204 u8 state);
1205 int (*ndo_switch_fib_ipv4_add)(struct net_device *dev,
1206 __be32 dst,
1207 int dst_len,
1208 struct fib_info *fi,
1209 u8 tos, u8 type,
1210 u32 nlflags,
1211 u32 tb_id);
1212 int (*ndo_switch_fib_ipv4_del)(struct net_device *dev,
1213 __be32 dst,
1214 int dst_len,
1215 struct fib_info *fi,
1216 u8 tos, u8 type,
1217 u32 tb_id);
1218#endif
1219}; 1181};
1220 1182
1221/** 1183/**
@@ -1577,6 +1539,9 @@ struct net_device {
1577 const struct net_device_ops *netdev_ops; 1539 const struct net_device_ops *netdev_ops;
1578 const struct ethtool_ops *ethtool_ops; 1540 const struct ethtool_ops *ethtool_ops;
1579 const struct forwarding_accel_ops *fwd_ops; 1541 const struct forwarding_accel_ops *fwd_ops;
1542#ifdef CONFIG_NET_SWITCHDEV
1543 const struct swdev_ops *swdev_ops;
1544#endif
1580 1545
1581 const struct header_ops *header_ops; 1546 const struct header_ops *header_ops;
1582 1547
diff --git a/include/net/switchdev.h b/include/net/switchdev.h
index 1a9382febcc3..e5de53f92482 100644
--- a/include/net/switchdev.h
+++ b/include/net/switchdev.h
@@ -14,6 +14,44 @@
14#include <linux/netdevice.h> 14#include <linux/netdevice.h>
15#include <linux/notifier.h> 15#include <linux/notifier.h>
16 16
17struct fib_info;
18
19/**
20 * struct switchdev_ops - switchdev operations
21 *
22 * int (*swdev_parent_id_get)(struct net_device *dev,
23 * struct netdev_phys_item_id *psid);
24 * Called to get an ID of the switch chip this port is part of.
25 * If driver implements this, it indicates that it represents a port
26 * of a switch chip.
27 *
28 * int (*swdev_port_stp_update)(struct net_device *dev, u8 state);
29 * Called to notify switch device port of bridge port STP
30 * state change.
31 *
32 * int (*swdev_fib_ipv4_add)(struct net_device *dev, __be32 dst,
33 * int dst_len, struct fib_info *fi,
34 * u8 tos, u8 type, u32 nlflags, u32 tb_id);
35 * Called to add/modify IPv4 route to switch device.
36 *
37 * int (*swdev_fib_ipv4_del)(struct net_device *dev, __be32 dst,
38 * int dst_len, struct fib_info *fi,
39 * u8 tos, u8 type, u32 tb_id);
40 * Called to delete IPv4 route from switch device.
41 */
42struct swdev_ops {
43 int (*swdev_parent_id_get)(struct net_device *dev,
44 struct netdev_phys_item_id *psid);
45 int (*swdev_port_stp_update)(struct net_device *dev, u8 state);
46 int (*swdev_fib_ipv4_add)(struct net_device *dev, __be32 dst,
47 int dst_len, struct fib_info *fi,
48 u8 tos, u8 type, u32 nlflags,
49 u32 tb_id);
50 int (*swdev_fib_ipv4_del)(struct net_device *dev, __be32 dst,
51 int dst_len, struct fib_info *fi,
52 u8 tos, u8 type, u32 tb_id);
53};
54
17enum netdev_switch_notifier_type { 55enum netdev_switch_notifier_type {
18 NETDEV_SWITCH_FDB_ADD = 1, 56 NETDEV_SWITCH_FDB_ADD = 1,
19 NETDEV_SWITCH_FDB_DEL, 57 NETDEV_SWITCH_FDB_DEL,
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 6511552039d6..f0af7aa331c1 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -16,6 +16,7 @@
16#include <linux/of_net.h> 16#include <linux/of_net.h>
17#include <linux/of_mdio.h> 17#include <linux/of_mdio.h>
18#include <net/rtnetlink.h> 18#include <net/rtnetlink.h>
19#include <net/switchdev.h>
19#include <linux/if_bridge.h> 20#include <linux/if_bridge.h>
20#include "dsa_priv.h" 21#include "dsa_priv.h"
21 22
@@ -572,8 +573,11 @@ static const struct net_device_ops dsa_slave_netdev_ops = {
572 .ndo_set_rx_mode = dsa_slave_set_rx_mode, 573 .ndo_set_rx_mode = dsa_slave_set_rx_mode,
573 .ndo_set_mac_address = dsa_slave_set_mac_address, 574 .ndo_set_mac_address = dsa_slave_set_mac_address,
574 .ndo_do_ioctl = dsa_slave_ioctl, 575 .ndo_do_ioctl = dsa_slave_ioctl,
575 .ndo_switch_parent_id_get = dsa_slave_parent_id_get, 576};
576 .ndo_switch_port_stp_update = dsa_slave_stp_update, 577
578static const struct swdev_ops dsa_slave_swdev_ops = {
579 .swdev_parent_id_get = dsa_slave_parent_id_get,
580 .swdev_port_stp_update = dsa_slave_stp_update,
577}; 581};
578 582
579static void dsa_slave_adjust_link(struct net_device *dev) 583static void dsa_slave_adjust_link(struct net_device *dev)
@@ -755,6 +759,7 @@ int dsa_slave_create(struct dsa_switch *ds, struct device *parent,
755 eth_hw_addr_inherit(slave_dev, master); 759 eth_hw_addr_inherit(slave_dev, master);
756 slave_dev->tx_queue_len = 0; 760 slave_dev->tx_queue_len = 0;
757 slave_dev->netdev_ops = &dsa_slave_netdev_ops; 761 slave_dev->netdev_ops = &dsa_slave_netdev_ops;
762 slave_dev->swdev_ops = &dsa_slave_swdev_ops;
758 763
759 SET_NETDEV_DEV(slave_dev, parent); 764 SET_NETDEV_DEV(slave_dev, parent);
760 slave_dev->dev.of_node = ds->pd->port_dn[port]; 765 slave_dev->dev.of_node = ds->pd->port_dn[port];
diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
index b7a23132c610..c9bfa004abed 100644
--- a/net/switchdev/switchdev.c
+++ b/net/switchdev/switchdev.c
@@ -28,11 +28,11 @@
28int netdev_switch_parent_id_get(struct net_device *dev, 28int netdev_switch_parent_id_get(struct net_device *dev,
29 struct netdev_phys_item_id *psid) 29 struct netdev_phys_item_id *psid)
30{ 30{
31 const struct net_device_ops *ops = dev->netdev_ops; 31 const struct swdev_ops *ops = dev->swdev_ops;
32 32
33 if (!ops->ndo_switch_parent_id_get) 33 if (!ops || !ops->swdev_parent_id_get)
34 return -EOPNOTSUPP; 34 return -EOPNOTSUPP;
35 return ops->ndo_switch_parent_id_get(dev, psid); 35 return ops->swdev_parent_id_get(dev, psid);
36} 36}
37EXPORT_SYMBOL_GPL(netdev_switch_parent_id_get); 37EXPORT_SYMBOL_GPL(netdev_switch_parent_id_get);
38 38
@@ -46,12 +46,12 @@ EXPORT_SYMBOL_GPL(netdev_switch_parent_id_get);
46 */ 46 */
47int netdev_switch_port_stp_update(struct net_device *dev, u8 state) 47int netdev_switch_port_stp_update(struct net_device *dev, u8 state)
48{ 48{
49 const struct net_device_ops *ops = dev->netdev_ops; 49 const struct swdev_ops *ops = dev->swdev_ops;
50 50
51 if (!ops->ndo_switch_port_stp_update) 51 if (!ops || !ops->swdev_port_stp_update)
52 return -EOPNOTSUPP; 52 return -EOPNOTSUPP;
53 WARN_ON(!ops->ndo_switch_parent_id_get); 53 WARN_ON(!ops->swdev_parent_id_get);
54 return ops->ndo_switch_port_stp_update(dev, state); 54 return ops->swdev_port_stp_update(dev, state);
55} 55}
56EXPORT_SYMBOL_GPL(netdev_switch_port_stp_update); 56EXPORT_SYMBOL_GPL(netdev_switch_port_stp_update);
57 57
@@ -230,17 +230,17 @@ EXPORT_SYMBOL_GPL(ndo_dflt_netdev_switch_port_bridge_dellink);
230 230
231static struct net_device *netdev_switch_get_lowest_dev(struct net_device *dev) 231static struct net_device *netdev_switch_get_lowest_dev(struct net_device *dev)
232{ 232{
233 const struct net_device_ops *ops = dev->netdev_ops; 233 const struct swdev_ops *ops = dev->swdev_ops;
234 struct net_device *lower_dev; 234 struct net_device *lower_dev;
235 struct net_device *port_dev; 235 struct net_device *port_dev;
236 struct list_head *iter; 236 struct list_head *iter;
237 237
238 /* Recusively search down until we find a sw port dev. 238 /* Recusively search down until we find a sw port dev.
239 * (A sw port dev supports ndo_switch_parent_id_get). 239 * (A sw port dev supports swdev_parent_id_get).
240 */ 240 */
241 241
242 if (dev->features & NETIF_F_HW_SWITCH_OFFLOAD && 242 if (dev->features & NETIF_F_HW_SWITCH_OFFLOAD &&
243 ops->ndo_switch_parent_id_get) 243 ops && ops->swdev_parent_id_get)
244 return dev; 244 return dev;
245 245
246 netdev_for_each_lower_dev(dev, lower_dev, iter) { 246 netdev_for_each_lower_dev(dev, lower_dev, iter) {
@@ -304,7 +304,7 @@ int netdev_switch_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi,
304 u8 tos, u8 type, u32 nlflags, u32 tb_id) 304 u8 tos, u8 type, u32 nlflags, u32 tb_id)
305{ 305{
306 struct net_device *dev; 306 struct net_device *dev;
307 const struct net_device_ops *ops; 307 const struct swdev_ops *ops;
308 int err = 0; 308 int err = 0;
309 309
310 /* Don't offload route if using custom ip rules or if 310 /* Don't offload route if using custom ip rules or if
@@ -322,12 +322,12 @@ int netdev_switch_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi,
322 dev = netdev_switch_get_dev_by_nhs(fi); 322 dev = netdev_switch_get_dev_by_nhs(fi);
323 if (!dev) 323 if (!dev)
324 return 0; 324 return 0;
325 ops = dev->netdev_ops; 325 ops = dev->swdev_ops;
326 326
327 if (ops->ndo_switch_fib_ipv4_add) { 327 if (ops->swdev_fib_ipv4_add) {
328 err = ops->ndo_switch_fib_ipv4_add(dev, htonl(dst), dst_len, 328 err = ops->swdev_fib_ipv4_add(dev, htonl(dst), dst_len,
329 fi, tos, type, nlflags, 329 fi, tos, type, nlflags,
330 tb_id); 330 tb_id);
331 if (!err) 331 if (!err)
332 fi->fib_flags |= RTNH_F_EXTERNAL; 332 fi->fib_flags |= RTNH_F_EXTERNAL;
333 } 333 }
@@ -352,7 +352,7 @@ int netdev_switch_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi,
352 u8 tos, u8 type, u32 tb_id) 352 u8 tos, u8 type, u32 tb_id)
353{ 353{
354 struct net_device *dev; 354 struct net_device *dev;
355 const struct net_device_ops *ops; 355 const struct swdev_ops *ops;
356 int err = 0; 356 int err = 0;
357 357
358 if (!(fi->fib_flags & RTNH_F_EXTERNAL)) 358 if (!(fi->fib_flags & RTNH_F_EXTERNAL))
@@ -361,11 +361,11 @@ int netdev_switch_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi,
361 dev = netdev_switch_get_dev_by_nhs(fi); 361 dev = netdev_switch_get_dev_by_nhs(fi);
362 if (!dev) 362 if (!dev)
363 return 0; 363 return 0;
364 ops = dev->netdev_ops; 364 ops = dev->swdev_ops;
365 365
366 if (ops->ndo_switch_fib_ipv4_del) { 366 if (ops->swdev_fib_ipv4_del) {
367 err = ops->ndo_switch_fib_ipv4_del(dev, htonl(dst), dst_len, 367 err = ops->swdev_fib_ipv4_del(dev, htonl(dst), dst_len,
368 fi, tos, type, tb_id); 368 fi, tos, type, tb_id);
369 if (!err) 369 if (!err)
370 fi->fib_flags &= ~RTNH_F_EXTERNAL; 370 fi->fib_flags &= ~RTNH_F_EXTERNAL;
371 } 371 }