Commit 1d4ddc4a authored by Shannon Nelson's avatar Shannon Nelson Committed by David S. Miller

ionic: move lif mac address functions

The routines that add and delete mac addresses from the
firmware really should be in the file with the rest of
the filter management.  This simply moves the functions
with no logic changes.
Signed-off-by: default avatarShannon Nelson <snelson@pensando.io>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c1634b11
...@@ -1242,137 +1242,6 @@ void ionic_get_stats64(struct net_device *netdev, ...@@ -1242,137 +1242,6 @@ void ionic_get_stats64(struct net_device *netdev,
ns->tx_errors = ns->tx_aborted_errors; ns->tx_errors = ns->tx_aborted_errors;
} }
int ionic_lif_addr_add(struct ionic_lif *lif, const u8 *addr)
{
struct ionic_admin_ctx ctx = {
.work = COMPLETION_INITIALIZER_ONSTACK(ctx.work),
.cmd.rx_filter_add = {
.opcode = IONIC_CMD_RX_FILTER_ADD,
.lif_index = cpu_to_le16(lif->index),
.match = cpu_to_le16(IONIC_RX_FILTER_MATCH_MAC),
},
};
int nfilters = le32_to_cpu(lif->identity->eth.max_ucast_filters);
bool mc = is_multicast_ether_addr(addr);
struct ionic_rx_filter *f;
int err = 0;
memcpy(ctx.cmd.rx_filter_add.mac.addr, addr, ETH_ALEN);
spin_lock_bh(&lif->rx_filters.lock);
f = ionic_rx_filter_by_addr(lif, addr);
if (f) {
/* don't bother if we already have it and it is sync'd */
if (f->state == IONIC_FILTER_STATE_SYNCED) {
spin_unlock_bh(&lif->rx_filters.lock);
return 0;
}
/* mark preemptively as sync'd to block any parallel attempts */
f->state = IONIC_FILTER_STATE_SYNCED;
} else {
/* save as SYNCED to catch any DEL requests while processing */
err = ionic_rx_filter_save(lif, 0, IONIC_RXQ_INDEX_ANY, 0, &ctx,
IONIC_FILTER_STATE_SYNCED);
}
spin_unlock_bh(&lif->rx_filters.lock);
if (err)
return err;
netdev_dbg(lif->netdev, "rx_filter add ADDR %pM\n", addr);
/* Don't bother with the write to FW if we know there's no room,
* we can try again on the next sync attempt.
*/
if ((lif->nucast + lif->nmcast) >= nfilters)
err = -ENOSPC;
else
err = ionic_adminq_post_wait(lif, &ctx);
spin_lock_bh(&lif->rx_filters.lock);
if (err && err != -EEXIST) {
/* set the state back to NEW so we can try again later */
f = ionic_rx_filter_by_addr(lif, addr);
if (f && f->state == IONIC_FILTER_STATE_SYNCED) {
f->state = IONIC_FILTER_STATE_NEW;
set_bit(IONIC_LIF_F_FILTER_SYNC_NEEDED, lif->state);
}
spin_unlock_bh(&lif->rx_filters.lock);
if (err == -ENOSPC)
return 0;
else
return err;
}
if (mc)
lif->nmcast++;
else
lif->nucast++;
f = ionic_rx_filter_by_addr(lif, addr);
if (f && f->state == IONIC_FILTER_STATE_OLD) {
/* Someone requested a delete while we were adding
* so update the filter info with the results from the add
* and the data will be there for the delete on the next
* sync cycle.
*/
err = ionic_rx_filter_save(lif, 0, IONIC_RXQ_INDEX_ANY, 0, &ctx,
IONIC_FILTER_STATE_OLD);
} else {
err = ionic_rx_filter_save(lif, 0, IONIC_RXQ_INDEX_ANY, 0, &ctx,
IONIC_FILTER_STATE_SYNCED);
}
spin_unlock_bh(&lif->rx_filters.lock);
return err;
}
int ionic_lif_addr_del(struct ionic_lif *lif, const u8 *addr)
{
struct ionic_admin_ctx ctx = {
.work = COMPLETION_INITIALIZER_ONSTACK(ctx.work),
.cmd.rx_filter_del = {
.opcode = IONIC_CMD_RX_FILTER_DEL,
.lif_index = cpu_to_le16(lif->index),
},
};
struct ionic_rx_filter *f;
int state;
int err;
spin_lock_bh(&lif->rx_filters.lock);
f = ionic_rx_filter_by_addr(lif, addr);
if (!f) {
spin_unlock_bh(&lif->rx_filters.lock);
return -ENOENT;
}
netdev_dbg(lif->netdev, "rx_filter del ADDR %pM (id %d)\n",
addr, f->filter_id);
state = f->state;
ctx.cmd.rx_filter_del.filter_id = cpu_to_le32(f->filter_id);
ionic_rx_filter_free(lif, f);
if (is_multicast_ether_addr(addr) && lif->nmcast)
lif->nmcast--;
else if (!is_multicast_ether_addr(addr) && lif->nucast)
lif->nucast--;
spin_unlock_bh(&lif->rx_filters.lock);
if (state != IONIC_FILTER_STATE_NEW) {
err = ionic_adminq_post_wait(lif, &ctx);
if (err && err != -EEXIST)
return err;
}
return 0;
}
static int ionic_addr_add(struct net_device *netdev, const u8 *addr) static int ionic_addr_add(struct net_device *netdev, const u8 *addr)
{ {
return ionic_lif_list_addr(netdev_priv(netdev), addr, ADD_ADDR); return ionic_lif_list_addr(netdev_priv(netdev), addr, ADD_ADDR);
......
...@@ -286,6 +286,137 @@ int ionic_lif_list_addr(struct ionic_lif *lif, const u8 *addr, bool mode) ...@@ -286,6 +286,137 @@ int ionic_lif_list_addr(struct ionic_lif *lif, const u8 *addr, bool mode)
return 0; return 0;
} }
int ionic_lif_addr_add(struct ionic_lif *lif, const u8 *addr)
{
struct ionic_admin_ctx ctx = {
.work = COMPLETION_INITIALIZER_ONSTACK(ctx.work),
.cmd.rx_filter_add = {
.opcode = IONIC_CMD_RX_FILTER_ADD,
.lif_index = cpu_to_le16(lif->index),
.match = cpu_to_le16(IONIC_RX_FILTER_MATCH_MAC),
},
};
int nfilters = le32_to_cpu(lif->identity->eth.max_ucast_filters);
bool mc = is_multicast_ether_addr(addr);
struct ionic_rx_filter *f;
int err = 0;
memcpy(ctx.cmd.rx_filter_add.mac.addr, addr, ETH_ALEN);
spin_lock_bh(&lif->rx_filters.lock);
f = ionic_rx_filter_by_addr(lif, addr);
if (f) {
/* don't bother if we already have it and it is sync'd */
if (f->state == IONIC_FILTER_STATE_SYNCED) {
spin_unlock_bh(&lif->rx_filters.lock);
return 0;
}
/* mark preemptively as sync'd to block any parallel attempts */
f->state = IONIC_FILTER_STATE_SYNCED;
} else {
/* save as SYNCED to catch any DEL requests while processing */
err = ionic_rx_filter_save(lif, 0, IONIC_RXQ_INDEX_ANY, 0, &ctx,
IONIC_FILTER_STATE_SYNCED);
}
spin_unlock_bh(&lif->rx_filters.lock);
if (err)
return err;
netdev_dbg(lif->netdev, "rx_filter add ADDR %pM\n", addr);
/* Don't bother with the write to FW if we know there's no room,
* we can try again on the next sync attempt.
*/
if ((lif->nucast + lif->nmcast) >= nfilters)
err = -ENOSPC;
else
err = ionic_adminq_post_wait(lif, &ctx);
spin_lock_bh(&lif->rx_filters.lock);
if (err && err != -EEXIST) {
/* set the state back to NEW so we can try again later */
f = ionic_rx_filter_by_addr(lif, addr);
if (f && f->state == IONIC_FILTER_STATE_SYNCED) {
f->state = IONIC_FILTER_STATE_NEW;
set_bit(IONIC_LIF_F_FILTER_SYNC_NEEDED, lif->state);
}
spin_unlock_bh(&lif->rx_filters.lock);
if (err == -ENOSPC)
return 0;
else
return err;
}
if (mc)
lif->nmcast++;
else
lif->nucast++;
f = ionic_rx_filter_by_addr(lif, addr);
if (f && f->state == IONIC_FILTER_STATE_OLD) {
/* Someone requested a delete while we were adding
* so update the filter info with the results from the add
* and the data will be there for the delete on the next
* sync cycle.
*/
err = ionic_rx_filter_save(lif, 0, IONIC_RXQ_INDEX_ANY, 0, &ctx,
IONIC_FILTER_STATE_OLD);
} else {
err = ionic_rx_filter_save(lif, 0, IONIC_RXQ_INDEX_ANY, 0, &ctx,
IONIC_FILTER_STATE_SYNCED);
}
spin_unlock_bh(&lif->rx_filters.lock);
return err;
}
int ionic_lif_addr_del(struct ionic_lif *lif, const u8 *addr)
{
struct ionic_admin_ctx ctx = {
.work = COMPLETION_INITIALIZER_ONSTACK(ctx.work),
.cmd.rx_filter_del = {
.opcode = IONIC_CMD_RX_FILTER_DEL,
.lif_index = cpu_to_le16(lif->index),
},
};
struct ionic_rx_filter *f;
int state;
int err;
spin_lock_bh(&lif->rx_filters.lock);
f = ionic_rx_filter_by_addr(lif, addr);
if (!f) {
spin_unlock_bh(&lif->rx_filters.lock);
return -ENOENT;
}
netdev_dbg(lif->netdev, "rx_filter del ADDR %pM (id %d)\n",
addr, f->filter_id);
state = f->state;
ctx.cmd.rx_filter_del.filter_id = cpu_to_le32(f->filter_id);
ionic_rx_filter_free(lif, f);
if (is_multicast_ether_addr(addr) && lif->nmcast)
lif->nmcast--;
else if (!is_multicast_ether_addr(addr) && lif->nucast)
lif->nucast--;
spin_unlock_bh(&lif->rx_filters.lock);
if (state != IONIC_FILTER_STATE_NEW) {
err = ionic_adminq_post_wait(lif, &ctx);
if (err && err != -EEXIST)
return err;
}
return 0;
}
struct sync_item { struct sync_item {
struct list_head list; struct list_head list;
struct ionic_rx_filter f; struct ionic_rx_filter f;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment