提交 64f63d59 编写于 作者: D David S. Miller

Merge branch 'bnx2x-next'

Yuval Mintz says:

====================
bnx2x: driver updates

This series contains several changes - the biggest change is the
addition of Geneve NDO support [allows device to perform RSS according
to inner-headers of encapsulated packet, similar to what it does for
vxlan]. It also extends dcbx support, as well as introducing some minor
changes.

Dave,

Please consider applying this series to `net-next'.
[Do notice patch #3 fails checkpatch due to consistency with existing
HSI]
====================
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
...@@ -1277,8 +1277,7 @@ enum sp_rtnl_flag { ...@@ -1277,8 +1277,7 @@ enum sp_rtnl_flag {
BNX2X_SP_RTNL_HYPERVISOR_VLAN, BNX2X_SP_RTNL_HYPERVISOR_VLAN,
BNX2X_SP_RTNL_TX_STOP, BNX2X_SP_RTNL_TX_STOP,
BNX2X_SP_RTNL_GET_DRV_VERSION, BNX2X_SP_RTNL_GET_DRV_VERSION,
BNX2X_SP_RTNL_ADD_VXLAN_PORT, BNX2X_SP_RTNL_CHANGE_UDP_PORT,
BNX2X_SP_RTNL_DEL_VXLAN_PORT,
}; };
enum bnx2x_iov_flag { enum bnx2x_iov_flag {
...@@ -1327,6 +1326,17 @@ struct bnx2x_vlan_entry { ...@@ -1327,6 +1326,17 @@ struct bnx2x_vlan_entry {
bool hw; bool hw;
}; };
enum bnx2x_udp_port_type {
BNX2X_UDP_PORT_VXLAN,
BNX2X_UDP_PORT_GENEVE,
BNX2X_UDP_PORT_MAX,
};
struct bnx2x_udp_tunnel {
u16 dst_port;
u8 count;
};
struct bnx2x { struct bnx2x {
/* Fields used in the tx and intr/napi performance paths /* Fields used in the tx and intr/napi performance paths
* are grouped together in the beginning of the structure * are grouped together in the beginning of the structure
...@@ -1830,9 +1840,10 @@ struct bnx2x { ...@@ -1830,9 +1840,10 @@ struct bnx2x {
struct list_head vlan_reg; struct list_head vlan_reg;
u16 vlan_cnt; u16 vlan_cnt;
u16 vlan_credit; u16 vlan_credit;
u16 vxlan_dst_port;
u8 vxlan_dst_port_count;
bool accept_any_vlan; bool accept_any_vlan;
/* Vxlan/Geneve related information */
struct bnx2x_udp_tunnel udp_tunnel_ports[BNX2X_UDP_PORT_MAX];
}; };
/* Tx queues may be less or equal to Rx queues */ /* Tx queues may be less or equal to Rx queues */
......
...@@ -5086,4 +5086,3 @@ void bnx2x_schedule_sp_rtnl(struct bnx2x *bp, enum sp_rtnl_flag flag, ...@@ -5086,4 +5086,3 @@ void bnx2x_schedule_sp_rtnl(struct bnx2x *bp, enum sp_rtnl_flag flag,
flag); flag);
schedule_delayed_work(&bp->sp_rtnl_task, 0); schedule_delayed_work(&bp->sp_rtnl_task, 0);
} }
EXPORT_SYMBOL(bnx2x_schedule_sp_rtnl);
...@@ -923,6 +923,7 @@ static inline int bnx2x_func_start(struct bnx2x *bp) ...@@ -923,6 +923,7 @@ static inline int bnx2x_func_start(struct bnx2x *bp)
struct bnx2x_func_state_params func_params = {NULL}; struct bnx2x_func_state_params func_params = {NULL};
struct bnx2x_func_start_params *start_params = struct bnx2x_func_start_params *start_params =
&func_params.params.start; &func_params.params.start;
u16 port;
/* Prepare parameters for function state transitions */ /* Prepare parameters for function state transitions */
__set_bit(RAMROD_COMP_WAIT, &func_params.ramrod_flags); __set_bit(RAMROD_COMP_WAIT, &func_params.ramrod_flags);
...@@ -959,8 +960,14 @@ static inline int bnx2x_func_start(struct bnx2x *bp) ...@@ -959,8 +960,14 @@ static inline int bnx2x_func_start(struct bnx2x *bp)
start_params->network_cos_mode = STATIC_COS; start_params->network_cos_mode = STATIC_COS;
else /* CHIP_IS_E1X */ else /* CHIP_IS_E1X */
start_params->network_cos_mode = FW_WRR; start_params->network_cos_mode = FW_WRR;
if (bp->udp_tunnel_ports[BNX2X_UDP_PORT_VXLAN].count) {
start_params->vxlan_dst_port = bp->vxlan_dst_port; port = bp->udp_tunnel_ports[BNX2X_UDP_PORT_VXLAN].dst_port;
start_params->vxlan_dst_port = port;
}
if (bp->udp_tunnel_ports[BNX2X_UDP_PORT_GENEVE].count) {
port = bp->udp_tunnel_ports[BNX2X_UDP_PORT_GENEVE].dst_port;
start_params->geneve_dst_port = port;
}
start_params->inner_rss = 1; start_params->inner_rss = 1;
......
...@@ -195,6 +195,7 @@ static void bnx2x_dcbx_get_ap_feature(struct bnx2x *bp, ...@@ -195,6 +195,7 @@ static void bnx2x_dcbx_get_ap_feature(struct bnx2x *bp,
u32 error) { u32 error) {
u8 index; u8 index;
u32 *ttp = bp->dcbx_port_params.app.traffic_type_priority; u32 *ttp = bp->dcbx_port_params.app.traffic_type_priority;
u8 iscsi_pri_found = 0, fcoe_pri_found = 0;
if (GET_FLAGS(error, DCBX_LOCAL_APP_ERROR)) if (GET_FLAGS(error, DCBX_LOCAL_APP_ERROR))
DP(BNX2X_MSG_DCB, "DCBX_LOCAL_APP_ERROR\n"); DP(BNX2X_MSG_DCB, "DCBX_LOCAL_APP_ERROR\n");
...@@ -210,29 +211,57 @@ static void bnx2x_dcbx_get_ap_feature(struct bnx2x *bp, ...@@ -210,29 +211,57 @@ static void bnx2x_dcbx_get_ap_feature(struct bnx2x *bp,
bp->dcbx_port_params.app.enabled = true; bp->dcbx_port_params.app.enabled = true;
/* Use 0 as the default application priority for all. */
for (index = 0 ; index < LLFC_DRIVER_TRAFFIC_TYPE_MAX; index++) for (index = 0 ; index < LLFC_DRIVER_TRAFFIC_TYPE_MAX; index++)
ttp[index] = 0; ttp[index] = 0;
if (app->default_pri < MAX_PFC_PRIORITIES)
ttp[LLFC_TRAFFIC_TYPE_NW] = app->default_pri;
for (index = 0 ; index < DCBX_MAX_APP_PROTOCOL; index++) { for (index = 0 ; index < DCBX_MAX_APP_PROTOCOL; index++) {
struct dcbx_app_priority_entry *entry = struct dcbx_app_priority_entry *entry =
app->app_pri_tbl; app->app_pri_tbl;
enum traffic_type type = MAX_TRAFFIC_TYPE;
if (GET_FLAGS(entry[index].appBitfield, if (GET_FLAGS(entry[index].appBitfield,
DCBX_APP_SF_ETH_TYPE) && DCBX_APP_SF_DEFAULT) &&
ETH_TYPE_FCOE == entry[index].app_id) GET_FLAGS(entry[index].appBitfield,
bnx2x_dcbx_get_ap_priority(bp, DCBX_APP_SF_ETH_TYPE)) {
entry[index].pri_bitmap, type = LLFC_TRAFFIC_TYPE_NW;
LLFC_TRAFFIC_TYPE_FCOE); } else if (GET_FLAGS(entry[index].appBitfield,
DCBX_APP_SF_PORT) &&
TCP_PORT_ISCSI == entry[index].app_id) {
type = LLFC_TRAFFIC_TYPE_ISCSI;
iscsi_pri_found = 1;
} else if (GET_FLAGS(entry[index].appBitfield,
DCBX_APP_SF_ETH_TYPE) &&
ETH_TYPE_FCOE == entry[index].app_id) {
type = LLFC_TRAFFIC_TYPE_FCOE;
fcoe_pri_found = 1;
}
if (GET_FLAGS(entry[index].appBitfield, if (type == MAX_TRAFFIC_TYPE)
DCBX_APP_SF_PORT) && continue;
TCP_PORT_ISCSI == entry[index].app_id)
bnx2x_dcbx_get_ap_priority(bp, bnx2x_dcbx_get_ap_priority(bp,
entry[index].pri_bitmap, entry[index].pri_bitmap,
LLFC_TRAFFIC_TYPE_ISCSI); type);
}
/* If we have received a non-zero default application
* priority, then use that for applications which are
* not configured with any priority.
*/
if (ttp[LLFC_TRAFFIC_TYPE_NW] != 0) {
if (!iscsi_pri_found) {
ttp[LLFC_TRAFFIC_TYPE_ISCSI] =
ttp[LLFC_TRAFFIC_TYPE_NW];
DP(BNX2X_MSG_DCB,
"ISCSI is using default priority.\n");
}
if (!fcoe_pri_found) {
ttp[LLFC_TRAFFIC_TYPE_FCOE] =
ttp[LLFC_TRAFFIC_TYPE_NW];
DP(BNX2X_MSG_DCB,
"FCoE is using default priority.\n");
}
} }
} else { } else {
DP(BNX2X_MSG_DCB, "DCBX_LOCAL_APP_DISABLED\n"); DP(BNX2X_MSG_DCB, "DCBX_LOCAL_APP_DISABLED\n");
......
...@@ -981,6 +981,11 @@ static void bnx2x_get_regs(struct net_device *dev, ...@@ -981,6 +981,11 @@ static void bnx2x_get_regs(struct net_device *dev,
memcpy(p, &dump_hdr, sizeof(struct dump_header)); memcpy(p, &dump_hdr, sizeof(struct dump_header));
p += dump_hdr.header_size + 1; p += dump_hdr.header_size + 1;
/* This isn't really an error, but since attention handling is going
* to print the GRC timeouts using this macro, we use the same.
*/
BNX2X_ERR("Generating register dump. Might trigger harmless GRC timeouts\n");
/* Actually read the registers */ /* Actually read the registers */
__bnx2x_get_regs(bp, p); __bnx2x_get_regs(bp, p);
......
...@@ -1831,10 +1831,13 @@ struct dcbx_app_priority_entry { ...@@ -1831,10 +1831,13 @@ struct dcbx_app_priority_entry {
#elif defined(__LITTLE_ENDIAN) #elif defined(__LITTLE_ENDIAN)
u8 appBitfield; u8 appBitfield;
#define DCBX_APP_ENTRY_VALID 0x01 #define DCBX_APP_ENTRY_VALID 0x01
#define DCBX_APP_ENTRY_SF_MASK 0x30 #define DCBX_APP_ENTRY_SF_MASK 0xF0
#define DCBX_APP_ENTRY_SF_SHIFT 4 #define DCBX_APP_ENTRY_SF_SHIFT 4
#define DCBX_APP_ENTRY_VALID 0x01
#define DCBX_APP_SF_ETH_TYPE 0x10 #define DCBX_APP_SF_ETH_TYPE 0x10
#define DCBX_APP_SF_PORT 0x20 #define DCBX_APP_SF_PORT 0x20
#define DCBX_APP_SF_UDP 0x40
#define DCBX_APP_SF_DEFAULT 0x80
u8 pri_bitmap; u8 pri_bitmap;
u16 app_id; u16 app_id;
#endif #endif
......
...@@ -59,7 +59,9 @@ ...@@ -59,7 +59,9 @@
#include <linux/semaphore.h> #include <linux/semaphore.h>
#include <linux/stringify.h> #include <linux/stringify.h>
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#if IS_ENABLED(CONFIG_GENEVE)
#include <net/geneve.h>
#endif
#include "bnx2x.h" #include "bnx2x.h"
#include "bnx2x_init.h" #include "bnx2x_init.h"
#include "bnx2x_init_ops.h" #include "bnx2x_init_ops.h"
...@@ -10076,11 +10078,13 @@ static void bnx2x_parity_recover(struct bnx2x *bp) ...@@ -10076,11 +10078,13 @@ static void bnx2x_parity_recover(struct bnx2x *bp)
} }
} }
#ifdef CONFIG_BNX2X_VXLAN #if defined(CONFIG_BNX2X_VXLAN) || IS_ENABLED(CONFIG_GENEVE)
static int bnx2x_vxlan_port_update(struct bnx2x *bp, u16 port) static int bnx2x_udp_port_update(struct bnx2x *bp)
{ {
struct bnx2x_func_switch_update_params *switch_update_params; struct bnx2x_func_switch_update_params *switch_update_params;
struct bnx2x_func_state_params func_params = {NULL}; struct bnx2x_func_state_params func_params = {NULL};
struct bnx2x_udp_tunnel *udp_tunnel;
u16 vxlan_port = 0, geneve_port = 0;
int rc; int rc;
switch_update_params = &func_params.params.switch_update; switch_update_params = &func_params.params.switch_update;
...@@ -10095,69 +10099,125 @@ static int bnx2x_vxlan_port_update(struct bnx2x *bp, u16 port) ...@@ -10095,69 +10099,125 @@ static int bnx2x_vxlan_port_update(struct bnx2x *bp, u16 port)
/* Function parameters */ /* Function parameters */
__set_bit(BNX2X_F_UPDATE_TUNNEL_CFG_CHNG, __set_bit(BNX2X_F_UPDATE_TUNNEL_CFG_CHNG,
&switch_update_params->changes); &switch_update_params->changes);
switch_update_params->vxlan_dst_port = port;
if (bp->udp_tunnel_ports[BNX2X_UDP_PORT_GENEVE].count) {
udp_tunnel = &bp->udp_tunnel_ports[BNX2X_UDP_PORT_GENEVE];
geneve_port = udp_tunnel->dst_port;
switch_update_params->geneve_dst_port = geneve_port;
}
if (bp->udp_tunnel_ports[BNX2X_UDP_PORT_VXLAN].count) {
udp_tunnel = &bp->udp_tunnel_ports[BNX2X_UDP_PORT_VXLAN];
vxlan_port = udp_tunnel->dst_port;
switch_update_params->vxlan_dst_port = vxlan_port;
}
/* Re-enable inner-rss for the offloaded UDP tunnels */
__set_bit(BNX2X_F_UPDATE_TUNNEL_INNER_RSS,
&switch_update_params->changes);
rc = bnx2x_func_state_change(bp, &func_params); rc = bnx2x_func_state_change(bp, &func_params);
if (rc) if (rc)
BNX2X_ERR("failed to change vxlan dst port to %d (rc = 0x%x)\n", BNX2X_ERR("failed to set UDP dst port to %04x %04x (rc = 0x%x)\n",
port, rc); vxlan_port, geneve_port, rc);
else
DP(BNX2X_MSG_SP,
"Configured UDP ports: Vxlan [%04x] Geneve [%04x]\n",
vxlan_port, geneve_port);
return rc; return rc;
} }
static void __bnx2x_add_vxlan_port(struct bnx2x *bp, u16 port) static void __bnx2x_add_udp_port(struct bnx2x *bp, u16 port,
enum bnx2x_udp_port_type type)
{ {
if (!netif_running(bp->dev)) struct bnx2x_udp_tunnel *udp_port = &bp->udp_tunnel_ports[type];
if (!netif_running(bp->dev) || !IS_PF(bp))
return;
if (udp_port->count && udp_port->dst_port == port) {
udp_port->count++;
return; return;
}
if (bp->vxlan_dst_port_count && bp->vxlan_dst_port == port) { if (udp_port->count) {
bp->vxlan_dst_port_count++; DP(BNX2X_MSG_SP,
"UDP tunnel [%d] - destination port limit reached\n",
type);
return; return;
} }
if (bp->vxlan_dst_port_count || !IS_PF(bp)) { udp_port->dst_port = port;
DP(BNX2X_MSG_SP, "Vxlan destination port limit reached\n"); udp_port->count = 1;
bnx2x_schedule_sp_rtnl(bp, BNX2X_SP_RTNL_CHANGE_UDP_PORT, 0);
}
static void __bnx2x_del_udp_port(struct bnx2x *bp, u16 port,
enum bnx2x_udp_port_type type)
{
struct bnx2x_udp_tunnel *udp_port = &bp->udp_tunnel_ports[type];
if (!IS_PF(bp))
return;
if (!udp_port->count || udp_port->dst_port != port) {
DP(BNX2X_MSG_SP, "Invalid UDP tunnel [%d] port\n",
type);
return; return;
} }
bp->vxlan_dst_port = port; /* Remove reference, and make certain it's no longer in use */
bp->vxlan_dst_port_count = 1; udp_port->count--;
bnx2x_schedule_sp_rtnl(bp, BNX2X_SP_RTNL_ADD_VXLAN_PORT, 0); if (udp_port->count)
return;
udp_port->dst_port = 0;
if (netif_running(bp->dev))
bnx2x_schedule_sp_rtnl(bp, BNX2X_SP_RTNL_CHANGE_UDP_PORT, 0);
else
DP(BNX2X_MSG_SP, "Deleted UDP tunnel [%d] port %d\n",
type, port);
} }
#endif
#ifdef CONFIG_BNX2X_VXLAN
static void bnx2x_add_vxlan_port(struct net_device *netdev, static void bnx2x_add_vxlan_port(struct net_device *netdev,
sa_family_t sa_family, __be16 port) sa_family_t sa_family, __be16 port)
{ {
struct bnx2x *bp = netdev_priv(netdev); struct bnx2x *bp = netdev_priv(netdev);
u16 t_port = ntohs(port); u16 t_port = ntohs(port);
__bnx2x_add_vxlan_port(bp, t_port); __bnx2x_add_udp_port(bp, t_port, BNX2X_UDP_PORT_VXLAN);
} }
static void __bnx2x_del_vxlan_port(struct bnx2x *bp, u16 port) static void bnx2x_del_vxlan_port(struct net_device *netdev,
sa_family_t sa_family, __be16 port)
{ {
if (!bp->vxlan_dst_port_count || bp->vxlan_dst_port != port || struct bnx2x *bp = netdev_priv(netdev);
!IS_PF(bp)) { u16 t_port = ntohs(port);
DP(BNX2X_MSG_SP, "Invalid vxlan port\n");
return;
}
bp->vxlan_dst_port_count--;
if (bp->vxlan_dst_port_count)
return;
if (netif_running(bp->dev)) { __bnx2x_del_udp_port(bp, t_port, BNX2X_UDP_PORT_VXLAN);
bnx2x_schedule_sp_rtnl(bp, BNX2X_SP_RTNL_DEL_VXLAN_PORT, 0); }
} else { #endif
bp->vxlan_dst_port = 0;
netdev_info(bp->dev, "Deleted vxlan dest port %d", port); #if IS_ENABLED(CONFIG_GENEVE)
} static void bnx2x_add_geneve_port(struct net_device *netdev,
sa_family_t sa_family, __be16 port)
{
struct bnx2x *bp = netdev_priv(netdev);
u16 t_port = ntohs(port);
__bnx2x_add_udp_port(bp, t_port, BNX2X_UDP_PORT_GENEVE);
} }
static void bnx2x_del_vxlan_port(struct net_device *netdev, static void bnx2x_del_geneve_port(struct net_device *netdev,
sa_family_t sa_family, __be16 port) sa_family_t sa_family, __be16 port)
{ {
struct bnx2x *bp = netdev_priv(netdev); struct bnx2x *bp = netdev_priv(netdev);
u16 t_port = ntohs(port); u16 t_port = ntohs(port);
__bnx2x_del_vxlan_port(bp, t_port); __bnx2x_del_udp_port(bp, t_port, BNX2X_UDP_PORT_GENEVE);
} }
#endif #endif
...@@ -10169,9 +10229,6 @@ static int bnx2x_close(struct net_device *dev); ...@@ -10169,9 +10229,6 @@ static int bnx2x_close(struct net_device *dev);
static void bnx2x_sp_rtnl_task(struct work_struct *work) static void bnx2x_sp_rtnl_task(struct work_struct *work)
{ {
struct bnx2x *bp = container_of(work, struct bnx2x, sp_rtnl_task.work); struct bnx2x *bp = container_of(work, struct bnx2x, sp_rtnl_task.work);
#ifdef CONFIG_BNX2X_VXLAN
u16 port;
#endif
rtnl_lock(); rtnl_lock();
...@@ -10270,23 +10327,27 @@ static void bnx2x_sp_rtnl_task(struct work_struct *work) ...@@ -10270,23 +10327,27 @@ static void bnx2x_sp_rtnl_task(struct work_struct *work)
&bp->sp_rtnl_state)) &bp->sp_rtnl_state))
bnx2x_update_mng_version(bp); bnx2x_update_mng_version(bp);
#ifdef CONFIG_BNX2X_VXLAN #if defined(CONFIG_BNX2X_VXLAN) || IS_ENABLED(CONFIG_GENEVE)
port = bp->vxlan_dst_port; if (test_and_clear_bit(BNX2X_SP_RTNL_CHANGE_UDP_PORT,
if (test_and_clear_bit(BNX2X_SP_RTNL_ADD_VXLAN_PORT,
&bp->sp_rtnl_state)) {
if (!bnx2x_vxlan_port_update(bp, port))
netdev_info(bp->dev, "Added vxlan dest port %d", port);
else
bp->vxlan_dst_port = 0;
}
if (test_and_clear_bit(BNX2X_SP_RTNL_DEL_VXLAN_PORT,
&bp->sp_rtnl_state)) { &bp->sp_rtnl_state)) {
if (!bnx2x_vxlan_port_update(bp, 0)) { if (bnx2x_udp_port_update(bp)) {
netdev_info(bp->dev, /* On error, forget configuration */
"Deleted vxlan dest port %d", port); memset(bp->udp_tunnel_ports, 0,
bp->vxlan_dst_port = 0; sizeof(struct bnx2x_udp_tunnel) *
vxlan_get_rx_port(bp->dev); BNX2X_UDP_PORT_MAX);
} else {
/* Since we don't store additional port information,
* if no port is configured for any feature ask for
* information about currently configured ports.
*/
#ifdef CONFIG_BNX2X_VXLAN
if (!bp->udp_tunnel_ports[BNX2X_UDP_PORT_VXLAN].count)
vxlan_get_rx_port(bp->dev);
#endif
#if IS_ENABLED(CONFIG_GENEVE)
if (!bp->udp_tunnel_ports[BNX2X_UDP_PORT_GENEVE].count)
geneve_get_rx_port(bp->dev);
#endif
} }
} }
#endif #endif
...@@ -12368,8 +12429,10 @@ static int bnx2x_init_bp(struct bnx2x *bp) ...@@ -12368,8 +12429,10 @@ static int bnx2x_init_bp(struct bnx2x *bp)
if (SHMEM2_HAS(bp, dcbx_lldp_params_offset) && if (SHMEM2_HAS(bp, dcbx_lldp_params_offset) &&
SHMEM2_HAS(bp, dcbx_lldp_dcbx_stat_offset) && SHMEM2_HAS(bp, dcbx_lldp_dcbx_stat_offset) &&
SHMEM2_HAS(bp, dcbx_en) &&
SHMEM2_RD(bp, dcbx_lldp_params_offset) && SHMEM2_RD(bp, dcbx_lldp_params_offset) &&
SHMEM2_RD(bp, dcbx_lldp_dcbx_stat_offset)) { SHMEM2_RD(bp, dcbx_lldp_dcbx_stat_offset) &&
SHMEM2_RD(bp, dcbx_en[BP_PORT(bp)])) {
bnx2x_dcbx_set_state(bp, true, BNX2X_DCBX_ENABLED_ON_NEG_ON); bnx2x_dcbx_set_state(bp, true, BNX2X_DCBX_ENABLED_ON_NEG_ON);
bnx2x_dcbx_init_params(bp); bnx2x_dcbx_init_params(bp);
} else { } else {
...@@ -12494,6 +12557,10 @@ static int bnx2x_open(struct net_device *dev) ...@@ -12494,6 +12557,10 @@ static int bnx2x_open(struct net_device *dev)
if (IS_PF(bp)) if (IS_PF(bp))
vxlan_get_rx_port(dev); vxlan_get_rx_port(dev);
#endif #endif
#if IS_ENABLED(CONFIG_GENEVE)
if (IS_PF(bp))
geneve_get_rx_port(dev);
#endif
return 0; return 0;
} }
...@@ -13011,6 +13078,10 @@ static const struct net_device_ops bnx2x_netdev_ops = { ...@@ -13011,6 +13078,10 @@ static const struct net_device_ops bnx2x_netdev_ops = {
.ndo_add_vxlan_port = bnx2x_add_vxlan_port, .ndo_add_vxlan_port = bnx2x_add_vxlan_port,
.ndo_del_vxlan_port = bnx2x_del_vxlan_port, .ndo_del_vxlan_port = bnx2x_del_vxlan_port,
#endif #endif
#if IS_ENABLED(CONFIG_GENEVE)
.ndo_add_geneve_port = bnx2x_add_geneve_port,
.ndo_del_geneve_port = bnx2x_del_geneve_port,
#endif
}; };
static int bnx2x_set_coherency_mask(struct bnx2x *bp) static int bnx2x_set_coherency_mask(struct bnx2x *bp)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册