Skip to content

Commit de62486

Browse files
diana5nanadavem330
authored andcommitted
nfp: add support for multicast filter
Rewrite nfp_net_set_rx_mode() to implement interface to delivery mc address and operations to firmware by using general mailbox for filtering multicast packets. The operations include add mc address and delete mc address. And the limitation of mc addresses number is 1024 for each net device. User triggers adding mc address by using command below: ip maddress add <mc address> dev <interface name> User triggers deleting mc address by using command below: ip maddress del <mc address> dev <interface name> Signed-off-by: Diana Wang <[email protected]> Signed-off-by: Simon Horman <[email protected]> Reviewed-by: Leon Romanovsky <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 38db82e commit de62486

File tree

3 files changed

+79
-4
lines changed

3 files changed

+79
-4
lines changed

drivers/net/ethernet/netronome/nfp/nfp_net.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@
8888
#define NFP_NET_FL_BATCH 16 /* Add freelist in this Batch size */
8989
#define NFP_NET_XDP_MAX_COMPLETE 2048 /* XDP bufs to reclaim in NAPI poll */
9090

91+
/* MC definitions */
92+
#define NFP_NET_CFG_MAC_MC_MAX 1024 /* The maximum number of MC address per port*/
93+
9194
/* Offload definitions */
9295
#define NFP_NET_N_VXLAN_PORTS (NFP_NET_CFG_VXLAN_SZ / sizeof(__be16))
9396

