diff options
author | Shahed Shaikh <shahed.shaikh@qlogic.com> | 2014-03-21 04:41:17 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-03-24 00:44:23 -0400 |
commit | 2b3d7b758c68775cdebd95787454d12e0b8247e7 (patch) | |
tree | bdd7a6ba0ae3c31914d29ecb47d34309a4ddd676 /drivers/net/ethernet/qlogic | |
parent | 381709de1582ed868161d37a1ad54ba110c4353c (diff) |
qlcnic: Add VXLAN Rx offload support
This patch adds Rx checksum offload support for VXLAN.
Implements .ndo_{add|del}_vxlan_port netdev ops.
Adapter supports only one VXLAN port, so program adapter with
very first UDP port which VXLAN driver is listening to.
Signed-off-by: Shahed Shaikh <shahed.shaikh@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/qlogic')
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 11 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | 87 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c | 13 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 38 |
8 files changed, 156 insertions, 2 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h index 5c48263207dd..59255fb8cded 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | |||
@@ -535,6 +535,7 @@ struct qlcnic_hardware_context { | |||
535 | u8 extend_lb_time; | 535 | u8 extend_lb_time; |
536 | u8 phys_port_id[ETH_ALEN]; | 536 | u8 phys_port_id[ETH_ALEN]; |
537 | u8 lb_mode; | 537 | u8 lb_mode; |
538 | u16 vxlan_port; | ||
538 | }; | 539 | }; |
539 | 540 | ||
540 | struct qlcnic_adapter_stats { | 541 | struct qlcnic_adapter_stats { |
@@ -551,6 +552,7 @@ struct qlcnic_adapter_stats { | |||
551 | u64 lso_frames; | 552 | u64 lso_frames; |
552 | u64 encap_lso_frames; | 553 | u64 encap_lso_frames; |
553 | u64 encap_tx_csummed; | 554 | u64 encap_tx_csummed; |
555 | u64 encap_rx_csummed; | ||
554 | u64 xmit_on; | 556 | u64 xmit_on; |
555 | u64 xmit_off; | 557 | u64 xmit_off; |
556 | u64 skb_alloc_failure; | 558 | u64 skb_alloc_failure; |
@@ -912,6 +914,7 @@ struct qlcnic_mac_vlan_list { | |||
912 | #define QLCNIC_FW_CAPABILITY_2_BEACON BIT_7 | 914 | #define QLCNIC_FW_CAPABILITY_2_BEACON BIT_7 |
913 | #define QLCNIC_FW_CAPABILITY_2_PER_PORT_ESWITCH_CFG BIT_9 | 915 | #define QLCNIC_FW_CAPABILITY_2_PER_PORT_ESWITCH_CFG BIT_9 |
914 | 916 | ||
917 | #define QLCNIC_83XX_FW_CAPAB_ENCAP_RX_OFFLOAD BIT_0 | ||
915 | #define QLCNIC_83XX_FW_CAPAB_ENCAP_TX_OFFLOAD BIT_1 | 918 | #define QLCNIC_83XX_FW_CAPAB_ENCAP_TX_OFFLOAD BIT_1 |
916 | #define QLCNIC_83XX_FW_CAPAB_ENCAP_CKO_OFFLOAD BIT_4 | 919 | #define QLCNIC_83XX_FW_CAPAB_ENCAP_CKO_OFFLOAD BIT_4 |
917 | 920 | ||
@@ -1008,6 +1011,8 @@ struct qlcnic_ipaddr { | |||
1008 | #define QLCNIC_APP_CHANGED_FLAGS 0x20000 | 1011 | #define QLCNIC_APP_CHANGED_FLAGS 0x20000 |
1009 | #define QLCNIC_HAS_PHYS_PORT_ID 0x40000 | 1012 | #define QLCNIC_HAS_PHYS_PORT_ID 0x40000 |
1010 | #define QLCNIC_TSS_RSS 0x80000 | 1013 | #define QLCNIC_TSS_RSS 0x80000 |
1014 | #define QLCNIC_ADD_VXLAN_PORT 0x100000 | ||
1015 | #define QLCNIC_DEL_VXLAN_PORT 0x200000 | ||
1011 | 1016 | ||
1012 | #define QLCNIC_IS_MSI_FAMILY(adapter) \ | 1017 | #define QLCNIC_IS_MSI_FAMILY(adapter) \ |
1013 | ((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED)) | 1018 | ((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED)) |
@@ -1828,6 +1833,12 @@ static inline bool qlcnic_encap_tx_offload(struct qlcnic_adapter *adapter) | |||
1828 | QLCNIC_83XX_FW_CAPAB_ENCAP_TX_OFFLOAD; | 1833 | QLCNIC_83XX_FW_CAPAB_ENCAP_TX_OFFLOAD; |
1829 | } | 1834 | } |
1830 | 1835 | ||
1836 | static inline bool qlcnic_encap_rx_offload(struct qlcnic_adapter *adapter) | ||
1837 | { | ||
1838 | return adapter->ahw->extra_capability[0] & | ||
1839 | QLCNIC_83XX_FW_CAPAB_ENCAP_RX_OFFLOAD; | ||
1840 | } | ||
1841 | |||
1831 | static inline int qlcnic_start_firmware(struct qlcnic_adapter *adapter) | 1842 | static inline int qlcnic_start_firmware(struct qlcnic_adapter *adapter) |
1832 | { | 1843 | { |
1833 | return adapter->nic_ops->start_firmware(adapter); | 1844 | return adapter->nic_ops->start_firmware(adapter); |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c index 3b83fbde4975..b7cffb46a75d 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | |||
@@ -77,7 +77,7 @@ static const struct qlcnic_mailbox_metadata qlcnic_83xx_mbx_tbl[] = { | |||
77 | {QLCNIC_CMD_GET_PORT_CONFIG, 2, 2}, | 77 | {QLCNIC_CMD_GET_PORT_CONFIG, 2, 2}, |
78 | {QLCNIC_CMD_GET_LINK_STATUS, 2, 4}, | 78 | {QLCNIC_CMD_GET_LINK_STATUS, 2, 4}, |
79 | {QLCNIC_CMD_IDC_ACK, 5, 1}, | 79 | {QLCNIC_CMD_IDC_ACK, 5, 1}, |
80 | {QLCNIC_CMD_INIT_NIC_FUNC, 2, 1}, | 80 | {QLCNIC_CMD_INIT_NIC_FUNC, 3, 1}, |
81 | {QLCNIC_CMD_STOP_NIC_FUNC, 2, 1}, | 81 | {QLCNIC_CMD_STOP_NIC_FUNC, 2, 1}, |
82 | {QLCNIC_CMD_SET_LED_CONFIG, 5, 1}, | 82 | {QLCNIC_CMD_SET_LED_CONFIG, 5, 1}, |
83 | {QLCNIC_CMD_GET_LED_CONFIG, 1, 5}, | 83 | {QLCNIC_CMD_GET_LED_CONFIG, 1, 5}, |
@@ -87,6 +87,7 @@ static const struct qlcnic_mailbox_metadata qlcnic_83xx_mbx_tbl[] = { | |||
87 | {QLCNIC_CMD_BC_EVENT_SETUP, 2, 1}, | 87 | {QLCNIC_CMD_BC_EVENT_SETUP, 2, 1}, |
88 | {QLCNIC_CMD_DCB_QUERY_CAP, 1, 2}, | 88 | {QLCNIC_CMD_DCB_QUERY_CAP, 1, 2}, |
89 | {QLCNIC_CMD_DCB_QUERY_PARAM, 1, 50}, | 89 | {QLCNIC_CMD_DCB_QUERY_PARAM, 1, 50}, |
90 | {QLCNIC_CMD_SET_INGRESS_ENCAP, 2, 1}, | ||
90 | }; | 91 | }; |
91 | 92 | ||
92 | const u32 qlcnic_83xx_ext_reg_tbl[] = { | 93 | const u32 qlcnic_83xx_ext_reg_tbl[] = { |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h index 81c1889f6f3e..88d809c35633 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h | |||
@@ -528,8 +528,9 @@ enum qlc_83xx_ext_regs { | |||
528 | }; | 528 | }; |
529 | 529 | ||
530 | /* Initialize/Stop NIC command bit definitions */ | 530 | /* Initialize/Stop NIC command bit definitions */ |
531 | #define QLC_REGISTER_DCB_AEN BIT_1 | ||
532 | #define QLC_REGISTER_LB_IDC BIT_0 | 531 | #define QLC_REGISTER_LB_IDC BIT_0 |
532 | #define QLC_REGISTER_DCB_AEN BIT_1 | ||
533 | #define QLC_83XX_MULTI_TENANCY_INFO BIT_29 | ||
533 | #define QLC_INIT_FW_RESOURCES BIT_31 | 534 | #define QLC_INIT_FW_RESOURCES BIT_31 |
534 | 535 | ||
535 | /* 83xx funcitons */ | 536 | /* 83xx funcitons */ |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c index 90a2dda351ec..ec399b7f5bd7 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | |||
@@ -1020,10 +1020,97 @@ static int qlcnic_83xx_idc_check_state_validity(struct qlcnic_adapter *adapter, | |||
1020 | return 0; | 1020 | return 0; |
1021 | } | 1021 | } |
1022 | 1022 | ||
1023 | #define QLC_83XX_ENCAP_TYPE_VXLAN BIT_1 | ||
1024 | #define QLC_83XX_MATCH_ENCAP_ID BIT_2 | ||
1025 | #define QLC_83XX_SET_VXLAN_UDP_DPORT BIT_3 | ||
1026 | #define QLC_83XX_VXLAN_UDP_DPORT(PORT) ((PORT & 0xffff) << 16) | ||
1027 | |||
1028 | #define QLCNIC_ENABLE_INGRESS_ENCAP_PARSING 1 | ||
1029 | #define QLCNIC_DISABLE_INGRESS_ENCAP_PARSING 0 | ||
1030 | |||
1031 | static int qlcnic_set_vxlan_port(struct qlcnic_adapter *adapter) | ||
1032 | { | ||
1033 | u16 port = adapter->ahw->vxlan_port; | ||
1034 | struct qlcnic_cmd_args cmd; | ||
1035 | int ret = 0; | ||
1036 | |||
1037 | memset(&cmd, 0, sizeof(cmd)); | ||
1038 | |||
1039 | ret = qlcnic_alloc_mbx_args(&cmd, adapter, | ||
1040 | QLCNIC_CMD_INIT_NIC_FUNC); | ||
1041 | if (ret) | ||
1042 | return ret; | ||
1043 | |||
1044 | cmd.req.arg[1] = QLC_83XX_MULTI_TENANCY_INFO; | ||
1045 | cmd.req.arg[2] = QLC_83XX_ENCAP_TYPE_VXLAN | | ||
1046 | QLC_83XX_SET_VXLAN_UDP_DPORT | | ||
1047 | QLC_83XX_VXLAN_UDP_DPORT(port); | ||
1048 | |||
1049 | ret = qlcnic_issue_cmd(adapter, &cmd); | ||
1050 | if (ret) | ||
1051 | netdev_err(adapter->netdev, | ||
1052 | "Failed to set VXLAN port %d in adapter\n", | ||
1053 | port); | ||
1054 | |||
1055 | qlcnic_free_mbx_args(&cmd); | ||
1056 | |||
1057 | return ret; | ||
1058 | } | ||
1059 | |||
1060 | static int qlcnic_set_vxlan_parsing(struct qlcnic_adapter *adapter, | ||
1061 | bool state) | ||
1062 | { | ||
1063 | u16 vxlan_port = adapter->ahw->vxlan_port; | ||
1064 | struct qlcnic_cmd_args cmd; | ||
1065 | int ret = 0; | ||
1066 | |||
1067 | memset(&cmd, 0, sizeof(cmd)); | ||
1068 | |||
1069 | ret = qlcnic_alloc_mbx_args(&cmd, adapter, | ||
1070 | QLCNIC_CMD_SET_INGRESS_ENCAP); | ||
1071 | if (ret) | ||
1072 | return ret; | ||
1073 | |||
1074 | cmd.req.arg[1] = state ? QLCNIC_ENABLE_INGRESS_ENCAP_PARSING : | ||
1075 | QLCNIC_DISABLE_INGRESS_ENCAP_PARSING; | ||
1076 | |||
1077 | ret = qlcnic_issue_cmd(adapter, &cmd); | ||
1078 | if (ret) | ||
1079 | netdev_err(adapter->netdev, | ||
1080 | "Failed to %s VXLAN parsing for port %d\n", | ||
1081 | state ? "enable" : "disable", vxlan_port); | ||
1082 | else | ||
1083 | netdev_info(adapter->netdev, | ||
1084 | "%s VXLAN parsing for port %d\n", | ||
1085 | state ? "Enabled" : "Disabled", vxlan_port); | ||
1086 | |||
1087 | qlcnic_free_mbx_args(&cmd); | ||
1088 | |||
1089 | return ret; | ||
1090 | } | ||
1091 | |||
1023 | static void qlcnic_83xx_periodic_tasks(struct qlcnic_adapter *adapter) | 1092 | static void qlcnic_83xx_periodic_tasks(struct qlcnic_adapter *adapter) |
1024 | { | 1093 | { |
1094 | struct qlcnic_hardware_context *ahw = adapter->ahw; | ||
1095 | |||
1025 | if (adapter->fhash.fnum) | 1096 | if (adapter->fhash.fnum) |
1026 | qlcnic_prune_lb_filters(adapter); | 1097 | qlcnic_prune_lb_filters(adapter); |
1098 | |||
1099 | if (adapter->flags & QLCNIC_ADD_VXLAN_PORT) { | ||
1100 | if (qlcnic_set_vxlan_port(adapter)) | ||
1101 | return; | ||
1102 | |||
1103 | if (qlcnic_set_vxlan_parsing(adapter, true)) | ||
1104 | return; | ||
1105 | |||
1106 | adapter->flags &= ~QLCNIC_ADD_VXLAN_PORT; | ||
1107 | } else if (adapter->flags & QLCNIC_DEL_VXLAN_PORT) { | ||
1108 | if (qlcnic_set_vxlan_parsing(adapter, false)) | ||
1109 | return; | ||
1110 | |||
1111 | ahw->vxlan_port = 0; | ||
1112 | adapter->flags &= ~QLCNIC_DEL_VXLAN_PORT; | ||
1113 | } | ||
1027 | } | 1114 | } |
1028 | 1115 | ||
1029 | /** | 1116 | /** |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c index dfc25f7c2cf2..5bacf5210aed 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c | |||
@@ -51,6 +51,8 @@ static const struct qlcnic_stats qlcnic_gstrings_stats[] = { | |||
51 | QLC_OFF(stats.encap_lso_frames)}, | 51 | QLC_OFF(stats.encap_lso_frames)}, |
52 | {"encap_tx_csummed", QLC_SIZEOF(stats.encap_tx_csummed), | 52 | {"encap_tx_csummed", QLC_SIZEOF(stats.encap_tx_csummed), |
53 | QLC_OFF(stats.encap_tx_csummed)}, | 53 | QLC_OFF(stats.encap_tx_csummed)}, |
54 | {"encap_rx_csummed", QLC_SIZEOF(stats.encap_rx_csummed), | ||
55 | QLC_OFF(stats.encap_rx_csummed)}, | ||
54 | {"skb_alloc_failure", QLC_SIZEOF(stats.skb_alloc_failure), | 56 | {"skb_alloc_failure", QLC_SIZEOF(stats.skb_alloc_failure), |
55 | QLC_OFF(stats.skb_alloc_failure)}, | 57 | QLC_OFF(stats.skb_alloc_failure)}, |
56 | {"mac_filter_limit_overrun", QLC_SIZEOF(stats.mac_filter_limit_overrun), | 58 | {"mac_filter_limit_overrun", QLC_SIZEOF(stats.mac_filter_limit_overrun), |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h index 576b301b11ef..cbe2399c30a0 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h | |||
@@ -98,6 +98,7 @@ enum qlcnic_regs { | |||
98 | #define QLCNIC_CMD_GET_LINK_EVENT 0x48 | 98 | #define QLCNIC_CMD_GET_LINK_EVENT 0x48 |
99 | #define QLCNIC_CMD_CONFIGURE_MAC_RX_MODE 0x49 | 99 | #define QLCNIC_CMD_CONFIGURE_MAC_RX_MODE 0x49 |
100 | #define QLCNIC_CMD_CONFIGURE_HW_LRO 0x4A | 100 | #define QLCNIC_CMD_CONFIGURE_HW_LRO 0x4A |
101 | #define QLCNIC_CMD_SET_INGRESS_ENCAP 0x4E | ||
101 | #define QLCNIC_CMD_INIT_NIC_FUNC 0x60 | 102 | #define QLCNIC_CMD_INIT_NIC_FUNC 0x60 |
102 | #define QLCNIC_CMD_STOP_NIC_FUNC 0x61 | 103 | #define QLCNIC_CMD_STOP_NIC_FUNC 0x61 |
103 | #define QLCNIC_CMD_IDC_ACK 0x63 | 104 | #define QLCNIC_CMD_IDC_ACK 0x63 |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c index 7252af99ad01..173b3d12991f 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c | |||
@@ -1703,6 +1703,13 @@ static inline int qlcnic_83xx_is_lb_pkt(u64 sts_data, int lro_pkt) | |||
1703 | return (sts_data & QLC_83XX_NORMAL_LB_PKT) ? 1 : 0; | 1703 | return (sts_data & QLC_83XX_NORMAL_LB_PKT) ? 1 : 0; |
1704 | } | 1704 | } |
1705 | 1705 | ||
1706 | #define QLCNIC_ENCAP_LENGTH_MASK 0x7f | ||
1707 | |||
1708 | static inline u8 qlcnic_encap_length(u64 sts_data) | ||
1709 | { | ||
1710 | return sts_data & QLCNIC_ENCAP_LENGTH_MASK; | ||
1711 | } | ||
1712 | |||
1706 | static struct qlcnic_rx_buffer * | 1713 | static struct qlcnic_rx_buffer * |
1707 | qlcnic_83xx_process_rcv(struct qlcnic_adapter *adapter, | 1714 | qlcnic_83xx_process_rcv(struct qlcnic_adapter *adapter, |
1708 | struct qlcnic_host_sds_ring *sds_ring, | 1715 | struct qlcnic_host_sds_ring *sds_ring, |
@@ -1753,6 +1760,12 @@ qlcnic_83xx_process_rcv(struct qlcnic_adapter *adapter, | |||
1753 | 1760 | ||
1754 | skb->protocol = eth_type_trans(skb, netdev); | 1761 | skb->protocol = eth_type_trans(skb, netdev); |
1755 | 1762 | ||
1763 | if (qlcnic_encap_length(sts_data[1]) && | ||
1764 | skb->ip_summed == CHECKSUM_UNNECESSARY) { | ||
1765 | skb->encapsulation = 1; | ||
1766 | adapter->stats.encap_rx_csummed++; | ||
1767 | } | ||
1768 | |||
1756 | if (vid != 0xffff) | 1769 | if (vid != 0xffff) |
1757 | __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vid); | 1770 | __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vid); |
1758 | 1771 | ||
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 6655bf49c79b..79be451a3ffc 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/aer.h> | 21 | #include <linux/aer.h> |
22 | #include <linux/log2.h> | 22 | #include <linux/log2.h> |
23 | #include <linux/pci.h> | 23 | #include <linux/pci.h> |
24 | #include <net/vxlan.h> | ||
24 | 25 | ||
25 | MODULE_DESCRIPTION("QLogic 1/10 GbE Converged/Intelligent Ethernet Driver"); | 26 | MODULE_DESCRIPTION("QLogic 1/10 GbE Converged/Intelligent Ethernet Driver"); |
26 | MODULE_LICENSE("GPL"); | 27 | MODULE_LICENSE("GPL"); |
@@ -461,6 +462,35 @@ static int qlcnic_get_phys_port_id(struct net_device *netdev, | |||
461 | return 0; | 462 | return 0; |
462 | } | 463 | } |
463 | 464 | ||
465 | static void qlcnic_add_vxlan_port(struct net_device *netdev, | ||
466 | sa_family_t sa_family, __be16 port) | ||
467 | { | ||
468 | struct qlcnic_adapter *adapter = netdev_priv(netdev); | ||
469 | struct qlcnic_hardware_context *ahw = adapter->ahw; | ||
470 | |||
471 | /* Adapter supports only one VXLAN port. Use very first port | ||
472 | * for enabling offload | ||
473 | */ | ||
474 | if (!qlcnic_encap_rx_offload(adapter) || ahw->vxlan_port) | ||
475 | return; | ||
476 | |||
477 | ahw->vxlan_port = ntohs(port); | ||
478 | adapter->flags |= QLCNIC_ADD_VXLAN_PORT; | ||
479 | } | ||
480 | |||
481 | static void qlcnic_del_vxlan_port(struct net_device *netdev, | ||
482 | sa_family_t sa_family, __be16 port) | ||
483 | { | ||
484 | struct qlcnic_adapter *adapter = netdev_priv(netdev); | ||
485 | struct qlcnic_hardware_context *ahw = adapter->ahw; | ||
486 | |||
487 | if (!qlcnic_encap_rx_offload(adapter) || !ahw->vxlan_port || | ||
488 | (ahw->vxlan_port != ntohs(port))) | ||
489 | return; | ||
490 | |||
491 | adapter->flags |= QLCNIC_DEL_VXLAN_PORT; | ||
492 | } | ||
493 | |||
464 | static const struct net_device_ops qlcnic_netdev_ops = { | 494 | static const struct net_device_ops qlcnic_netdev_ops = { |
465 | .ndo_open = qlcnic_open, | 495 | .ndo_open = qlcnic_open, |
466 | .ndo_stop = qlcnic_close, | 496 | .ndo_stop = qlcnic_close, |
@@ -479,6 +509,8 @@ static const struct net_device_ops qlcnic_netdev_ops = { | |||
479 | .ndo_fdb_del = qlcnic_fdb_del, | 509 | .ndo_fdb_del = qlcnic_fdb_del, |
480 | .ndo_fdb_dump = qlcnic_fdb_dump, | 510 | .ndo_fdb_dump = qlcnic_fdb_dump, |
481 | .ndo_get_phys_port_id = qlcnic_get_phys_port_id, | 511 | .ndo_get_phys_port_id = qlcnic_get_phys_port_id, |
512 | .ndo_add_vxlan_port = qlcnic_add_vxlan_port, | ||
513 | .ndo_del_vxlan_port = qlcnic_del_vxlan_port, | ||
482 | #ifdef CONFIG_NET_POLL_CONTROLLER | 514 | #ifdef CONFIG_NET_POLL_CONTROLLER |
483 | .ndo_poll_controller = qlcnic_poll_controller, | 515 | .ndo_poll_controller = qlcnic_poll_controller, |
484 | #endif | 516 | #endif |
@@ -1943,6 +1975,9 @@ qlcnic_attach(struct qlcnic_adapter *adapter) | |||
1943 | 1975 | ||
1944 | qlcnic_create_sysfs_entries(adapter); | 1976 | qlcnic_create_sysfs_entries(adapter); |
1945 | 1977 | ||
1978 | if (qlcnic_encap_rx_offload(adapter)) | ||
1979 | vxlan_get_rx_port(netdev); | ||
1980 | |||
1946 | adapter->is_up = QLCNIC_ADAPTER_UP_MAGIC; | 1981 | adapter->is_up = QLCNIC_ADAPTER_UP_MAGIC; |
1947 | return 0; | 1982 | return 0; |
1948 | 1983 | ||
@@ -2215,6 +2250,9 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter, struct net_device *netdev, | |||
2215 | NETIF_F_TSO6; | 2250 | NETIF_F_TSO6; |
2216 | } | 2251 | } |
2217 | 2252 | ||
2253 | if (qlcnic_encap_rx_offload(adapter)) | ||
2254 | netdev->hw_enc_features |= NETIF_F_RXCSUM; | ||
2255 | |||
2218 | netdev->hw_features = netdev->features; | 2256 | netdev->hw_features = netdev->features; |
2219 | netdev->priv_flags |= IFF_UNICAST_FLT; | 2257 | netdev->priv_flags |= IFF_UNICAST_FLT; |
2220 | netdev->irq = adapter->msix_entries[0].vector; | 2258 | netdev->irq = adapter->msix_entries[0].vector; |