Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f9e56875 authored by Kalle Valo's avatar Kalle Valo
Browse files
ath.git patches for 5.4. Major changes:

wil6210

* add support for Enhanced Directional Multi-Gigabit (EDMG) channels 9-11

* add debugfs file to show PCM ring content

* report boottime_ns in scan results

ath9k

* add a separate loader for AR92XX (and older) pci(e) without eeprom,
  enabled with the new ATH9K_PCI_NO_EEPROM Kconfig option
parents 98ab76ef 50e107ff
Loading
Loading
Loading
Loading
+89 −2
Original line number Diff line number Diff line
@@ -2151,6 +2151,10 @@ static bool ath10k_htt_rx_proc_rx_ind_hl(struct ath10k_htt *htt,
	struct ath10k_peer *peer;
	struct htt_rx_indication_mpdu_range *mpdu_ranges;
	struct fw_rx_desc_hl *fw_desc;
	enum htt_txrx_sec_cast_type sec_index;
	enum htt_security_types sec_type;
	union htt_rx_pn_t new_pn = {0};
	struct htt_hl_rx_desc *rx_desc;
	struct ieee80211_hdr *hdr;
	struct ieee80211_rx_status *rx_status;
	u16 peer_id;
@@ -2158,9 +2162,11 @@ static bool ath10k_htt_rx_proc_rx_ind_hl(struct ath10k_htt *htt,
	int num_mpdu_ranges;
	size_t tot_hdr_len;
	struct ieee80211_channel *ch;
	bool pn_invalid;
	bool pn_invalid, qos, first_msdu;
	u32 tid, rx_desc_info;

	peer_id = __le16_to_cpu(rx->hdr.peer_id);
	tid = MS(rx->hdr.info0, HTT_RX_INDICATION_INFO0_EXT_TID);

	spin_lock_bh(&ar->data_lock);
	peer = ath10k_peer_find_by_id(ar, peer_id);
@@ -2168,6 +2174,9 @@ static bool ath10k_htt_rx_proc_rx_ind_hl(struct ath10k_htt *htt,
	if (!peer && peer_id != HTT_INVALID_PEERID)
		ath10k_warn(ar, "Got RX ind from invalid peer: %u\n", peer_id);

	if (!peer)
		return true;

	num_mpdu_ranges = MS(__le32_to_cpu(rx->hdr.info1),
			     HTT_RX_INDICATION_INFO1_NUM_MPDU_RANGES);
	mpdu_ranges = htt_rx_ind_get_mpdu_ranges_hl(rx);
@@ -2192,10 +2201,24 @@ static bool ath10k_htt_rx_proc_rx_ind_hl(struct ath10k_htt *htt,
		goto err;
	}

	if (check_pn_type == HTT_RX_PN_CHECK) {
	rx_desc = (struct htt_hl_rx_desc *)&rx->mpdu_ranges[num_mpdu_ranges];
	rx_desc_info = __le32_to_cpu(rx_desc->info);

	if (MS(rx_desc_info, HTT_RX_DESC_HL_INFO_MCAST_BCAST))
		sec_index = HTT_TXRX_SEC_MCAST;
	else
		sec_index = HTT_TXRX_SEC_UCAST;

	sec_type = peer->rx_pn[sec_index].sec_type;
	first_msdu = rx->fw_desc.flags & FW_RX_DESC_FLAGS_FIRST_MSDU;

	ath10k_htt_rx_mpdu_desc_pn_hl(rx_desc, &new_pn, peer->rx_pn[sec_index].pn_len);

	if (check_pn_type == HTT_RX_PN_CHECK && tid >= IEEE80211_NUM_TIDS) {
		spin_lock_bh(&ar->data_lock);
		pn_invalid = ath10k_htt_rx_pn_check_replay_hl(ar, peer, rx);
		spin_unlock_bh(&ar->data_lock);

		if (pn_invalid)
			goto err;
	}
@@ -2211,6 +2234,7 @@ static bool ath10k_htt_rx_proc_rx_ind_hl(struct ath10k_htt *htt,
	skb_pull(skb, tot_hdr_len);

	hdr = (struct ieee80211_hdr *)skb->data;
	qos = ieee80211_is_data_qos(hdr->frame_control);
	rx_status = IEEE80211_SKB_RXCB(skb);
	rx_status->chains |= BIT(0);
	if (rx->ppdu.combined_rssi == 0) {
@@ -2254,6 +2278,55 @@ static bool ath10k_htt_rx_proc_rx_ind_hl(struct ath10k_htt *htt,
		rx_status->flag |= RX_FLAG_DECRYPTED |
				   RX_FLAG_IV_STRIPPED |
				   RX_FLAG_MMIC_STRIPPED;

		if (tid < IEEE80211_NUM_TIDS &&
		    first_msdu &&
		    check_pn_type == HTT_RX_PN_CHECK &&
		   (sec_type == HTT_SECURITY_AES_CCMP ||
		    sec_type == HTT_SECURITY_TKIP ||
		    sec_type == HTT_SECURITY_TKIP_NOMIC)) {
			u8 offset, *ivp, i;
			s8 keyidx = 0;
			__le64 pn48 = cpu_to_le64(new_pn.pn48);

			hdr = (struct ieee80211_hdr *)skb->data;
			offset = ieee80211_hdrlen(hdr->frame_control);
			hdr->frame_control |= __cpu_to_le16(IEEE80211_FCTL_PROTECTED);
			rx_status->flag &= ~RX_FLAG_IV_STRIPPED;

			memmove(skb->data - IEEE80211_CCMP_HDR_LEN,
				skb->data, offset);
			skb_push(skb, IEEE80211_CCMP_HDR_LEN);
			ivp = skb->data + offset;
			memset(skb->data + offset, 0, IEEE80211_CCMP_HDR_LEN);
			/* Ext IV */
			ivp[IEEE80211_WEP_IV_LEN - 1] |= ATH10K_IEEE80211_EXTIV;

			for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {
				if (peer->keys[i] &&
				    peer->keys[i]->flags & IEEE80211_KEY_FLAG_PAIRWISE)
					keyidx = peer->keys[i]->keyidx;
			}

			/* Key ID */
			ivp[IEEE80211_WEP_IV_LEN - 1] |= keyidx << 6;

			if (sec_type == HTT_SECURITY_AES_CCMP) {
				rx_status->flag |= RX_FLAG_MIC_STRIPPED;
				/* pn 0, pn 1 */
				memcpy(skb->data + offset, &pn48, 2);
				/* pn 1, pn 3 , pn 34 , pn 5 */
				memcpy(skb->data + offset + 4, ((u8 *)&pn48) + 2, 4);
			} else {
				rx_status->flag |= RX_FLAG_ICV_STRIPPED;
				/* TSC 0 */
				memcpy(skb->data + offset + 2, &pn48, 1);
				/* TSC 1 */
				memcpy(skb->data + offset, ((u8 *)&pn48) + 1, 1);
				/* TSC 2 , TSC 3 , TSC 4 , TSC 5*/
				memcpy(skb->data + offset + 4, ((u8 *)&pn48) + 2, 4);
			}
		}
	}

	if (tkip_mic_type == HTT_RX_TKIP_MIC)
@@ -2263,6 +2336,20 @@ static bool ath10k_htt_rx_proc_rx_ind_hl(struct ath10k_htt *htt,
	if (mpdu_ranges->mpdu_range_status == HTT_RX_IND_MPDU_STATUS_TKIP_MIC_ERR)
		rx_status->flag |= RX_FLAG_MMIC_ERROR;

	if (!qos && tid < IEEE80211_NUM_TIDS) {
		u8 offset;
		__le16 qos_ctrl = 0;

		hdr = (struct ieee80211_hdr *)skb->data;
		offset = ieee80211_hdrlen(hdr->frame_control);

		hdr->frame_control |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
		memmove(skb->data - IEEE80211_QOS_CTL_LEN, skb->data, offset);
		skb_push(skb, IEEE80211_QOS_CTL_LEN);
		qos_ctrl = cpu_to_le16(tid);
		memcpy(skb->data + offset, &qos_ctrl, IEEE80211_QOS_CTL_LEN);
	}

	ieee80211_rx_ni(ar->hw, skb);

	/* We have delivered the skb to the upper layers (mac80211) so we
+8 −0
Original line number Diff line number Diff line
@@ -1237,6 +1237,7 @@ static int ath10k_htt_tx_hl(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txm
	struct ath10k *ar = htt->ar;
	int res, data_len;
	struct htt_cmd_hdr *cmd_hdr;
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data;
	struct htt_data_tx_desc *tx_desc;
	struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu);
	struct sk_buff *tmp_skb;
@@ -1247,6 +1248,13 @@ static int ath10k_htt_tx_hl(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txm
	u16 flags1 = 0;
	u16 msdu_id = 0;

	if ((ieee80211_is_action(hdr->frame_control) ||
	     ieee80211_is_deauth(hdr->frame_control) ||
	     ieee80211_is_disassoc(hdr->frame_control)) &&
	     ieee80211_has_protected(hdr->frame_control)) {
		skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
	}

	data_len = msdu->len;

	switch (txmode) {
+5 −4
Original line number Diff line number Diff line
@@ -5503,10 +5503,6 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw,

	mutex_lock(&ar->conf_mutex);

	spin_lock_bh(&ar->data_lock);
	ath10k_mac_vif_beacon_cleanup(arvif);
	spin_unlock_bh(&ar->data_lock);

	ret = ath10k_spectral_vif_stop(arvif);
	if (ret)
		ath10k_warn(ar, "failed to stop spectral for vdev %i: %d\n",
@@ -5575,6 +5571,11 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw,
			peer->vif = NULL;
		}
	}

	/* Clean this up late, less opportunity for firmware to access
	 * DMA memory we have deleted.
	 */
	ath10k_mac_vif_beacon_cleanup(arvif);
	spin_unlock_bh(&ar->data_lock);

	ath10k_peer_cleanup(ar, arvif->vdev_id);
+21 −8
Original line number Diff line number Diff line
@@ -381,16 +381,11 @@ static int ath10k_sdio_mbox_rx_process_packet(struct ath10k *ar,
	struct ath10k_htc_hdr *htc_hdr = (struct ath10k_htc_hdr *)skb->data;
	bool trailer_present = htc_hdr->flags & ATH10K_HTC_FLAG_TRAILER_PRESENT;
	enum ath10k_htc_ep_id eid;
	u16 payload_len;
	u8 *trailer;
	int ret;

	payload_len = le16_to_cpu(htc_hdr->len);
	skb->len = payload_len + sizeof(struct ath10k_htc_hdr);

	if (trailer_present) {
		trailer = skb->data + sizeof(*htc_hdr) +
			  payload_len - htc_hdr->trailer_len;
		trailer = skb->data + skb->len - htc_hdr->trailer_len;

		eid = pipe_id_to_eid(htc_hdr->eid);

@@ -632,14 +627,32 @@ static int ath10k_sdio_mbox_rx_packet(struct ath10k *ar,
{
	struct ath10k_sdio *ar_sdio = ath10k_sdio_priv(ar);
	struct sk_buff *skb = pkt->skb;
	struct ath10k_htc_hdr *htc_hdr;
	int ret;

	ret = ath10k_sdio_readsb(ar, ar_sdio->mbox_info.htc_addr,
				 skb->data, pkt->alloc_len);
	pkt->status = ret;
	if (!ret)
	if (ret)
		goto out;

	/* Update actual length. The original length may be incorrect,
	 * as the FW will bundle multiple packets as long as their sizes
	 * fit within the same aligned length (pkt->alloc_len).
	 */
	htc_hdr = (struct ath10k_htc_hdr *)skb->data;
	pkt->act_len = le16_to_cpu(htc_hdr->len) + sizeof(*htc_hdr);
	if (pkt->act_len > pkt->alloc_len) {
		ath10k_warn(ar, "rx packet too large (%zu > %zu)\n",
			    pkt->act_len, pkt->alloc_len);
		ret = -EMSGSIZE;
		goto out;
	}

	skb_put(skb, pkt->act_len);

out:
	pkt->status = ret;

	return ret;
}

+1 −1
Original line number Diff line number Diff line
@@ -841,7 +841,7 @@ static int ath10k_wmi_tlv_op_pull_ch_info_ev(struct ath10k *ar,
					     struct wmi_ch_info_ev_arg *arg)
{
	const void **tb;
	const struct wmi_chan_info_event *ev;
	const struct wmi_tlv_chan_info_event *ev;
	int ret;

	tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
Loading