Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'ionic-next'

Shannon Nelson says:

====================
ionic: queue and filter mgmt updates

After a pair of simple code cleanups, we change the mac filter
management to split the updates between the driver's filter
list and the device's filter list so that we can keep the calls
to dev_uc_sync() and dev_mc_sync() under the netif_addr_lock
in ndo_set_rx_mode, and then sync the driver's list to the
device later in the rx_mode work task.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+286 -112
+13
drivers/net/ethernet/pensando/ionic/ionic_dev.c
··· 15 15 { 16 16 struct ionic *ionic = from_timer(ionic, t, watchdog_timer); 17 17 struct ionic_lif *lif = ionic->lif; 18 + struct ionic_deferred_work *work; 18 19 int hb; 19 20 20 21 mod_timer(&ionic->watchdog_timer, ··· 32 31 if (hb >= 0 && 33 32 !test_bit(IONIC_LIF_F_FW_RESET, lif->state)) 34 33 ionic_link_status_check_request(lif, CAN_NOT_SLEEP); 34 + 35 + if (test_bit(IONIC_LIF_F_FILTER_SYNC_NEEDED, lif->state)) { 36 + work = kzalloc(sizeof(*work), GFP_ATOMIC); 37 + if (!work) { 38 + netdev_err(lif->netdev, "rxmode change dropped\n"); 39 + return; 40 + } 41 + 42 + work->type = IONIC_DW_TYPE_RX_MODE; 43 + netdev_dbg(lif->netdev, "deferred: rx_mode\n"); 44 + ionic_lif_deferred_enqueue(&lif->deferred, work); 45 + } 35 46 } 36 47 37 48 void ionic_init_devinfo(struct ionic *ionic)
+120 -100
drivers/net/ethernet/pensando/ionic/ionic_lif.c
··· 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); ··· 88 91 switch (w->type) { 89 92 case IONIC_DW_TYPE_RX_MODE: 90 93 ionic_lif_rx_mode(lif); 91 - break; 92 - case IONIC_DW_TYPE_RX_ADDR_ADD: 93 - ionic_lif_addr_add(lif, w->addr); 94 - break; 95 - case IONIC_DW_TYPE_RX_ADDR_DEL: 96 - ionic_lif_addr_del(lif, w->addr); 97 94 break; 98 95 case IONIC_DW_TYPE_LINK_STATUS: 99 96 ionic_link_status_check(lif); ··· 1069 1078 if (err && err != -EEXIST) 1070 1079 return err; 1071 1080 1072 - return ionic_rx_filter_save(lif, 0, qid, 0, &ctx); 1081 + spin_lock_bh(&lif->rx_filters.lock); 1082 + err = ionic_rx_filter_save(lif, 0, qid, 0, &ctx, IONIC_FILTER_STATE_SYNCED); 1083 + spin_unlock_bh(&lif->rx_filters.lock); 1084 + 1085 + return err; 1073 1086 } 1074 1087 1075 1088 int ionic_lif_set_hwstamp_rxfilt(struct ionic_lif *lif, u64 pkt_class) ··· 1246 1251 ns->tx_errors = ns->tx_aborted_errors; 1247 1252 } 1248 1253 1249 - static int ionic_lif_addr_add(struct ionic_lif *lif, const u8 *addr) 1254 + int ionic_lif_addr_add(struct ionic_lif *lif, const u8 *addr) 1250 1255 { 1251 1256 struct ionic_admin_ctx ctx = { 1252 1257 .work = COMPLETION_INITIALIZER_ONSTACK(ctx.work), ··· 1256 1261 .match = cpu_to_le16(IONIC_RX_FILTER_MATCH_MAC), 1257 1262 }, 1258 1263 }; 1264 + int nfilters = le32_to_cpu(lif->identity->eth.max_ucast_filters); 1265 + bool mc = is_multicast_ether_addr(addr); 1259 1266 struct ionic_rx_filter *f; 1260 - int err; 1267 + int err = 0; 1261 1268 1262 - /* don't bother if we already have it */ 1263 1269 spin_lock_bh(&lif->rx_filters.lock); 1264 1270 f = ionic_rx_filter_by_addr(lif, addr); 1271 + if (f) { 1272 + /* don't bother if we already have it and it is sync'd */ 1273 + if (f->state == IONIC_FILTER_STATE_SYNCED) { 1274 + spin_unlock_bh(&lif->rx_filters.lock); 1275 + return 0; 1276 + } 1277 + 1278 + /* mark preemptively as sync'd to block any parallel attempts */ 1279 + f->state = IONIC_FILTER_STATE_SYNCED; 1280 + } else { 1281 + /* save as SYNCED to catch any DEL requests while processing */ 1282 + memcpy(ctx.cmd.rx_filter_add.mac.addr, addr, ETH_ALEN); 1283 + err = ionic_rx_filter_save(lif, 0, IONIC_RXQ_INDEX_ANY, 0, &ctx, 1284 + IONIC_FILTER_STATE_SYNCED); 1285 + } 1265 1286 spin_unlock_bh(&lif->rx_filters.lock); 1266 - if (f) 1267 - return 0; 1287 + if (err) 1288 + return err; 1268 1289 1269 1290 netdev_dbg(lif->netdev, "rx_filter add ADDR %pM\n", addr); 1270 1291 1271 - memcpy(ctx.cmd.rx_filter_add.mac.addr, addr, ETH_ALEN); 1272 - err = ionic_adminq_post_wait(lif, &ctx); 1273 - if (err && err != -EEXIST) 1274 - return err; 1292 + /* Don't bother with the write to FW if we know there's no room, 1293 + * we can try again on the next sync attempt. 1294 + */ 1295 + if ((lif->nucast + lif->nmcast) >= nfilters) 1296 + err = -ENOSPC; 1297 + else 1298 + err = ionic_adminq_post_wait(lif, &ctx); 1275 1299 1276 - return ionic_rx_filter_save(lif, 0, IONIC_RXQ_INDEX_ANY, 0, &ctx); 1300 + spin_lock_bh(&lif->rx_filters.lock); 1301 + if (err && err != -EEXIST) { 1302 + /* set the state back to NEW so we can try again later */ 1303 + f = ionic_rx_filter_by_addr(lif, addr); 1304 + if (f && f->state == IONIC_FILTER_STATE_SYNCED) 1305 + f->state = IONIC_FILTER_STATE_NEW; 1306 + 1307 + spin_unlock_bh(&lif->rx_filters.lock); 1308 + 1309 + if (err == -ENOSPC) 1310 + return 0; 1311 + else 1312 + return err; 1313 + } 1314 + 1315 + if (mc) 1316 + lif->nmcast++; 1317 + else 1318 + lif->nucast++; 1319 + 1320 + f = ionic_rx_filter_by_addr(lif, addr); 1321 + if (f && f->state == IONIC_FILTER_STATE_OLD) { 1322 + /* Someone requested a delete while we were adding 1323 + * so update the filter info with the results from the add 1324 + * and the data will be there for the delete on the next 1325 + * sync cycle. 1326 + */ 1327 + err = ionic_rx_filter_save(lif, 0, IONIC_RXQ_INDEX_ANY, 0, &ctx, 1328 + IONIC_FILTER_STATE_OLD); 1329 + } else { 1330 + err = ionic_rx_filter_save(lif, 0, IONIC_RXQ_INDEX_ANY, 0, &ctx, 1331 + IONIC_FILTER_STATE_SYNCED); 1332 + } 1333 + 1334 + spin_unlock_bh(&lif->rx_filters.lock); 1335 + 1336 + return err; 1277 1337 } 1278 1338 1279 - static int ionic_lif_addr_del(struct ionic_lif *lif, const u8 *addr) 1339 + int ionic_lif_addr_del(struct ionic_lif *lif, const u8 *addr) 1280 1340 { 1281 1341 struct ionic_admin_ctx ctx = { 1282 1342 .work = COMPLETION_INITIALIZER_ONSTACK(ctx.work), ··· 1341 1291 }, 1342 1292 }; 1343 1293 struct ionic_rx_filter *f; 1294 + int state; 1344 1295 int err; 1345 1296 1346 1297 spin_lock_bh(&lif->rx_filters.lock); ··· 1354 1303 netdev_dbg(lif->netdev, "rx_filter del ADDR %pM (id %d)\n", 1355 1304 addr, f->filter_id); 1356 1305 1306 + state = f->state; 1357 1307 ctx.cmd.rx_filter_del.filter_id = cpu_to_le32(f->filter_id); 1358 1308 ionic_rx_filter_free(lif, f); 1309 + 1310 + if (is_multicast_ether_addr(addr) && lif->nmcast) 1311 + lif->nmcast--; 1312 + else if (!is_multicast_ether_addr(addr) && lif->nucast) 1313 + lif->nucast--; 1314 + 1359 1315 spin_unlock_bh(&lif->rx_filters.lock); 1360 1316 1361 - err = ionic_adminq_post_wait(lif, &ctx); 1362 - if (err && err != -EEXIST) 1363 - return err; 1364 - 1365 - return 0; 1366 - } 1367 - 1368 - static int ionic_lif_addr(struct ionic_lif *lif, const u8 *addr, bool add) 1369 - { 1370 - unsigned int nmfilters; 1371 - unsigned int nufilters; 1372 - 1373 - if (add) { 1374 - /* Do we have space for this filter? We test the counters 1375 - * here before checking the need for deferral so that we 1376 - * can return an overflow error to the stack. 1377 - */ 1378 - nmfilters = le32_to_cpu(lif->identity->eth.max_mcast_filters); 1379 - nufilters = le32_to_cpu(lif->identity->eth.max_ucast_filters); 1380 - 1381 - if ((is_multicast_ether_addr(addr) && lif->nmcast < nmfilters)) 1382 - lif->nmcast++; 1383 - else if (!is_multicast_ether_addr(addr) && 1384 - lif->nucast < nufilters) 1385 - lif->nucast++; 1386 - else 1387 - return -ENOSPC; 1388 - } else { 1389 - if (is_multicast_ether_addr(addr) && lif->nmcast) 1390 - lif->nmcast--; 1391 - else if (!is_multicast_ether_addr(addr) && lif->nucast) 1392 - lif->nucast--; 1317 + if (state != IONIC_FILTER_STATE_NEW) { 1318 + err = ionic_adminq_post_wait(lif, &ctx); 1319 + if (err && err != -EEXIST) 1320 + return err; 1393 1321 } 1394 - 1395 - netdev_dbg(lif->netdev, "rx_filter %s %pM\n", 1396 - add ? "add" : "del", addr); 1397 - if (add) 1398 - return ionic_lif_addr_add(lif, addr); 1399 - else 1400 - return ionic_lif_addr_del(lif, addr); 1401 1322 1402 1323 return 0; 1403 1324 } 1404 1325 1405 1326 static int ionic_addr_add(struct net_device *netdev, const u8 *addr) 1406 1327 { 1407 - return ionic_lif_addr(netdev_priv(netdev), addr, ADD_ADDR); 1328 + return ionic_lif_list_addr(netdev_priv(netdev), addr, ADD_ADDR); 1408 1329 } 1409 1330 1410 1331 static int ionic_addr_del(struct net_device *netdev, const u8 *addr) 1411 1332 { 1412 - return ionic_lif_addr(netdev_priv(netdev), addr, DEL_ADDR); 1333 + return ionic_lif_list_addr(netdev_priv(netdev), addr, DEL_ADDR); 1413 1334 } 1414 1335 1415 - static void ionic_lif_rx_mode(struct ionic_lif *lif) 1336 + void ionic_lif_rx_mode(struct ionic_lif *lif) 1416 1337 { 1417 1338 struct net_device *netdev = lif->netdev; 1418 1339 unsigned int nfilters; ··· 1405 1382 rx_mode |= (nd_flags & IFF_PROMISC) ? IONIC_RX_MODE_F_PROMISC : 0; 1406 1383 rx_mode |= (nd_flags & IFF_ALLMULTI) ? IONIC_RX_MODE_F_ALLMULTI : 0; 1407 1384 1408 - /* sync unicast addresses 1409 - * next check to see if we're in an overflow state 1385 + /* sync the mac filters */ 1386 + ionic_rx_filter_sync(lif); 1387 + 1388 + /* check for overflow state 1410 1389 * if so, we track that we overflowed and enable NIC PROMISC 1411 1390 * else if the overflow is set and not needed 1412 1391 * we remove our overflow flag and check the netdev flags 1413 1392 * to see if we can disable NIC PROMISC 1414 1393 */ 1415 - __dev_uc_sync(netdev, ionic_addr_add, ionic_addr_del); 1416 1394 nfilters = le32_to_cpu(lif->identity->eth.max_ucast_filters); 1417 - if (netdev_uc_count(netdev) + 1 > nfilters) { 1395 + if ((lif->nucast + lif->nmcast) >= nfilters) { 1418 1396 rx_mode |= IONIC_RX_MODE_F_PROMISC; 1397 + rx_mode |= IONIC_RX_MODE_F_ALLMULTI; 1419 1398 lif->uc_overflow = true; 1399 + lif->mc_overflow = true; 1420 1400 } else if (lif->uc_overflow) { 1421 1401 lif->uc_overflow = false; 1402 + lif->mc_overflow = false; 1422 1403 if (!(nd_flags & IFF_PROMISC)) 1423 1404 rx_mode &= ~IONIC_RX_MODE_F_PROMISC; 1424 - } 1425 - 1426 - /* same for multicast */ 1427 - __dev_mc_sync(netdev, ionic_addr_add, ionic_addr_del); 1428 - nfilters = le32_to_cpu(lif->identity->eth.max_mcast_filters); 1429 - if (netdev_mc_count(netdev) > nfilters) { 1430 - rx_mode |= IONIC_RX_MODE_F_ALLMULTI; 1431 - lif->mc_overflow = true; 1432 - } else if (lif->mc_overflow) { 1433 - lif->mc_overflow = false; 1434 1405 if (!(nd_flags & IFF_ALLMULTI)) 1435 1406 rx_mode &= ~IONIC_RX_MODE_F_ALLMULTI; 1436 1407 } ··· 1467 1450 mutex_unlock(&lif->config_lock); 1468 1451 } 1469 1452 1470 - static void ionic_set_rx_mode(struct net_device *netdev, bool can_sleep) 1453 + static void ionic_ndo_set_rx_mode(struct net_device *netdev) 1471 1454 { 1472 1455 struct ionic_lif *lif = netdev_priv(netdev); 1473 1456 struct ionic_deferred_work *work; 1474 1457 1475 - if (!can_sleep) { 1476 - work = kzalloc(sizeof(*work), GFP_ATOMIC); 1477 - if (!work) { 1478 - netdev_err(lif->netdev, "rxmode change dropped\n"); 1479 - return; 1480 - } 1481 - work->type = IONIC_DW_TYPE_RX_MODE; 1482 - netdev_dbg(lif->netdev, "deferred: rx_mode\n"); 1483 - ionic_lif_deferred_enqueue(&lif->deferred, work); 1484 - } else { 1485 - ionic_lif_rx_mode(lif); 1486 - } 1487 - } 1458 + /* Sync the kernel filter list with the driver filter list */ 1459 + __dev_uc_sync(netdev, ionic_addr_add, ionic_addr_del); 1460 + __dev_mc_sync(netdev, ionic_addr_add, ionic_addr_del); 1488 1461 1489 - static void ionic_ndo_set_rx_mode(struct net_device *netdev) 1490 - { 1491 - ionic_set_rx_mode(netdev, CAN_NOT_SLEEP); 1462 + /* Shove off the rest of the rxmode work to the work task 1463 + * which will include syncing the filters to the firmware. 1464 + */ 1465 + work = kzalloc(sizeof(*work), GFP_ATOMIC); 1466 + if (!work) { 1467 + netdev_err(lif->netdev, "rxmode change dropped\n"); 1468 + return; 1469 + } 1470 + work->type = IONIC_DW_TYPE_RX_MODE; 1471 + netdev_dbg(lif->netdev, "deferred: rx_mode\n"); 1472 + ionic_lif_deferred_enqueue(&lif->deferred, work); 1492 1473 } 1493 1474 1494 1475 static __le64 ionic_netdev_features_to_nic(netdev_features_t features) ··· 1707 1692 if (!is_zero_ether_addr(netdev->dev_addr)) { 1708 1693 netdev_info(netdev, "deleting mac addr %pM\n", 1709 1694 netdev->dev_addr); 1710 - ionic_addr_del(netdev, netdev->dev_addr); 1695 + ionic_lif_addr_del(netdev_priv(netdev), netdev->dev_addr); 1711 1696 } 1712 1697 1713 1698 eth_commit_mac_addr_change(netdev, addr); 1714 1699 netdev_info(netdev, "updating mac addr %pM\n", mac); 1715 1700 1716 - return ionic_addr_add(netdev, mac); 1701 + return ionic_lif_addr_add(netdev_priv(netdev), mac); 1717 1702 } 1718 1703 1719 1704 static void ionic_stop_queues_reconfig(struct ionic_lif *lif) ··· 1819 1804 if (err) 1820 1805 return err; 1821 1806 1822 - return ionic_rx_filter_save(lif, 0, IONIC_RXQ_INDEX_ANY, 0, &ctx); 1807 + spin_lock_bh(&lif->rx_filters.lock); 1808 + err = ionic_rx_filter_save(lif, 0, IONIC_RXQ_INDEX_ANY, 0, &ctx, 1809 + IONIC_FILTER_STATE_SYNCED); 1810 + spin_unlock_bh(&lif->rx_filters.lock); 1811 + 1812 + return err; 1823 1813 } 1824 1814 1825 1815 static int ionic_vlan_rx_kill_vid(struct net_device *netdev, __be16 proto, ··· 2127 2107 if (lif->netdev->features & NETIF_F_RXHASH) 2128 2108 ionic_lif_rss_init(lif); 2129 2109 2130 - ionic_set_rx_mode(lif->netdev, CAN_SLEEP); 2110 + ionic_lif_rx_mode(lif); 2131 2111 2132 2112 return 0; 2133 2113 ··· 3215 3195 */ 3216 3196 if (!ether_addr_equal(ctx.comp.lif_getattr.mac, 3217 3197 netdev->dev_addr)) 3218 - ionic_lif_addr(lif, netdev->dev_addr, ADD_ADDR); 3198 + ionic_lif_addr_add(lif, netdev->dev_addr); 3219 3199 } else { 3220 3200 /* Update the netdev mac with the device's mac */ 3221 3201 memcpy(addr.sa_data, ctx.comp.lif_getattr.mac, netdev->addr_len); ··· 3232 3212 3233 3213 netdev_dbg(lif->netdev, "adding station MAC addr %pM\n", 3234 3214 netdev->dev_addr); 3235 - ionic_lif_addr(lif, netdev->dev_addr, ADD_ADDR); 3215 + ionic_lif_addr_add(lif, netdev->dev_addr); 3236 3216 3237 3217 return 0; 3238 3218 }
+6 -2
drivers/net/ethernet/pensando/ionic/ionic_lif.h
··· 98 98 99 99 enum ionic_deferred_work_type { 100 100 IONIC_DW_TYPE_RX_MODE, 101 - IONIC_DW_TYPE_RX_ADDR_ADD, 102 - IONIC_DW_TYPE_RX_ADDR_DEL, 103 101 IONIC_DW_TYPE_LINK_STATUS, 104 102 IONIC_DW_TYPE_LIF_RESET, 105 103 }; ··· 145 147 IONIC_LIF_F_SW_DEBUG_STATS, 146 148 IONIC_LIF_F_UP, 147 149 IONIC_LIF_F_LINK_CHECK_REQUESTED, 150 + IONIC_LIF_F_FILTER_SYNC_NEEDED, 148 151 IONIC_LIF_F_FW_RESET, 149 152 IONIC_LIF_F_SPLIT_INTR, 150 153 IONIC_LIF_F_BROKEN, ··· 294 295 int ionic_lif_init(struct ionic_lif *lif); 295 296 void ionic_lif_free(struct ionic_lif *lif); 296 297 void ionic_lif_deinit(struct ionic_lif *lif); 298 + 299 + int ionic_lif_addr_add(struct ionic_lif *lif, const u8 *addr); 300 + int ionic_lif_addr_del(struct ionic_lif *lif, const u8 *addr); 301 + 297 302 int ionic_lif_register(struct ionic_lif *lif); 298 303 void ionic_lif_unregister(struct ionic_lif *lif); 299 304 int ionic_lif_identify(struct ionic *ionic, u8 lif_type, ··· 345 342 346 343 int ionic_lif_rss_config(struct ionic_lif *lif, u16 types, 347 344 const u8 *key, const u32 *indir); 345 + void ionic_lif_rx_mode(struct ionic_lif *lif); 348 346 int ionic_reconfigure_queues(struct ionic_lif *lif, 349 347 struct ionic_queue_params *qparam); 350 348
+134 -9
drivers/net/ethernet/pensando/ionic/ionic_rx_filter.c
··· 4 4 #include <linux/netdevice.h> 5 5 #include <linux/dynamic_debug.h> 6 6 #include <linux/etherdevice.h> 7 + #include <linux/list.h> 7 8 8 9 #include "ionic.h" 9 10 #include "ionic_lif.h" ··· 121 120 } 122 121 123 122 int ionic_rx_filter_save(struct ionic_lif *lif, u32 flow_id, u16 rxq_index, 124 - u32 hash, struct ionic_admin_ctx *ctx) 123 + u32 hash, struct ionic_admin_ctx *ctx, 124 + enum ionic_filter_state state) 125 125 { 126 126 struct device *dev = lif->ionic->dev; 127 127 struct ionic_rx_filter_add_cmd *ac; 128 - struct ionic_rx_filter *f; 128 + struct ionic_rx_filter *f = NULL; 129 129 struct hlist_head *head; 130 130 unsigned int key; 131 131 ··· 135 133 switch (le16_to_cpu(ac->match)) { 136 134 case IONIC_RX_FILTER_MATCH_VLAN: 137 135 key = le16_to_cpu(ac->vlan.vlan); 136 + f = ionic_rx_filter_by_vlan(lif, le16_to_cpu(ac->vlan.vlan)); 138 137 break; 139 138 case IONIC_RX_FILTER_MATCH_MAC: 140 139 key = *(u32 *)ac->mac.addr; 140 + f = ionic_rx_filter_by_addr(lif, ac->mac.addr); 141 141 break; 142 142 case IONIC_RX_FILTER_MATCH_MAC_VLAN: 143 143 key = le16_to_cpu(ac->mac_vlan.vlan); ··· 151 147 return -EINVAL; 152 148 } 153 149 154 - f = devm_kzalloc(dev, sizeof(*f), GFP_KERNEL); 155 - if (!f) 156 - return -ENOMEM; 150 + if (f) { 151 + /* remove from current linking so we can refresh it */ 152 + hlist_del(&f->by_id); 153 + hlist_del(&f->by_hash); 154 + } else { 155 + f = devm_kzalloc(dev, sizeof(*f), GFP_ATOMIC); 156 + if (!f) 157 + return -ENOMEM; 158 + } 157 159 158 160 f->flow_id = flow_id; 159 161 f->filter_id = le32_to_cpu(ctx->comp.rx_filter_add.filter_id); 162 + f->state = state; 160 163 f->rxq_index = rxq_index; 161 164 memcpy(&f->cmd, ac, sizeof(f->cmd)); 162 165 netdev_dbg(lif->netdev, "rx_filter add filter_id %d\n", f->filter_id); 163 166 164 167 INIT_HLIST_NODE(&f->by_hash); 165 168 INIT_HLIST_NODE(&f->by_id); 166 - 167 - spin_lock_bh(&lif->rx_filters.lock); 168 169 169 170 key = hash_32(key, IONIC_RX_FILTER_HASH_BITS); 170 171 head = &lif->rx_filters.by_hash[key]; ··· 178 169 key = f->filter_id & IONIC_RX_FILTER_HLISTS_MASK; 179 170 head = &lif->rx_filters.by_id[key]; 180 171 hlist_add_head(&f->by_id, head); 181 - 182 - spin_unlock_bh(&lif->rx_filters.lock); 183 172 184 173 return 0; 185 174 } ··· 237 230 } 238 231 239 232 return NULL; 233 + } 234 + 235 + int ionic_lif_list_addr(struct ionic_lif *lif, const u8 *addr, bool mode) 236 + { 237 + struct ionic_rx_filter *f; 238 + int err; 239 + 240 + spin_lock_bh(&lif->rx_filters.lock); 241 + 242 + f = ionic_rx_filter_by_addr(lif, addr); 243 + if (mode == ADD_ADDR && !f) { 244 + struct ionic_admin_ctx ctx = { 245 + .work = COMPLETION_INITIALIZER_ONSTACK(ctx.work), 246 + .cmd.rx_filter_add = { 247 + .opcode = IONIC_CMD_RX_FILTER_ADD, 248 + .lif_index = cpu_to_le16(lif->index), 249 + .match = cpu_to_le16(IONIC_RX_FILTER_MATCH_MAC), 250 + }, 251 + }; 252 + 253 + memcpy(ctx.cmd.rx_filter_add.mac.addr, addr, ETH_ALEN); 254 + err = ionic_rx_filter_save(lif, 0, IONIC_RXQ_INDEX_ANY, 0, &ctx, 255 + IONIC_FILTER_STATE_NEW); 256 + if (err) { 257 + spin_unlock_bh(&lif->rx_filters.lock); 258 + return err; 259 + } 260 + 261 + } else if (mode == ADD_ADDR && f) { 262 + if (f->state == IONIC_FILTER_STATE_OLD) 263 + f->state = IONIC_FILTER_STATE_SYNCED; 264 + 265 + } else if (mode == DEL_ADDR && f) { 266 + if (f->state == IONIC_FILTER_STATE_NEW) 267 + ionic_rx_filter_free(lif, f); 268 + else if (f->state == IONIC_FILTER_STATE_SYNCED) 269 + f->state = IONIC_FILTER_STATE_OLD; 270 + } else if (mode == DEL_ADDR && !f) { 271 + spin_unlock_bh(&lif->rx_filters.lock); 272 + return -ENOENT; 273 + } 274 + 275 + spin_unlock_bh(&lif->rx_filters.lock); 276 + 277 + set_bit(IONIC_LIF_F_FILTER_SYNC_NEEDED, lif->state); 278 + 279 + return 0; 280 + } 281 + 282 + struct sync_item { 283 + struct list_head list; 284 + struct ionic_rx_filter f; 285 + }; 286 + 287 + void ionic_rx_filter_sync(struct ionic_lif *lif) 288 + { 289 + struct device *dev = lif->ionic->dev; 290 + struct list_head sync_add_list; 291 + struct list_head sync_del_list; 292 + struct sync_item *sync_item; 293 + struct ionic_rx_filter *f; 294 + struct hlist_head *head; 295 + struct hlist_node *tmp; 296 + struct sync_item *spos; 297 + unsigned int i; 298 + 299 + INIT_LIST_HEAD(&sync_add_list); 300 + INIT_LIST_HEAD(&sync_del_list); 301 + 302 + clear_bit(IONIC_LIF_F_FILTER_SYNC_NEEDED, lif->state); 303 + 304 + /* Copy the filters to be added and deleted 305 + * into a separate local list that needs no locking. 306 + */ 307 + spin_lock_bh(&lif->rx_filters.lock); 308 + for (i = 0; i < IONIC_RX_FILTER_HLISTS; i++) { 309 + head = &lif->rx_filters.by_id[i]; 310 + hlist_for_each_entry_safe(f, tmp, head, by_id) { 311 + if (f->state == IONIC_FILTER_STATE_NEW || 312 + f->state == IONIC_FILTER_STATE_OLD) { 313 + sync_item = devm_kzalloc(dev, sizeof(*sync_item), 314 + GFP_KERNEL); 315 + if (!sync_item) 316 + goto loop_out; 317 + 318 + sync_item->f = *f; 319 + 320 + if (f->state == IONIC_FILTER_STATE_NEW) 321 + list_add(&sync_item->list, &sync_add_list); 322 + else 323 + list_add(&sync_item->list, &sync_del_list); 324 + } 325 + } 326 + } 327 + loop_out: 328 + spin_unlock_bh(&lif->rx_filters.lock); 329 + 330 + /* If the add or delete fails, it won't get marked as sync'd 331 + * and will be tried again in the next sync action. 332 + * Do the deletes first in case we're in an overflow state and 333 + * they can clear room for some new filters 334 + */ 335 + list_for_each_entry_safe(sync_item, spos, &sync_del_list, list) { 336 + (void)ionic_lif_addr_del(lif, sync_item->f.cmd.mac.addr); 337 + 338 + list_del(&sync_item->list); 339 + devm_kfree(dev, sync_item); 340 + } 341 + 342 + list_for_each_entry_safe(sync_item, spos, &sync_add_list, list) { 343 + (void)ionic_lif_addr_add(lif, sync_item->f.cmd.mac.addr); 344 + 345 + if (sync_item->f.state != IONIC_FILTER_STATE_SYNCED) 346 + set_bit(IONIC_LIF_F_FILTER_SYNC_NEEDED, lif->state); 347 + 348 + list_del(&sync_item->list); 349 + devm_kfree(dev, sync_item); 350 + } 240 351 }
+13 -1
drivers/net/ethernet/pensando/ionic/ionic_rx_filter.h
··· 5 5 #define _IONIC_RX_FILTER_H_ 6 6 7 7 #define IONIC_RXQ_INDEX_ANY (0xFFFF) 8 + 9 + enum ionic_filter_state { 10 + IONIC_FILTER_STATE_SYNCED, 11 + IONIC_FILTER_STATE_NEW, 12 + IONIC_FILTER_STATE_OLD, 13 + }; 14 + 8 15 struct ionic_rx_filter { 9 16 u32 flow_id; 10 17 u32 filter_id; 11 18 u16 rxq_index; 19 + enum ionic_filter_state state; 12 20 struct ionic_rx_filter_add_cmd cmd; 13 21 struct hlist_node by_hash; 14 22 struct hlist_node by_id; ··· 36 28 int ionic_rx_filters_init(struct ionic_lif *lif); 37 29 void ionic_rx_filters_deinit(struct ionic_lif *lif); 38 30 int ionic_rx_filter_save(struct ionic_lif *lif, u32 flow_id, u16 rxq_index, 39 - u32 hash, struct ionic_admin_ctx *ctx); 31 + u32 hash, struct ionic_admin_ctx *ctx, 32 + enum ionic_filter_state state); 40 33 struct ionic_rx_filter *ionic_rx_filter_by_vlan(struct ionic_lif *lif, u16 vid); 41 34 struct ionic_rx_filter *ionic_rx_filter_by_addr(struct ionic_lif *lif, const u8 *addr); 42 35 struct ionic_rx_filter *ionic_rx_filter_rxsteer(struct ionic_lif *lif); 36 + void ionic_rx_filter_sync(struct ionic_lif *lif); 37 + int ionic_lif_list_addr(struct ionic_lif *lif, const u8 *addr, bool mode); 38 + int ionic_rx_filters_need_sync(struct ionic_lif *lif); 43 39 44 40 #endif /* _IONIC_RX_FILTER_H_ */