@@ -30,9 +30,6 @@ static const u8 ionic_qtype_versions[IONIC_QTYPE_MAX] = {
30
30
*/
31
31
};
32
32
33
- static void ionic_lif_rx_mode (struct ionic_lif * lif );
34
- static int ionic_lif_addr_add (struct ionic_lif * lif , const u8 * addr );
35
- static int ionic_lif_addr_del (struct ionic_lif * lif , const u8 * addr );
36
33
static void ionic_link_status_check (struct ionic_lif * lif );
37
34
static void ionic_lif_handle_fw_down (struct ionic_lif * lif );
38
35
static void ionic_lif_handle_fw_up (struct ionic_lif * lif );
@@ -92,12 +89,6 @@ static void ionic_lif_deferred_work(struct work_struct *work)
92
89
case IONIC_DW_TYPE_RX_MODE :
93
90
ionic_lif_rx_mode (lif );
94
91
break ;
95
- case IONIC_DW_TYPE_RX_ADDR_ADD :
96
- ionic_lif_addr_add (lif , w -> addr );
97
- break ;
98
- case IONIC_DW_TYPE_RX_ADDR_DEL :
99
- ionic_lif_addr_del (lif , w -> addr );
100
- break ;
101
92
case IONIC_DW_TYPE_LINK_STATUS :
102
93
ionic_link_status_check (lif );
103
94
break ;
@@ -1078,7 +1069,11 @@ static int ionic_lif_add_hwstamp_rxfilt(struct ionic_lif *lif, u64 pkt_class)
1078
1069
if (err && err != - EEXIST )
1079
1070
return err ;
1080
1071
1081
- return ionic_rx_filter_save (lif , 0 , qid , 0 , & ctx );
1072
+ spin_lock_bh (& lif -> rx_filters .lock );
1073
+ err = ionic_rx_filter_save (lif , 0 , qid , 0 , & ctx , IONIC_FILTER_STATE_SYNCED );
1074
+ spin_unlock_bh (& lif -> rx_filters .lock );
1075
+
1076
+ return err ;
1082
1077
}
1083
1078
1084
1079
int ionic_lif_set_hwstamp_rxfilt (struct ionic_lif * lif , u64 pkt_class )
@@ -1251,7 +1246,7 @@ void ionic_get_stats64(struct net_device *netdev,
1251
1246
ns -> tx_errors = ns -> tx_aborted_errors ;
1252
1247
}
1253
1248
1254
- static int ionic_lif_addr_add (struct ionic_lif * lif , const u8 * addr )
1249
+ int ionic_lif_addr_add (struct ionic_lif * lif , const u8 * addr )
1255
1250
{
1256
1251
struct ionic_admin_ctx ctx = {
1257
1252
.work = COMPLETION_INITIALIZER_ONSTACK (ctx .work ),
@@ -1261,27 +1256,82 @@ static int ionic_lif_addr_add(struct ionic_lif *lif, const u8 *addr)
1261
1256
.match = cpu_to_le16 (IONIC_RX_FILTER_MATCH_MAC ),
1262
1257
},
1263
1258
};
1259
+ int nfilters = le32_to_cpu (lif -> identity -> eth .max_ucast_filters );
1260
+ bool mc = is_multicast_ether_addr (addr );
1264
1261
struct ionic_rx_filter * f ;
1265
- int err ;
1262
+ int err = 0 ;
1266
1263
1267
- /* don't bother if we already have it */
1268
1264
spin_lock_bh (& lif -> rx_filters .lock );
1269
1265
f = ionic_rx_filter_by_addr (lif , addr );
1266
+ if (f ) {
1267
+ /* don't bother if we already have it and it is sync'd */
1268
+ if (f -> state == IONIC_FILTER_STATE_SYNCED ) {
1269
+ spin_unlock_bh (& lif -> rx_filters .lock );
1270
+ return 0 ;
1271
+ }
1272
+
1273
+ /* mark preemptively as sync'd to block any parallel attempts */
1274
+ f -> state = IONIC_FILTER_STATE_SYNCED ;
1275
+ } else {
1276
+ /* save as SYNCED to catch any DEL requests while processing */
1277
+ memcpy (ctx .cmd .rx_filter_add .mac .addr , addr , ETH_ALEN );
1278
+ err = ionic_rx_filter_save (lif , 0 , IONIC_RXQ_INDEX_ANY , 0 , & ctx ,
1279
+ IONIC_FILTER_STATE_SYNCED );
1280
+ }
1270
1281
spin_unlock_bh (& lif -> rx_filters .lock );
1271
- if (f )
1272
- return 0 ;
1282
+ if (err )
1283
+ return err ;
1273
1284
1274
1285
netdev_dbg (lif -> netdev , "rx_filter add ADDR %pM\n" , addr );
1275
1286
1276
- memcpy (ctx .cmd .rx_filter_add .mac .addr , addr , ETH_ALEN );
1277
- err = ionic_adminq_post_wait (lif , & ctx );
1278
- if (err && err != - EEXIST )
1279
- return err ;
1287
+ /* Don't bother with the write to FW if we know there's no room,
1288
+ * we can try again on the next sync attempt.
1289
+ */
1290
+ if ((lif -> nucast + lif -> nmcast ) >= nfilters )
1291
+ err = - ENOSPC ;
1292
+ else
1293
+ err = ionic_adminq_post_wait (lif , & ctx );
1280
1294
1281
- return ionic_rx_filter_save (lif , 0 , IONIC_RXQ_INDEX_ANY , 0 , & ctx );
1295
+ spin_lock_bh (& lif -> rx_filters .lock );
1296
+ if (err && err != - EEXIST ) {
1297
+ /* set the state back to NEW so we can try again later */
1298
+ f = ionic_rx_filter_by_addr (lif , addr );
1299
+ if (f && f -> state == IONIC_FILTER_STATE_SYNCED )
1300
+ f -> state = IONIC_FILTER_STATE_NEW ;
1301
+
1302
+ spin_unlock_bh (& lif -> rx_filters .lock );
1303
+
1304
+ if (err == - ENOSPC )
1305
+ return 0 ;
1306
+ else
1307
+ return err ;
1308
+ }
1309
+
1310
+ if (mc )
1311
+ lif -> nmcast ++ ;
1312
+ else
1313
+ lif -> nucast ++ ;
1314
+
1315
+ f = ionic_rx_filter_by_addr (lif , addr );
1316
+ if (f && f -> state == IONIC_FILTER_STATE_OLD ) {
1317
+ /* Someone requested a delete while we were adding
1318
+ * so update the filter info with the results from the add
1319
+ * and the data will be there for the delete on the next
1320
+ * sync cycle.
1321
+ */
1322
+ err = ionic_rx_filter_save (lif , 0 , IONIC_RXQ_INDEX_ANY , 0 , & ctx ,
1323
+ IONIC_FILTER_STATE_OLD );
1324
+ } else {
1325
+ err = ionic_rx_filter_save (lif , 0 , IONIC_RXQ_INDEX_ANY , 0 , & ctx ,
1326
+ IONIC_FILTER_STATE_SYNCED );
1327
+ }
1328
+
1329
+ spin_unlock_bh (& lif -> rx_filters .lock );
1330
+
1331
+ return err ;
1282
1332
}
1283
1333
1284
- static int ionic_lif_addr_del (struct ionic_lif * lif , const u8 * addr )
1334
+ int ionic_lif_addr_del (struct ionic_lif * lif , const u8 * addr )
1285
1335
{
1286
1336
struct ionic_admin_ctx ctx = {
1287
1337
.work = COMPLETION_INITIALIZER_ONSTACK (ctx .work ),
@@ -1291,6 +1341,7 @@ static int ionic_lif_addr_del(struct ionic_lif *lif, const u8 *addr)
1291
1341
},
1292
1342
};
1293
1343
struct ionic_rx_filter * f ;
1344
+ int state ;
1294
1345
int err ;
1295
1346
1296
1347
spin_lock_bh (& lif -> rx_filters .lock );
@@ -1303,65 +1354,37 @@ static int ionic_lif_addr_del(struct ionic_lif *lif, const u8 *addr)
1303
1354
netdev_dbg (lif -> netdev , "rx_filter del ADDR %pM (id %d)\n" ,
1304
1355
addr , f -> filter_id );
1305
1356
1357
+ state = f -> state ;
1306
1358
ctx .cmd .rx_filter_del .filter_id = cpu_to_le32 (f -> filter_id );
1307
1359
ionic_rx_filter_free (lif , f );
1308
- spin_unlock_bh (& lif -> rx_filters .lock );
1309
1360
1310
- err = ionic_adminq_post_wait (lif , & ctx );
1311
- if (err && err != - EEXIST )
1312
- return err ;
1361
+ if (is_multicast_ether_addr (addr ) && lif -> nmcast )
1362
+ lif -> nmcast -- ;
1363
+ else if (!is_multicast_ether_addr (addr ) && lif -> nucast )
1364
+ lif -> nucast -- ;
1313
1365
1314
- return 0 ;
1315
- }
1316
-
1317
- static int ionic_lif_addr (struct ionic_lif * lif , const u8 * addr , bool add )
1318
- {
1319
- unsigned int nmfilters ;
1320
- unsigned int nufilters ;
1366
+ spin_unlock_bh (& lif -> rx_filters .lock );
1321
1367
1322
- if (add ) {
1323
- /* Do we have space for this filter? We test the counters
1324
- * here before checking the need for deferral so that we
1325
- * can return an overflow error to the stack.
1326
- */
1327
- nmfilters = le32_to_cpu (lif -> identity -> eth .max_mcast_filters );
1328
- nufilters = le32_to_cpu (lif -> identity -> eth .max_ucast_filters );
1329
-
1330
- if ((is_multicast_ether_addr (addr ) && lif -> nmcast < nmfilters ))
1331
- lif -> nmcast ++ ;
1332
- else if (!is_multicast_ether_addr (addr ) &&
1333
- lif -> nucast < nufilters )
1334
- lif -> nucast ++ ;
1335
- else
1336
- return - ENOSPC ;
1337
- } else {
1338
- if (is_multicast_ether_addr (addr ) && lif -> nmcast )
1339
- lif -> nmcast -- ;
1340
- else if (!is_multicast_ether_addr (addr ) && lif -> nucast )
1341
- lif -> nucast -- ;
1368
+ if (state != IONIC_FILTER_STATE_NEW ) {
1369
+ err = ionic_adminq_post_wait (lif , & ctx );
1370
+ if (err && err != - EEXIST )
1371
+ return err ;
1342
1372
}
1343
1373
1344
- netdev_dbg (lif -> netdev , "rx_filter %s %pM\n" ,
1345
- add ? "add" : "del" , addr );
1346
- if (add )
1347
- return ionic_lif_addr_add (lif , addr );
1348
- else
1349
- return ionic_lif_addr_del (lif , addr );
1350
-
1351
1374
return 0 ;
1352
1375
}
1353
1376
1354
1377
static int ionic_addr_add (struct net_device * netdev , const u8 * addr )
1355
1378
{
1356
- return ionic_lif_addr (netdev_priv (netdev ), addr , ADD_ADDR );
1379
+ return ionic_lif_list_addr (netdev_priv (netdev ), addr , ADD_ADDR );
1357
1380
}
1358
1381
1359
1382
static int ionic_addr_del (struct net_device * netdev , const u8 * addr )
1360
1383
{
1361
- return ionic_lif_addr (netdev_priv (netdev ), addr , DEL_ADDR );
1384
+ return ionic_lif_list_addr (netdev_priv (netdev ), addr , DEL_ADDR );
1362
1385
}
1363
1386
1364
- static void ionic_lif_rx_mode (struct ionic_lif * lif )
1387
+ void ionic_lif_rx_mode (struct ionic_lif * lif )
1365
1388
{
1366
1389
struct net_device * netdev = lif -> netdev ;
1367
1390
unsigned int nfilters ;
@@ -1382,32 +1405,26 @@ static void ionic_lif_rx_mode(struct ionic_lif *lif)
1382
1405
rx_mode |= (nd_flags & IFF_PROMISC ) ? IONIC_RX_MODE_F_PROMISC : 0 ;
1383
1406
rx_mode |= (nd_flags & IFF_ALLMULTI ) ? IONIC_RX_MODE_F_ALLMULTI : 0 ;
1384
1407
1385
- /* sync unicast addresses
1386
- * next check to see if we're in an overflow state
1408
+ /* sync the mac filters */
1409
+ ionic_rx_filter_sync (lif );
1410
+
1411
+ /* check for overflow state
1387
1412
* if so, we track that we overflowed and enable NIC PROMISC
1388
1413
* else if the overflow is set and not needed
1389
1414
* we remove our overflow flag and check the netdev flags
1390
1415
* to see if we can disable NIC PROMISC
1391
1416
*/
1392
- __dev_uc_sync (netdev , ionic_addr_add , ionic_addr_del );
1393
1417
nfilters = le32_to_cpu (lif -> identity -> eth .max_ucast_filters );
1394
- if (netdev_uc_count ( netdev ) + 1 > nfilters ) {
1418
+ if (( lif -> nucast + lif -> nmcast ) >= nfilters ) {
1395
1419
rx_mode |= IONIC_RX_MODE_F_PROMISC ;
1420
+ rx_mode |= IONIC_RX_MODE_F_ALLMULTI ;
1396
1421
lif -> uc_overflow = true;
1422
+ lif -> mc_overflow = true;
1397
1423
} else if (lif -> uc_overflow ) {
1398
1424
lif -> uc_overflow = false;
1425
+ lif -> mc_overflow = false;
1399
1426
if (!(nd_flags & IFF_PROMISC ))
1400
1427
rx_mode &= ~IONIC_RX_MODE_F_PROMISC ;
1401
- }
1402
-
1403
- /* same for multicast */
1404
- __dev_mc_sync (netdev , ionic_addr_add , ionic_addr_del );
1405
- nfilters = le32_to_cpu (lif -> identity -> eth .max_mcast_filters );
1406
- if (netdev_mc_count (netdev ) > nfilters ) {
1407
- rx_mode |= IONIC_RX_MODE_F_ALLMULTI ;
1408
- lif -> mc_overflow = true;
1409
- } else if (lif -> mc_overflow ) {
1410
- lif -> mc_overflow = false;
1411
1428
if (!(nd_flags & IFF_ALLMULTI ))
1412
1429
rx_mode &= ~IONIC_RX_MODE_F_ALLMULTI ;
1413
1430
}
@@ -1450,28 +1467,26 @@ static void ionic_lif_rx_mode(struct ionic_lif *lif)
1450
1467
mutex_unlock (& lif -> config_lock );
1451
1468
}
1452
1469
1453
- static void ionic_set_rx_mode (struct net_device * netdev , bool can_sleep )
1470
+ static void ionic_ndo_set_rx_mode (struct net_device * netdev )
1454
1471
{
1455
1472
struct ionic_lif * lif = netdev_priv (netdev );
1456
1473
struct ionic_deferred_work * work ;
1457
1474
1458
- if (!can_sleep ) {
1459
- work = kzalloc (sizeof (* work ), GFP_ATOMIC );
1460
- if (!work ) {
1461
- netdev_err (lif -> netdev , "rxmode change dropped\n" );
1462
- return ;
1463
- }
1464
- work -> type = IONIC_DW_TYPE_RX_MODE ;
1465
- netdev_dbg (lif -> netdev , "deferred: rx_mode\n" );
1466
- ionic_lif_deferred_enqueue (& lif -> deferred , work );
1467
- } else {
1468
- ionic_lif_rx_mode (lif );
1469
- }
1470
- }
1475
+ /* Sync the kernel filter list with the driver filter list */
1476
+ __dev_uc_sync (netdev , ionic_addr_add , ionic_addr_del );
1477
+ __dev_mc_sync (netdev , ionic_addr_add , ionic_addr_del );
1471
1478
1472
- static void ionic_ndo_set_rx_mode (struct net_device * netdev )
1473
- {
1474
- ionic_set_rx_mode (netdev , CAN_NOT_SLEEP );
1479
+ /* Shove off the rest of the rxmode work to the work task
1480
+ * which will include syncing the filters to the firmware.
1481
+ */
1482
+ work = kzalloc (sizeof (* work ), GFP_ATOMIC );
1483
+ if (!work ) {
1484
+ netdev_err (lif -> netdev , "rxmode change dropped\n" );
1485
+ return ;
1486
+ }
1487
+ work -> type = IONIC_DW_TYPE_RX_MODE ;
1488
+ netdev_dbg (lif -> netdev , "deferred: rx_mode\n" );
1489
+ ionic_lif_deferred_enqueue (& lif -> deferred , work );
1475
1490
}
1476
1491
1477
1492
static __le64 ionic_netdev_features_to_nic (netdev_features_t features )
@@ -1692,13 +1707,13 @@ static int ionic_set_mac_address(struct net_device *netdev, void *sa)
1692
1707
if (!is_zero_ether_addr (netdev -> dev_addr )) {
1693
1708
netdev_info (netdev , "deleting mac addr %pM\n" ,
1694
1709
netdev -> dev_addr );
1695
- ionic_addr_del ( netdev , netdev -> dev_addr );
1710
+ ionic_lif_addr_del ( netdev_priv ( netdev ) , netdev -> dev_addr );
1696
1711
}
1697
1712
1698
1713
eth_commit_mac_addr_change (netdev , addr );
1699
1714
netdev_info (netdev , "updating mac addr %pM\n" , mac );
1700
1715
1701
- return ionic_addr_add ( netdev , mac );
1716
+ return ionic_lif_addr_add ( netdev_priv ( netdev ) , mac );
1702
1717
}
1703
1718
1704
1719
static void ionic_stop_queues_reconfig (struct ionic_lif * lif )
@@ -1804,7 +1819,12 @@ static int ionic_vlan_rx_add_vid(struct net_device *netdev, __be16 proto,
1804
1819
if (err )
1805
1820
return err ;
1806
1821
1807
- return ionic_rx_filter_save (lif , 0 , IONIC_RXQ_INDEX_ANY , 0 , & ctx );
1822
+ spin_lock_bh (& lif -> rx_filters .lock );
1823
+ err = ionic_rx_filter_save (lif , 0 , IONIC_RXQ_INDEX_ANY , 0 , & ctx ,
1824
+ IONIC_FILTER_STATE_SYNCED );
1825
+ spin_unlock_bh (& lif -> rx_filters .lock );
1826
+
1827
+ return err ;
1808
1828
}
1809
1829
1810
1830
static int ionic_vlan_rx_kill_vid (struct net_device * netdev , __be16 proto ,
@@ -2107,7 +2127,7 @@ static int ionic_txrx_init(struct ionic_lif *lif)
2107
2127
if (lif -> netdev -> features & NETIF_F_RXHASH )
2108
2128
ionic_lif_rss_init (lif );
2109
2129
2110
- ionic_set_rx_mode (lif -> netdev , CAN_SLEEP );
2130
+ ionic_lif_rx_mode (lif );
2111
2131
2112
2132
return 0 ;
2113
2133
@@ -3195,7 +3215,7 @@ static int ionic_station_set(struct ionic_lif *lif)
3195
3215
*/
3196
3216
if (!ether_addr_equal (ctx .comp .lif_getattr .mac ,
3197
3217
netdev -> dev_addr ))
3198
- ionic_lif_addr (lif , netdev -> dev_addr , ADD_ADDR );
3218
+ ionic_lif_addr_add (lif , netdev -> dev_addr );
3199
3219
} else {
3200
3220
/* Update the netdev mac with the device's mac */
3201
3221
memcpy (addr .sa_data , ctx .comp .lif_getattr .mac , netdev -> addr_len );
@@ -3212,7 +3232,7 @@ static int ionic_station_set(struct ionic_lif *lif)
3212
3232
3213
3233
netdev_dbg (lif -> netdev , "adding station MAC addr %pM\n" ,
3214
3234
netdev -> dev_addr );
3215
- ionic_lif_addr (lif , netdev -> dev_addr , ADD_ADDR );
3235
+ ionic_lif_addr_add (lif , netdev -> dev_addr );
3216
3236
3217
3237
return 0 ;
3218
3238
}
0 commit comments