linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/16] iwlwifi: updates intended for v4.21 2019-01-21
@ 2019-01-21  7:50 Luca Coelho
  2019-01-21  7:50 ` [PATCH 01/16] iwlwifi: mvm: support mac80211 AMSDU Luca Coelho
                   ` (15 more replies)
  0 siblings, 16 replies; 19+ messages in thread
From: Luca Coelho @ 2019-01-21  7:50 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Luca Coelho

From: Luca Coelho <luciano.coelho@intel.com>

Hi,

Here's the second set of patches intended for v5.1.  It's the usual
development, new features, cleanups and bugfixes.

The changes are:

* Some updates in the documentation;
* A bunch of fixes for issues found with static analyzers;
* A couple of janitorial fixes from the community;
* Some fixes in P2P;
* Support for mac80211 AMSDU handling;
* Other cleanups and small fixes;

As usual, I'm pushing this to a pending branch, for kbuild bot, and
will send a pull-request later.

Please review.

Cheers,
Luca.


Colin Ian King (1):
  iwlwifi: fix spelling mistake "registrating" -> "registering"

Ilan Peer (3):
  iwlwifi: mvm: Flush transmit queues on P2P Device ROC done
  iwlwifi: mvm: Set Tx rate and flags when there is not station
  iwlwifi: mvm: Do not set RTS/CTS protection for P2P Device MAC

Johannes Berg (2):
  iwlwifi: fw api: remove unused/deprecated filter status
  iwlwifi: fw api: document WoWLAN patterns command

Liad Kaufman (4):
  iwlwifi: update hcmds documentation
  iwlwifi: mvm: make num_active_macs unsigned
  iwlwifi: tighten boundary checks
  iwlwifi: memcpy from dev_cmd and not dev_cmd->hdr

Luca Coelho (1):
  iwlwifi: mvm: fix values in the table example

Mordechay Goodstein (2):
  iwlwifi: mvm: avoid possible access out of array.
  iwlwifi: avoid access out of memory allocated

Sara Sharon (2):
  iwlwifi: mvm: support mac80211 AMSDU
  iwlwifi: mvm: bring back mvm GSO code

YueHaibing (1):
  iwlwifi: use kmemdup in iwl_parse_nvm_mcc_info()

 drivers/net/wireless/intel/iwlwifi/dvm/main.c |  2 +-
 .../wireless/intel/iwlwifi/fw/api/commands.h  |  8 +-
 .../net/wireless/intel/iwlwifi/fw/api/d3.h    | 10 +++
 .../net/wireless/intel/iwlwifi/fw/api/rx.h    |  4 -
 drivers/net/wireless/intel/iwlwifi/fw/dbg.c   |  8 ++
 .../wireless/intel/iwlwifi/iwl-nvm-parse.c    |  4 +-
 .../net/wireless/intel/iwlwifi/mvm/mac-ctxt.c |  2 -
 .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 33 +++++++
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h  |  3 +
 .../net/wireless/intel/iwlwifi/mvm/rs-fw.c    | 14 +++
 drivers/net/wireless/intel/iwlwifi/mvm/rs.c   | 26 ++++--
 drivers/net/wireless/intel/iwlwifi/mvm/sf.c   |  4 +-
 drivers/net/wireless/intel/iwlwifi/mvm/sta.c  | 19 ++--
 .../wireless/intel/iwlwifi/mvm/time-event.c   |  1 +
 drivers/net/wireless/intel/iwlwifi/mvm/tx.c   | 90 +++++++++++--------
 .../net/wireless/intel/iwlwifi/pcie/tx-gen2.c | 10 ++-
 drivers/net/wireless/intel/iwlwifi/pcie/tx.c  |  3 +-
 17 files changed, 173 insertions(+), 68 deletions(-)

-- 
2.20.1


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 01/16] iwlwifi: mvm: support mac80211 AMSDU
  2019-01-21  7:50 [PATCH 00/16] iwlwifi: updates intended for v4.21 2019-01-21 Luca Coelho
@ 2019-01-21  7:50 ` Luca Coelho
  2019-01-22 12:53   ` Kalle Valo
  2019-01-21  7:50 ` [PATCH 02/16] iwlwifi: mvm: fix values in the table example Luca Coelho
                   ` (14 subsequent siblings)
  15 siblings, 1 reply; 19+ messages in thread
From: Luca Coelho @ 2019-01-21  7:50 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Sara Sharon, Luca Coelho

From: Sara Sharon <sara.sharon@intel.com>

Support getting mac80211 building AMSDUs for us. Remove GSO
support from mvm - we don't need it anymore.

Signed-off-by: Sara Sharon <sara.sharon@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 .../net/wireless/intel/iwlwifi/mvm/mac80211.c |  34 +++
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h  |   3 +
 .../net/wireless/intel/iwlwifi/mvm/rs-fw.c    |  14 ++
 drivers/net/wireless/intel/iwlwifi/mvm/rs.c   |  14 ++
 drivers/net/wireless/intel/iwlwifi/mvm/tx.c   | 229 +-----------------
 5 files changed, 68 insertions(+), 226 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index 58bb92b0ef05..5c0816b81298 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -440,6 +440,8 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
 	ieee80211_hw_set(hw, SUPPORTS_VHT_EXT_NSS_BW);
 	ieee80211_hw_set(hw, BUFF_MMPDU_TXQ);
 	ieee80211_hw_set(hw, STA_MMPDU_TXQ);
+	ieee80211_hw_set(hw, TX_AMSDU);
+	ieee80211_hw_set(hw, TX_FRAG_LIST);
 
 	if (iwl_mvm_has_tlc_offload(mvm)) {
 		ieee80211_hw_set(hw, TX_AMPDU_SETUP_IN_HW);
@@ -485,6 +487,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
 
 	hw->uapsd_queues = IWL_MVM_UAPSD_QUEUES;
 	hw->uapsd_max_sp_len = IWL_UAPSD_MAX_SP;
+	hw->max_tx_fragments = mvm->trans->max_skb_frags;
 
 	BUILD_BUG_ON(ARRAY_SIZE(mvm->ciphers) < ARRAY_SIZE(mvm_ciphers) + 6);
 	memcpy(mvm->ciphers, mvm_ciphers, sizeof(mvm_ciphers));
@@ -751,6 +754,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
 	}
 
 	hw->netdev_features |= mvm->cfg->features;
+	hw->netdev_features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
 	if (!iwl_mvm_is_csum_supported(mvm)) {
 		hw->netdev_features &= ~(IWL_TX_CSUM_NETIF_FLAGS |
 					 NETIF_F_RXCSUM);
@@ -3035,6 +3039,8 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
 			iwl_mvm_tdls_check_trigger(mvm, vif, sta->addr,
 						   NL80211_TDLS_SETUP);
 		}
+
+		sta->max_rc_amsdu_len = 1;
 	} else if (old_state == IEEE80211_STA_NONE &&
 		   new_state == IEEE80211_STA_AUTH) {
 		/*
@@ -4724,6 +4730,33 @@ static void iwl_mvm_sync_rx_queues(struct ieee80211_hw *hw)
 	mutex_unlock(&mvm->mutex);
 }
 
+static bool iwl_mvm_can_hw_csum(struct sk_buff *skb)
+{
+#if IS_ENABLED(CONFIG_INET)
+	u8 protocol = ip_hdr(skb)->protocol;
+
+	return protocol == IPPROTO_TCP || protocol == IPPROTO_UDP;
+#else
+	return false;
+#endif
+}
+
+static bool iwl_mvm_mac_can_aggregate(struct ieee80211_hw *hw,
+				      struct sk_buff *head,
+				      struct sk_buff *skb)
+{
+	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
+
+	/* For now don't aggregate IPv6 in AMSDU */
+	if (skb->protocol != htons(ETH_P_IP))
+		return false;
+
+	if (!iwl_mvm_is_csum_supported(mvm))
+		return true;
+
+	return iwl_mvm_can_hw_csum(skb) == iwl_mvm_can_hw_csum(head);
+}
+
 const struct ieee80211_ops iwl_mvm_hw_ops = {
 	.tx = iwl_mvm_mac_tx,
 	.wake_tx_queue = iwl_mvm_mac_wake_tx_queue,
@@ -4800,6 +4833,7 @@ const struct ieee80211_ops iwl_mvm_hw_ops = {
 #endif
 	.get_survey = iwl_mvm_mac_get_survey,
 	.sta_statistics = iwl_mvm_mac_sta_statistics,
+	.can_aggregate_in_amsdu = iwl_mvm_mac_can_aggregate,
 #ifdef CONFIG_IWLWIFI_DEBUGFS
 	.sta_add_debugfs = iwl_mvm_sta_add_debugfs,
 #endif
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index 39ee3ace59b6..503e51d32e7f 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -1504,6 +1504,9 @@ void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm, struct iwl_tx_cmd *tx_cmd,
 			    struct ieee80211_tx_info *info,
 			    struct ieee80211_sta *sta, __le16 fc);
 void iwl_mvm_mac_itxq_xmit(struct ieee80211_hw *hw, struct ieee80211_txq *txq);
+unsigned int iwl_mvm_max_amsdu_size(struct iwl_mvm *mvm,
+				    struct ieee80211_sta *sta,
+				    unsigned int tid);
 
 #ifdef CONFIG_IWLWIFI_DEBUG
 const char *iwl_mvm_get_tx_fail_reason(u32 status);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c
index a0ea0c160fd6..a28283ff7295 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c
@@ -315,12 +315,26 @@ void iwl_mvm_tlc_update_notif(struct iwl_mvm *mvm,
 
 	if (flags & IWL_TLC_NOTIF_FLAG_AMSDU) {
 		u16 size = le32_to_cpu(notif->amsdu_size);
+		int i;
 
 		if (WARN_ON(sta->max_amsdu_len < size))
 			goto out;
 
 		mvmsta->amsdu_enabled = le32_to_cpu(notif->amsdu_enabled);
 		mvmsta->max_amsdu_len = size;
+		sta->max_rc_amsdu_len = mvmsta->max_amsdu_len;
+
+		for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
+			if (mvmsta->amsdu_enabled & BIT(i))
+				sta->max_tid_amsdu_len[i] =
+					iwl_mvm_max_amsdu_size(mvm, sta, i);
+			else
+				/*
+				 * Not so elegant, but this will effectively
+				 * prevent AMSDU on this TID
+				 */
+				sta->max_tid_amsdu_len[i] = 1;
+		}
 
 		IWL_DEBUG_RATE(mvm,
 			       "AMSDU update. AMSDU size: %d, AMSDU selected size: %d, AMSDU TID bitmap 0x%X\n",
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
index 089972280daa..9b5682ce4b39 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
@@ -1744,6 +1744,7 @@ static void rs_set_amsdu_len(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
 			     enum rs_action scale_action)
 {
 	struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
+	int i;
 
 	/*
 	 * In case TLC offload is not active amsdu_enabled is either 0xFFFF
@@ -1757,6 +1758,19 @@ static void rs_set_amsdu_len(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
 		mvmsta->amsdu_enabled = 0xFFFF;
 
 	mvmsta->max_amsdu_len = sta->max_amsdu_len;
+	sta->max_rc_amsdu_len = mvmsta->max_amsdu_len;
+
+	for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
+		if (mvmsta->amsdu_enabled)
+			sta->max_tid_amsdu_len[i] =
+				iwl_mvm_max_amsdu_size(mvm, sta, i);
+		else
+			/*
+			 * Not so elegant, but this will effectively
+			 * prevent AMSDU on this TID
+			 */
+			sta->max_tid_amsdu_len[i] = 1;
+	}
 }
 
 /*
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
index dfdfaa9ecfdb..2f2c355c13b0 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
@@ -779,78 +779,8 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb)
 	return 0;
 }
 
-#ifdef CONFIG_INET
-
-static int
-iwl_mvm_tx_tso_segment(struct sk_buff *skb, unsigned int num_subframes,
-		       netdev_features_t netdev_flags,
-		       struct sk_buff_head *mpdus_skb)
-{
-	struct sk_buff *tmp, *next;
-	struct ieee80211_hdr *hdr = (void *)skb->data;
-	char cb[sizeof(skb->cb)];
-	u16 i = 0;
-	unsigned int tcp_payload_len;
-	unsigned int mss = skb_shinfo(skb)->gso_size;
-	bool ipv4 = (skb->protocol == htons(ETH_P_IP));
-	u16 ip_base_id = ipv4 ? ntohs(ip_hdr(skb)->id) : 0;
-
-	skb_shinfo(skb)->gso_size = num_subframes * mss;
-	memcpy(cb, skb->cb, sizeof(cb));
-
-	next = skb_gso_segment(skb, netdev_flags);
-	skb_shinfo(skb)->gso_size = mss;
-	if (WARN_ON_ONCE(IS_ERR(next)))
-		return -EINVAL;
-	else if (next)
-		consume_skb(skb);
-
-	while (next) {
-		tmp = next;
-		next = tmp->next;
-
-		memcpy(tmp->cb, cb, sizeof(tmp->cb));
-		/*
-		 * Compute the length of all the data added for the A-MSDU.
-		 * This will be used to compute the length to write in the TX
-		 * command. We have: SNAP + IP + TCP for n -1 subframes and
-		 * ETH header for n subframes.
-		 */
-		tcp_payload_len = skb_tail_pointer(tmp) -
-			skb_transport_header(tmp) -
-			tcp_hdrlen(tmp) + tmp->data_len;
-
-		if (ipv4)
-			ip_hdr(tmp)->id = htons(ip_base_id + i * num_subframes);
-
-		if (tcp_payload_len > mss) {
-			skb_shinfo(tmp)->gso_size = mss;
-		} else {
-			if (ieee80211_is_data_qos(hdr->frame_control)) {
-				u8 *qc;
-
-				if (ipv4)
-					ip_send_check(ip_hdr(tmp));
-
-				qc = ieee80211_get_qos_ctl((void *)tmp->data);
-				*qc &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT;
-			}
-			skb_shinfo(tmp)->gso_size = 0;
-		}
-
-		tmp->prev = NULL;
-		tmp->next = NULL;
-
-		__skb_queue_tail(mpdus_skb, tmp);
-		i++;
-	}
-
-	return 0;
-}
-
-static unsigned int iwl_mvm_max_amsdu_size(struct iwl_mvm *mvm,
-					   struct ieee80211_sta *sta,
-					   unsigned int tid)
+unsigned int iwl_mvm_max_amsdu_size(struct iwl_mvm *mvm,
+				    struct ieee80211_sta *sta, unsigned int tid)
 {
 	struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
 	enum nl80211_band band = mvmsta->vif->bss_conf.chandef.chan->band;
@@ -878,128 +808,6 @@ static unsigned int iwl_mvm_max_amsdu_size(struct iwl_mvm *mvm,
 		     mvm->fwrt.smem_cfg.lmac[lmac].txfifo_size[txf] - 256);
 }
 
