Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 4 Jun 2017 21:10:15 +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: r319578 - head/sys/dev/iwm
Message-ID:  <201706042110.v54LAFX3014104@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: adrian
Date: Sun Jun  4 21:10:14 2017
New Revision: 319578
URL: https://svnweb.freebsd.org/changeset/base/319578

Log:
  [iwm] Check for lar_disable tunable, and lar_enabled flag from NVM.
  
  * LAR can be disabled with the hw.iwm.lar.disable tunable now.
  
  * On Family 8000 devices we need to check the lar_enabled flag from
    nvm_data in addition to the TLV_CAPA_LAR_SUPPORT flag from the firmware.
  
  * Add a separate IWM_DEBUG_LAR debugging flag.
  
  Obtained from:	dragonflybsd.git 0593e39cb295aa996ecf789ed4990c3b255f1770

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

Modified: head/sys/dev/iwm/if_iwm.c
==============================================================================
--- head/sys/dev/iwm/if_iwm.c	Sun Jun  4 21:05:58 2017	(r319577)
+++ head/sys/dev/iwm/if_iwm.c	Sun Jun  4 21:10:14 2017	(r319578)
@@ -356,6 +356,8 @@ static int	iwm_media_change(struct ifnet *);
 static int	iwm_newstate(struct ieee80211vap *, enum ieee80211_state, int);
 static void	iwm_endscan_cb(void *, int);
 static int	iwm_send_bt_init_conf(struct iwm_softc *);
+static boolean_t iwm_mvm_is_lar_supported(struct iwm_softc *);
+static boolean_t iwm_mvm_is_wifi_mcc_supported(struct iwm_softc *);
 static int	iwm_send_update_mcc_cmd(struct iwm_softc *, const char *);
 static void	iwm_mvm_tt_tx_backoff(struct iwm_softc *, uint32_t);
 static int	iwm_init_hw(struct iwm_softc *);