@@ -476,6 +479,7 @@ struct nfp_stat_pair {
476479
* @rx_dma_off: Offset at which DMA packets (for XDP headroom)
477480
* @rx_offset: Offset in the RX buffers where packet data starts
478481
* @ctrl: Local copy of the control register/word.
482+
* @ctrl_w1: Local copy of the control register/word1.
479483
* @fl_bufsz: Currently configured size of the freelist buffers
480484
* @xdp_prog: Installed XDP program
481485
* @tx_rings: Array of pre-allocated TX ring structures
@@ -508,6 +512,7 @@ struct nfp_net_dp {
508512
u32 rx_dma_off;
509513

510514
u32 ctrl;
515+
u32 ctrl_w1;
511516
u32 fl_bufsz;
512517

513518
struct bpf_prog *xdp_prog;

drivers/net/ethernet/netronome/nfp/nfp_net_common.c

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,6 +1007,7 @@ static int nfp_net_set_config_and_enable(struct nfp_net *nn)
10071007
new_ctrl |= NFP_NET_CFG_CTRL_RINGCFG;
10081008

10091009
nn_writel(nn, NFP_NET_CFG_CTRL, new_ctrl);
1010+
nn_writel(nn, NFP_NET_CFG_CTRL_WORD1, nn->dp.ctrl_w1);
10101011
err = nfp_net_reconfig(nn, update);
10111012
if (err) {
10121013
nfp_net_clear_config_and_disable(nn);
@@ -1333,18 +1334,59 @@ int nfp_ctrl_open(struct nfp_net *nn)
13331334
return err;
13341335
}
13351336

1337+
static int nfp_net_mc_cfg(struct net_device *netdev, const unsigned char *addr, const u32 cmd)
1338+
{
1339+
struct nfp_net *nn = netdev_priv(netdev);
1340+
int ret;
1341+
1342+
ret = nfp_net_mbox_lock(nn, NFP_NET_CFG_MULTICAST_SZ);
1343+
if (ret)
1344+
return ret;
1345+
1346+
nn_writel(nn, nn->tlv_caps.mbox_off + NFP_NET_CFG_MULTICAST_MAC_HI,
1347+
get_unaligned_be32(addr));
1348+
nn_writew(nn, nn->tlv_caps.mbox_off + NFP_NET_CFG_MULTICAST_MAC_LO,
1349+
get_unaligned_be16(addr + 4));
1350+
1351+
return nfp_net_mbox_reconfig_and_unlock(nn, cmd);
1352+
}
1353+
1354+
static int nfp_net_mc_sync(struct net_device *netdev, const unsigned char *addr)
1355+
{
1356+
struct nfp_net *nn = netdev_priv(netdev);
1357+
1358+
if (netdev_mc_count(netdev) > NFP_NET_CFG_MAC_MC_MAX) {
1359+
nn_err(nn, "Requested number of MC addresses (%d) exceeds maximum (%d).\n",
1360+
netdev_mc_count(netdev), NFP_NET_CFG_MAC_MC_MAX);
1361+
return -EINVAL;
1362+
}
1363+
1364+
return nfp_net_mc_cfg(netdev, addr, NFP_NET_CFG_MBOX_CMD_MULTICAST_ADD);
1365+
}
1366+
1367+
static int nfp_net_mc_unsync(struct net_device *netdev, const unsigned char *addr)
1368+
{
1369+
return nfp_net_mc_cfg(netdev, addr, NFP_NET_CFG_MBOX_CMD_MULTICAST_DEL);
1370+
}
1371+
13361372
static void nfp_net_set_rx_mode(struct net_device *netdev)
13371373
{
13381374
struct nfp_net *nn = netdev_priv(netdev);
1339-
u32 new_ctrl;
1375+
u32 new_ctrl, new_ctrl_w1;
13401376

13411377
new_ctrl = nn->dp.ctrl;
1378+
new_ctrl_w1 = nn->dp.ctrl_w1;
13421379

13431380
if (!netdev_mc_empty(netdev) || netdev->flags & IFF_ALLMULTI)
13441381
new_ctrl |= nn->cap & NFP_NET_CFG_CTRL_L2MC;
13451382
else
13461383
new_ctrl &= ~NFP_NET_CFG_CTRL_L2MC;
13471384

1385+
if (netdev->flags & IFF_ALLMULTI)
1386+
new_ctrl_w1 &= ~NFP_NET_CFG_CTRL_MCAST_FILTER;
1387+
else
1388+
new_ctrl_w1 |= nn->cap_w1 & NFP_NET_CFG_CTRL_MCAST_FILTER;
1389+
13481390
if (netdev->flags & IFF_PROMISC) {
13491391
if (nn->cap & NFP_NET_CFG_CTRL_PROMISC)
13501392
new_ctrl |= NFP_NET_CFG_CTRL_PROMISC;
@@ -1354,13 +1396,21 @@ static void nfp_net_set_rx_mode(struct net_device *netdev)
13541396
new_ctrl &= ~NFP_NET_CFG_CTRL_PROMISC;
13551397
}
13561398

1357-
if (new_ctrl == nn->dp.ctrl)
1399+
if ((nn->cap_w1 & NFP_NET_CFG_CTRL_MCAST_FILTER) &&
1400+
__dev_mc_sync(netdev, nfp_net_mc_sync, nfp_net_mc_unsync))
1401+
netdev_err(netdev, "Sync mc address failed\n");
1402+
1403+
if (new_ctrl == nn->dp.ctrl && new_ctrl_w1 == nn->dp.ctrl_w1)
13581404
return;
13591405

1360-
nn_writel(nn, NFP_NET_CFG_CTRL, new_ctrl);
1406+
if (new_ctrl != nn->dp.ctrl)
1407+
nn_writel(nn, NFP_NET_CFG_CTRL, new_ctrl);
1408+
if (new_ctrl_w1 != nn->dp.ctrl_w1)
1409+
nn_writel(nn, NFP_NET_CFG_CTRL_WORD1, new_ctrl_w1);
13611410
nfp_net_reconfig_post(nn, NFP_NET_CFG_UPDATE_GEN);
13621411

13631412
nn->dp.ctrl = new_ctrl;
1413+
nn->dp.ctrl_w1 = new_ctrl_w1;
13641414
}
13651415

13661416
static void nfp_net_rss_init_itbl(struct nfp_net *nn)
@@ -2092,7 +2142,7 @@ void nfp_net_info(struct nfp_net *nn)
20922142
nn->fw_ver.extend, nn->fw_ver.class,
20932143
nn->fw_ver.major, nn->fw_ver.minor,
20942144
nn->max_mtu);
2095-
nn_info(nn, "CAP: %#x %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
2145+
nn_info(nn, "CAP: %#x %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
20962146
nn->cap,
20972147
nn->cap & NFP_NET_CFG_CTRL_PROMISC ? "PROMISC " : "",
20982148
nn->cap & NFP_NET_CFG_CTRL_L2BC ? "L2BCFILT " : "",
@@ -2120,6 +2170,7 @@ void nfp_net_info(struct nfp_net *nn)
21202170
nn->cap & NFP_NET_CFG_CTRL_CSUM_COMPLETE ?
21212171
"RXCSUM_COMPLETE " : "",
21222172
nn->cap & NFP_NET_CFG_CTRL_LIVE_ADDR ? "LIVE_ADDR " : "",
2173+
nn->cap_w1 & NFP_NET_CFG_CTRL_MCAST_FILTER ? "MULTICAST_FILTER " : "",
21232174
nfp_app_extra_cap(nn->app, nn));
21242175
}
21252176

@@ -2548,13 +2599,17 @@ int nfp_net_init(struct nfp_net *nn)
25482599
if (nn->cap & NFP_NET_CFG_CTRL_TXRWB)
25492600
nn->dp.ctrl |= NFP_NET_CFG_CTRL_TXRWB;
25502601

2602+
if (nn->cap_w1 & NFP_NET_CFG_CTRL_MCAST_FILTER)
2603+
nn->dp.ctrl_w1 |= NFP_NET_CFG_CTRL_MCAST_FILTER;
2604+
25512605
/* Stash the re-configuration queue away. First odd queue in TX Bar */
25522606
nn->qcp_cfg = nn->tx_bar + NFP_QCP_QUEUE_ADDR_SZ;
25532607

25542608
/* Make sure the FW knows the netdev is supposed to be disabled here */
25552609
nn_writel(nn, NFP_NET_CFG_CTRL, 0);
25562610
nn_writeq(nn, NFP_NET_CFG_TXRS_ENABLE, 0);
25572611
nn_writeq(nn, NFP_NET_CFG_RXRS_ENABLE, 0);
2612+
nn_writel(nn, NFP_NET_CFG_CTRL_WORD1, 0);
25582613
err = nfp_net_reconfig(nn, NFP_NET_CFG_UPDATE_RING |
25592614
NFP_NET_CFG_UPDATE_GEN);
25602615
if (err)

drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@
267267
#define NFP_NET_CFG_CTRL_WORD1 0x0098
268268
#define NFP_NET_CFG_CTRL_PKT_TYPE (0x1 << 0) /* Pkttype offload */
269269
#define NFP_NET_CFG_CTRL_IPSEC (0x1 << 1) /* IPsec offload */
270+
#define NFP_NET_CFG_CTRL_MCAST_FILTER (0x1 << 2) /* Multicast Filter */
270271

271272
#define NFP_NET_CFG_CAP_WORD1 0x00a4
272273

@@ -413,6 +414,9 @@
413414
#define NFP_NET_CFG_MBOX_CMD_PCI_DSCP_PRIOMAP_SET 5
414415
#define NFP_NET_CFG_MBOX_CMD_TLV_CMSG 6
415416

417+
#define NFP_NET_CFG_MBOX_CMD_MULTICAST_ADD 8
418+
#define NFP_NET_CFG_MBOX_CMD_MULTICAST_DEL 9
419+
416420
/* VLAN filtering using general use mailbox
417421
* %NFP_NET_CFG_VLAN_FILTER: Base address of VLAN filter mailbox
418422
* %NFP_NET_CFG_VLAN_FILTER_VID: VLAN ID to filter
@@ -424,6 +428,17 @@
424428
#define NFP_NET_CFG_VLAN_FILTER_PROTO (NFP_NET_CFG_VLAN_FILTER + 2)
425429
#define NFP_NET_CFG_VLAN_FILTER_SZ 0x0004
426430

431+
/* Multicast filtering using general use mailbox
432+
* %NFP_NET_CFG_MULTICAST: Base address of Multicast filter mailbox
433+
* %NFP_NET_CFG_MULTICAST_MAC_HI: High 32-bits of Multicast MAC address
434+
* %NFP_NET_CFG_MULTICAST_MAC_LO: Low 16-bits of Multicast MAC address
435+
* %NFP_NET_CFG_MULTICAST_SZ: Size of the Multicast filter mailbox in bytes
436+
*/
437+
#define NFP_NET_CFG_MULTICAST NFP_NET_CFG_MBOX_SIMPLE_VAL
438+
#define NFP_NET_CFG_MULTICAST_MAC_HI NFP_NET_CFG_MULTICAST
439+
#define NFP_NET_CFG_MULTICAST_MAC_LO (NFP_NET_CFG_MULTICAST + 6)
440+
#define NFP_NET_CFG_MULTICAST_SZ 0x0006
441+
427442
/* TLV capabilities
428443
* %NFP_NET_CFG_TLV_TYPE: Offset of type within the TLV
429444
* %NFP_NET_CFG_TLV_TYPE_REQUIRED: Driver must be able to parse the TLV

0 commit comments

Comments
 (0)