-static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb,
-			  struct ieee80211_tx_info *info,
-			  struct ieee80211_sta *sta,
-			  struct sk_buff_head *mpdus_skb)
-{
-	struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
-	struct ieee80211_hdr *hdr = (void *)skb->data;
-	unsigned int mss = skb_shinfo(skb)->gso_size;
-	unsigned int num_subframes, tcp_payload_len, subf_len, max_amsdu_len;
-	u16 snap_ip_tcp, pad;
-	unsigned int dbg_max_amsdu_len;
-	netdev_features_t netdev_flags = NETIF_F_CSUM_MASK | NETIF_F_SG;
-	u8 tid;
-
-	snap_ip_tcp = 8 + skb_transport_header(skb) - skb_network_header(skb) +
-		tcp_hdrlen(skb);
-
-	dbg_max_amsdu_len = READ_ONCE(mvm->max_amsdu_len);
-
-	if (!mvmsta->max_amsdu_len ||
-	    !ieee80211_is_data_qos(hdr->frame_control) ||
-	    (!mvmsta->amsdu_enabled && !dbg_max_amsdu_len))
-		return iwl_mvm_tx_tso_segment(skb, 1, netdev_flags, mpdus_skb);
-
-	/*
-	 * Do not build AMSDU for IPv6 with extension headers.
-	 * ask stack to segment and checkum the generated MPDUs for us.
-	 */
-	if (skb->protocol == htons(ETH_P_IPV6) &&
-	    ((struct ipv6hdr *)skb_network_header(skb))->nexthdr !=
-	    IPPROTO_TCP) {
-		netdev_flags &= ~NETIF_F_CSUM_MASK;
-		return iwl_mvm_tx_tso_segment(skb, 1, netdev_flags, mpdus_skb);
-	}
-
-	tid = ieee80211_get_tid(hdr);
-	if (WARN_ON_ONCE(tid >= IWL_MAX_TID_COUNT))
-		return -EINVAL;
-
-	/*
-	 * No need to lock amsdu_in_ampdu_allowed since it can't be modified
-	 * during an BA session.
-	 */
-	if (info->flags & IEEE80211_TX_CTL_AMPDU &&
-	    !mvmsta->tid_data[tid].amsdu_in_ampdu_allowed)
-		return iwl_mvm_tx_tso_segment(skb, 1, netdev_flags, mpdus_skb);
-
-	if (iwl_mvm_vif_low_latency(iwl_mvm_vif_from_mac80211(mvmsta->vif)) ||
-	    !(mvmsta->amsdu_enabled & BIT(tid)))
-		return iwl_mvm_tx_tso_segment(skb, 1, netdev_flags, mpdus_skb);
-
-	max_amsdu_len = iwl_mvm_max_amsdu_size(mvm, sta, tid);
-
-	if (unlikely(dbg_max_amsdu_len))
-		max_amsdu_len = min_t(unsigned int, max_amsdu_len,
-				      dbg_max_amsdu_len);
-
-	/*
-	 * Limit A-MSDU in A-MPDU to 4095 bytes when VHT is not
-	 * supported. This is a spec requirement (IEEE 802.11-2015
-	 * section 8.7.3 NOTE 3).
-	 */
-	if (info->flags & IEEE80211_TX_CTL_AMPDU &&
-	    !sta->vht_cap.vht_supported)
-		max_amsdu_len = min_t(unsigned int, max_amsdu_len, 4095);
-
-	/* Sub frame header + SNAP + IP header + TCP header + MSS */
-	subf_len = sizeof(struct ethhdr) + snap_ip_tcp + mss;
-	pad = (4 - subf_len) & 0x3;
-
-	/*
-	 * If we have N subframes in the A-MSDU, then the A-MSDU's size is
-	 * N * subf_len + (N - 1) * pad.
-	 */
-	num_subframes = (max_amsdu_len + pad) / (subf_len + pad);
-
-	if (sta->max_amsdu_subframes &&
-	    num_subframes > sta->max_amsdu_subframes)
-		num_subframes = sta->max_amsdu_subframes;
-
-	tcp_payload_len = skb_tail_pointer(skb) - skb_transport_header(skb) -
-		tcp_hdrlen(skb) + skb->data_len;
-
-	/*
-	 * Make sure we have enough TBs for the A-MSDU:
-	 *	2 for each subframe
-	 *	1 more for each fragment
-	 *	1 more for the potential data in the header
-	 */
-	if ((num_subframes * 2 + skb_shinfo(skb)->nr_frags + 1) >
-	    mvm->trans->max_skb_frags)
-		num_subframes = 1;
-
-	if (num_subframes > 1)
-		*ieee80211_get_qos_ctl(hdr) |= IEEE80211_QOS_CTL_A_MSDU_PRESENT;
-
-	/* This skb fits in one single A-MSDU */
-	if (num_subframes * mss >= tcp_payload_len) {
-		__skb_queue_tail(mpdus_skb, skb);
-		return 0;
-	}
-
-	/*
-	 * Trick the segmentation function to make it
-	 * create SKBs that can fit into one A-MSDU.
-	 */
-	return iwl_mvm_tx_tso_segment(skb, num_subframes, netdev_flags,
-				      mpdus_skb);
-}
-#else /* CONFIG_INET */
-static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb,
-			  struct ieee80211_tx_info *info,
-			  struct ieee80211_sta *sta,
-			  struct sk_buff_head *mpdus_skb)
-{
-	/* Impossible to get TSO with CONFIG_INET */
-	WARN_ON(1);
-
-	return -1;
-}
-#endif
-
 /* Check if there are any timed-out TIDs on a given shared TXQ */
 static bool iwl_mvm_txq_should_update(struct iwl_mvm *mvm, int txq_id)
 {
@@ -1178,9 +986,6 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
 {
 	struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
 	struct ieee80211_tx_info info;
-	struct sk_buff_head mpdus_skbs;
-	unsigned int payload_len;
-	int ret;
 
 	if (WARN_ON_ONCE(!mvmsta))
 		return -1;
@@ -1190,35 +995,7 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
 
 	memcpy(&info, skb->cb, sizeof(info));
 
-	if (!skb_is_gso(skb))
-		return iwl_mvm_tx_mpdu(mvm, skb, &info, sta);
-
-	payload_len = skb_tail_pointer(skb) - skb_transport_header(skb) -
-		tcp_hdrlen(skb) + skb->data_len;
-
-	if (payload_len <= skb_shinfo(skb)->gso_size)
-		return iwl_mvm_tx_mpdu(mvm, skb, &info, sta);
-
-	__skb_queue_head_init(&mpdus_skbs);
-
-	ret = iwl_mvm_tx_tso(mvm, skb, &info, sta, &mpdus_skbs);
-	if (ret)
-		return ret;
-
-	if (WARN_ON(skb_queue_empty(&mpdus_skbs)))
-		return ret;
-
-	while (!skb_queue_empty(&mpdus_skbs)) {
-		skb = __skb_dequeue(&mpdus_skbs);
-
-		ret = iwl_mvm_tx_mpdu(mvm, skb, &info, sta);
-		if (ret) {
-			__skb_queue_purge(&mpdus_skbs);
-			return ret;
-		}
-	}
-
-	return 0;
+	return iwl_mvm_tx_mpdu(mvm, skb, &info, sta);
 }
 
 static void iwl_mvm_check_ratid_empty(struct iwl_mvm *mvm,
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 02/16] iwlwifi: mvm: fix values in the table example
  2019-01-21  7:50 [PATCH 00/16] iwlwifi: updates intended for v4.21 2019-01-21 Luca Coelho
  2019-01-21  7:50 ` [PATCH 01/16] iwlwifi: mvm: support mac80211 AMSDU Luca Coelho
@ 2019-01-21  7:50 ` Luca Coelho
  2019-01-21  7:50 ` [PATCH 03/16] iwlwifi: use kmemdup in iwl_parse_nvm_mcc_info() Luca Coelho
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Luca Coelho @ 2019-01-21  7:50 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Luca Coelho, Rémy Grünblatt

From: Luca Coelho <luciano.coelho@intel.com>

We erroneously had some values for NGI in the table we give as an
example in rs_fill_rates_for_column(), when they should be SGI.
Change them so that they match what we say.

Reported-by: Rémy Grünblatt <remy@grunblatt.org>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/rs.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
index 9b5682ce4b39..09866f50857a 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
@@ -3346,12 +3346,12 @@ static void rs_fill_rates_for_column(struct iwl_mvm *mvm,
 /* Building the rate table is non trivial. When we're in MIMO2/VHT/80Mhz/SGI
  * column the rate table should look like this:
  *
- * rate[0] 0x400D019 VHT | ANT: AB BW: 80Mhz MCS: 9 NSS: 2 SGI
- * rate[1] 0x400D019 VHT | ANT: AB BW: 80Mhz MCS: 9 NSS: 2 SGI
- * rate[2] 0x400D018 VHT | ANT: AB BW: 80Mhz MCS: 8 NSS: 2 SGI
- * rate[3] 0x400D018 VHT | ANT: AB BW: 80Mhz MCS: 8 NSS: 2 SGI
- * rate[4] 0x400D017 VHT | ANT: AB BW: 80Mhz MCS: 7 NSS: 2 SGI
- * rate[5] 0x400D017 VHT | ANT: AB BW: 80Mhz MCS: 7 NSS: 2 SGI
+ * rate[0] 0x400F019 VHT | ANT: AB BW: 80Mhz MCS: 9 NSS: 2 SGI
+ * rate[1] 0x400F019 VHT | ANT: AB BW: 80Mhz MCS: 9 NSS: 2 SGI
+ * rate[2] 0x400F018 VHT | ANT: AB BW: 80Mhz MCS: 8 NSS: 2 SGI
+ * rate[3] 0x400F018 VHT | ANT: AB BW: 80Mhz MCS: 8 NSS: 2 SGI
+ * rate[4] 0x400F017 VHT | ANT: AB BW: 80Mhz MCS: 7 NSS: 2 SGI
+ * rate[5] 0x400F017 VHT | ANT: AB BW: 80Mhz MCS: 7 NSS: 2 SGI
  * rate[6] 0x4005007 VHT | ANT: A BW: 80Mhz MCS: 7 NSS: 1 NGI
  * rate[7] 0x4009006 VHT | ANT: B BW: 80Mhz MCS: 6 NSS: 1 NGI
  * rate[8] 0x4005005 VHT | ANT: A BW: 80Mhz MCS: 5 NSS: 1 NGI
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 03/16] iwlwifi: use kmemdup in iwl_parse_nvm_mcc_info()
  2019-01-21  7:50 [PATCH 00/16] iwlwifi: updates intended for v4.21 2019-01-21 Luca Coelho
  2019-01-21  7:50 ` [PATCH 01/16] iwlwifi: mvm: support mac80211 AMSDU Luca Coelho
  2019-01-21  7:50 ` [PATCH 02/16] iwlwifi: mvm: fix values in the table example Luca Coelho
@ 2019-01-21  7:50 ` Luca Coelho
  2019-01-21  7:50 ` [PATCH 04/16] iwlwifi: fix spelling mistake "registrating" -> "registering" Luca Coelho
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Luca Coelho @ 2019-01-21  7:50 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, YueHaibing, Luca Coelho

From: YueHaibing <yuehaibing@huawei.com>

Use kmemdup rather than duplicating its implementation in
iwl_parse_nvm_mcc_info().

Signed-off-by: YueHaibing <yuehaibing@huawei.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
index 173ade96f119..484ef4556953 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
@@ -1195,14 +1195,12 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
 	regd_to_copy = sizeof(struct ieee80211_regdomain) +
 		valid_rules * sizeof(struct ieee80211_reg_rule);
 
-	copy_rd = kzalloc(regd_to_copy, GFP_KERNEL);
+	copy_rd = kmemdup(regd, regd_to_copy, GFP_KERNEL);
 	if (!copy_rd) {
 		copy_rd = ERR_PTR(-ENOMEM);
 		goto out;
 	}
 
-	memcpy(copy_rd, regd, regd_to_copy);
-
 out:
 	kfree(regdb_ptrs);
 	kfree(regd);
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 04/16] iwlwifi: fix spelling mistake "registrating" -> "registering"
  2019-01-21  7:50 [PATCH 00/16] iwlwifi: updates intended for v4.21 2019-01-21 Luca Coelho
                   ` (2 preceding siblings ...)
  2019-01-21  7:50 ` [PATCH 03/16] iwlwifi: use kmemdup in iwl_parse_nvm_mcc_info() Luca Coelho
@ 2019-01-21  7:50 ` Luca Coelho
  2019-01-21  7:50 ` [PATCH 05/16] iwlwifi: mvm: bring back mvm GSO code Luca Coelho
                   ` (11 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Luca Coelho @ 2019-01-21  7:50 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Colin Ian King, Luca Coelho

From: Colin Ian King <colin.king@canonical.com>

Trivial fix to spelling mistake in IWL_ERR error message

Signed-off-by: Colin Ian King <colin.king@canonical.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/dvm/main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/main.c b/drivers/net/wireless/intel/iwlwifi/dvm/main.c
index c219bca5cff4..bd3c3b921d4c 100644
--- a/drivers/net/wireless/intel/iwlwifi/dvm/main.c
+++ b/drivers/net/wireless/intel/iwlwifi/dvm/main.c
@@ -1054,7 +1054,7 @@ static void iwl_bg_restart(struct work_struct *data)
 			ieee80211_restart_hw(priv->hw);
 		else
 			IWL_ERR(priv,
-				"Cannot request restart before registrating with mac80211\n");
+				"Cannot request restart before registering with mac80211\n");
 	} else {
 		WARN_ON(1);
 	}
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 05/16] iwlwifi: mvm: bring back mvm GSO code
  2019-01-21  7:50 [PATCH 00/16] iwlwifi: updates intended for v4.21 2019-01-21 Luca Coelho
                   ` (3 preceding siblings ...)
  2019-01-21  7:50 ` [PATCH 04/16] iwlwifi: fix spelling mistake "registrating" -> "registering" Luca Coelho
