Skip to content

Commit db316d5

Browse files
committed
Merge branch 'dsa-netconsole'
Florian Fainelli says: ==================== net: GENET, SYSTEMPORT and DSA netconsole This patch series adds support for netconsole in the GENET, SYSTEMPORT and DSA drivers. A small refactoring to the DSA transmit path is required to avoid duplicating the dsa_netpoll_send_skb() into each and every tagging protocol supported. Testing on e.g: mv643xx_eth and/or e1000e would be much appreciated! Changes in v2: - properly disable/enable interrupts in GENET and SYSTEMPORT - pass the reallocated SKB back to dsa_slave_xmit() in case a tag protocol had to alter the original SKB ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 0f7bffd + 04ff53f commit db316d5

File tree

8 files changed

+142
-49
lines changed

8 files changed

+142
-49
lines changed

drivers/net/ethernet/broadcom/bcmsysport.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -933,6 +933,21 @@ static irqreturn_t bcm_sysport_wol_isr(int irq, void *dev_id)
933933
return IRQ_HANDLED;
934934
}
935935

936+
#ifdef CONFIG_NET_POLL_CONTROLLER
937+
static void bcm_sysport_poll_controller(struct net_device *dev)
938+
{
939+
struct bcm_sysport_priv *priv = netdev_priv(dev);
940+
941+
disable_irq(priv->irq0);
942+
bcm_sysport_rx_isr(priv->irq0, priv);
943+
enable_irq(priv->irq0);
944+
945+
disable_irq(priv->irq1);
946+
bcm_sysport_tx_isr(priv->irq1, priv);
947+
enable_irq(priv->irq1);
948+
}
949+
#endif
950+
936951
static struct sk_buff *bcm_sysport_insert_tsb(struct sk_buff *skb,
937952
struct net_device *dev)
938953
{
@@ -1723,6 +1738,9 @@ static const struct net_device_ops bcm_sysport_netdev_ops = {
17231738
.ndo_set_features = bcm_sysport_set_features,
17241739
.ndo_set_rx_mode = bcm_sysport_set_rx_mode,
17251740
.ndo_set_mac_address = bcm_sysport_change_mac,
1741+
#ifdef CONFIG_NET_POLL_CONTROLLER
1742+
.ndo_poll_controller = bcm_sysport_poll_controller,
1743+
#endif
17261744
};
17271745

17281746
#define REV_FMT "v%2x.%02x"

drivers/net/ethernet/broadcom/genet/bcmgenet.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2388,6 +2388,23 @@ static irqreturn_t bcmgenet_wol_isr(int irq, void *dev_id)
23882388
return IRQ_HANDLED;
23892389
}
23902390

2391+
#ifdef CONFIG_NET_POLL_CONTROLLER
2392+
static void bcmgenet_poll_controller(struct net_device *dev)
2393+
{
2394+
struct bcmgenet_priv *priv = netdev_priv(dev);
2395+
2396+
/* Invoke the main RX/TX interrupt handler */
2397+
disable_irq(priv->irq0);
2398+
bcmgenet_isr0(priv->irq0, priv);
2399+
enable_irq(priv->irq0);
2400+
2401+
/* And the interrupt handler for RX/TX priority queues */
2402+
disable_irq(priv->irq1);
2403+
bcmgenet_isr1(priv->irq1, priv);
2404+
enable_irq(priv->irq1);
2405+
}
2406+
#endif
2407+
23912408
static void bcmgenet_umac_reset(struct bcmgenet_priv *priv)
23922409
{
23932410
u32 reg;
@@ -2939,6 +2956,9 @@ static const struct net_device_ops bcmgenet_netdev_ops = {
29392956
.ndo_set_mac_address = bcmgenet_set_mac_addr,
29402957
.ndo_do_ioctl = bcmgenet_ioctl,
29412958
.ndo_set_features = bcmgenet_set_features,
2959+
#ifdef CONFIG_NET_POLL_CONTROLLER
2960+
.ndo_poll_controller = bcmgenet_poll_controller,
2961+
#endif
29422962
};
29432963

29442964
/* Array of GENET hardware parameters/characteristics */

net/dsa/dsa_priv.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,10 @@
1313

1414
#include <linux/phy.h>
1515
#include <linux/netdevice.h>
16+
#include <linux/netpoll.h>
1617

1718
struct dsa_device_ops {
18-
netdev_tx_t (*xmit)(struct sk_buff *skb, struct net_device *dev);
19+
struct sk_buff *(*xmit)(struct sk_buff *skb, struct net_device *dev);
1920
int (*rcv)(struct sk_buff *skb, struct net_device *dev,
2021
struct packet_type *pt, struct net_device *orig_dev);
2122
};
@@ -26,7 +27,7 @@ struct dsa_slave_priv {
2627
* switch port.
2728
*/
2829
struct net_device *dev;
29-
netdev_tx_t (*xmit)(struct sk_buff *skb,
30+
struct sk_buff * (*xmit)(struct sk_buff *skb,
3031
struct net_device *dev);
3132

3233
/*
@@ -47,6 +48,9 @@ struct dsa_slave_priv {
4748
int old_duplex;
4849

4950
struct net_device *bridge_dev;
51+
#ifdef CONFIG_NET_POLL_CONTROLLER
52+
struct netpoll *netpoll;
53+
#endif
5054
};
5155

5256
/* dsa.c */

net/dsa/slave.c

Lines changed: 86 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <net/rtnetlink.h>
1919
#include <net/switchdev.h>
2020
#include <linux/if_bridge.h>
21+
#include <linux/netpoll.h>
2122
#include "dsa_priv.h"
2223

2324
/* slave mii_bus handling ***************************************************/
@@ -418,24 +419,53 @@ static int dsa_slave_port_attr_get(struct net_device *dev,
418419
return 0;
419420
}
420421

421-
static netdev_tx_t dsa_slave_xmit(struct sk_buff *skb, struct net_device *dev)
422+
static inline netdev_tx_t dsa_netpoll_send_skb(struct dsa_slave_priv *p,
423+
struct sk_buff *skb)
422424
{
423-
struct dsa_slave_priv *p = netdev_priv(dev);
424-
425-
return p->xmit(skb, dev);
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;
426432
}
427433

428-
static netdev_tx_t dsa_slave_notag_xmit(struct sk_buff *skb,
429-
struct net_device *dev)
434+
static netdev_tx_t dsa_slave_xmit(struct sk_buff *skb, struct net_device *dev)
430435
{
431436
struct dsa_slave_priv *p = netdev_priv(dev);
437+
struct sk_buff *nskb;
432438

433-
skb->dev = p->parent->dst->master_netdev;
434-
dev_queue_xmit(skb);
439+
dev->stats.tx_packets++;
440+
dev->stats.tx_bytes += skb->len;
441+
442+
/* Transmit function may have to reallocate the original SKB */
443+
nskb = p->xmit(skb, dev);
444+
if (!nskb)
445+
return NETDEV_TX_OK;
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+
453+
/* Queue the SKB for transmission on the parent interface, but
454+
* do not modify its EtherType
455+
*/
456+
nskb->dev = p->parent->dst->master_netdev;
457+
dev_queue_xmit(nskb);
435458

436459
return NETDEV_TX_OK;
437460
}
438461

462+
static struct sk_buff *dsa_slave_notag_xmit(struct sk_buff *skb,
463+
struct net_device *dev)
464+
{
465+
/* Just return the original SKB */
466+
return skb;
467+
}
468+
439469

440470
/* ethtool operations *******************************************************/
441471
static int
@@ -665,6 +695,49 @@ static int dsa_slave_get_eee(struct net_device *dev, struct ethtool_eee *e)
665695
return ret;
666696
}
667697

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+
668741
static const struct ethtool_ops dsa_slave_ethtool_ops = {
669742
.get_settings = dsa_slave_get_settings,
670743
.set_settings = dsa_slave_set_settings,
@@ -697,6 +770,11 @@ static const struct net_device_ops dsa_slave_netdev_ops = {
697770
.ndo_fdb_dump = dsa_slave_fdb_dump,
698771
.ndo_do_ioctl = dsa_slave_ioctl,
699772
.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
700778
};
701779

702780
static const struct switchdev_ops dsa_slave_switchdev_ops = {

net/dsa/tag_brcm.c

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,11 @@
5858
#define BRCM_EG_TC_MASK 0x7
5959
#define BRCM_EG_PID_MASK 0x1f
6060

61-
static netdev_tx_t brcm_tag_xmit(struct sk_buff *skb, struct net_device *dev)
61+
static struct sk_buff *brcm_tag_xmit(struct sk_buff *skb, struct net_device *dev)
6262
{
6363
struct dsa_slave_priv *p = netdev_priv(dev);
6464
u8 *brcm_tag;
6565

66-
dev->stats.tx_packets++;
67-
dev->stats.tx_bytes += skb->len;
68-
6966
if (skb_cow_head(skb, BRCM_TAG_LEN) < 0)
7067
goto out_free;
7168

@@ -87,17 +84,11 @@ static netdev_tx_t brcm_tag_xmit(struct sk_buff *skb, struct net_device *dev)
8784
brcm_tag[2] = BRCM_IG_DSTMAP2_MASK;
8885
brcm_tag[3] = (1 << p->port) & BRCM_IG_DSTMAP1_MASK;
8986

90-
/* Queue the SKB for transmission on the parent interface, but
91-
* do not modify its EtherType
92-
*/
93-
skb->dev = p->parent->dst->master_netdev;
94-
dev_queue_xmit(skb);
95-
96-
return NETDEV_TX_OK;
87+
return skb;
9788

9889
out_free:
9990
kfree_skb(skb);
100-
return NETDEV_TX_OK;
91+
return NULL;
10192
}
10293

10394
static int brcm_tag_rcv(struct sk_buff *skb, struct net_device *dev,

net/dsa/tag_dsa.c

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,11 @@
1515

1616
#define DSA_HLEN 4
1717

18-
static netdev_tx_t dsa_xmit(struct sk_buff *skb, struct net_device *dev)
18+
static struct sk_buff *dsa_xmit(struct sk_buff *skb, struct net_device *dev)
1919
{
2020
struct dsa_slave_priv *p = netdev_priv(dev);
2121
u8 *dsa_header;
2222

23-
dev->stats.tx_packets++;
24-
dev->stats.tx_bytes += skb->len;
25-
2623
/*
2724
* Convert the outermost 802.1q tag to a DSA tag for tagged
2825
* packets, or insert a DSA tag between the addresses and
@@ -63,14 +60,11 @@ static netdev_tx_t dsa_xmit(struct sk_buff *skb, struct net_device *dev)
6360
dsa_header[3] = 0x00;
6461
}
6562

66-
skb->dev = p->parent->dst->master_netdev;
67-
dev_queue_xmit(skb);
68-
69-
return NETDEV_TX_OK;
63+
return skb;
7064

7165
out_free:
7266
kfree_skb(skb);
73-
return NETDEV_TX_OK;
67+
return NULL;
7468
}
7569

7670
static int dsa_rcv(struct sk_buff *skb, struct net_device *dev,

net/dsa/tag_edsa.c

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,11 @@
1616
#define DSA_HLEN 4
1717
#define EDSA_HLEN 8
1818

19-
static netdev_tx_t edsa_xmit(struct sk_buff *skb, struct net_device *dev)
19+
static struct sk_buff *edsa_xmit(struct sk_buff *skb, struct net_device *dev)
2020
{
2121
struct dsa_slave_priv *p = netdev_priv(dev);
2222
u8 *edsa_header;
2323

24-
dev->stats.tx_packets++;
25-
dev->stats.tx_bytes += skb->len;
26-
2724
/*
2825
* Convert the outermost 802.1q tag to a DSA tag and prepend
2926
* a DSA ethertype field is the packet is tagged, or insert
@@ -76,14 +73,11 @@ static netdev_tx_t edsa_xmit(struct sk_buff *skb, struct net_device *dev)
7673
edsa_header[7] = 0x00;
7774
}
7875

79-
skb->dev = p->parent->dst->master_netdev;
80-
dev_queue_xmit(skb);
81-
82-
return NETDEV_TX_OK;
76+
return skb;
8377

8478
out_free:
8579
kfree_skb(skb);
86-
return NETDEV_TX_OK;
80+
return NULL;
8781
}
8882

8983
static int edsa_rcv(struct sk_buff *skb, struct net_device *dev,

net/dsa/tag_trailer.c

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,13 @@
1313
#include <linux/slab.h>
1414
#include "dsa_priv.h"
1515

16-
static netdev_tx_t trailer_xmit(struct sk_buff *skb, struct net_device *dev)
16+
static struct sk_buff *trailer_xmit(struct sk_buff *skb, struct net_device *dev)
1717
{
1818
struct dsa_slave_priv *p = netdev_priv(dev);
1919
struct sk_buff *nskb;
2020
int padlen;
2121
u8 *trailer;
2222

23-
dev->stats.tx_packets++;
24-
dev->stats.tx_bytes += skb->len;
25-
2623
/*
2724
* We have to make sure that the trailer ends up as the very
2825
* last 4 bytes of the packet. This means that we have to pad
@@ -36,7 +33,7 @@ static netdev_tx_t trailer_xmit(struct sk_buff *skb, struct net_device *dev)
3633
nskb = alloc_skb(NET_IP_ALIGN + skb->len + padlen + 4, GFP_ATOMIC);
3734
if (nskb == NULL) {
3835
kfree_skb(skb);
39-
return NETDEV_TX_OK;
36+
return NULL;
4037
}
4138
skb_reserve(nskb, NET_IP_ALIGN);
4239

@@ -57,10 +54,7 @@ static netdev_tx_t trailer_xmit(struct sk_buff *skb, struct net_device *dev)
5754
trailer[2] = 0x10;
5855
trailer[3] = 0x00;
5956

60-
nskb->dev = p->parent->dst->master_netdev;
61-
dev_queue_xmit(nskb);
62-
63-
return NETDEV_TX_OK;
57+
return nskb;
6458
}
6559

6660
static int trailer_rcv(struct sk_buff *skb, struct net_device *dev,

0 commit comments

Comments
 (0)