18
18
#include <net/rtnetlink.h>
19
19
#include <net/switchdev.h>
20
20
#include <linux/if_bridge.h>
21
+ #include <linux/netpoll.h>
21
22
#include "dsa_priv.h"
22
23
23
24
/* slave mii_bus handling ***************************************************/
@@ -418,6 +419,18 @@ static int dsa_slave_port_attr_get(struct net_device *dev,
418
419
return 0 ;
419
420
}
420
421
422
+ static inline netdev_tx_t dsa_netpoll_send_skb (struct dsa_slave_priv * p ,
423
+ struct sk_buff * skb )
424
+ {
425
+ #ifdef CONFIG_NET_POLL_CONTROLLER
426
+ if (p -> netpoll )
427
+ netpoll_send_skb (p -> netpoll , skb );
428
+ #else
429
+ BUG ();
430
+ #endif
431
+ return NETDEV_TX_OK ;
432
+ }
433
+
421
434
static netdev_tx_t dsa_slave_xmit (struct sk_buff * skb , struct net_device * dev )
422
435
{
423
436
struct dsa_slave_priv * p = netdev_priv (dev );
@@ -431,6 +444,12 @@ static netdev_tx_t dsa_slave_xmit(struct sk_buff *skb, struct net_device *dev)
431
444
if (!nskb )
432
445
return NETDEV_TX_OK ;
433
446
447
+ /* SKB for netpoll still need to be mangled with the protocol-specific
448
+ * tag to be successfully transmitted
449
+ */
450
+ if (unlikely (netpoll_tx_running (dev )))
451
+ return dsa_netpoll_send_skb (p , nskb );
452
+
434
453
/* Queue the SKB for transmission on the parent interface, but
435
454
* do not modify its EtherType
436
455
*/
@@ -676,6 +695,49 @@ static int dsa_slave_get_eee(struct net_device *dev, struct ethtool_eee *e)
676
695
return ret ;
677
696
}
678
697
698
+ #ifdef CONFIG_NET_POLL_CONTROLLER
699
+ static int dsa_slave_netpoll_setup (struct net_device * dev ,
700
+ struct netpoll_info * ni )
701
+ {
702
+ struct dsa_slave_priv * p = netdev_priv (dev );
703
+ struct dsa_switch * ds = p -> parent ;
704
+ struct net_device * master = ds -> dst -> master_netdev ;
705
+ struct netpoll * netpoll ;
706
+ int err = 0 ;
707
+
708
+ netpoll = kzalloc (sizeof (* netpoll ), GFP_KERNEL );
709
+ if (!netpoll )
710
+ return - ENOMEM ;
711
+
712
+ err = __netpoll_setup (netpoll , master );
713
+ if (err ) {
714
+ kfree (netpoll );
715
+ goto out ;
716
+ }
717
+
718
+ p -> netpoll = netpoll ;
719
+ out :
720
+ return err ;
721
+ }
722
+
723
+ static void dsa_slave_netpoll_cleanup (struct net_device * dev )
724
+ {
725
+ struct dsa_slave_priv * p = netdev_priv (dev );
726
+ struct netpoll * netpoll = p -> netpoll ;
727
+
728
+ if (!netpoll )
729
+ return ;
730
+
731
+ p -> netpoll = NULL ;
732
+
733
+ __netpoll_free_async (netpoll );
734
+ }
735
+
736
+ static void dsa_slave_poll_controller (struct net_device * dev )
737
+ {
738
+ }
739
+ #endif
740
+
679
741
static const struct ethtool_ops dsa_slave_ethtool_ops = {
680
742
.get_settings = dsa_slave_get_settings ,
681
743
.set_settings = dsa_slave_set_settings ,
@@ -708,6 +770,11 @@ static const struct net_device_ops dsa_slave_netdev_ops = {
708
770
.ndo_fdb_dump = dsa_slave_fdb_dump ,
709
771
.ndo_do_ioctl = dsa_slave_ioctl ,
710
772
.ndo_get_iflink = dsa_slave_get_iflink ,
773
+ #ifdef CONFIG_NET_POLL_CONTROLLER
774
+ .ndo_netpoll_setup = dsa_slave_netpoll_setup ,
775
+ .ndo_netpoll_cleanup = dsa_slave_netpoll_cleanup ,
776
+ .ndo_poll_controller = dsa_slave_poll_controller ,
777
+ #endif
711
778
};
712
779
713
780
static const struct switchdev_ops dsa_slave_switchdev_ops = {
0 commit comments