@ 2019-01-21  7:50 ` Luca Coelho
  2019-01-21  7:50 ` [PATCH 06/16] iwlwifi: mvm: Flush transmit queues on P2P Device ROC done Luca Coelho
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Luca Coelho @ 2019-01-21  7:50 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Sara Sharon, Luca Coelho

From: Sara Sharon <sara.sharon@intel.com>

We have a slightly better TCP performance with GSO.
Add it back, it can co-exist with the code that builds
AMSDUs in mac80211.

Signed-off-by: Sara Sharon <sara.sharon@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 .../net/wireless/intel/iwlwifi/mvm/mac80211.c |   1 -
 drivers/net/wireless/intel/iwlwifi/mvm/tx.c   | 224 +++++++++++++++++-
 2 files changed, 223 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index 5c0816b81298..9a4fef834941 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -754,7 +754,6 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
 	}
 
 	hw->netdev_features |= mvm->cfg->features;
-	hw->netdev_features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
 	if (!iwl_mvm_is_csum_supported(mvm)) {
 		hw->netdev_features &= ~(IWL_TX_CSUM_NETIF_FLAGS |
 					 NETIF_F_RXCSUM);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
index 2f2c355c13b0..da8b69c9468c 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
@@ -808,6 +808,197 @@ unsigned int iwl_mvm_max_amsdu_size(struct iwl_mvm *mvm,
 		     mvm->fwrt.smem_cfg.lmac[lmac].txfifo_size[txf] - 256);
 }
 
+#ifdef CONFIG_INET
+
+static int
+iwl_mvm_tx_tso_segment(struct sk_buff *skb, unsigned int num_subframes,
+		       netdev_features_t netdev_flags,
+		       struct sk_buff_head *mpdus_skb)
+{
+	struct sk_buff *tmp, *next;
+	struct ieee80211_hdr *hdr = (void *)skb->data;
+	char cb[sizeof(skb->cb)];
+	u16 i = 0;
+	unsigned int tcp_payload_len;
+	unsigned int mss = skb_shinfo(skb)->gso_size;
+	bool ipv4 = (skb->protocol == htons(ETH_P_IP));
+	u16 ip_base_id = ipv4 ? ntohs(ip_hdr(skb)->id) : 0;
+
+	skb_shinfo(skb)->gso_size = num_subframes * mss;
+	memcpy(cb, skb->cb, sizeof(cb));
+
+	next = skb_gso_segment(skb, netdev_flags);
+	skb_shinfo(skb)->gso_size = mss;
+	if (WARN_ON_ONCE(IS_ERR(next)))
+		return -EINVAL;
+	else if (next)
+		consume_skb(skb);
+
+	while (next) {
+		tmp = next;
+		next = tmp->next;
+
+		memcpy(tmp->cb, cb, sizeof(tmp->cb));
+		/*
+		 * Compute the length of all the data added for the A-MSDU.
+		 * This will be used to compute the length to write in the TX
+		 * command. We have: SNAP + IP + TCP for n -1 subframes and
+		 * ETH header for n subframes.
+		 */
+		tcp_payload_len = skb_tail_pointer(tmp) -
+			skb_transport_header(tmp) -
+			tcp_hdrlen(tmp) + tmp->data_len;
+
+		if (ipv4)
+			ip_hdr(tmp)->id = htons(ip_base_id + i * num_subframes);
+
+		if (tcp_payload_len > mss) {
+			skb_shinfo(tmp)->gso_size = mss;
+		} else {
+			if (ieee80211_is_data_qos(hdr->frame_control)) {
+				u8 *qc;
+
+				if (ipv4)
+					ip_send_check(ip_hdr(tmp));
+
+				qc = ieee80211_get_qos_ctl((void *)tmp->data);
+				*qc &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT;
+			}
+			skb_shinfo(tmp)->gso_size = 0;
+		}
+
+		tmp->prev = NULL;
+		tmp->next = NULL;
+
+		__skb_queue_tail(mpdus_skb, tmp);
+		i++;
+	}
+
+	return 0;
+}
+
+static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb,
+			  struct ieee80211_tx_info *info,
+			  struct ieee80211_sta *sta,
+			  struct sk_buff_head *mpdus_skb)
+{
+	struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
+	struct ieee80211_hdr *hdr = (void *)skb->data;
+	unsigned int mss = skb_shinfo(skb)->gso_size;
+	unsigned int num_subframes, tcp_payload_len, subf_len, max_amsdu_len;
+	u16 snap_ip_tcp, pad;
+	unsigned int dbg_max_amsdu_len;
+	netdev_features_t netdev_flags = NETIF_F_CSUM_MASK | NETIF_F_SG;
+	u8 tid;
+
+	snap_ip_tcp = 8 + skb_transport_header(skb) - skb_network_header(skb) +
+		tcp_hdrlen(skb);
+
+	dbg_max_amsdu_len = READ_ONCE(mvm->max_amsdu_len);
+
+	if (!mvmsta->max_amsdu_len ||
+	    !ieee80211_is_data_qos(hdr->frame_control) ||
+	    (!mvmsta->amsdu_enabled && !dbg_max_amsdu_len))
+		return iwl_mvm_tx_tso_segment(skb, 1, netdev_flags, mpdus_skb);
+
+	/*
+	 * Do not build AMSDU for IPv6 with extension headers.
+	 * ask stack to segment and checkum the generated MPDUs for us.
+	 */
+	if (skb->protocol == htons(ETH_P_IPV6) &&
+	    ((struct ipv6hdr *)skb_network_header(skb))->nexthdr !=
+	    IPPROTO_TCP) {
+		netdev_flags &= ~NETIF_F_CSUM_MASK;
+		return iwl_mvm_tx_tso_segment(skb, 1, netdev_flags, mpdus_skb);
+	}
+
+	tid = ieee80211_get_tid(hdr);
+	if (WARN_ON_ONCE(tid >= IWL_MAX_TID_COUNT))
+		return -EINVAL;
+
+	/*
+	 * No need to lock amsdu_in_ampdu_allowed since it can't be modified
+	 * during an BA session.
+	 */
+	if (info->flags & IEEE80211_TX_CTL_AMPDU &&
+	    !mvmsta->tid_data[tid].amsdu_in_ampdu_allowed)
+		return iwl_mvm_tx_tso_segment(skb, 1, netdev_flags, mpdus_skb);
+
+	if (iwl_mvm_vif_low_latency(iwl_mvm_vif_from_mac80211(mvmsta->vif)) ||
+	    !(mvmsta->amsdu_enabled & BIT(tid)))
+		return iwl_mvm_tx_tso_segment(skb, 1, netdev_flags, mpdus_skb);
+
+	max_amsdu_len = iwl_mvm_max_amsdu_size(mvm, sta, tid);
+
+	if (unlikely(dbg_max_amsdu_len))
+		max_amsdu_len = min_t(unsigned int, max_amsdu_len,
+				      dbg_max_amsdu_len);
+
+	/*
+	 * Limit A-MSDU in A-MPDU to 4095 bytes when VHT is not
+	 * supported. This is a spec requirement (IEEE 802.11-2015
+	 * section 8.7.3 NOTE 3).
+	 */
+	if (info->flags & IEEE80211_TX_CTL_AMPDU &&
+	    !sta->vht_cap.vht_supported)
+		max_amsdu_len = min_t(unsigned int, max_amsdu_len, 4095);
+
+	/* Sub frame header + SNAP + IP header + TCP header + MSS */
+	subf_len = sizeof(struct ethhdr) + snap_ip_tcp + mss;
+	pad = (4 - subf_len) & 0x3;
+
+	/*
+	 * If we have N subframes in the A-MSDU, then the A-MSDU's size is
+	 * N * subf_len + (N - 1) * pad.
+	 */
+	num_subframes = (max_amsdu_len + pad) / (subf_len + pad);
+
+	if (sta->max_amsdu_subframes &&
+	    num_subframes > sta->max_amsdu_subframes)
+		num_subframes = sta->max_amsdu_subframes;
+
+	tcp_payload_len = skb_tail_pointer(skb) - skb_transport_header(skb) -
+		tcp_hdrlen(skb) + skb->data_len;
+
+	/*
+	 * Make sure we have enough TBs for the A-MSDU:
+	 *	2 for each subframe
+	 *	1 more for each fragment
+	 *	1 more for the potential data in the header
+	 */
+	if ((num_subframes * 2 + skb_shinfo(skb)->nr_frags + 1) >
+	    mvm->trans->max_skb_frags)
+		num_subframes = 1;
+
+	if (num_subframes > 1)
+		*ieee80211_get_qos_ctl(hdr) |= IEEE80211_QOS_CTL_A_MSDU_PRESENT;
+
+	/* This skb fits in one single A-MSDU */
+	if (num_subframes * mss >= tcp_payload_len) {
+		__skb_queue_tail(mpdus_skb, skb);
+		return 0;
+	}
+
+	/*
+	 * Trick the segmentation function to make it
+	 * create SKBs that can fit into one A-MSDU.
+	 */
+	return iwl_mvm_tx_tso_segment(skb, num_subframes, netdev_flags,
+				      mpdus_skb);
+}
+#else /* CONFIG_INET */
+static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb,
+			  struct ieee80211_tx_info *info,
+			  struct ieee80211_sta *sta,
+			  struct sk_buff_head *mpdus_skb)
+{
+	/* Impossible to get TSO with CONFIG_INET */
+	WARN_ON(1);
+
+	return -1;
+}
+#endif
+
 /* Check if there are any timed-out TIDs on a given shared TXQ */
 static bool iwl_mvm_txq_should_update(struct iwl_mvm *mvm, int txq_id)
 {
@@ -986,6 +1177,9 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
 {
 	struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
 	struct ieee80211_tx_info info;
+	struct sk_buff_head mpdus_skbs;
+	unsigned int payload_len;
+	int ret;
 
 	if (WARN_ON_ONCE(!mvmsta))
 		return -1;
@@ -995,7 +1189,35 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
 
 	memcpy(&info, skb->cb, sizeof(info));
 
-	return iwl_mvm_tx_mpdu(mvm, skb, &info, sta);
+	if (!skb_is_gso(skb))
+		return iwl_mvm_tx_mpdu(mvm, skb, &info, sta);
+
+	payload_len = skb_tail_pointer(skb) - skb_transport_header(skb) -
+		tcp_hdrlen(skb) + skb->data_len;
+
+	if (payload_len <= skb_shinfo(skb)->gso_size)
+		return iwl_mvm_tx_mpdu(mvm, skb, &info, sta);
+
+	__skb_queue_head_init(&mpdus_skbs);
+
+	ret = iwl_mvm_tx_tso(mvm, skb, &info, sta, &mpdus_skbs);
+	if (ret)
+		return ret;
+
+	if (WARN_ON(skb_queue_empty(&mpdus_skbs)))
+		return ret;
+
+	while (!skb_queue_empty(&mpdus_skbs)) {
+		skb = __skb_dequeue(&mpdus_skbs);
+
+		ret = iwl_mvm_tx_mpdu(mvm, skb, &info, sta);
+		if (ret) {
+			__skb_queue_purge(&mpdus_skbs);
+			return ret;
+		}
+	}
+
+	return 0;
 }
 
 static void iwl_mvm_check_ratid_empty(struct iwl_mvm *mvm,
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 06/16] iwlwifi: mvm: Flush transmit queues on P2P Device ROC done
  2019-01-21  7:50 [PATCH 00/16] iwlwifi: updates intended for v4.21 2019-01-21 Luca Coelho
                   ` (4 preceding siblings ...)
  2019-01-21  7:50 ` [PATCH 05/16] iwlwifi: mvm: bring back mvm GSO code Luca Coelho
@ 2019-01-21  7:50 ` Luca Coelho
  2019-01-21  7:50 ` [PATCH 07/16] iwlwifi: mvm: Set Tx rate and flags when there is not station Luca Coelho
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Luca Coelho @ 2019-01-21  7:50 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Ilan Peer, Luca Coelho

From: Ilan Peer <ilan.peer@intel.com>

When a time event for a P2P Device interface is done, it is possible
that there is still a frame pending for transmission that should be
flushed.

Set the IWL_MVM_STATUS_NEED_FLUSH_P2P to indicate to the ROC worker
that P2P Device station queue need also to be flushed.

Signed-off-by: Ilan Peer <ilan.peer@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/time-event.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c
index e1a6f4e22253..9fa1a36dcda3 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c
@@ -334,6 +334,7 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm,
 		switch (te_data->vif->type) {
 		case NL80211_IFTYPE_P2P_DEVICE:
 			ieee80211_remain_on_channel_expired(mvm->hw);
+			set_bit(IWL_MVM_STATUS_NEED_FLUSH_P2P, &mvm->status);
 			iwl_mvm_roc_finished(mvm);
 			break;
 		case NL80211_IFTYPE_STATION:
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 07/16] iwlwifi: mvm: Set Tx rate and flags when there is not station
  2019-01-21  7:50 [PATCH 00/16] iwlwifi: updates intended for v4.21 2019-01-21 Luca Coelho
                   ` (5 preceding siblings ...)
  2019-01-21  7:50 ` [PATCH 06/16] iwlwifi: mvm: Flush transmit queues on P2P Device ROC done Luca Coelho
@ 2019-01-21  7:50 ` Luca Coelho
  2019-01-21  7:50 ` [PATCH 08/16] iwlwifi: mvm: Do not set RTS/CTS protection for P2P Device MAC Luca Coelho
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Luca Coelho @ 2019-01-21  7:50 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Ilan Peer, Luca Coelho

From: Ilan Peer <ilan.peer@intel.com>

When a frame is transmitted without a station, need to set the rate
and flags in the Tx command, as the FW does not have any information as
to what rate and flags should be used for this frame.

Signed-off-by: Ilan Peer <ilan.peer@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
index da8b69c9468c..2adef6e3e0ac 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
@@ -533,10 +533,11 @@ iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb,
 
 		/*
 		 * For data packets rate info comes from the fw. Only
-		 * set rate/antenna during connection establishment.
+		 * set rate/antenna during connection establishment or in case
+		 * no station is given.
 		 */
-		if (sta && (!ieee80211_is_data(hdr->frame_control) ||
-			    mvmsta->sta_state < IEEE80211_STA_AUTHORIZED)) {
+		if (!sta || !ieee80211_is_data(hdr->frame_control) ||
+		    mvmsta->sta_state < IEEE80211_STA_AUTHORIZED) {
 			flags |= IWL_TX_FLAGS_CMD_RATE;
 			rate_n_flags =
 				iwl_mvm_get_tx_rate_n_flags(mvm, info, sta,
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 08/16] iwlwifi: mvm: Do not set RTS/CTS protection for P2P Device MAC
  2019-01-21  7:50 [PATCH 00/16] iwlwifi: updates intended for v4.21 2019-01-21 Luca Coelho
                   ` (6 preceding siblings ...)
  2019-01-21  7:50 ` [PATCH 07/16] iwlwifi: mvm: Set Tx rate and flags when there is not station Luca Coelho
@ 2019-01-21  7:50 ` Luca Coelho
  2019-01-21  7:50 ` [PATCH 09/16] iwlwifi: update hcmds documentation Luca Coelho
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Luca Coelho @ 2019-01-21  7:50 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Ilan Peer, Luca Coelho

From: Ilan Peer <ilan.peer@intel.com>

As this is not needed and might cause interoperability issues
during pairing with devices that would not reply to RTS frames.

Signed-off-by: Ilan Peer <ilan.peer@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
index a79c79701cc4..11714eb8da5e 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
@@ -793,8 +793,6 @@ static int iwl_mvm_mac_ctxt_cmd_p2p_device(struct iwl_mvm *mvm,
 
 	iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, NULL, action);
 
-	cmd.protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT);
-
 	/* Override the filter flags to accept only probe requests */
 	cmd.filter_flags = cpu_to_le32(MAC_FILTER_IN_PROBE_REQUEST);
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 09/16] iwlwifi: update hcmds documentation
  2019-01-21  7:50 [PATCH 00/16] iwlwifi: updates intended for v4.21 2019-01-21 Luca Coelho
                   ` (7 preceding siblings ...)
  2019-01-21  7:50 ` [PATCH 08/16] iwlwifi: mvm: Do not set RTS/CTS protection for P2P Device MAC Luca Coelho
@ 2019-01-21  7:50 ` Luca Coelho
  2019-01-21  7:50 ` [PATCH 10/16] iwlwifi: mvm: make num_active_macs unsigned Luca Coelho
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Luca Coelho @ 2019-01-21  7:50 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Liad Kaufman, Luca Coelho

From: Liad Kaufman <liad.kaufman@intel.com>

A few commands refer to a struct that no longer exists
in the mentioned name. Our trace-cmd parsing scripts
rely on these mentioned names and can't find them,
resulting in these commands not being parsed nicely.

Signed-off-by: Liad Kaufman <liad.kaufman@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/fw/api/commands.h | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h b/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h
index 8b4922bbe139..89c0cfddcc3f 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h
@@ -415,7 +415,11 @@ enum iwl_legacy_cmds {
 	TX_ANT_CONFIGURATION_CMD = 0x98,
 
 	/**
-	 * @STATISTICS_CMD: &struct iwl_statistics_cmd
+	 * @STATISTICS_CMD:
+	 * one of &struct iwl_statistics_cmd,
+	 * &struct iwl_notif_statistics_v11,
+	 * &struct iwl_notif_statistics_v10,
+	 * &struct iwl_notif_statistics
 	 */
 	STATISTICS_CMD = 0x9c,
 
@@ -423,7 +427,7 @@ enum iwl_legacy_cmds {
 	 * @STATISTICS_NOTIFICATION:
 	 * one of &struct iwl_notif_statistics_v10,
 	 * &struct iwl_notif_statistics_v11,
-	 * &struct iwl_notif_statistics_cdb
+	 * &struct iwl_notif_statistics
 	 */
 	STATISTICS_NOTIFICATION = 0x9d,
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 10/16] iwlwifi: mvm: make num_active_macs unsigned
  2019-01-21  7:50 [PATCH 00/16] iwlwifi: updates intended for v4.21 2019-01-21 Luca Coelho
                   ` (8 preceding siblings ...)
  2019-01-21  7:50 ` [PATCH 09/16] iwlwifi: update hcmds documentation Luca Coelho
@ 2019-01-21  7:50 ` Luca Coelho
  2019-01-21  7:50 ` [PATCH 11/16] iwlwifi: tighten boundary checks Luca Coelho
                   ` (5 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Luca Coelho @ 2019-01-21  7:50 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Liad Kaufman, Luca Coelho

From: Liad Kaufman <liad.kaufman@intel.com>

There is no point in having num_active_macs signed
since it should never be negative. Set it to be an
unsigned variable to ensure this.

Signed-off-by: Liad Kaufman <liad.kaufman@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/sf.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sf.c b/drivers/net/wireless/intel/iwlwifi/mvm/sf.c
index d1d76bb9a750..9da0dae78510 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sf.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sf.c
@@ -7,6 +7,7 @@
  *
  * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
+ * Copyright (C) 2018 Intel Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -28,6 +29,7 @@
  *
  * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
+ * Copyright (C) 2018 Intel Corporation
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -64,7 +66,7 @@ struct iwl_mvm_active_iface_iterator_data {
 	struct ieee80211_vif *ignore_vif;
 	u8 sta_vif_ap_sta_id;
 	enum iwl_sf_state sta_vif_state;
-	int num_active_macs;
+	u32 num_active_macs;
 };
 
 /*
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 11/16] iwlwifi: tighten boundary checks
  2019-01-21  7:50 [PATCH 00/16] iwlwifi: updates intended for v4.21 2019-01-21 Luca Coelho
                   ` (9 preceding siblings ...)
  2019-01-21  7:50 ` [PATCH 10/16] iwlwifi: mvm: make num_active_macs unsigned Luca Coelho
@ 2019-01-21  7:50 ` Luca Coelho
  2019-01-21  7:50 ` [PATCH 12/16] iwlwifi: memcpy from dev_cmd and not dev_cmd->hdr Luca Coelho
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Luca Coelho @ 2019-01-21  7:50 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Liad Kaufman, Luca Coelho

From: Liad Kaufman <liad.kaufman@intel.com>

The driver assumes certain sizes and lengths aren't crossed in some
places.  Make sure this indeed happens.

Found by Klocwork.

Signed-off-by: Liad Kaufman <liad.kaufman@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/fw/dbg.c   |  2 ++
 drivers/net/wireless/intel/iwlwifi/mvm/tx.c   | 24 +++++++++++++++----
 .../net/wireless/intel/iwlwifi/pcie/tx-gen2.c |  6 ++++-
 3 files changed, 26 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
index 5f16879ab26a..56e99b5661f7 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
@@ -835,6 +835,8 @@ _iwl_fw_error_dump(struct iwl_fw_runtime *fwrt,
 	if (!fwrt->trans->cfg->dccm_offset || !fwrt->trans->cfg->dccm_len) {
 		const struct fw_img *img;
 
+		if (fwrt->cur_fw_img >= IWL_UCODE_TYPE_MAX)
+			return NULL;
 		img = &fwrt->fw->img[fwrt->cur_fw_img];
 		sram_ofs = img->sec[IWL_UCODE_SECTION_DATA].offset;
 		sram_len = img->sec[IWL_UCODE_SECTION_DATA].len;
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
index 2adef6e3e0ac..ac62eb8c4b36 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
@@ -1024,7 +1024,12 @@ static void iwl_mvm_tx_airtime(struct iwl_mvm *mvm,
 			       int airtime)
 {
 	int mac = mvmsta->mac_id_n_color & FW_CTXT_ID_MSK;
-	struct iwl_mvm_tcm_mac *mdata = &mvm->tcm.data[mac];
+	struct iwl_mvm_tcm_mac *mdata;
+
+	if (mac >= NUM_MAC_INDEX_DRIVER)
+		return;
+
+	mdata = &mvm->tcm.data[mac];
 
 	if (mvm->tcm.paused)
 		return;
@@ -1035,14 +1040,21 @@ static void iwl_mvm_tx_airtime(struct iwl_mvm *mvm,
 	mdata->tx.airtime += airtime;
 }
 
-static void iwl_mvm_tx_pkt_queued(struct iwl_mvm *mvm,
-				  struct iwl_mvm_sta *mvmsta, int tid)
+static int iwl_mvm_tx_pkt_queued(struct iwl_mvm *mvm,
+				 struct iwl_mvm_sta *mvmsta, int tid)
 {
 	u32 ac = tid_to_mac80211_ac[tid];
 	int mac = mvmsta->mac_id_n_color & FW_CTXT_ID_MSK;
-	struct iwl_mvm_tcm_mac *mdata = &mvm->tcm.data[mac];
+	struct iwl_mvm_tcm_mac *mdata;
+
+	if (mac >= NUM_MAC_INDEX_DRIVER)
+		return -EINVAL;
+
+	mdata = &mvm->tcm.data[mac];
 
 	mdata->tx.pkts[ac]++;
+
+	return 0;
 }
 
 /*
@@ -1162,7 +1174,9 @@ static int iwl_mvm_tx_mpdu(struct iwl_mvm *mvm, struct sk_buff *skb,
 
 	spin_unlock(&mvmsta->lock);
 
-	iwl_mvm_tx_pkt_queued(mvm, mvmsta, tid == IWL_MAX_TID_COUNT ? 0 : tid);
+	if (iwl_mvm_tx_pkt_queued(mvm, mvmsta,
+				  tid == IWL_MAX_TID_COUNT ? 0 : tid))
+		goto drop;
 
 	return 0;
 
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
index 156ca1b1f621..af2791502b7d 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
@@ -214,7 +214,11 @@ static int iwl_pcie_gen2_set_tb(struct iwl_trans *trans,
 {
 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
 	int idx = iwl_pcie_gen2_get_num_tbs(trans, tfd);
-	struct iwl_tfh_tb *tb = &tfd->tbs[idx];
+	struct iwl_tfh_tb *tb;
+
+	if (WARN_ON(idx >= IWL_NUM_OF_TBS))
+		return -EINVAL;
+	tb = &tfd->tbs[idx];
 
 	/* Each TFD can point to a maximum max_tbs Tx buffers */
 	if (le16_to_cpu(tfd->num_tbs) >= trans_pcie->max_tbs) {
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 12/16] iwlwifi: memcpy from dev_cmd and not dev_cmd->hdr
  2019-01-21  7:50 [PATCH 00/16] iwlwifi: updates intended for v4.21 2019-01-21 Luca Coelho
                   ` (10 preceding siblings ...)
  2019-01-21  7:50 ` [PATCH 11/16] iwlwifi: tighten boundary checks Luca Coelho
@ 2019-01-21  7:50 ` Luca Coelho
  2019-01-21  7:50 ` [PATCH 13/16] iwlwifi: mvm: avoid possible access out of array Luca Coelho
                   ` (3 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Luca Coelho @ 2019-01-21  7:50 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Liad Kaufman, Luca Coelho

From: Liad Kaufman <liad.kaufman@intel.com>

Klocwork complains about copying from dev_cmd->hdr if
copying more than 4 bytes since it means part of the
copy is from the next field. This isn't a real bug,
but for not failing Klocwork next time - fix this.

Signed-off-by: Liad Kaufman <liad.kaufman@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c | 4 ++--
 drivers/net/wireless/intel/iwlwifi/pcie/tx.c      | 3 +--
 2 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
index af2791502b7d..d2bd7f528a20 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
@@ -412,7 +412,7 @@ iwl_tfh_tfd *iwl_pcie_gen2_build_tx_amsdu(struct iwl_trans *trans,
 		goto out_err;
 
 	/* building the A-MSDU might have changed this data, memcpy it now */
-	memcpy(&txq->first_tb_bufs[idx], &dev_cmd->hdr, IWL_FIRST_TB_SIZE);
+	memcpy(&txq->first_tb_bufs[idx], dev_cmd, IWL_FIRST_TB_SIZE);
 	return tfd;
 
 out_err:
@@ -473,7 +473,7 @@ iwl_tfh_tfd *iwl_pcie_gen2_build_tx(struct iwl_trans *trans,
 	tb_phys = iwl_pcie_get_first_tb_dma(txq, idx);
 
 	/* The first TB points to bi-directional DMA data */
-	memcpy(&txq->first_tb_bufs[idx], &dev_cmd->hdr, IWL_FIRST_TB_SIZE);
+	memcpy(&txq->first_tb_bufs[idx], dev_cmd, IWL_FIRST_TB_SIZE);
 
 	iwl_pcie_gen2_set_tb(trans, tfd, tb_phys, IWL_FIRST_TB_SIZE);
 
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
index ee990a7a5411..7073116c73b7 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
@@ -2438,8 +2438,7 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
 	}
 
 	/* building the A-MSDU might have changed this data, so memcpy it now */
-	memcpy(&txq->first_tb_bufs[txq->write_ptr], &dev_cmd->hdr,
-	       IWL_FIRST_TB_SIZE);
+	memcpy(&txq->first_tb_bufs[txq->write_ptr], dev_cmd, IWL_FIRST_TB_SIZE);
 
 	tfd = iwl_pcie_get_tfd(trans, txq, txq->write_ptr);
 	/* Set up entry for this TFD in Tx byte-count array */
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 13/16] iwlwifi: mvm: avoid possible access out of array.
  2019-01-21  7:50 [PATCH 00/16] iwlwifi: updates intended for v4.21 2019-01-21 Luca Coelho
                   ` (11 preceding siblings ...)
  2019-01-21  7:50 ` [PATCH 12/16] iwlwifi: memcpy from dev_cmd and not dev_cmd->hdr Luca Coelho
@ 2019-01-21  7:50 ` Luca Coelho
  2019-01-21  7:50 ` [PATCH 14/16] iwlwifi: avoid access out of memory allocated Luca Coelho
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Luca Coelho @ 2019-01-21  7:50 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Mordechay Goodstein, Luca Coelho

From: Mordechay Goodstein <mordechay.goodstein@intel.com>

The value in txq_id can be out of array scope,
validate it before accessing the array.

Signed-off-by: Mordechay Goodstein <mordechay.goodstein@intel.com>
Fixes: cf961e16620f ("iwlwifi: mvm: support dqa-mode agg on non-shared queue")
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
index 09f294c466da..5f42897dcd55 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
@@ -2702,7 +2702,7 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
 	struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
 	struct iwl_mvm_tid_data *tid_data;
 	u16 normalized_ssn;
-	int txq_id;
+	u16 txq_id;
 	int ret;
 
 	if (WARN_ON_ONCE(tid >= IWL_MAX_TID_COUNT))
@@ -2744,17 +2744,24 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
 	 */
 	txq_id = mvmsta->tid_data[tid].txq_id;
 	if (txq_id == IWL_MVM_INVALID_QUEUE) {
-		txq_id = iwl_mvm_find_free_queue(mvm, mvmsta->sta_id,
-						 IWL_MVM_DQA_MIN_DATA_QUEUE,
-						 IWL_MVM_DQA_MAX_DATA_QUEUE);
-		if (txq_id < 0) {
-			ret = txq_id;
+		ret = iwl_mvm_find_free_queue(mvm, mvmsta->sta_id,
+					      IWL_MVM_DQA_MIN_DATA_QUEUE,
+					      IWL_MVM_DQA_MAX_DATA_QUEUE);
+		if (ret < 0) {
 			IWL_ERR(mvm, "Failed to allocate agg queue\n");
 			goto out;
 		}
 
+		txq_id = ret;
+
 		/* TXQ hasn't yet been enabled, so mark it only as reserved */
 		mvm->queue_info[txq_id].status = IWL_MVM_QUEUE_RESERVED;
+	} else if (WARN_ON(txq_id >= IWL_MAX_HW_QUEUES)) {
+		ret = -ENXIO;
+		IWL_ERR(mvm, "tid_id %d out of range (0, %d)!\n",
+			tid, IWL_MAX_HW_QUEUES - 1);
+		goto out;
+
 	} else if (unlikely(mvm->queue_info[txq_id].status ==
 			    IWL_MVM_QUEUE_SHARED)) {
 		ret = -ENXIO;
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 14/16] iwlwifi: avoid access out of memory allocated
  2019-01-21  7:50 [PATCH 00/16] iwlwifi: updates intended for v4.21 2019-01-21 Luca Coelho
                   ` (12 preceding siblings ...)
  2019-01-21  7:50 ` [PATCH 13/16] iwlwifi: mvm: avoid possible access out of array Luca Coelho
@ 2019-01-21  7:50 ` Luca Coelho
  2019-01-21  7:50 ` [PATCH 15/16] iwlwifi: fw api: remove unused/deprecated filter status Luca Coelho
  2019-01-21  7:50 ` [PATCH 16/16] iwlwifi: fw api: document WoWLAN patterns command Luca Coelho
  15 siblings, 0 replies; 19+ messages in thread
From: Luca Coelho @ 2019-01-21  7:50 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Mordechay Goodstein, Luca Coelho

From: Mordechay Goodstein <mordechay.goodstein@intel.com>

The value in num_lmac can be bigger than mem_cfg->lmac array,
warn in case it's bigger.

Signed-off-by: Mordechay Goodstein <mordechay.goodstein@intel.com>
Fixes: 68025d5f9bfe ("iwlwifi: dbg: refactor dump code to improve readability")
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
index 56e99b5661f7..a97bf17da14d 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
@@ -748,6 +748,9 @@ static int iwl_fw_rxf_len(struct iwl_fw_runtime *fwrt,
 	ADD_LEN(fifo_len, mem_cfg->rxfifo2_size, hdr_len);
 
 	/* Count RXF1 sizes */
+	if (WARN_ON(mem_cfg->num_lmacs > MAX_NUM_LMAC))
+		mem_cfg->num_lmacs = MAX_NUM_LMAC;
+
 	for (i = 0; i < mem_cfg->num_lmacs; i++)
 		ADD_LEN(fifo_len, mem_cfg->lmac[i].rxfifo1_size, hdr_len);
 
@@ -766,6 +769,9 @@ static int iwl_fw_txf_len(struct iwl_fw_runtime *fwrt,
 		goto dump_internal_txf;
 
 	/* Count TXF sizes */
+	if (WARN_ON(mem_cfg->num_lmacs > MAX_NUM_LMAC))
+		mem_cfg->num_lmacs = MAX_NUM_LMAC;
+
 	for (i = 0; i < mem_cfg->num_lmacs; i++) {
 		int j;
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 15/16] iwlwifi: fw api: remove unused/deprecated filter status
  2019-01-21  7:50 [PATCH 00/16] iwlwifi: updates intended for v4.21 2019-01-21 Luca Coelho
                   ` (13 preceding siblings ...)
  2019-01-21  7:50 ` [PATCH 14/16] iwlwifi: avoid access out of memory allocated Luca Coelho
@ 2019-01-21  7:50 ` Luca Coelho
  2019-01-21  7:50 ` [PATCH 16/16] iwlwifi: fw api: document WoWLAN patterns command Luca Coelho
  15 siblings, 0 replies; 19+ messages in thread
From: Luca Coelho @ 2019-01-21  7:50 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Johannes Berg, Luca Coelho

From: Johannes Berg <johannes.berg@intel.com>

These are unused by both firmware and driver, remove them.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/fw/api/rx.h | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h b/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h
index 0791a854fc8f..b4f7ea30a7c1 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h
@@ -209,8 +209,6 @@ enum iwl_rx_phy_flags {
  * @RX_MPDU_RES_STATUS_CSUM_OK: checksum found no errors
  * @RX_MPDU_RES_STATUS_STA_ID_MSK: station ID mask
  * @RX_MDPU_RES_STATUS_STA_ID_SHIFT: station ID bit shift
- * @RX_MPDU_RES_STATUS_FILTERING_MSK: filter status
- * @RX_MPDU_RES_STATUS2_FILTERING_MSK: filter status 2
  */
 enum iwl_mvm_rx_status {
 	RX_MPDU_RES_STATUS_CRC_OK			= BIT(0),
@@ -238,8 +236,6 @@ enum iwl_mvm_rx_status {
 	RX_MPDU_RES_STATUS_CSUM_OK			= BIT(17),
 	RX_MDPU_RES_STATUS_STA_ID_SHIFT			= 24,
 	RX_MPDU_RES_STATUS_STA_ID_MSK			= 0x1f << RX_MDPU_RES_STATUS_STA_ID_SHIFT,
-	RX_MPDU_RES_STATUS_FILTERING_MSK		= (0xc00000),
-	RX_MPDU_RES_STATUS2_FILTERING_MSK		= (0xc0000000),
 };
 
 /* 9000 series API */
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 16/16] iwlwifi: fw api: document WoWLAN patterns command
  2019-01-21  7:50 [PATCH 00/16] iwlwifi: updates intended for v4.21 2019-01-21 Luca Coelho
                   ` (14 preceding siblings ...)
  2019-01-21  7:50 ` [PATCH 15/16] iwlwifi: fw api: remove unused/deprecated filter status Luca Coelho
@ 2019-01-21  7:50 ` Luca Coelho
  15 siblings, 0 replies; 19+ messages in thread
From: Luca Coelho @ 2019-01-21  7:50 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Johannes Berg, Luca Coelho

From: Johannes Berg <johannes.berg@intel.com>

Document the WoWLAN patterns command structure.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/fw/api/d3.h | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h b/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h
index 6fae02fa4cad..86ea0784e1a3 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h
@@ -224,8 +224,18 @@ struct iwl_wowlan_pattern {
 
 #define IWL_WOWLAN_MAX_PATTERNS	20
 
+/**
+ * struct iwl_wowlan_patterns_cmd - WoWLAN wakeup patterns
+ */
 struct iwl_wowlan_patterns_cmd {
+	/**
+	 * @n_patterns: number of patterns
+	 */
 	__le32 n_patterns;
+
+	/**
+	 * @patterns: the patterns, array length in @n_patterns
+	 */
 	struct iwl_wowlan_pattern patterns[];
 } __packed; /* WOWLAN_PATTERN_ARRAY_API_S_VER_1 */
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH 01/16] iwlwifi: mvm: support mac80211 AMSDU
  2019-01-21  7:50 ` [PATCH 01/16] iwlwifi: mvm: support mac80211 AMSDU Luca Coelho
@ 2019-01-22 12:53   ` Kalle Valo
  2019-01-23  8:25     ` [PATCH v2] " Luca Coelho
  0 siblings, 1 reply; 19+ messages in thread
From: Kalle Valo @ 2019-01-22 12:53 UTC (permalink / raw)
  To: Luca Coelho; +Cc: linux-wireless, Sara Sharon, Luca Coelho

Luca Coelho <luca@coelho.fi> writes:

> From: Sara Sharon <sara.sharon@intel.com>
>
> Support getting mac80211 building AMSDUs for us. Remove GSO
> support from mvm - we don't need it anymore.
>
> Signed-off-by: Sara Sharon <sara.sharon@intel.com>
> Signed-off-by: Luca Coelho <luciano.coelho@intel.com>

[...]

> +static bool iwl_mvm_can_hw_csum(struct sk_buff *skb)
> +{
> +#if IS_ENABLED(CONFIG_INET)
> +	u8 protocol = ip_hdr(skb)->protocol;
> +
> +	return protocol == IPPROTO_TCP || protocol == IPPROTO_UDP;
> +#else
> +	return false;
> +#endif
> +}

I remember Andrew Morton a long time ago saying "Write in C, not in CPP"
or something like that. So would this work instead:

	u8 protocol = ip_hdr(skb)->protocol;

        if (!IS_ENABLED(CONFIG_INET))
                return false;

	return protocol == IPPROTO_TCP || protocol == IPPROTO_UDP;

Totally untested, of course :)

-- 
Kalle Valo

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v2] iwlwifi: mvm: support mac80211 AMSDU
  2019-01-22 12:53   ` Kalle Valo
@ 2019-01-23  8:25     ` Luca Coelho
  0 siblings, 0 replies; 19+ messages in thread
From: Luca Coelho @ 2019-01-23  8:25 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Sara Sharon, Luca Coelho

From: Sara Sharon <sara.sharon@intel.com>

Support getting mac80211 building AMSDUs for us. Remove GSO
support from mvm - we don't need it anymore.

Signed-off-by: Sara Sharon <sara.sharon@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
In v2:
   * use IS_ENABLED() in C not CPP

.../net/wireless/intel/iwlwifi/mvm/mac80211.c |  33 +++
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h  |   3 +
 .../net/wireless/intel/iwlwifi/mvm/rs-fw.c    |  14 ++
 drivers/net/wireless/intel/iwlwifi/mvm/rs.c   |  14 ++
 drivers/net/wireless/intel/iwlwifi/mvm/tx.c   | 229 +-----------------
 5 files changed, 67 insertions(+), 226 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index 58bb92b0ef05..3b24cced3f6f 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -440,6 +440,8 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
 	ieee80211_hw_set(hw, SUPPORTS_VHT_EXT_NSS_BW);
 	ieee80211_hw_set(hw, BUFF_MMPDU_TXQ);
 	ieee80211_hw_set(hw, STA_MMPDU_TXQ);
+	ieee80211_hw_set(hw, TX_AMSDU);
+	ieee80211_hw_set(hw, TX_FRAG_LIST);
 
 	if (iwl_mvm_has_tlc_offload(mvm)) {
 		ieee80211_hw_set(hw, TX_AMPDU_SETUP_IN_HW);
@@ -485,6 +487,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
 
 	hw->uapsd_queues = IWL_MVM_UAPSD_QUEUES;
 	hw->uapsd_max_sp_len = IWL_UAPSD_MAX_SP;
+	hw->max_tx_fragments = mvm->trans->max_skb_frags;
 
 	BUILD_BUG_ON(ARRAY_SIZE(mvm->ciphers) < ARRAY_SIZE(mvm_ciphers) + 6);
 	memcpy(mvm->ciphers, mvm_ciphers, sizeof(mvm_ciphers));
@@ -751,6 +754,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
 	}
 
 	hw->netdev_features |= mvm->cfg->features;
+	hw->netdev_features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
 	if (!iwl_mvm_is_csum_supported(mvm)) {
 		hw->netdev_features &= ~(IWL_TX_CSUM_NETIF_FLAGS |
 					 NETIF_F_RXCSUM);
@@ -3035,6 +3039,8 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
 			iwl_mvm_tdls_check_trigger(mvm, vif, sta->addr,
 						   NL80211_TDLS_SETUP);
 		}
+
+		sta->max_rc_amsdu_len = 1;
 	} else if (old_state == IEEE80211_STA_NONE &&
 		   new_state == IEEE80211_STA_AUTH) {
 		/*
@@ -4724,6 +4730,32 @@ static void iwl_mvm_sync_rx_queues(struct ieee80211_hw *hw)
 	mutex_unlock(&mvm->mutex);
 }
 
+static bool iwl_mvm_can_hw_csum(struct sk_buff *skb)
+{
+	u8 protocol = ip_hdr(skb)->protocol;
+
+	if (!IS_ENABLED(CONFIG_INET))
+		return false;
+
+	return protocol == IPPROTO_TCP || protocol == IPPROTO_UDP;
+}
+
+static bool iwl_mvm_mac_can_aggregate(struct ieee80211_hw *hw,
+				      struct sk_buff *head,
+				      struct sk_buff *skb)
+{
+	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
+
+	/* For now don't aggregate IPv6 in AMSDU */
+	if (skb->protocol != htons(ETH_P_IP))
+		return false;
+
+	if (!iwl_mvm_is_csum_supported(mvm))
+		return true;
+
+	return iwl_mvm_can_hw_csum(skb) == iwl_mvm_can_hw_csum(head);
+}
+
 const struct ieee80211_ops iwl_mvm_hw_ops = {
 	.tx = iwl_mvm_mac_tx,
 	.wake_tx_queue = iwl_mvm_mac_wake_tx_queue,
@@ -4800,6 +4832,7 @@ const struct ieee80211_ops iwl_mvm_hw_ops = {
 #endif
 	.get_survey = iwl_mvm_mac_get_survey,
 	.sta_statistics = iwl_mvm_mac_sta_statistics,
+	.can_aggregate_in_amsdu = iwl_mvm_mac_can_aggregate,
 #ifdef CONFIG_IWLWIFI_DEBUGFS
 	.sta_add_debugfs = iwl_mvm_sta_add_debugfs,
 #endif
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index 39ee3ace59b6..503e51d32e7f 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -1504,6 +1504,9 @@ void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm, struct iwl_tx_cmd *tx_cmd,
 			    struct ieee80211_tx_info *info,
 			    struct ieee80211_sta *sta, __le16 fc);
 void iwl_mvm_mac_itxq_xmit(struct ieee80211_hw *hw, struct ieee80211_txq *txq);
+unsigned int iwl_mvm_max_amsdu_size(struct iwl_mvm *mvm,
+				    struct ieee80211_sta *sta,
+				    unsigned int tid);
 
 #ifdef CONFIG_IWLWIFI_DEBUG
 const char *iwl_mvm_get_tx_fail_reason(u32 status);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c
index a0ea0c160fd6..a28283ff7295 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c
@@ -315,12 +315,26 @@ void iwl_mvm_tlc_update_notif(struct iwl_mvm *mvm,
 
 	if (flags & IWL_TLC_NOTIF_FLAG_AMSDU) {
 		u16 size = le32_to_cpu(notif->amsdu_size);
+		int i;
 
 		if (WARN_ON(sta->max_amsdu_len < size))
 			goto out;
 
 		mvmsta->amsdu_enabled = le32_to_cpu(notif->amsdu_enabled);
 		mvmsta->max_amsdu_len = size;
+		sta->max_rc_amsdu_len = mvmsta->max_amsdu_len;
+
+		for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
+			if (mvmsta->amsdu_enabled & BIT(i))
+				sta->max_tid_amsdu_len[i] =
+					iwl_mvm_max_amsdu_size(mvm, sta, i);
+			else
+				/*
+				 * Not so elegant, but this will effectively
+				 * prevent AMSDU on this TID
+				 */
+				sta->max_tid_amsdu_len[i] = 1;
+		}
 
 		IWL_DEBUG_RATE(mvm,
 			       "AMSDU update. AMSDU size: %d, AMSDU selected size: %d, AMSDU TID bitmap 0x%X\n",
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
index 089972280daa..9b5682ce4b39 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
@@ -1744,6 +1744,7 @@ static void rs_set_amsdu_len(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
 			     enum rs_action scale_action)
 {
 	struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
+	int i;
 
 	/*
 	 * In case TLC offload is not active amsdu_enabled is either 0xFFFF
@@ -1757,6 +1758,19 @@ static void rs_set_amsdu_len(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
 		mvmsta->amsdu_enabled = 0xFFFF;
 
 	mvmsta->max_amsdu_len = sta->max_amsdu_len;
+	sta->max_rc_amsdu_len = mvmsta->max_amsdu_len;
+
+	for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
+		if (mvmsta->amsdu_enabled)
+			sta->max_tid_amsdu_len[i] =
+				iwl_mvm_max_amsdu_size(mvm, sta, i);
+		else
+			/*
+			 * Not so elegant, but this will effectively
+			 * prevent AMSDU on this TID
+			 */
+			sta->max_tid_amsdu_len[i] = 1;
+	}
 }
 
 /*
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
index dfdfaa9ecfdb..2f2c355c13b0 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
@@ -779,78 +779,8 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb)
 	return 0;
 }
 
-#ifdef CONFIG_INET
-
-static int
-iwl_mvm_tx_tso_segment(struct sk_buff *skb, unsigned int num_subframes,
-		       netdev_features_t netdev_flags,
-		       struct sk_buff_head *mpdus_skb)
-{
-	struct sk_buff *tmp, *next;
-	struct ieee80211_hdr *hdr = (void *)skb->data;
-	char cb[sizeof(skb->cb)];
-	u16 i = 0;
-	unsigned int tcp_payload_len;
-	unsigned int mss = skb_shinfo(skb)->gso_size;
-	bool ipv4 = (skb->protocol == htons(ETH_P_IP));
-	u16 ip_base_id = ipv4 ? ntohs(ip_hdr(skb)->id) : 0;
-
-	skb_shinfo(skb)->gso_size = num_subframes * mss;
-	memcpy(cb, skb->cb, sizeof(cb));
-
-	next = skb_gso_segment(skb, netdev_flags);
-	skb_shinfo(skb)->gso_size = mss;
-	if (WARN_ON_ONCE(IS_ERR(next)))
-		return -EINVAL;
-	else if (next)
-		consume_skb(skb);
-
-	while (next) {
-		tmp = next;
-		next = tmp->next;
-
-		memcpy(tmp->cb, cb, sizeof(tmp->cb));
-		/*
-		 * Compute the length of all the data added for the A-MSDU.
-		 * This will be used to compute the length to write in the TX
-		 * command. We have: SNAP + IP + TCP for n -1 subframes and
-		 * ETH header for n subframes.
-		 */
-		tcp_payload_len = skb_tail_pointer(tmp) -
-			skb_transport_header(tmp) -
-			tcp_hdrlen(tmp) + tmp->data_len;
-
-		if (ipv4)
-			ip_hdr(tmp)->id = htons(ip_base_id + i * num_subframes);
-
-		if (tcp_payload_len > mss) {
-			skb_shinfo(tmp)->gso_size = mss;
-		} else {
-			if (ieee80211_is_data_qos(hdr->frame_control)) {
-				u8 *qc;
-
-				if (ipv4)
-					ip_send_check(ip_hdr(tmp));
-
-				qc = ieee80211_get_qos_ctl((void *)tmp->data);
-				*qc &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT;
-			}
-			skb_shinfo(tmp)->gso_size = 0;
-		}
-
-		tmp->prev = NULL;
-		tmp->next = NULL;
-
-		__skb_queue_tail(mpdus_skb, tmp);
-		i++;
-	}
-
-	return 0;
-}
-
-static unsigned int iwl_mvm_max_amsdu_size(struct iwl_mvm *mvm,
-					   struct ieee80211_sta *sta,
-					   unsigned int tid)
+unsigned int iwl_mvm_max_amsdu_size(struct iwl_mvm *mvm,
+				    struct ieee80211_sta *sta, unsigned int tid)
 {
 	struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
 	enum nl80211_band band = mvmsta->vif->bss_conf.chandef.chan->band;
@@ -878,128 +808,6 @@ static unsigned int iwl_mvm_max_amsdu_size(struct iwl_mvm *mvm,
 		     mvm->fwrt.smem_cfg.lmac[lmac].txfifo_size[txf] - 256);
 }
 
-static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb,
-			  struct ieee80211_tx_info *info,
-			  struct ieee80211_sta *sta,
-			  struct sk_buff_head *mpdus_skb)
-{
-	struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
-	struct ieee80211_hdr *hdr = (void *)skb->data;
-	unsigned int mss = skb_shinfo(skb)->gso_size;
-	unsigned int num_subframes, tcp_payload_len, subf_len, max_amsdu_len;
-	u16 snap_ip_tcp, pad;
-	unsigned int dbg_max_amsdu_len;
-	netdev_features_t netdev_flags = NETIF_F_CSUM_MASK | NETIF_F_SG;
-	u8 tid;
-
-	snap_ip_tcp = 8 + skb_transport_header(skb) - skb_network_header(skb) +
-		tcp_hdrlen(skb);
-
-	dbg_max_amsdu_len = READ_ONCE(mvm->max_amsdu_len);
-
-	if (!mvmsta->max_amsdu_len ||
-	    !ieee80211_is_data_qos(hdr->frame_control) ||
-	    (!mvmsta->amsdu_enabled && !dbg_max_amsdu_len))
-		return iwl_mvm_tx_tso_segment(skb, 1, netdev_flags, mpdus_skb);
-
-	/*
-	 * Do not build AMSDU for IPv6 with extension headers.
-	 * ask stack to segment and checkum the generated MPDUs for us.
-	 */
-	if (skb->protocol == htons(ETH_P_IPV6) &&
-	    ((struct ipv6hdr *)skb_network_header(skb))->nexthdr !=
-	    IPPROTO_TCP) {
-		netdev_flags &= ~NETIF_F_CSUM_MASK;
-		return iwl_mvm_tx_tso_segment(skb, 1, netdev_flags, mpdus_skb);
-	}
-
-	tid = ieee80211_get_tid(hdr);
-	if (WARN_ON_ONCE(tid >= IWL_MAX_TID_COUNT))
-		return -EINVAL;
-
-	/*
-	 * No need to lock amsdu_in_ampdu_allowed since it can't be modified
-	 * during an BA session.
-	 */
-	if (info->flags & IEEE80211_TX_CTL_AMPDU &&
-	    !mvmsta->tid_data[tid].amsdu_in_ampdu_allowed)
-		return iwl_mvm_tx_tso_segment(skb, 1, netdev_flags, mpdus_skb);
-
-	if (iwl_mvm_vif_low_latency(iwl_mvm_vif_from_mac80211(mvmsta->vif)) ||
-	    !(mvmsta->amsdu_enabled & BIT(tid)))
-		return iwl_mvm_tx_tso_segment(skb, 1, netdev_flags, mpdus_skb);
-
-	max_amsdu_len = iwl_mvm_max_amsdu_size(mvm, sta, tid);
-
-	if (unlikely(dbg_max_amsdu_len))
-		max_amsdu_len = min_t(unsigned int, max_amsdu_len,
-				      dbg_max_amsdu_len);
-
-	/*
-	 * Limit A-MSDU in A-MPDU to 4095 bytes when VHT is not
-	 * supported. This is a spec requirement (IEEE 802.11-2015
-	 * section 8.7.3 NOTE 3).
-	 */
-	if (info->flags & IEEE80211_TX_CTL_AMPDU &&
-	    !sta->vht_cap.vht_supported)
-		max_amsdu_len = min_t(unsigned int, max_amsdu_len, 4095);
-
-	/* Sub frame header + SNAP + IP header + TCP header + MSS */
-	subf_len = sizeof(struct ethhdr) + snap_ip_tcp + mss;
-	pad = (4 - subf_len) & 0x3;
-
-	/*
-	 * If we have N subframes in the A-MSDU, then the A-MSDU's size is
-	 * N * subf_len + (N - 1) * pad.
-	 */
-	num_subframes = (max_amsdu_len + pad) / (subf_len + pad);
-
-	if (sta->max_amsdu_subframes &&
-	    num_subframes > sta->max_amsdu_subframes)
-		num_subframes = sta->max_amsdu_subframes;
-
-	tcp_payload_len = skb_tail_pointer(skb) - skb_transport_header(skb) -
-		tcp_hdrlen(skb) + skb->data_len;
-
-	/*
-	 * Make sure we have enough TBs for the A-MSDU:
-	 *	2 for each subframe
-	 *	1 more for each fragment
-	 *	1 more for the potential data in the header
-	 */
-	if ((num_subframes * 2 + skb_shinfo(skb)->nr_frags + 1) >
-	    mvm->trans->max_skb_frags)
-		num_subframes = 1;
-
-	if (num_subframes > 1)
-		*ieee80211_get_qos_ctl(hdr) |= IEEE80211_QOS_CTL_A_MSDU_PRESENT;
-
-	/* This skb fits in one single A-MSDU */
-	if (num_subframes * mss >= tcp_payload_len) {
-		__skb_queue_tail(mpdus_skb, skb);
-		return 0;
-	}
-
-	/*
-	 * Trick the segmentation function to make it
-	 * create SKBs that can fit into one A-MSDU.
-	 */
-	return iwl_mvm_tx_tso_segment(skb, num_subframes, netdev_flags,
-				      mpdus_skb);
-}
-#else /* CONFIG_INET */
-static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb,
-			  struct ieee80211_tx_info *info,
-			  struct ieee80211_sta *sta,
-			  struct sk_buff_head *mpdus_skb)
-{
-	/* Impossible to get TSO with CONFIG_INET */
-	WARN_ON(1);
-
-	return -1;
-}
-#endif
-
 /* Check if there are any timed-out TIDs on a given shared TXQ */
 static bool iwl_mvm_txq_should_update(struct iwl_mvm *mvm, int txq_id)
 {
@@ -1178,9 +986,6 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
 {
 	struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
 	struct ieee80211_tx_info info;
-	struct sk_buff_head mpdus_skbs;
-	unsigned int payload_len;
-	int ret;
 
 	if (WARN_ON_ONCE(!mvmsta))
 		return -1;
@@ -1190,35 +995,7 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
 
 	memcpy(&info, skb->cb, sizeof(info));
 
-	if (!skb_is_gso(skb))
-		return iwl_mvm_tx_mpdu(mvm, skb, &info, sta);
-
-	payload_len = skb_tail_pointer(skb) - skb_transport_header(skb) -
-		tcp_hdrlen(skb) + skb->data_len;
-
-	if (payload_len <= skb_shinfo(skb)->gso_size)
-		return iwl_mvm_tx_mpdu(mvm, skb, &info, sta);
-
-	__skb_queue_head_init(&mpdus_skbs);
-
-	ret = iwl_mvm_tx_tso(mvm, skb, &info, sta, &mpdus_skbs);
-	if (ret)
-		return ret;
-
-	if (WARN_ON(skb_queue_empty(&mpdus_skbs)))
-		return ret;
-
-	while (!skb_queue_empty(&mpdus_skbs)) {
-		skb = __skb_dequeue(&mpdus_skbs);
-
-		ret = iwl_mvm_tx_mpdu(mvm, skb, &info, sta);
-		if (ret) {
-			__skb_queue_purge(&mpdus_skbs);
-			return ret;
-		}
-	}
-
-	return 0;
+	return iwl_mvm_tx_mpdu(mvm, skb, &info, sta);
 }
 
 static void iwl_mvm_check_ratid_empty(struct iwl_mvm *mvm,
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2019-01-23  8:25 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-01-21  7:50 [PATCH 00/16] iwlwifi: updates intended for v4.21 2019-01-21 Luca Coelho
2019-01-21  7:50 ` [PATCH 01/16] iwlwifi: mvm: support mac80211 AMSDU Luca Coelho
2019-01-22 12:53   ` Kalle Valo
2019-01-23  8:25     ` [PATCH v2] " Luca Coelho
2019-01-21  7:50 ` [PATCH 02/16] iwlwifi: mvm: fix values in the table example Luca Coelho
2019-01-21  7:50 ` [PATCH 03/16] iwlwifi: use kmemdup in iwl_parse_nvm_mcc_info() Luca Coelho
2019-01-21  7:50 ` [PATCH 04/16] iwlwifi: fix spelling mistake "registrating" -> "registering" Luca Coelho
2019-01-21  7:50 ` [PATCH 05/16] iwlwifi: mvm: bring back mvm GSO code Luca Coelho
2019-01-21  7:50 ` [PATCH 06/16] iwlwifi: mvm: Flush transmit queues on P2P Device ROC done Luca Coelho
2019-01-21  7:50 ` [PATCH 07/16] iwlwifi: mvm: Set Tx rate and flags when there is not station Luca Coelho
2019-01-21  7:50 ` [PATCH 08/16] iwlwifi: mvm: Do not set RTS/CTS protection for P2P Device MAC Luca Coelho
2019-01-21  7:50 ` [PATCH 09/16] iwlwifi: update hcmds documentation Luca Coelho
2019-01-21  7:50 ` [PATCH 10/16] iwlwifi: mvm: make num_active_macs unsigned Luca Coelho
2019-01-21  7:50 ` [PATCH 11/16] iwlwifi: tighten boundary checks Luca Coelho
2019-01-21  7:50 ` [PATCH 12/16] iwlwifi: memcpy from dev_cmd and not dev_cmd->hdr Luca Coelho
2019-01-21  7:50 ` [PATCH 13/16] iwlwifi: mvm: avoid possible access out of array Luca Coelho
2019-01-21  7:50 ` [PATCH 14/16] iwlwifi: avoid access out of memory allocated Luca Coelho
2019-01-21  7:50 ` [PATCH 15/16] iwlwifi: fw api: remove unused/deprecated filter status Luca Coelho
2019-01-21  7:50 ` [PATCH 16/16] iwlwifi: fw api: document WoWLAN patterns command Luca Coelho

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).