aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/broadcom
diff options
context:
space:
mode:
authorYuval Mintz <Yuval.Mintz@qlogic.com>2016-02-16 11:07:58 -0500
committerDavid S. Miller <davem@davemloft.net>2016-02-16 20:12:16 -0500
commit883ce97d25b019ce8437ba6f49e38302ca5ec23f (patch)
tree70c8ac3ffd6bcca8743cc3fc996fe641a6b8b731 /drivers/net/ethernet/broadcom
parent445204644ba6e5565d7aba85a4323b52960179db (diff)
bnx2x: Add Geneve inner-RSS support
This adds the ability to perform RSS hashing based on encapsulated headers for a geneve-encapsulated packet. This also changes the Vxlan implementation in bnx2x to be uniform for both vxlan and geneve [from configuration perspective]. Signed-off-by: Yuval Mintz <Yuval.Mintz@qlogic.com> Signed-off-by: Ariel Elior <Ariel.Elior@qlogic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/broadcom')
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x.h19
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h11
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c175
3 files changed, 146 insertions, 59 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
index cae0956186ce..7dd7490fdac1 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
@@ -1277,8 +1277,7 @@ enum sp_rtnl_flag {
1277 BNX2X_SP_RTNL_HYPERVISOR_VLAN, 1277 BNX2X_SP_RTNL_HYPERVISOR_VLAN,
1278 BNX2X_SP_RTNL_TX_STOP, 1278 BNX2X_SP_RTNL_TX_STOP,
1279 BNX2X_SP_RTNL_GET_DRV_VERSION, 1279 BNX2X_SP_RTNL_GET_DRV_VERSION,
1280 BNX2X_SP_RTNL_ADD_VXLAN_PORT, 1280 BNX2X_SP_RTNL_CHANGE_UDP_PORT,
1281 BNX2X_SP_RTNL_DEL_VXLAN_PORT,
1282}; 1281};
1283 1282
1284enum bnx2x_iov_flag { 1283enum bnx2x_iov_flag {
@@ -1327,6 +1326,17 @@ struct bnx2x_vlan_entry {
1327 bool hw; 1326 bool hw;
1328}; 1327};
1329 1328
1329enum bnx2x_udp_port_type {
1330 BNX2X_UDP_PORT_VXLAN,
1331 BNX2X_UDP_PORT_GENEVE,
1332 BNX2X_UDP_PORT_MAX,
1333};
1334
1335struct bnx2x_udp_tunnel {
1336 u16 dst_port;
1337 u8 count;
1338};
1339
1330struct bnx2x { 1340struct bnx2x {
1331 /* Fields used in the tx and intr/napi performance paths 1341 /* Fields used in the tx and intr/napi performance paths
1332 * are grouped together in the beginning of the structure 1342 * are grouped together in the beginning of the structure
@@ -1830,9 +1840,10 @@ struct bnx2x {
1830 struct list_head vlan_reg; 1840 struct list_head vlan_reg;
1831 u16 vlan_cnt; 1841 u16 vlan_cnt;
1832 u16 vlan_credit; 1842 u16 vlan_credit;
1833 u16 vxlan_dst_port;
1834 u8 vxlan_dst_port_count;
1835 bool accept_any_vlan; 1843 bool accept_any_vlan;
1844
1845 /* Vxlan/Geneve related information */
1846 struct bnx2x_udp_tunnel udp_tunnel_ports[BNX2X_UDP_PORT_MAX];
1836}; 1847};
1837 1848
1838/* Tx queues may be less or equal to Rx queues */ 1849/* Tx queues may be less or equal to Rx queues */
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
index 4cbb03f87b5a..37369865ca6d 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
@@ -923,6 +923,7 @@ static inline int bnx2x_func_start(struct bnx2x *bp)
923 struct bnx2x_func_state_params func_params = {NULL}; 923 struct bnx2x_func_state_params func_params = {NULL};
924 struct bnx2x_func_start_params *start_params = 924 struct bnx2x_func_start_params *start_params =
925 &func_params.params.start; 925 &func_params.params.start;
926 u16 port;
926 927
927 /* Prepare parameters for function state transitions */ 928 /* Prepare parameters for function state transitions */
928 __set_bit(RAMROD_COMP_WAIT, &func_params.ramrod_flags); 929 __set_bit(RAMROD_COMP_WAIT, &func_params.ramrod_flags);
@@ -959,8 +960,14 @@ static inline int bnx2x_func_start(struct bnx2x *bp)
959 start_params->network_cos_mode = STATIC_COS; 960 start_params->network_cos_mode = STATIC_COS;
960 else /* CHIP_IS_E1X */ 961 else /* CHIP_IS_E1X */
961 start_params->network_cos_mode = FW_WRR; 962 start_params->network_cos_mode = FW_WRR;
962 963 if (bp->udp_tunnel_ports[BNX2X_UDP_PORT_VXLAN].count) {
963 start_params->vxlan_dst_port = bp->vxlan_dst_port; 964 port = bp->udp_tunnel_ports[BNX2X_UDP_PORT_VXLAN].dst_port;
965 start_params->vxlan_dst_port = port;
966 }
967 if (bp->udp_tunnel_ports[BNX2X_UDP_PORT_GENEVE].count) {
968 port = bp->udp_tunnel_ports[BNX2X_UDP_PORT_GENEVE].dst_port;
969 start_params->geneve_dst_port = port;
970 }
964 971
965 start_params->inner_rss = 1; 972 start_params->inner_rss = 1;
966 973
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 6c4e3a69976f..5d6b2d95eb9d 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -59,7 +59,9 @@
59#include <linux/semaphore.h> 59#include <linux/semaphore.h>
60#include <linux/stringify.h> 60#include <linux/stringify.h>
61#include <linux/vmalloc.h> 61#include <linux/vmalloc.h>
62 62#if IS_ENABLED(CONFIG_GENEVE)
63#include <net/geneve.h>
64#endif
63#include "bnx2x.h" 65#include "bnx2x.h"
64#include "bnx2x_init.h" 66#include "bnx2x_init.h"
65#include "bnx2x_init_ops.h" 67#include "bnx2x_init_ops.h"
@@ -10076,11 +10078,13 @@ static void bnx2x_parity_recover(struct bnx2x *bp)
10076 } 10078 }
10077} 10079}
10078 10080
10079#ifdef CONFIG_BNX2X_VXLAN 10081#if defined(CONFIG_BNX2X_VXLAN) || IS_ENABLED(CONFIG_GENEVE)
10080static int bnx2x_vxlan_port_update(struct bnx2x *bp, u16 port) 10082static int bnx2x_udp_port_update(struct bnx2x *bp)
10081{ 10083{
10082 struct bnx2x_func_switch_update_params *switch_update_params; 10084 struct bnx2x_func_switch_update_params *switch_update_params;
10083 struct bnx2x_func_state_params func_params = {NULL}; 10085 struct bnx2x_func_state_params func_params = {NULL};
10086 struct bnx2x_udp_tunnel *udp_tunnel;
10087 u16 vxlan_port = 0, geneve_port = 0;
10084 int rc; 10088 int rc;
10085 10089
10086 switch_update_params = &func_params.params.switch_update; 10090 switch_update_params = &func_params.params.switch_update;
@@ -10095,69 +10099,125 @@ static int bnx2x_vxlan_port_update(struct bnx2x *bp, u16 port)
10095 /* Function parameters */ 10099 /* Function parameters */
10096 __set_bit(BNX2X_F_UPDATE_TUNNEL_CFG_CHNG, 10100 __set_bit(BNX2X_F_UPDATE_TUNNEL_CFG_CHNG,
10097 &switch_update_params->changes); 10101 &switch_update_params->changes);
10098 switch_update_params->vxlan_dst_port = port; 10102
10103 if (bp->udp_tunnel_ports[BNX2X_UDP_PORT_GENEVE].count) {
10104 udp_tunnel = &bp->udp_tunnel_ports[BNX2X_UDP_PORT_GENEVE];
10105 geneve_port = udp_tunnel->dst_port;
10106 switch_update_params->geneve_dst_port = geneve_port;
10107 }
10108
10109 if (bp->udp_tunnel_ports[BNX2X_UDP_PORT_VXLAN].count) {
10110 udp_tunnel = &bp->udp_tunnel_ports[BNX2X_UDP_PORT_VXLAN];
10111 vxlan_port = udp_tunnel->dst_port;
10112 switch_update_params->vxlan_dst_port = vxlan_port;
10113 }
10114
10115 /* Re-enable inner-rss for the offloaded UDP tunnels */
10116 __set_bit(BNX2X_F_UPDATE_TUNNEL_INNER_RSS,
10117 &switch_update_params->changes);
10118
10099 rc = bnx2x_func_state_change(bp, &func_params); 10119 rc = bnx2x_func_state_change(bp, &func_params);
10100 if (rc) 10120 if (rc)
10101 BNX2X_ERR("failed to change vxlan dst port to %d (rc = 0x%x)\n", 10121 BNX2X_ERR("failed to set UDP dst port to %04x %04x (rc = 0x%x)\n",
10102 port, rc); 10122 vxlan_port, geneve_port, rc);
10123 else
10124 DP(BNX2X_MSG_SP,
10125 "Configured UDP ports: Vxlan [%04x] Geneve [%04x]\n",
10126 vxlan_port, geneve_port);
10127
10103 return rc; 10128 return rc;
10104} 10129}
10105 10130
10106static void __bnx2x_add_vxlan_port(struct bnx2x *bp, u16 port) 10131static void __bnx2x_add_udp_port(struct bnx2x *bp, u16 port,
10132 enum bnx2x_udp_port_type type)
10107{ 10133{
10108 if (!netif_running(bp->dev)) 10134 struct bnx2x_udp_tunnel *udp_port = &bp->udp_tunnel_ports[type];
10135
10136 if (!netif_running(bp->dev) || !IS_PF(bp))
10137 return;
10138
10139 if (udp_port->count && udp_port->dst_port == port) {
10140 udp_port->count++;
10109 return; 10141 return;
10142 }
10110 10143
10111 if (bp->vxlan_dst_port_count && bp->vxlan_dst_port == port) { 10144 if (udp_port->count) {
10112 bp->vxlan_dst_port_count++; 10145 DP(BNX2X_MSG_SP,
10146 "UDP tunnel [%d] - destination port limit reached\n",
10147 type);
10113 return; 10148 return;
10114 } 10149 }
10115 10150
10116 if (bp->vxlan_dst_port_count || !IS_PF(bp)) { 10151 udp_port->dst_port = port;
10117 DP(BNX2X_MSG_SP, "Vxlan destination port limit reached\n"); 10152 udp_port->count = 1;
10153 bnx2x_schedule_sp_rtnl(bp, BNX2X_SP_RTNL_CHANGE_UDP_PORT, 0);
10154}
10155
10156static void __bnx2x_del_udp_port(struct bnx2x *bp, u16 port,
10157 enum bnx2x_udp_port_type type)
10158{
10159 struct bnx2x_udp_tunnel *udp_port = &bp->udp_tunnel_ports[type];
10160
10161 if (!IS_PF(bp))
10162 return;
10163
10164 if (!udp_port->count || udp_port->dst_port != port) {
10165 DP(BNX2X_MSG_SP, "Invalid UDP tunnel [%d] port\n",
10166 type);
10118 return; 10167 return;
10119 } 10168 }
10120 10169
10121 bp->vxlan_dst_port = port; 10170 /* Remove reference, and make certain it's no longer in use */
10122 bp->vxlan_dst_port_count = 1; 10171 udp_port->count--;
10123 bnx2x_schedule_sp_rtnl(bp, BNX2X_SP_RTNL_ADD_VXLAN_PORT, 0); 10172 if (udp_port->count)
10173 return;
10174 udp_port->dst_port = 0;
10175
10176 if (netif_running(bp->dev))
10177 bnx2x_schedule_sp_rtnl(bp, BNX2X_SP_RTNL_CHANGE_UDP_PORT, 0);
10178 else
10179 DP(BNX2X_MSG_SP, "Deleted UDP tunnel [%d] port %d\n",
10180 type, port);
10124} 10181}
10182#endif
10125 10183
10184#ifdef CONFIG_BNX2X_VXLAN
10126static void bnx2x_add_vxlan_port(struct net_device *netdev, 10185static void bnx2x_add_vxlan_port(struct net_device *netdev,
10127 sa_family_t sa_family, __be16 port) 10186 sa_family_t sa_family, __be16 port)
10128{ 10187{
10129 struct bnx2x *bp = netdev_priv(netdev); 10188 struct bnx2x *bp = netdev_priv(netdev);
10130 u16 t_port = ntohs(port); 10189 u16 t_port = ntohs(port);
10131 10190
10132 __bnx2x_add_vxlan_port(bp, t_port); 10191 __bnx2x_add_udp_port(bp, t_port, BNX2X_UDP_PORT_VXLAN);
10133} 10192}
10134 10193
10135static void __bnx2x_del_vxlan_port(struct bnx2x *bp, u16 port) 10194static void bnx2x_del_vxlan_port(struct net_device *netdev,
10195 sa_family_t sa_family, __be16 port)
10136{ 10196{
10137 if (!bp->vxlan_dst_port_count || bp->vxlan_dst_port != port || 10197 struct bnx2x *bp = netdev_priv(netdev);
10138 !IS_PF(bp)) { 10198 u16 t_port = ntohs(port);
10139 DP(BNX2X_MSG_SP, "Invalid vxlan port\n");
10140 return;
10141 }
10142 bp->vxlan_dst_port_count--;
10143 if (bp->vxlan_dst_port_count)
10144 return;
10145 10199
10146 if (netif_running(bp->dev)) { 10200 __bnx2x_del_udp_port(bp, t_port, BNX2X_UDP_PORT_VXLAN);
10147 bnx2x_schedule_sp_rtnl(bp, BNX2X_SP_RTNL_DEL_VXLAN_PORT, 0); 10201}
10148 } else { 10202#endif
10149 bp->vxlan_dst_port = 0; 10203
10150 netdev_info(bp->dev, "Deleted vxlan dest port %d", port); 10204#if IS_ENABLED(CONFIG_GENEVE)
10151 } 10205static void bnx2x_add_geneve_port(struct net_device *netdev,
10206 sa_family_t sa_family, __be16 port)
10207{
10208 struct bnx2x *bp = netdev_priv(netdev);
10209 u16 t_port = ntohs(port);
10210
10211 __bnx2x_add_udp_port(bp, t_port, BNX2X_UDP_PORT_GENEVE);
10152} 10212}
10153 10213
10154static void bnx2x_del_vxlan_port(struct net_device *netdev, 10214static void bnx2x_del_geneve_port(struct net_device *netdev,
10155 sa_family_t sa_family, __be16 port) 10215 sa_family_t sa_family, __be16 port)
10156{ 10216{
10157 struct bnx2x *bp = netdev_priv(netdev); 10217 struct bnx2x *bp = netdev_priv(netdev);
10158 u16 t_port = ntohs(port); 10218 u16 t_port = ntohs(port);
10159 10219
10160 __bnx2x_del_vxlan_port(bp, t_port); 10220 __bnx2x_del_udp_port(bp, t_port, BNX2X_UDP_PORT_GENEVE);
10161} 10221}
10162#endif 10222#endif
10163 10223
@@ -10169,9 +10229,6 @@ static int bnx2x_close(struct net_device *dev);
10169static void bnx2x_sp_rtnl_task(struct work_struct *work) 10229static void bnx2x_sp_rtnl_task(struct work_struct *work)
10170{ 10230{
10171 struct bnx2x *bp = container_of(work, struct bnx2x, sp_rtnl_task.work); 10231 struct bnx2x *bp = container_of(work, struct bnx2x, sp_rtnl_task.work);
10172#ifdef CONFIG_BNX2X_VXLAN
10173 u16 port;
10174#endif
10175 10232
10176 rtnl_lock(); 10233 rtnl_lock();
10177 10234
@@ -10270,23 +10327,27 @@ sp_rtnl_not_reset:
10270 &bp->sp_rtnl_state)) 10327 &bp->sp_rtnl_state))
10271 bnx2x_update_mng_version(bp); 10328 bnx2x_update_mng_version(bp);
10272 10329
10273#ifdef CONFIG_BNX2X_VXLAN 10330#if defined(CONFIG_BNX2X_VXLAN) || IS_ENABLED(CONFIG_GENEVE)
10274 port = bp->vxlan_dst_port; 10331 if (test_and_clear_bit(BNX2X_SP_RTNL_CHANGE_UDP_PORT,
10275 if (test_and_clear_bit(BNX2X_SP_RTNL_ADD_VXLAN_PORT,
10276 &bp->sp_rtnl_state)) {
10277 if (!bnx2x_vxlan_port_update(bp, port))
10278 netdev_info(bp->dev, "Added vxlan dest port %d", port);
10279 else
10280 bp->vxlan_dst_port = 0;
10281 }
10282
10283 if (test_and_clear_bit(BNX2X_SP_RTNL_DEL_VXLAN_PORT,
10284 &bp->sp_rtnl_state)) { 10332 &bp->sp_rtnl_state)) {
10285 if (!bnx2x_vxlan_port_update(bp, 0)) { 10333 if (bnx2x_udp_port_update(bp)) {
10286 netdev_info(bp->dev, 10334 /* On error, forget configuration */
10287 "Deleted vxlan dest port %d", port); 10335 memset(bp->udp_tunnel_ports, 0,
10288 bp->vxlan_dst_port = 0; 10336 sizeof(struct bnx2x_udp_tunnel) *
10289 vxlan_get_rx_port(bp->dev); 10337 BNX2X_UDP_PORT_MAX);
10338 } else {
10339 /* Since we don't store additional port information,
10340 * if no port is configured for any feature ask for
10341 * information about currently configured ports.
10342 */
10343#ifdef CONFIG_BNX2X_VXLAN
10344 if (!bp->udp_tunnel_ports[BNX2X_UDP_PORT_VXLAN].count)
10345 vxlan_get_rx_port(bp->dev);
10346#endif
10347#if IS_ENABLED(CONFIG_GENEVE)
10348 if (!bp->udp_tunnel_ports[BNX2X_UDP_PORT_GENEVE].count)
10349 geneve_get_rx_port(bp->dev);
10350#endif
10290 } 10351 }
10291 } 10352 }
10292#endif 10353#endif
@@ -12494,6 +12555,10 @@ static int bnx2x_open(struct net_device *dev)
12494 if (IS_PF(bp)) 12555 if (IS_PF(bp))
12495 vxlan_get_rx_port(dev); 12556 vxlan_get_rx_port(dev);
12496#endif 12557#endif
12558#if IS_ENABLED(CONFIG_GENEVE)
12559 if (IS_PF(bp))
12560 geneve_get_rx_port(dev);
12561#endif
12497 12562
12498 return 0; 12563 return 0;
12499} 12564}
@@ -13011,6 +13076,10 @@ static const struct net_device_ops bnx2x_netdev_ops = {
13011 .ndo_add_vxlan_port = bnx2x_add_vxlan_port, 13076 .ndo_add_vxlan_port = bnx2x_add_vxlan_port,
13012 .ndo_del_vxlan_port = bnx2x_del_vxlan_port, 13077 .ndo_del_vxlan_port = bnx2x_del_vxlan_port,
13013#endif 13078#endif
13079#if IS_ENABLED(CONFIG_GENEVE)
13080 .ndo_add_geneve_port = bnx2x_add_geneve_port,
13081 .ndo_del_geneve_port = bnx2x_del_geneve_port,
13082#endif
13014}; 13083};
13015 13084
13016static int bnx2x_set_coherency_mask(struct bnx2x *bp) 13085static int bnx2x_set_coherency_mask(struct bnx2x *bp)