@@ -394,6 +396,9 @@ static void	iwm_scan_curchan(struct ieee80211_scan_sta
 static void	iwm_scan_mindwell(struct ieee80211_scan_state *);
 static int	iwm_detach(device_t);
 
+static int	iwm_lar_disable = 0;
+TUNABLE_INT("hw.iwm.lar.disable", &iwm_lar_disable);
+
 /*
  * Firmware parser.
  */
@@ -2186,6 +2191,7 @@ iwm_parse_nvm_data(struct iwm_softc *sc,
 {
 	struct iwm_nvm_data *data;
 	uint32_t sku, radio_cfg;
+	uint16_t lar_config;
 
 	if (sc->cfg->device_family != IWM_DEVICE_FAMILY_8000) {
 		data = malloc(sizeof(*data) +
@@ -2211,6 +2217,16 @@ iwm_parse_nvm_data(struct iwm_softc *sc,
 
 	data->n_hw_addrs = iwm_get_n_hw_addrs(sc, nvm_sw);
 
+	if (sc->cfg->device_family == IWM_DEVICE_FAMILY_8000) {
+		uint16_t lar_offset = data->nvm_version < 0xE39 ?
+				       IWM_NVM_LAR_OFFSET_8000_OLD :
+				       IWM_NVM_LAR_OFFSET_8000;
+
+		lar_config = le16_to_cpup(regulatory + lar_offset);
+		data->lar_enabled = !!(lar_config &
+				       IWM_NVM_LAR_ENABLED_8000);
+	}
+
 	/* If no valid mac address was found - bail out */
 	if (iwm_set_hw_address(sc, data, nvm_hw, mac_override)) {
 		free(data, M_DEVBUF);
@@ -4507,6 +4523,35 @@ iwm_send_bt_init_conf(struct iwm_softc *sc)
 	    &bt_cmd);
 }
 
+static boolean_t
+iwm_mvm_is_lar_supported(struct iwm_softc *sc)
+{
+	boolean_t nvm_lar = sc->nvm_data->lar_enabled;
+	boolean_t tlv_lar = fw_has_capa(&sc->ucode_capa,
+					IWM_UCODE_TLV_CAPA_LAR_SUPPORT);
+
+	if (iwm_lar_disable)
+		return FALSE;
+
+	/*
+	 * Enable LAR only if it is supported by the FW (TLV) &&
+	 * enabled in the NVM
+	 */
+	if (sc->cfg->device_family == IWM_DEVICE_FAMILY_8000)
+		return nvm_lar && tlv_lar;
+	else
+		return tlv_lar;
+}
+
+static boolean_t
+iwm_mvm_is_wifi_mcc_supported(struct iwm_softc *sc)
+{
+	return fw_has_api(&sc->ucode_capa,
+			  IWM_UCODE_TLV_API_WIFI_MCC_UPDATE) ||
+	       fw_has_capa(&sc->ucode_capa,
+			   IWM_UCODE_TLV_CAPA_LAR_MULTI_MCC);
+}
+
 static int
 iwm_send_update_mcc_cmd(struct iwm_softc *sc, const char *alpha2)
 {
@@ -4527,10 +4572,15 @@ iwm_send_update_mcc_cmd(struct iwm_softc *sc, const ch
 	int resp_v2 = fw_has_capa(&sc->ucode_capa,
 	    IWM_UCODE_TLV_CAPA_LAR_SUPPORT_V2);
 
+	if (!iwm_mvm_is_lar_supported(sc)) {
+		IWM_DPRINTF(sc, IWM_DEBUG_LAR, "%s: no LAR support\n",
+		    __func__);
+		return 0;
+	}
+
 	memset(&mcc_cmd, 0, sizeof(mcc_cmd));
 	mcc_cmd.mcc = htole16(alpha2[0] << 8 | alpha2[1]);
-	if (fw_has_api(&sc->ucode_capa, IWM_UCODE_TLV_API_WIFI_MCC_UPDATE) ||
-	    fw_has_capa(&sc->ucode_capa, IWM_UCODE_TLV_CAPA_LAR_MULTI_MCC))
+	if (iwm_mvm_is_wifi_mcc_supported(sc))
 		mcc_cmd.source_id = IWM_MCC_SOURCE_GET_CURRENT;
 	else
 		mcc_cmd.source_id = IWM_MCC_SOURCE_OLD_FW;
@@ -4540,7 +4590,7 @@ iwm_send_update_mcc_cmd(struct iwm_softc *sc, const ch
 	else
 		hcmd.len[0] = sizeof(struct iwm_mcc_update_cmd_v1);
 
-	IWM_DPRINTF(sc, IWM_DEBUG_NODE,
+	IWM_DPRINTF(sc, IWM_DEBUG_LAR,
 	    "send MCC update to FW with '%c%c' src = %d\n",
 	    alpha2[0], alpha2[1], mcc_cmd.source_id);
 
@@ -4566,7 +4616,7 @@ iwm_send_update_mcc_cmd(struct iwm_softc *sc, const ch
 	if (mcc == 0)
 		mcc = 0x3030;  /* "00" - world */
 
-	IWM_DPRINTF(sc, IWM_DEBUG_NODE,
+	IWM_DPRINTF(sc, IWM_DEBUG_LAR,
 	    "regulatory domain '%c%c' (%d channels available)\n",
 	    mcc >> 8, mcc & 0xff, n_channels);
 #endif
@@ -4675,10 +4725,8 @@ iwm_init_hw(struct iwm_softc *sc)
 	if (error)
 		goto error;
 
-	if (fw_has_capa(&sc->ucode_capa, IWM_UCODE_TLV_CAPA_LAR_SUPPORT)) {
-		if ((error = iwm_send_update_mcc_cmd(sc, "ZZ")) != 0)
-			goto error;
-	}
+	if ((error = iwm_send_update_mcc_cmd(sc, "ZZ")) != 0)
+		goto error;
 
 	if (fw_has_capa(&sc->ucode_capa, IWM_UCODE_TLV_CAPA_UMAC_SCAN)) {
 		if ((error = iwm_mvm_config_umac_scan(sc)) != 0)
@@ -5275,7 +5323,7 @@ iwm_handle_rxb(struct iwm_softc *sc, struct mbuf *m)
 			sc->sc_fw_mcc[0] = (notif->mcc & 0xff00) >> 8;
 			sc->sc_fw_mcc[1] = notif->mcc & 0xff;
 			sc->sc_fw_mcc[2] = '\0';
-			IWM_DPRINTF(sc, IWM_DEBUG_RESET,
+			IWM_DPRINTF(sc, IWM_DEBUG_LAR,
 			    "fw source %d sent CC '%s'\n",
 			    notif->source_id, sc->sc_fw_mcc);
 			break;

Modified: head/sys/dev/iwm/if_iwm_debug.h
==============================================================================
--- head/sys/dev/iwm/if_iwm_debug.h	Sun Jun  4 21:05:58 2017	(r319577)
+++ head/sys/dev/iwm/if_iwm_debug.h	Sun Jun  4 21:10:14 2017	(r319578)
@@ -43,6 +43,7 @@ enum {
 	IWM_DEBUG_EEPROM	= 0x00080000,	/* EEPROM/channel information */
 	IWM_DEBUG_TEMP		= 0x00100000,	/* Thermal Sensor handling */
 	IWM_DEBUG_FW		= 0x00200000,	/* Firmware management */
+	IWM_DEBUG_LAR		= 0x00400000,	/* Location Aware Regulatory */
 	IWM_DEBUG_REGISTER	= 0x20000000,	/* print chipset register */
 	IWM_DEBUG_TRACE		= 0x40000000,	/* Print begin and start driver function */
 	IWM_DEBUG_FATAL		= 0x80000000,	/* fatal errors */

Modified: head/sys/dev/iwm/if_iwmvar.h
==============================================================================
--- head/sys/dev/iwm/if_iwmvar.h	Sun Jun  4 21:05:58 2017	(r319577)
+++ head/sys/dev/iwm/if_iwmvar.h	Sun Jun  4 21:10:14 2017	(r319578)
@@ -232,6 +232,7 @@ struct iwm_nvm_data {
 	uint16_t nvm_version;
 	uint8_t max_tx_pwr_half_dbm;
 
+	boolean_t lar_enabled;
 	uint16_t nvm_ch_flags[];
 };
 



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