fm10k: convert to new udp_tunnel_nic infra
Straightforward conversion to new infra. Driver restores info after close/open cycle by calling its internal restore function so just use that, no need for udp_tunnel_nic_reset_ntf() here. Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
6a8c1a75e5
commit
f7529b4ba3
@@ -221,12 +221,6 @@ struct fm10k_iov_data {
|
|||||||
struct fm10k_vf_info vf_info[];
|
struct fm10k_vf_info vf_info[];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct fm10k_udp_port {
|
|
||||||
struct list_head list;
|
|
||||||
sa_family_t sa_family;
|
|
||||||
__be16 port;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum fm10k_macvlan_request_type {
|
enum fm10k_macvlan_request_type {
|
||||||
FM10K_UC_MAC_REQUEST,
|
FM10K_UC_MAC_REQUEST,
|
||||||
FM10K_MC_MAC_REQUEST,
|
FM10K_MC_MAC_REQUEST,
|
||||||
@@ -370,8 +364,8 @@ struct fm10k_intfc {
|
|||||||
u32 rssrk[FM10K_RSSRK_SIZE];
|
u32 rssrk[FM10K_RSSRK_SIZE];
|
||||||
|
|
||||||
/* UDP encapsulation port tracking information */
|
/* UDP encapsulation port tracking information */
|
||||||
struct list_head vxlan_port;
|
__be16 vxlan_port;
|
||||||
struct list_head geneve_port;
|
__be16 geneve_port;
|
||||||
|
|
||||||
/* MAC/VLAN update queue */
|
/* MAC/VLAN update queue */
|
||||||
struct list_head macvlan_requests;
|
struct list_head macvlan_requests;
|
||||||
|
@@ -635,15 +635,8 @@ static int fm10k_clean_rx_irq(struct fm10k_q_vector *q_vector,
|
|||||||
static struct ethhdr *fm10k_port_is_vxlan(struct sk_buff *skb)
|
static struct ethhdr *fm10k_port_is_vxlan(struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct fm10k_intfc *interface = netdev_priv(skb->dev);
|
struct fm10k_intfc *interface = netdev_priv(skb->dev);
|
||||||
struct fm10k_udp_port *vxlan_port;
|
|
||||||
|
|
||||||
/* we can only offload a vxlan if we recognize it as such */
|
if (interface->vxlan_port != udp_hdr(skb)->dest)
|
||||||
vxlan_port = list_first_entry_or_null(&interface->vxlan_port,
|
|
||||||
struct fm10k_udp_port, list);
|
|
||||||
|
|
||||||
if (!vxlan_port)
|
|
||||||
return NULL;
|
|
||||||
if (vxlan_port->port != udp_hdr(skb)->dest)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* return offset of udp_hdr plus 8 bytes for VXLAN header */
|
/* return offset of udp_hdr plus 8 bytes for VXLAN header */
|
||||||
|
@@ -366,39 +366,6 @@ static void fm10k_request_glort_range(struct fm10k_intfc *interface)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* fm10k_free_udp_port_info
|
|
||||||
* @interface: board private structure
|
|
||||||
*
|
|
||||||
* This function frees both geneve_port and vxlan_port structures
|
|
||||||
**/
|
|
||||||
static void fm10k_free_udp_port_info(struct fm10k_intfc *interface)
|
|
||||||
{
|
|
||||||
struct fm10k_udp_port *port;
|
|
||||||
|
|
||||||
/* flush all entries from vxlan list */
|
|
||||||
port = list_first_entry_or_null(&interface->vxlan_port,
|
|
||||||
struct fm10k_udp_port, list);
|
|
||||||
while (port) {
|
|
||||||
list_del(&port->list);
|
|
||||||
kfree(port);
|
|
||||||
port = list_first_entry_or_null(&interface->vxlan_port,
|
|
||||||
struct fm10k_udp_port,
|
|
||||||
list);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* flush all entries from geneve list */
|
|
||||||
port = list_first_entry_or_null(&interface->geneve_port,
|
|
||||||
struct fm10k_udp_port, list);
|
|
||||||
while (port) {
|
|
||||||
list_del(&port->list);
|
|
||||||
kfree(port);
|
|
||||||
port = list_first_entry_or_null(&interface->vxlan_port,
|
|
||||||
struct fm10k_udp_port,
|
|
||||||
list);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fm10k_restore_udp_port_info
|
* fm10k_restore_udp_port_info
|
||||||
* @interface: board private structure
|
* @interface: board private structure
|
||||||
@@ -408,131 +375,52 @@ static void fm10k_free_udp_port_info(struct fm10k_intfc *interface)
|
|||||||
static void fm10k_restore_udp_port_info(struct fm10k_intfc *interface)
|
static void fm10k_restore_udp_port_info(struct fm10k_intfc *interface)
|
||||||
{
|
{
|
||||||
struct fm10k_hw *hw = &interface->hw;
|
struct fm10k_hw *hw = &interface->hw;
|
||||||
struct fm10k_udp_port *port;
|
|
||||||
|
|
||||||
/* only the PF supports configuring tunnels */
|
/* only the PF supports configuring tunnels */
|
||||||
if (hw->mac.type != fm10k_mac_pf)
|
if (hw->mac.type != fm10k_mac_pf)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
port = list_first_entry_or_null(&interface->vxlan_port,
|
|
||||||
struct fm10k_udp_port, list);
|
|
||||||
|
|
||||||
/* restore tunnel configuration register */
|
/* restore tunnel configuration register */
|
||||||
fm10k_write_reg(hw, FM10K_TUNNEL_CFG,
|
fm10k_write_reg(hw, FM10K_TUNNEL_CFG,
|
||||||
(port ? ntohs(port->port) : 0) |
|
ntohs(interface->vxlan_port) |
|
||||||
(ETH_P_TEB << FM10K_TUNNEL_CFG_NVGRE_SHIFT));
|
(ETH_P_TEB << FM10K_TUNNEL_CFG_NVGRE_SHIFT));
|
||||||
|
|
||||||
port = list_first_entry_or_null(&interface->geneve_port,
|
|
||||||
struct fm10k_udp_port, list);
|
|
||||||
|
|
||||||
/* restore Geneve tunnel configuration register */
|
/* restore Geneve tunnel configuration register */
|
||||||
fm10k_write_reg(hw, FM10K_TUNNEL_CFG_GENEVE,
|
fm10k_write_reg(hw, FM10K_TUNNEL_CFG_GENEVE,
|
||||||
(port ? ntohs(port->port) : 0));
|
ntohs(interface->geneve_port));
|
||||||
}
|
|
||||||
|
|
||||||
static struct fm10k_udp_port *
|
|
||||||
fm10k_remove_tunnel_port(struct list_head *ports,
|
|
||||||
struct udp_tunnel_info *ti)
|
|
||||||
{
|
|
||||||
struct fm10k_udp_port *port;
|
|
||||||
|
|
||||||
list_for_each_entry(port, ports, list) {
|
|
||||||
if ((port->port == ti->port) &&
|
|
||||||
(port->sa_family == ti->sa_family)) {
|
|
||||||
list_del(&port->list);
|
|
||||||
return port;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fm10k_insert_tunnel_port(struct list_head *ports,
|
|
||||||
struct udp_tunnel_info *ti)
|
|
||||||
{
|
|
||||||
struct fm10k_udp_port *port;
|
|
||||||
|
|
||||||
/* remove existing port entry from the list so that the newest items
|
|
||||||
* are always at the tail of the list.
|
|
||||||
*/
|
|
||||||
port = fm10k_remove_tunnel_port(ports, ti);
|
|
||||||
if (!port) {
|
|
||||||
port = kmalloc(sizeof(*port), GFP_ATOMIC);
|
|
||||||
if (!port)
|
|
||||||
return;
|
|
||||||
port->port = ti->port;
|
|
||||||
port->sa_family = ti->sa_family;
|
|
||||||
}
|
|
||||||
|
|
||||||
list_add_tail(&port->list, ports);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fm10k_udp_tunnel_add
|
* fm10k_udp_tunnel_sync - Called when UDP tunnel ports change
|
||||||
* @dev: network interface device structure
|
* @dev: network interface device structure
|
||||||
* @ti: Tunnel endpoint information
|
* @table: Tunnel table (according to tables of @fm10k_udp_tunnels)
|
||||||
*
|
*
|
||||||
* This function is called when a new UDP tunnel port has been added.
|
* This function is called when a new UDP tunnel port is added or deleted.
|
||||||
* Due to hardware restrictions, only one port per type can be offloaded at
|
* Due to hardware restrictions, only one port per type can be offloaded at
|
||||||
* once.
|
* once. Core will send to the driver a port of its choice.
|
||||||
**/
|
**/
|
||||||
static void fm10k_udp_tunnel_add(struct net_device *dev,
|
static int fm10k_udp_tunnel_sync(struct net_device *dev, unsigned int table)
|
||||||
struct udp_tunnel_info *ti)
|
|
||||||
{
|
{
|
||||||
struct fm10k_intfc *interface = netdev_priv(dev);
|
struct fm10k_intfc *interface = netdev_priv(dev);
|
||||||
|
struct udp_tunnel_info ti;
|
||||||
|
|
||||||
/* only the PF supports configuring tunnels */
|
udp_tunnel_nic_get_port(dev, table, 0, &ti);
|
||||||
if (interface->hw.mac.type != fm10k_mac_pf)
|
if (!table)
|
||||||
return;
|
interface->vxlan_port = ti.port;
|
||||||
|
else
|
||||||
switch (ti->type) {
|
interface->geneve_port = ti.port;
|
||||||
case UDP_TUNNEL_TYPE_VXLAN:
|
|
||||||
fm10k_insert_tunnel_port(&interface->vxlan_port, ti);
|
|
||||||
break;
|
|
||||||
case UDP_TUNNEL_TYPE_GENEVE:
|
|
||||||
fm10k_insert_tunnel_port(&interface->geneve_port, ti);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
fm10k_restore_udp_port_info(interface);
|
fm10k_restore_udp_port_info(interface);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
static const struct udp_tunnel_nic_info fm10k_udp_tunnels = {
|
||||||
* fm10k_udp_tunnel_del
|
.sync_table = fm10k_udp_tunnel_sync,
|
||||||
* @dev: network interface device structure
|
.tables = {
|
||||||
* @ti: Tunnel end point information
|
{ .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, },
|
||||||
*
|
{ .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_GENEVE, },
|
||||||
* This function is called when a new UDP tunnel port is deleted. The freed
|
},
|
||||||
* port will be removed from the list, then we reprogram the offloaded port
|
};
|
||||||
* based on the head of the list.
|
|
||||||
**/
|
|
||||||
static void fm10k_udp_tunnel_del(struct net_device *dev,
|
|
||||||
struct udp_tunnel_info *ti)
|
|
||||||
{
|
|
||||||
struct fm10k_intfc *interface = netdev_priv(dev);
|
|
||||||
struct fm10k_udp_port *port = NULL;
|
|
||||||
|
|
||||||
if (interface->hw.mac.type != fm10k_mac_pf)
|
|
||||||
return;
|
|
||||||
|
|
||||||
switch (ti->type) {
|
|
||||||
case UDP_TUNNEL_TYPE_VXLAN:
|
|
||||||
port = fm10k_remove_tunnel_port(&interface->vxlan_port, ti);
|
|
||||||
break;
|
|
||||||
case UDP_TUNNEL_TYPE_GENEVE:
|
|
||||||
port = fm10k_remove_tunnel_port(&interface->geneve_port, ti);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if we did remove a port we need to free its memory */
|
|
||||||
kfree(port);
|
|
||||||
|
|
||||||
fm10k_restore_udp_port_info(interface);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fm10k_open - Called when a network interface is made active
|
* fm10k_open - Called when a network interface is made active
|
||||||
@@ -580,8 +468,6 @@ int fm10k_open(struct net_device *netdev)
|
|||||||
if (err)
|
if (err)
|
||||||
goto err_set_queues;
|
goto err_set_queues;
|
||||||
|
|
||||||
udp_tunnel_get_rx_info(netdev);
|
|
||||||
|
|
||||||
fm10k_up(interface);
|
fm10k_up(interface);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -615,8 +501,6 @@ int fm10k_close(struct net_device *netdev)
|
|||||||
|
|
||||||
fm10k_qv_free_irq(interface);
|
fm10k_qv_free_irq(interface);
|
||||||
|
|
||||||
fm10k_free_udp_port_info(interface);
|
|
||||||
|
|
||||||
fm10k_free_all_tx_resources(interface);
|
fm10k_free_all_tx_resources(interface);
|
||||||
fm10k_free_all_rx_resources(interface);
|
fm10k_free_all_rx_resources(interface);
|
||||||
|
|
||||||
@@ -1647,8 +1531,8 @@ static const struct net_device_ops fm10k_netdev_ops = {
|
|||||||
.ndo_set_vf_rate = fm10k_ndo_set_vf_bw,
|
.ndo_set_vf_rate = fm10k_ndo_set_vf_bw,
|
||||||
.ndo_get_vf_config = fm10k_ndo_get_vf_config,
|
.ndo_get_vf_config = fm10k_ndo_get_vf_config,
|
||||||
.ndo_get_vf_stats = fm10k_ndo_get_vf_stats,
|
.ndo_get_vf_stats = fm10k_ndo_get_vf_stats,
|
||||||
.ndo_udp_tunnel_add = fm10k_udp_tunnel_add,
|
.ndo_udp_tunnel_add = udp_tunnel_nic_add_port,
|
||||||
.ndo_udp_tunnel_del = fm10k_udp_tunnel_del,
|
.ndo_udp_tunnel_del = udp_tunnel_nic_del_port,
|
||||||
.ndo_dfwd_add_station = fm10k_dfwd_add_station,
|
.ndo_dfwd_add_station = fm10k_dfwd_add_station,
|
||||||
.ndo_dfwd_del_station = fm10k_dfwd_del_station,
|
.ndo_dfwd_del_station = fm10k_dfwd_del_station,
|
||||||
.ndo_features_check = fm10k_features_check,
|
.ndo_features_check = fm10k_features_check,
|
||||||
@@ -1695,6 +1579,8 @@ struct net_device *fm10k_alloc_netdev(const struct fm10k_info *info)
|
|||||||
NETIF_F_SG;
|
NETIF_F_SG;
|
||||||
|
|
||||||
dev->features |= NETIF_F_GSO_UDP_TUNNEL;
|
dev->features |= NETIF_F_GSO_UDP_TUNNEL;
|
||||||
|
|
||||||
|
dev->udp_tunnel_nic_info = &fm10k_udp_tunnels;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* all features defined to this point should be changeable */
|
/* all features defined to this point should be changeable */
|
||||||
|
@@ -2066,10 +2066,6 @@ static int fm10k_sw_init(struct fm10k_intfc *interface,
|
|||||||
interface->tx_itr = FM10K_TX_ITR_DEFAULT;
|
interface->tx_itr = FM10K_TX_ITR_DEFAULT;
|
||||||
interface->rx_itr = FM10K_ITR_ADAPTIVE | FM10K_RX_ITR_DEFAULT;
|
interface->rx_itr = FM10K_ITR_ADAPTIVE | FM10K_RX_ITR_DEFAULT;
|
||||||
|
|
||||||
/* initialize udp port lists */
|
|
||||||
INIT_LIST_HEAD(&interface->vxlan_port);
|
|
||||||
INIT_LIST_HEAD(&interface->geneve_port);
|
|
||||||
|
|
||||||
/* Initialize the MAC/VLAN queue */
|
/* Initialize the MAC/VLAN queue */
|
||||||
INIT_LIST_HEAD(&interface->macvlan_requests);
|
INIT_LIST_HEAD(&interface->macvlan_requests);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user