瀏覽代碼

qlcnic: track vxlan port count

The callback for adding vxlan port can be called with the same port for
both IPv4 and IPv6. Do not disable the offloading when the same port for
both protocols is added and later one of them removed.

Signed-off-by: Jiri Benc <jbenc@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Jiri Benc 10 年之前
父節點
當前提交
378fddc281
共有 2 個文件被更改,包括 14 次插入5 次删除
  1. 1 0
      drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
  2. 13 5
      drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c

+ 1 - 0
drivers/net/ethernet/qlogic/qlcnic/qlcnic.h

@@ -536,6 +536,7 @@ struct qlcnic_hardware_context {
 	u8 extend_lb_time;
 	u8 extend_lb_time;
 	u8 phys_port_id[ETH_ALEN];
 	u8 phys_port_id[ETH_ALEN];
 	u8 lb_mode;
 	u8 lb_mode;
+	u8 vxlan_port_count;
 	u16 vxlan_port;
 	u16 vxlan_port;
 	struct device *hwmon_dev;
 	struct device *hwmon_dev;
 	u32 post_mode;
 	u32 post_mode;

+ 13 - 5
drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c

@@ -483,11 +483,17 @@ static void qlcnic_add_vxlan_port(struct net_device *netdev,
 	/* Adapter supports only one VXLAN port. Use very first port
 	/* Adapter supports only one VXLAN port. Use very first port
 	 * for enabling offload
 	 * for enabling offload
 	 */
 	 */
-	if (!qlcnic_encap_rx_offload(adapter) || ahw->vxlan_port)
+	if (!qlcnic_encap_rx_offload(adapter))
 		return;
 		return;
+	if (!ahw->vxlan_port_count) {
+		ahw->vxlan_port_count = 1;
+		ahw->vxlan_port = ntohs(port);
+		adapter->flags |= QLCNIC_ADD_VXLAN_PORT;
+		return;
+	}
+	if (ahw->vxlan_port == ntohs(port))
+		ahw->vxlan_port_count++;
 
 
-	ahw->vxlan_port = ntohs(port);
-	adapter->flags |= QLCNIC_ADD_VXLAN_PORT;
 }
 }
 
 
 static void qlcnic_del_vxlan_port(struct net_device *netdev,
 static void qlcnic_del_vxlan_port(struct net_device *netdev,
@@ -496,11 +502,13 @@ static void qlcnic_del_vxlan_port(struct net_device *netdev,
 	struct qlcnic_adapter *adapter = netdev_priv(netdev);
 	struct qlcnic_adapter *adapter = netdev_priv(netdev);
 	struct qlcnic_hardware_context *ahw = adapter->ahw;
 	struct qlcnic_hardware_context *ahw = adapter->ahw;
 
 
-	if (!qlcnic_encap_rx_offload(adapter) || !ahw->vxlan_port ||
+	if (!qlcnic_encap_rx_offload(adapter) || !ahw->vxlan_port_count ||
 	    (ahw->vxlan_port != ntohs(port)))
 	    (ahw->vxlan_port != ntohs(port)))
 		return;
 		return;
 
 
-	adapter->flags |= QLCNIC_DEL_VXLAN_PORT;
+	ahw->vxlan_port_count--;
+	if (!ahw->vxlan_port_count)
+		adapter->flags |= QLCNIC_DEL_VXLAN_PORT;
 }
 }
 
 
 static netdev_features_t qlcnic_features_check(struct sk_buff *skb,
 static netdev_features_t qlcnic_features_check(struct sk_buff *skb,