Search Linux Wireless

[PATCH 05/12] ath9k: Consolidate channel list

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Sujith Manoharan <smanoharan@xxxxxxxxxxx>

ah_channels now contains unique channel entries with
channelFlags denoting all the modes supported by each channel.
Also, the CTLs are stored separately for each channel mode (11a, 11b, 11g).

Signed-off-by: Sujith <Sujith.Manoharan@xxxxxxxxxxx>
Signed-off-by: Luis R. Rodriguez <lrodriguez@xxxxxxxxxxx>
---
 drivers/net/wireless/ath9k/ath9k.h |    2 +-
 drivers/net/wireless/ath9k/hw.c    |    9 +--
 drivers/net/wireless/ath9k/regd.c  |  117 ++++++++++++++++++++++++-----------
 3 files changed, 85 insertions(+), 43 deletions(-)

diff --git a/drivers/net/wireless/ath9k/ath9k.h b/drivers/net/wireless/ath9k/ath9k.h
index 98466fd..c99c6ba 100644
--- a/drivers/net/wireless/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath9k/ath9k.h
@@ -483,7 +483,7 @@ struct ath9k_channel {
 	int16_t rawNoiseFloor;
 	int8_t antennaMax;
 	u_int32_t regDmnFlags;
-	u_int32_t conformanceTestLimit;
+	u_int32_t conformanceTestLimit[3]; /* 0:11a, 1: 11b, 2:11g */
 #ifdef ATH_NF_PER_CHAN
 	struct hal_nfcal_hist nfCalHist[NUM_NF_READINGS];
 #endif
diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c
index 35b9445..0104455 100644
--- a/drivers/net/wireless/ath9k/hw.c
+++ b/drivers/net/wireless/ath9k/hw.c
@@ -4313,12 +4313,11 @@ ath9k_hw_set_power_per_rate_table(struct ath_hal *ah,
 		for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i];
 		     i++) {
 			DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
-				 "  LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
+				"  LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
 				"pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
-				"chan %d chanctl 0x%x\n",
-				 i, cfgCtl, pCtlMode[ctlMode],
-				 pEepData->ctlIndex[i], chan->channel,
-				 chan->conformanceTestLimit);
+				"chan %d\n",
+				i, cfgCtl, pCtlMode[ctlMode],
+				pEepData->ctlIndex[i], chan->channel);
 
 			if ((((cfgCtl & ~CTL_MODE_M) |
 			      (pCtlMode[ctlMode] & CTL_MODE_M)) ==
diff --git a/drivers/net/wireless/ath9k/regd.c b/drivers/net/wireless/ath9k/regd.c
index f40cd66..588dd3d 100644
--- a/drivers/net/wireless/ath9k/regd.c
+++ b/drivers/net/wireless/ath9k/regd.c
@@ -394,6 +394,21 @@ static void ath9k_regd_init_rf_buffer(struct ath9k_channel *ichans,
 }
 #endif
 
+static int ath9k_regd_is_chan_present(struct ath_hal *ah,
+				      u_int16_t c)
+{
+	int i;
+
+	for (i = 0; i < 150; i++) {
+		if (!ah->ah_channels[i].channel)
+			return -1;
+		else if (ah->ah_channels[i].channel == c)
+			return i;
+	}
+
+	return -1;
+}
+
 static bool
 ath9k_regd_add_channel(struct ath_hal *ah,
 		       u_int16_t c,
@@ -409,7 +424,10 @@ ath9k_regd_add_channel(struct ath_hal *ah,
 		       struct ath9k_channel *ichans,
 		       bool enableExtendedChannels)
 {
-	struct ath9k_channel icv;
+	struct ath9k_channel *chan;
+	int ret;
+	u_int32_t channelFlags = 0;
+	u_int8_t privFlags = 0;
 
 	if (!(c_lo <= c && c <= c_hi)) {
 		DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
@@ -479,43 +497,36 @@ ath9k_regd_add_channel(struct ath_hal *ah,
 		return false;
 	}
 
-	memset(&icv, 0, sizeof(icv));
-	icv.channel = c;
-	icv.channelFlags = cm->flags;
+	/* Calculate channel flags */
+
+	channelFlags = cm->flags;
 
 	switch (fband->channelBW) {
 	case CHANNEL_HALF_BW:
-		icv.channelFlags |= CHANNEL_HALF;
+		channelFlags |= CHANNEL_HALF;
 		break;
 	case CHANNEL_QUARTER_BW:
-		icv.channelFlags |= CHANNEL_QUARTER;
+		channelFlags |= CHANNEL_QUARTER;
 		break;
 	}
 
-	icv.maxRegTxPower = fband->powerDfs;
-	icv.antennaMax = fband->antennaMax;
-	icv.regDmnFlags = rd->flags;
-	icv.conformanceTestLimit = ctl;
-	icv.maxTxPower = AR5416_MAX_RATE_POWER;
-	icv.minTxPower = AR5416_MAX_RATE_POWER;
-
 	if (fband->usePassScan & rd->pscan)
-		icv.channelFlags |= CHANNEL_PASSIVE;
+		channelFlags |= CHANNEL_PASSIVE;
 	else
-		icv.channelFlags &= ~CHANNEL_PASSIVE;
+		channelFlags &= ~CHANNEL_PASSIVE;
 	if (fband->useDfs & rd->dfsMask)
-		icv.privFlags = CHANNEL_DFS;
+		privFlags = CHANNEL_DFS;
 	else
-		icv.privFlags = 0;
+		privFlags = 0;
 	if (rd->flags & LIMIT_FRAME_4MS)
-		icv.privFlags |= CHANNEL_4MS_LIMIT;
-	if (icv.privFlags & CHANNEL_DFS)
-		icv.privFlags |= CHANNEL_DISALLOW_ADHOC;
-	if (icv.regDmnFlags & ADHOC_PER_11D)
-		icv.privFlags |= CHANNEL_PER_11D_ADHOC;
-
-	if (icv.channelFlags & CHANNEL_PASSIVE) {
-		if ((icv.channel < 2412) || (icv.channel > 2462)) {
+		privFlags |= CHANNEL_4MS_LIMIT;
+	if (privFlags & CHANNEL_DFS)
+		privFlags |= CHANNEL_DISALLOW_ADHOC;
+	if (rd->flags & ADHOC_PER_11D)
+		privFlags |= CHANNEL_PER_11D_ADHOC;
+
+	if (channelFlags & CHANNEL_PASSIVE) {
+		if ((c < 2412) || (c > 2462)) {
 			if (rd5GHz.regDmnEnum == MKK1 ||
 			    rd5GHz.regDmnEnum == MKK2) {
 				u_int32_t regcap = ah->ah_caps.halRegCap;
@@ -523,13 +534,13 @@ ath9k_regd_add_channel(struct ath_hal *ah,
 				      (AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN |
 				       AR_EEPROM_EEREGCAP_EN_KK_U2 |
 				       AR_EEPROM_EEREGCAP_EN_KK_MIDBAND)) &&
-				    isUNII1OddChan(icv.channel)) {
-					icv.channelFlags &= ~CHANNEL_PASSIVE;
+				    isUNII1OddChan(c)) {
+					channelFlags &= ~CHANNEL_PASSIVE;
 				} else {
-					icv.privFlags |= CHANNEL_DISALLOW_ADHOC;
+					privFlags |= CHANNEL_DISALLOW_ADHOC;
 				}
 			} else {
-				icv.privFlags |= CHANNEL_DISALLOW_ADHOC;
+				privFlags |= CHANNEL_DISALLOW_ADHOC;
 			}
 		}
 	}
@@ -538,14 +549,39 @@ ath9k_regd_add_channel(struct ath_hal *ah,
 			ATH9K_MODE_SEL_11NA_HT20 |
 			ATH9K_MODE_SEL_11NA_HT40PLUS |
 			ATH9K_MODE_SEL_11NA_HT40MINUS)) {
-		if (icv.regDmnFlags & (ADHOC_NO_11A | DISALLOW_ADHOC_11A))
-			icv.privFlags |= CHANNEL_DISALLOW_ADHOC;
+		if (rd->flags & (ADHOC_NO_11A | DISALLOW_ADHOC_11A))
+			privFlags |= CHANNEL_DISALLOW_ADHOC;
 	}
 
-	memcpy(&ichans[pos], &icv,
-	       sizeof(struct ath9k_channel));
+	/* Fill in channel details */
+
+	ret = ath9k_regd_is_chan_present(ah, c);
+	if (ret == -1) {
+		chan = &ah->ah_channels[pos];
+		chan->channel = c;
+		chan->maxRegTxPower = fband->powerDfs;
+		chan->antennaMax = fband->antennaMax;
+		chan->regDmnFlags = rd->flags;
+		chan->maxTxPower = AR5416_MAX_RATE_POWER;
+		chan->minTxPower = AR5416_MAX_RATE_POWER;
+		chan->channelFlags = channelFlags;
+		chan->privFlags = privFlags;
+	} else {
+		chan = &ah->ah_channels[ret];
+		chan->channelFlags |= channelFlags;
+		chan->privFlags |= privFlags;
+	}
 
-	return true;
+	/* Set CTLs */
+
+	if ((cm->flags & CHANNEL_ALL) == CHANNEL_A)
+		chan->conformanceTestLimit[0] = ctl;
+	else if ((cm->flags & CHANNEL_ALL) == CHANNEL_B)
+		chan->conformanceTestLimit[1] = ctl;
+	else if ((cm->flags & CHANNEL_ALL) == CHANNEL_G)
+		chan->conformanceTestLimit[2] = ctl;
+
+	return (ret == -1) ? true : false;
 }
 
 static bool ath9k_regd_japan_check(struct ath_hal *ah,
@@ -849,14 +885,15 @@ done:
 		ath9k_regd_sort(ichans, next,
 				sizeof(struct ath9k_channel),
 				ath9k_regd_chansort);
+
 		ah->ah_nchan = next;
 
 		DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "Channel list:\n");
 		for (i = 0; i < next; i++) {
 			DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
 				"chan: %d flags: 0x%x\n",
-				ichans[i].channel,
-				ichans[i].channelFlags);
+				ah->ah_channels[i].channel,
+				ah->ah_channels[i].channelFlags);
 		}
 	}
 	*nchans = next;
@@ -958,7 +995,13 @@ u_int ath9k_regd_get_ctl(struct ath_hal *ah, struct hal_channel *chan)
 	} else {
 		ichan = ath9k_regd_check_channel(ah, chan);
 		if (ichan != NULL) {
-			ctl = ichan->conformanceTestLimit;
+			/* FIXME */
+			if (IS_CHAN_A(ichan))
+				ctl = ichan->conformanceTestLimit[0];
+			else if (IS_CHAN_B(ichan))
+				ctl = ichan->conformanceTestLimit[1];
+			else if (IS_CHAN_G(ichan))
+				ctl = ichan->conformanceTestLimit[2];
 
 			if (IS_CHAN_PUREG(chan) && (ctl & 0xf) == CTL_11B)
 				ctl = (ctl & ~0xf) | CTL_11G;
-- 
1.5.6.rc2.15.g457bb.dirty

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux