Commit b238be07 authored by Sara Sharon's avatar Sara Sharon Committed by Emmanuel Grumbach

iwlwifi: mvm: report checksum is done also for IPv6 packets

Currently the code checks if hardware reported both L4 and L3
checksums as valid, and only then reports it as validated to
the stack.
However, IPv6 does not have checksum at all and the L3 checksum
valid bit is always off for IPv6 packets, with the result of the
stack re-validating L4 checksum.
Fix code to set CHECKSUM_UNNECESSARY also for IPv6 packets whose
TCP/UDP checksum was verified.
Signed-off-by: default avatarSara Sharon <sara.sharon@intel.com>
Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
parent b429a773
...@@ -268,12 +268,25 @@ enum iwl_rx_mpdu_amsdu_info { ...@@ -268,12 +268,25 @@ enum iwl_rx_mpdu_amsdu_info {
IWL_RX_MPDU_AMSDU_LAST_SUBFRAME = 0x80, IWL_RX_MPDU_AMSDU_LAST_SUBFRAME = 0x80,
}; };
enum iwl_rx_l3_proto_values {
IWL_RX_L3_TYPE_NONE,
IWL_RX_L3_TYPE_IPV4,
IWL_RX_L3_TYPE_IPV4_FRAG,
IWL_RX_L3_TYPE_IPV6_FRAG,
IWL_RX_L3_TYPE_IPV6,
IWL_RX_L3_TYPE_IPV6_IN_IPV4,
IWL_RX_L3_TYPE_ARP,
IWL_RX_L3_TYPE_EAPOL,
};
#define IWL_RX_L3_PROTO_POS 4
enum iwl_rx_l3l4_flags { enum iwl_rx_l3l4_flags {
IWL_RX_L3L4_IP_HDR_CSUM_OK = BIT(0), IWL_RX_L3L4_IP_HDR_CSUM_OK = BIT(0),
IWL_RX_L3L4_TCP_UDP_CSUM_OK = BIT(1), IWL_RX_L3L4_TCP_UDP_CSUM_OK = BIT(1),
IWL_RX_L3L4_TCP_FIN_SYN_RST_PSH = BIT(2), IWL_RX_L3L4_TCP_FIN_SYN_RST_PSH = BIT(2),
IWL_RX_L3L4_TCP_ACK = BIT(3), IWL_RX_L3L4_TCP_ACK = BIT(3),
IWL_RX_L3L4_L3_PROTO_MASK = 0xf << 4, IWL_RX_L3L4_L3_PROTO_MASK = 0xf << IWL_RX_L3_PROTO_POS,
IWL_RX_L3L4_L4_PROTO_MASK = 0xf << 8, IWL_RX_L3L4_L4_PROTO_MASK = 0xf << 8,
IWL_RX_L3L4_RSS_HASH_MASK = 0xf << 12, IWL_RX_L3L4_RSS_HASH_MASK = 0xf << 12,
}; };
......
...@@ -294,10 +294,15 @@ static void iwl_mvm_rx_csum(struct ieee80211_sta *sta, ...@@ -294,10 +294,15 @@ static void iwl_mvm_rx_csum(struct ieee80211_sta *sta,
{ {
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(mvmsta->vif); struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(mvmsta->vif);
u16 flags = le16_to_cpu(desc->l3l4_flags);
u8 l3_prot = (u8)((flags & IWL_RX_L3L4_L3_PROTO_MASK) >>
IWL_RX_L3_PROTO_POS);
if (mvmvif->features & NETIF_F_RXCSUM && if (mvmvif->features & NETIF_F_RXCSUM &&
desc->l3l4_flags & cpu_to_le16(IWL_RX_L3L4_IP_HDR_CSUM_OK) && flags & IWL_RX_L3L4_TCP_UDP_CSUM_OK &&
desc->l3l4_flags & cpu_to_le16(IWL_RX_L3L4_TCP_UDP_CSUM_OK)) (flags & IWL_RX_L3L4_IP_HDR_CSUM_OK ||
l3_prot == IWL_RX_L3_TYPE_IPV6 ||
l3_prot == IWL_RX_L3_TYPE_IPV6_FRAG))
skb->ip_summed = CHECKSUM_UNNECESSARY; skb->ip_summed = CHECKSUM_UNNECESSARY;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment