@@ -1334,14 +1334,54 @@ int nfp_ctrl_open(struct nfp_net *nn)
1334
1334
return err ;
1335
1335
}
1336
1336
1337
- struct nfp_mc_addr_entry {
1338
- u8 addr [ETH_ALEN ];
1339
- u32 cmd ;
1340
- struct list_head list ;
1341
- };
1337
+ int nfp_net_sched_mbox_amsg_work (struct nfp_net * nn , u32 cmd , const void * data , size_t len ,
1338
+ int (* cb )(struct nfp_net * , struct nfp_mbox_amsg_entry * ))
1339
+ {
1340
+ struct nfp_mbox_amsg_entry * entry ;
1341
+
1342
+ entry = kmalloc (sizeof (* entry ) + len , GFP_ATOMIC );
1343
+ if (!entry )
1344
+ return - ENOMEM ;
1345
+
1346
+ memcpy (entry -> msg , data , len );
1347
+ entry -> cmd = cmd ;
1348
+ entry -> cfg = cb ;
1349
+
1350
+ spin_lock_bh (& nn -> mbox_amsg .lock );
1351
+ list_add_tail (& entry -> list , & nn -> mbox_amsg .list );
1352
+ spin_unlock_bh (& nn -> mbox_amsg .lock );
1353
+
1354
+ schedule_work (& nn -> mbox_amsg .work );
1355
+
1356
+ return 0 ;
1357
+ }
1358
+
1359
+ static void nfp_net_mbox_amsg_work (struct work_struct * work )
1360
+ {
1361
+ struct nfp_net * nn = container_of (work , struct nfp_net , mbox_amsg .work );
1362
+ struct nfp_mbox_amsg_entry * entry , * tmp ;
1363
+ struct list_head tmp_list ;
1364
+
1365
+ INIT_LIST_HEAD (& tmp_list );
1366
+
1367
+ spin_lock_bh (& nn -> mbox_amsg .lock );
1368
+ list_splice_init (& nn -> mbox_amsg .list , & tmp_list );
1369
+ spin_unlock_bh (& nn -> mbox_amsg .lock );
1370
+
1371
+ list_for_each_entry_safe (entry , tmp , & tmp_list , list ) {
1372
+ int err = entry -> cfg (nn , entry );
1373
+
1374
+ if (err )
1375
+ nn_err (nn , "Config cmd %d to HW failed %d.\n" , entry -> cmd , err );
1376
+
1377
+ list_del (& entry -> list );
1378
+ kfree (entry );
1379
+ }
1380
+ }
1342
1381
1343
- static int nfp_net_mc_cfg (struct nfp_net * nn , const unsigned char * addr , const u32 cmd )
1382
+ static int nfp_net_mc_cfg (struct nfp_net * nn , struct nfp_mbox_amsg_entry * entry )
1344
1383
{
1384
+ unsigned char * addr = entry -> msg ;
1345
1385
int ret ;
1346
1386
1347
1387
ret = nfp_net_mbox_lock (nn , NFP_NET_CFG_MULTICAST_SZ );
@@ -1353,26 +1393,7 @@ static int nfp_net_mc_cfg(struct nfp_net *nn, const unsigned char *addr, const u
1353
1393
nn_writew (nn , nn -> tlv_caps .mbox_off + NFP_NET_CFG_MULTICAST_MAC_LO ,
1354
1394
get_unaligned_be16 (addr + 4 ));
1355
1395
1356
- return nfp_net_mbox_reconfig_and_unlock (nn , cmd );
1357
- }
1358
-
1359
- static int nfp_net_mc_prep (struct nfp_net * nn , const unsigned char * addr , const u32 cmd )
1360
- {
1361
- struct nfp_mc_addr_entry * entry ;
1362
-
1363
- entry = kmalloc (sizeof (* entry ), GFP_ATOMIC );
1364
- if (!entry )
1365
- return - ENOMEM ;
1366
-
1367
- ether_addr_copy (entry -> addr , addr );
1368
- entry -> cmd = cmd ;
1369
- spin_lock_bh (& nn -> mc_lock );
1370
- list_add_tail (& entry -> list , & nn -> mc_addrs );
1371
- spin_unlock_bh (& nn -> mc_lock );
1372
-
1373
- schedule_work (& nn -> mc_work );
1374
-
1375
- return 0 ;
1396
+ return nfp_net_mbox_reconfig_and_unlock (nn , entry -> cmd );
1376
1397
}
1377
1398
1378
1399
static int nfp_net_mc_sync (struct net_device * netdev , const unsigned char * addr )
@@ -1385,35 +1406,16 @@ static int nfp_net_mc_sync(struct net_device *netdev, const unsigned char *addr)
1385
1406
return - EINVAL ;
1386
1407
}
1387
1408
1388
- return nfp_net_mc_prep (nn , addr , NFP_NET_CFG_MBOX_CMD_MULTICAST_ADD );
1409
+ return nfp_net_sched_mbox_amsg_work (nn , NFP_NET_CFG_MBOX_CMD_MULTICAST_ADD , addr ,
1410
+ NFP_NET_CFG_MULTICAST_SZ , nfp_net_mc_cfg );
1389
1411
}
1390
1412
1391
1413
static int nfp_net_mc_unsync (struct net_device * netdev , const unsigned char * addr )
1392
1414
{
1393
1415
struct nfp_net * nn = netdev_priv (netdev );
1394
1416
1395
- return nfp_net_mc_prep (nn , addr , NFP_NET_CFG_MBOX_CMD_MULTICAST_DEL );
1396
- }
1397
-
1398
- static void nfp_net_mc_addr_config (struct work_struct * work )
1399
- {
1400
- struct nfp_net * nn = container_of (work , struct nfp_net , mc_work );
1401
- struct nfp_mc_addr_entry * entry , * tmp ;
1402
- struct list_head tmp_list ;
1403
-
1404
- INIT_LIST_HEAD (& tmp_list );
1405
-
1406
- spin_lock_bh (& nn -> mc_lock );
1407
- list_splice_init (& nn -> mc_addrs , & tmp_list );
1408
- spin_unlock_bh (& nn -> mc_lock );
1409
-
1410
- list_for_each_entry_safe (entry , tmp , & tmp_list , list ) {
1411
- if (nfp_net_mc_cfg (nn , entry -> addr , entry -> cmd ))
1412
- nn_err (nn , "Config mc address to HW failed.\n" );
1413
-
1414
- list_del (& entry -> list );
1415
- kfree (entry );
1416
- }
1417
+ return nfp_net_sched_mbox_amsg_work (nn , NFP_NET_CFG_MBOX_CMD_MULTICAST_DEL , addr ,
1418
+ NFP_NET_CFG_MULTICAST_SZ , nfp_net_mc_cfg );
1417
1419
}
1418
1420
1419
1421
static void nfp_net_set_rx_mode (struct net_device * netdev )
@@ -2681,9 +2683,9 @@ int nfp_net_init(struct nfp_net *nn)
2681
2683
if (!nn -> dp .netdev )
2682
2684
return 0 ;
2683
2685
2684
- spin_lock_init (& nn -> mc_lock );
2685
- INIT_LIST_HEAD (& nn -> mc_addrs );
2686
- INIT_WORK (& nn -> mc_work , nfp_net_mc_addr_config );
2686
+ spin_lock_init (& nn -> mbox_amsg . lock );
2687
+ INIT_LIST_HEAD (& nn -> mbox_amsg . list );
2688
+ INIT_WORK (& nn -> mbox_amsg . work , nfp_net_mbox_amsg_work );
2687
2689
2688
2690
return register_netdev (nn -> dp .netdev );
2689
2691
@@ -2704,6 +2706,6 @@ void nfp_net_clean(struct nfp_net *nn)
2704
2706
unregister_netdev (nn -> dp .netdev );
2705
2707
nfp_net_ipsec_clean (nn );
2706
2708
nfp_ccm_mbox_clean (nn );
2707
- flush_work (& nn -> mc_work );
2709
+ flush_work (& nn -> mbox_amsg . work );
2708
2710
nfp_net_reconfig_wait_posted (nn );
2709
2711
}
0 commit comments