@@ -1334,14 +1334,54 @@ int nfp_ctrl_open(struct nfp_net *nn)
13341334 return err ;
13351335}
13361336
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+ }
13421381
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 )
13441383{
1384+ unsigned char * addr = entry -> msg ;
13451385 int ret ;
13461386
13471387 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
13531393 nn_writew (nn , nn -> tlv_caps .mbox_off + NFP_NET_CFG_MULTICAST_MAC_LO ,
13541394 get_unaligned_be16 (addr + 4 ));
13551395
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 );
13761397}
13771398
13781399static 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)
13851406 return - EINVAL ;
13861407 }
13871408
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 );
13891411}
13901412
13911413static int nfp_net_mc_unsync (struct net_device * netdev , const unsigned char * addr )
13921414{
13931415 struct nfp_net * nn = netdev_priv (netdev );
13941416
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 );
14171419}
14181420
14191421static void nfp_net_set_rx_mode (struct net_device * netdev )
@@ -2681,9 +2683,9 @@ int nfp_net_init(struct nfp_net *nn)
26812683 if (!nn -> dp .netdev )
26822684 return 0 ;
26832685
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 );
26872689
26882690 return register_netdev (nn -> dp .netdev );
26892691
@@ -2704,6 +2706,6 @@ void nfp_net_clean(struct nfp_net *nn)
27042706 unregister_netdev (nn -> dp .netdev );
27052707 nfp_net_ipsec_clean (nn );
27062708 nfp_ccm_mbox_clean (nn );
2707- flush_work (& nn -> mc_work );
2709+ flush_work (& nn -> mbox_amsg . work );
27082710 nfp_net_reconfig_wait_posted (nn );
27092711}
0 commit comments