diff options
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/flower/main.h | 7 | ||||
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/flower/match.c | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c | 159 |
3 files changed, 37 insertions, 132 deletions
diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.h b/drivers/net/ethernet/netronome/nfp/flower/main.h index 977667ae0b5a..1b9d6fd084d8 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/main.h +++ b/drivers/net/ethernet/netronome/nfp/flower/main.h @@ -58,29 +58,23 @@ struct nfp_fl_stats_id { /** * struct nfp_fl_tunnel_offloads - priv data for tunnel offloads - * @mac_off_list: List of MAC addresses to offload * @mac_index_list: List of unique 8-bit indexes for non NFP netdevs * @ipv4_off_list: List of IPv4 addresses to offload * @neigh_off_list: List of neighbour offloads - * @mac_off_lock: Lock for the MAC address list * @mac_index_lock: Lock for the MAC index list * @ipv4_off_lock: Lock for the IPv4 address list * @neigh_off_lock: Lock for the neighbour address list * @mac_off_ids: IDA to manage id assignment for offloaded MACs - * @mac_off_count: Number of MACs in address list * @neigh_nb: Notifier to monitor neighbour state */ struct nfp_fl_tunnel_offloads { - struct list_head mac_off_list; struct list_head mac_index_list; struct list_head ipv4_off_list; struct list_head neigh_off_list; - struct mutex mac_off_lock; struct mutex mac_index_lock; struct mutex ipv4_off_lock; spinlock_t neigh_off_lock; struct ida mac_off_ids; - int mac_off_count; struct notifier_block neigh_nb; }; @@ -268,7 +262,6 @@ void nfp_tunnel_config_stop(struct nfp_app *app); int nfp_tunnel_mac_event_handler(struct nfp_app *app, struct net_device *netdev, unsigned long event, void *ptr); -void nfp_tunnel_write_macs(struct nfp_app *app); void nfp_tunnel_del_ipv4_off(struct nfp_app *app, __be32 ipv4); void nfp_tunnel_add_ipv4_off(struct nfp_app *app, __be32 ipv4); void nfp_tunnel_request_route(struct nfp_app *app, struct sk_buff *skb); diff --git a/drivers/net/ethernet/netronome/nfp/flower/match.c b/drivers/net/ethernet/netronome/nfp/flower/match.c index cdf75595f627..c04a0d6b0184 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/match.c +++ b/drivers/net/ethernet/netronome/nfp/flower/match.c @@ -403,9 +403,6 @@ int nfp_flower_compile_flow_match(struct nfp_app *app, ext += sizeof(struct nfp_flower_ipv4_udp_tun); msk += sizeof(struct nfp_flower_ipv4_udp_tun); - /* Configure tunnel end point MAC. */ - nfp_tunnel_write_macs(app); - /* Store the tunnel destination in the rule data. * This must be present and be an exact match. */ diff --git a/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c b/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c index 4e509c8c1aca..9b8c73bfcb5b 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c +++ b/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c @@ -99,32 +99,17 @@ struct nfp_ipv4_addr_entry { }; /** - * struct nfp_tun_mac_addr - configure MAC address of tunnel EP on NFP + * struct nfp_tun_mac_addr_offload - configure MAC address of tunnel EP on NFP * @reserved: reserved for future use - * @count: number of MAC addresses in the message - * @addresses.index: index of MAC address in the lookup table - * @addresses.addr: interface MAC address - * @addresses: series of MACs to offload + * @count: number of MAC addresses in the message (should be 1) + * @index: index of MAC address in the lookup table + * @addr: interface MAC address */ -struct nfp_tun_mac_addr { +struct nfp_tun_mac_addr_offload { __be16 reserved; __be16 count; - struct index_mac_addr { - __be16 index; - u8 addr[ETH_ALEN]; - } addresses[]; -}; - -/** - * struct nfp_tun_mac_offload_entry - list of MACs to offload - * @index: index of MAC address for offloading - * @addr: interface MAC address - * @list: list pointer - */ -struct nfp_tun_mac_offload_entry { __be16 index; u8 addr[ETH_ALEN]; - struct list_head list; }; #define NFP_MAX_MAC_INDEX 0xff @@ -473,64 +458,6 @@ void nfp_tunnel_del_ipv4_off(struct nfp_app *app, __be32 ipv4) nfp_tun_write_ipv4_list(app); } -void nfp_tunnel_write_macs(struct nfp_app *app) -{ - struct nfp_flower_priv *priv = app->priv; - struct nfp_tun_mac_offload_entry *entry; - struct nfp_tun_mac_addr *payload; - struct list_head *ptr, *storage; - int mac_count, err, pay_size; - - mutex_lock(&priv->tun.mac_off_lock); - if (!priv->tun.mac_off_count) { - mutex_unlock(&priv->tun.mac_off_lock); - return; - } - - pay_size = sizeof(struct nfp_tun_mac_addr) + - sizeof(struct index_mac_addr) * priv->tun.mac_off_count; - - payload = kzalloc(pay_size, GFP_KERNEL); - if (!payload) { - mutex_unlock(&priv->tun.mac_off_lock); - return; - } - - payload->count = cpu_to_be16(priv->tun.mac_off_count); - - mac_count = 0; - list_for_each_safe(ptr, storage, &priv->tun.mac_off_list) { - entry = list_entry(ptr, struct nfp_tun_mac_offload_entry, - list); - payload->addresses[mac_count].index = entry->index; - ether_addr_copy(payload->addresses[mac_count].addr, - entry->addr); - mac_count++; - } - - err = nfp_flower_xmit_tun_conf(app, NFP_FLOWER_CMSG_TYPE_TUN_MAC, - pay_size, payload, GFP_KERNEL); - - kfree(payload); - - if (err) { - mutex_unlock(&priv->tun.mac_off_lock); - /* Write failed so retain list for future retry. */ - return; - } - - /* If list was successfully offloaded, flush it. */ - list_for_each_safe(ptr, storage, &priv->tun.mac_off_list) { - entry = list_entry(ptr, struct nfp_tun_mac_offload_entry, - list); - list_del(&entry->list); - kfree(entry); - } - - priv->tun.mac_off_count = 0; - mutex_unlock(&priv->tun.mac_off_lock); -} - static int nfp_tun_get_mac_idx(struct nfp_app *app, int ifindex) { struct nfp_flower_priv *priv = app->priv; @@ -588,28 +515,35 @@ static void nfp_tun_del_mac_idx(struct nfp_app *app, int ifindex) mutex_unlock(&priv->tun.mac_index_lock); } -static void nfp_tun_add_to_mac_offload_list(struct net_device *netdev, - struct nfp_app *app) +static int __nfp_tunnel_offload_mac(struct nfp_app *app, u8 *mac, u16 idx) +{ + struct nfp_tun_mac_addr_offload payload; + + memset(&payload, 0, sizeof(payload)); + + /* FW supports multiple MACs per cmsg but restrict to single. */ + payload.count = cpu_to_be16(1); + payload.index = cpu_to_be16(idx); + ether_addr_copy(payload.addr, mac); + + return nfp_flower_xmit_tun_conf(app, NFP_FLOWER_CMSG_TYPE_TUN_MAC, + sizeof(struct nfp_tun_mac_addr_offload), + &payload, GFP_KERNEL); +} + +static int +nfp_tunnel_offload_mac(struct nfp_app *app, struct net_device *netdev) { - struct nfp_flower_priv *priv = app->priv; - struct nfp_tun_mac_offload_entry *entry; u16 nfp_mac_idx; int port = 0; - /* Check if MAC should be offloaded. */ - if (!is_valid_ether_addr(netdev->dev_addr)) - return; - if (nfp_netdev_is_nfp_repr(netdev)) port = nfp_repr_get_port_id(netdev); else if (!nfp_fl_is_netdev_to_offload(netdev)) - return; + return 0; - entry = kmalloc(sizeof(*entry), GFP_KERNEL); - if (!entry) { - nfp_flower_cmsg_warn(app, "Mem fail when offloading MAC.\n"); - return; - } + if (!is_valid_ether_addr(netdev->dev_addr)) + return -EINVAL; if (FIELD_GET(NFP_FLOWER_CMSG_PORT_TYPE, port) == NFP_FLOWER_CMSG_PORT_TYPE_PHYS_PORT) { @@ -618,40 +552,33 @@ static void nfp_tun_add_to_mac_offload_list(struct net_device *netdev, /* Must assign our own unique 8-bit index. */ int idx = nfp_tun_get_mac_idx(app, netdev->ifindex); - if (idx < 0) { - nfp_flower_cmsg_warn(app, "Can't assign non-repr MAC index.\n"); - kfree(entry); - return; - } + if (idx < 0) + return idx; + nfp_mac_idx = idx << 8 | NFP_FLOWER_CMSG_PORT_TYPE_OTHER_PORT; } else { - kfree(entry); - return; + return 0; } - entry->index = cpu_to_be16(nfp_mac_idx); - ether_addr_copy(entry->addr, netdev->dev_addr); - - mutex_lock(&priv->tun.mac_off_lock); - priv->tun.mac_off_count++; - list_add_tail(&entry->list, &priv->tun.mac_off_list); - mutex_unlock(&priv->tun.mac_off_lock); + return __nfp_tunnel_offload_mac(app, netdev->dev_addr, nfp_mac_idx); } int nfp_tunnel_mac_event_handler(struct nfp_app *app, struct net_device *netdev, unsigned long event, void *ptr) { + int err; + if (event == NETDEV_DOWN || event == NETDEV_UNREGISTER) { /* If non-nfp netdev then free its offload index. */ if (nfp_fl_is_netdev_to_offload(netdev)) nfp_tun_del_mac_idx(app, netdev->ifindex); } else if (event == NETDEV_UP || event == NETDEV_CHANGEADDR || event == NETDEV_REGISTER) { - nfp_tun_add_to_mac_offload_list(netdev, app); - - /* Force a list write to keep NFP up to date. */ - nfp_tunnel_write_macs(app); + err = nfp_tunnel_offload_mac(app, netdev); + if (err) + nfp_flower_cmsg_warn(app, "Failed to offload MAC on %s.\n", + netdev_name(netdev)); } return NOTIFY_OK; } @@ -661,9 +588,6 @@ int nfp_tunnel_config_start(struct nfp_app *app) struct nfp_flower_priv *priv = app->priv; /* Initialise priv data for MAC offloading. */ - priv->tun.mac_off_count = 0; - mutex_init(&priv->tun.mac_off_lock); - INIT_LIST_HEAD(&priv->tun.mac_off_list); mutex_init(&priv->tun.mac_index_lock); INIT_LIST_HEAD(&priv->tun.mac_index_list); ida_init(&priv->tun.mac_off_ids); @@ -682,7 +606,6 @@ int nfp_tunnel_config_start(struct nfp_app *app) void nfp_tunnel_config_stop(struct nfp_app *app) { - struct nfp_tun_mac_offload_entry *mac_entry; struct nfp_flower_priv *priv = app->priv; struct nfp_ipv4_route_entry *route_entry; struct nfp_tun_mac_non_nfp_idx *mac_idx; @@ -691,14 +614,6 @@ void nfp_tunnel_config_stop(struct nfp_app *app) unregister_netevent_notifier(&priv->tun.neigh_nb); - /* Free any memory that may be occupied by MAC list. */ - list_for_each_safe(ptr, storage, &priv->tun.mac_off_list) { - mac_entry = list_entry(ptr, struct nfp_tun_mac_offload_entry, - list); - list_del(&mac_entry->list); - kfree(mac_entry); - } - /* Free any memory that may be occupied by MAC index list. */ list_for_each_safe(ptr, storage, &priv->tun.mac_index_list) { mac_idx = list_entry(ptr, struct nfp_tun_mac_non_nfp_idx, |