Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 12 May 2017 05:50:38 +0000 (UTC)
From:      Adrian Chadd <adrian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r318219 - head/sys/dev/iwm
Message-ID:  <201705120550.v4C5ocfa053030@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: adrian
Date: Fri May 12 05:50:38 2017
New Revision: 318219
URL: https://svnweb.freebsd.org/changeset/base/318219

Log:
  [iwm] Properly implement iwm_wme_update callback function.
  
  * Inspired by iwn(4) and Linux iwlwifi.
  
  * Read wme parameters into a buffer within struct iwm_vap in
    iwm_wme_update().
  
  * If we aren't associated yet, the new settings will soon be sent
    by iwm_mvm_mac_ctxt_changed() during association.
  
  * If we are already associated, explicitly call iwm_mvm_mac_ctxt_changed()
    from iwm_wme_update() to send the new settings to the firmware.
  
  * Change iwm_mvm_ac_to_tx_fifo mapping, to fit the freebsd net80211
    WME stream class numbering, instead of Linux's enum ieee80211_ac_numbers.
  
  Obtained from:	dragonflybsd.git b8bd6cd746d1f45e616ccfcbeed06dfe452a1108

Modified:
  head/sys/dev/iwm/if_iwm.c
  head/sys/dev/iwm/if_iwm_mac_ctxt.c
  head/sys/dev/iwm/if_iwm_mac_ctxt.h
  head/sys/dev/iwm/if_iwmvar.h

Modified: head/sys/dev/iwm/if_iwm.c
==============================================================================
--- head/sys/dev/iwm/if_iwm.c	Fri May 12 05:49:24 2017	(r318218)
+++ head/sys/dev/iwm/if_iwm.c	Fri May 12 05:50:38 2017	(r318219)
@@ -1533,13 +1533,6 @@ iwm_nic_init(struct iwm_softc *sc)
 	return 0;
 }
 
-const uint8_t iwm_mvm_ac_to_tx_fifo[] = {
-	IWM_MVM_TX_FIFO_VO,
-	IWM_MVM_TX_FIFO_VI,
-	IWM_MVM_TX_FIFO_BE,
-	IWM_MVM_TX_FIFO_BK,
-};
-
 static int
 iwm_enable_txq(struct iwm_softc *sc, int sta_id, int qid, int fifo)
 {
@@ -4258,7 +4251,7 @@ iwm_release(struct iwm_softc *sc, struct
 	 * from RUN back to SCAN is:
 	 *
 	 * iwm_mvm_power_mac_disable(sc, in);
-	 * iwm_mvm_mac_ctxt_changed(sc, in);
+	 * iwm_mvm_mac_ctxt_changed(sc, vap);
 	 * iwm_mvm_rm_sta(sc, in);
 	 * iwm_mvm_update_quotas(sc, NULL);
 	 * iwm_mvm_mac_ctxt_changed(sc, in);
@@ -4295,7 +4288,7 @@ iwm_release(struct iwm_softc *sc, struct
 
 	iwm_mvm_power_mac_disable(sc, in);
 
-	if ((error = iwm_mvm_mac_ctxt_changed(sc, in)) != 0) {
+	if ((error = iwm_mvm_mac_ctxt_changed(sc, vap)) != 0) {
 		device_printf(sc->sc_dev, "mac ctxt change fail 1 %d\n", error);
 		return error;
 	}
@@ -4307,7 +4300,7 @@ iwm_release(struct iwm_softc *sc, struct
 	error = iwm_mvm_rm_sta(sc, in);
 	in->in_assoc = 0;
 	iwm_mvm_update_quotas(sc, NULL);
-	if ((error = iwm_mvm_mac_ctxt_changed(sc, in)) != 0) {
+	if ((error = iwm_mvm_mac_ctxt_changed(sc, vap)) != 0) {
 		device_printf(sc->sc_dev, "mac ctxt change fail 2 %d\n", error);
 		return error;
 	}
@@ -6260,12 +6253,47 @@ iwm_is_valid_ether_addr(uint8_t *addr)
 }
 
 static int
-iwm_update_edca(struct ieee80211com *ic)
+iwm_wme_update(struct ieee80211com *ic)
 {
+#define IWM_EXP2(x)	((1 << (x)) - 1)	/* CWmin = 2^ECWmin - 1 */
 	struct iwm_softc *sc = ic->ic_softc;
+	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
+	struct iwm_vap *ivp = IWM_VAP(vap);
+	struct iwm_node *in;
+	struct wmeParams tmp[WME_NUM_AC];
+	int aci, error;
+
+	if (vap == NULL)
+		return (0);
+
+	IEEE80211_LOCK(ic);
+	for (aci = 0; aci < WME_NUM_AC; aci++)
+		tmp[aci] = ic->ic_wme.wme_chanParams.cap_wmeParams[aci];
+	IEEE80211_UNLOCK(ic);
+
+	IWM_LOCK(sc);
+	for (aci = 0; aci < WME_NUM_AC; aci++) {
+		const struct wmeParams *ac = &tmp[aci];
+		ivp->queue_params[aci].aifsn = ac->wmep_aifsn;
+		ivp->queue_params[aci].cw_min = IWM_EXP2(ac->wmep_logcwmin);
+		ivp->queue_params[aci].cw_max = IWM_EXP2(ac->wmep_logcwmax);
+		ivp->queue_params[aci].edca_txop =
+		    IEEE80211_TXOP_TO_US(ac->wmep_txopLimit);
+	}
+	ivp->have_wme = TRUE;
+	if (ivp->is_uploaded && vap->iv_bss != NULL) {
+		in = IWM_NODE(vap->iv_bss);
+		if (in->in_assoc) {
+			if ((error = iwm_mvm_mac_ctxt_changed(sc, vap)) != 0) {
+				device_printf(sc->sc_dev,
+				    "%s: failed to update MAC\n", __func__);
+			}
+		}
+	}
+	IWM_UNLOCK(sc);
 
-	device_printf(sc->sc_dev, "%s: called\n", __func__);
 	return (0);
+#undef IWM_EXP2
 }
 
 static void
@@ -6322,7 +6350,7 @@ iwm_preinit(void *arg)
 	ic->ic_set_channel = iwm_set_channel;
 	ic->ic_scan_curchan = iwm_scan_curchan;
 	ic->ic_scan_mindwell = iwm_scan_mindwell;
-	ic->ic_wme.wme_update = iwm_update_edca;
+	ic->ic_wme.wme_update = iwm_wme_update;
 	ic->ic_parent = iwm_parent;
 	ic->ic_transmit = iwm_transmit;
 	iwm_radiotap_attach(sc);
@@ -6380,6 +6408,8 @@ iwm_vap_create(struct ieee80211com *ic, 
 	ivp->id = IWM_DEFAULT_MACID;
 	ivp->color = IWM_DEFAULT_COLOR;
 
+	ivp->have_wme = FALSE;
+
 	ieee80211_ratectl_init(vap);
 	/* Complete setup. */
 	ieee80211_vap_attach(vap, iwm_media_change, ieee80211_media_status,

Modified: head/sys/dev/iwm/if_iwm_mac_ctxt.c
==============================================================================
--- head/sys/dev/iwm/if_iwm_mac_ctxt.c	Fri May 12 05:49:24 2017	(r318218)
+++ head/sys/dev/iwm/if_iwm_mac_ctxt.c	Fri May 12 05:50:38 2017	(r318219)
@@ -161,6 +161,13 @@ __FBSDID("$FreeBSD$");
  * BEGIN mvm/mac-ctxt.c
  */
 
+const uint8_t iwm_mvm_ac_to_tx_fifo[] = {
+	IWM_MVM_TX_FIFO_BE,
+	IWM_MVM_TX_FIFO_BK,
+	IWM_MVM_TX_FIFO_VI,
+	IWM_MVM_TX_FIFO_VO,
+};
+
 static void
 iwm_mvm_ack_rates(struct iwm_softc *sc, int is2ghz,
 	int *cck_rates, int *ofdm_rates, struct iwm_node *in)
@@ -329,17 +336,20 @@ iwm_mvm_mac_ctxt_cmd_common(struct iwm_s
 	 * cmd->qos_flags |= cpu_to_le32(MAC_QOS_FLG_UPDATE_EDCA)
 	 */
 
-	/* XXX TODO: set wme parameters; also handle getting updated wme parameters */
-	for (i = 0; i < IWM_AC_NUM+1; i++) {
-		int txf = i;
-
-		cmd->ac[txf].cw_min = htole16(0x0f);
-		cmd->ac[txf].cw_max = htole16(0x3f);
-		cmd->ac[txf].aifsn = 1;
+	for (i = 0; i < WME_NUM_AC; i++) {
+		uint8_t txf = iwm_mvm_ac_to_tx_fifo[i];
+
+		cmd->ac[txf].cw_min = htole16(ivp->queue_params[i].cw_min);
+		cmd->ac[txf].cw_max = htole16(ivp->queue_params[i].cw_max);
+		cmd->ac[txf].edca_txop =
+		    htole16(ivp->queue_params[i].edca_txop);
+		cmd->ac[txf].aifsn = ivp->queue_params[i].aifsn;
 		cmd->ac[txf].fifos_mask = (1 << txf);
-		cmd->ac[txf].edca_txop = 0;
 	}
 
+	if (ivp->have_wme)
+		cmd->qos_flags |= htole32(IWM_MAC_QOS_FLG_UPDATE_EDCA);
+
 	if (ic->ic_flags & IEEE80211_F_USEPROT)
 		cmd->protection_flags |= htole32(IWM_MAC_PROT_FLG_TGG_PROTECT);
 

Modified: head/sys/dev/iwm/if_iwm_mac_ctxt.h
==============================================================================
--- head/sys/dev/iwm/if_iwm_mac_ctxt.h	Fri May 12 05:49:24 2017	(r318218)
+++ head/sys/dev/iwm/if_iwm_mac_ctxt.h	Fri May 12 05:50:38 2017	(r318219)
@@ -106,6 +106,8 @@
 #ifndef	__IF_IWM_MAC_CTXT_H__
 #define	__IF_IWM_MAC_CTXT_H__
 
+extern const uint8_t iwm_mvm_ac_to_tx_fifo[];
+
 extern	int iwm_mvm_mac_ctxt_add(struct iwm_softc *sc, struct ieee80211vap *vap);
 extern	int iwm_mvm_mac_ctxt_changed(struct iwm_softc *sc, struct ieee80211vap *vap);
 extern	int iwm_mvm_mac_ctxt_remove(struct iwm_softc *sc, struct ieee80211vap *vap);

Modified: head/sys/dev/iwm/if_iwmvar.h
==============================================================================
--- head/sys/dev/iwm/if_iwmvar.h	Fri May 12 05:49:24 2017	(r318218)
+++ head/sys/dev/iwm/if_iwmvar.h	Fri May 12 05:50:38 2017	(r318219)
@@ -377,6 +377,19 @@ struct iwm_vap {
 
 	uint16_t		id;
 	uint16_t		color;
+
+	boolean_t		have_wme;
+	/*
+	 * QoS data from net80211, need to store this here
+	 * as net80211 has a separate callback but we need
+	 * to have the data for the MAC context
+	 */
+        struct {
+		uint16_t cw_min;
+		uint16_t cw_max;
+		uint16_t edca_txop;
+		uint8_t aifsn;
+	} queue_params[WME_NUM_AC];
 };
 #define IWM_VAP(_vap)		((struct iwm_vap *)(_vap))
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201705120550.v4C5ocfa053030>