Selaa lähdekoodia

cfg80211: add 802.11ad (60gHz band) support

Add enumerations for both cfg80211 and nl80211.
This expands wiphy.bands etc. arrays.

Extend channel <-> frequency translation to cover 60g band
and modify the rate check logic since there are no legacy
mandatory rates (only MCS is used.)

Signed-off-by: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Vladimir Kondratiev 13 vuotta sitten
vanhempi
commit
3a0c52a6d8

+ 1 - 1
drivers/net/wireless/iwlegacy/3945-rs.c

@@ -946,7 +946,7 @@ il3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
 	case IEEE80211_BAND_5GHZ:
 	case IEEE80211_BAND_5GHZ:
 		rs_sta->expected_tpt = il3945_expected_tpt_a;
 		rs_sta->expected_tpt = il3945_expected_tpt_a;
 		break;
 		break;
-	case IEEE80211_NUM_BANDS:
+	default:
 		BUG();
 		BUG();
 		break;
 		break;
 	}
 	}

+ 2 - 0
include/linux/nl80211.h

@@ -2545,10 +2545,12 @@ enum nl80211_tx_rate_attributes {
  * enum nl80211_band - Frequency band
  * enum nl80211_band - Frequency band
  * @NL80211_BAND_2GHZ: 2.4 GHz ISM band
  * @NL80211_BAND_2GHZ: 2.4 GHz ISM band
  * @NL80211_BAND_5GHZ: around 5 GHz band (4.9 - 5.7 GHz)
  * @NL80211_BAND_5GHZ: around 5 GHz band (4.9 - 5.7 GHz)
+ * @NL80211_BAND_60GHZ: around 60 GHz band (58.32 - 64.80 GHz)
  */
  */
 enum nl80211_band {
 enum nl80211_band {
 	NL80211_BAND_2GHZ,
 	NL80211_BAND_2GHZ,
 	NL80211_BAND_5GHZ,
 	NL80211_BAND_5GHZ,
+	NL80211_BAND_60GHZ,
 };
 };
 
 
 /**
 /**

+ 2 - 0
include/net/cfg80211.h

@@ -70,11 +70,13 @@
  *
  *
  * @IEEE80211_BAND_2GHZ: 2.4GHz ISM band
  * @IEEE80211_BAND_2GHZ: 2.4GHz ISM band
  * @IEEE80211_BAND_5GHZ: around 5GHz band (4.9-5.7)
  * @IEEE80211_BAND_5GHZ: around 5GHz band (4.9-5.7)
+ * @IEEE80211_BAND_60GHZ: around 60 GHz band (58.32 - 64.80 GHz)
  * @IEEE80211_NUM_BANDS: number of defined bands
  * @IEEE80211_NUM_BANDS: number of defined bands
  */
  */
 enum ieee80211_band {
 enum ieee80211_band {
 	IEEE80211_BAND_2GHZ = NL80211_BAND_2GHZ,
 	IEEE80211_BAND_2GHZ = NL80211_BAND_2GHZ,
 	IEEE80211_BAND_5GHZ = NL80211_BAND_5GHZ,
 	IEEE80211_BAND_5GHZ = NL80211_BAND_5GHZ,
+	IEEE80211_BAND_60GHZ = NL80211_BAND_60GHZ,
 
 
 	/* keep last */
 	/* keep last */
 	IEEE80211_NUM_BANDS
 	IEEE80211_NUM_BANDS

+ 2 - 0
net/mac80211/tx.c

@@ -140,6 +140,8 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx,
 			if (r->flags & IEEE80211_RATE_MANDATORY_A)
 			if (r->flags & IEEE80211_RATE_MANDATORY_A)
 				mrate = r->bitrate;
 				mrate = r->bitrate;
 			break;
 			break;
+		case IEEE80211_BAND_60GHZ:
+			/* TODO, for now fall through */
 		case IEEE80211_NUM_BANDS:
 		case IEEE80211_NUM_BANDS:
 			WARN_ON(1);
 			WARN_ON(1);
 			break;
 			break;

+ 8 - 2
net/wireless/core.c

@@ -468,8 +468,14 @@ int wiphy_register(struct wiphy *wiphy)
 			continue;
 			continue;
 
 
 		sband->band = band;
 		sband->band = band;
-
-		if (WARN_ON(!sband->n_channels || !sband->n_bitrates))
+		if (WARN_ON(!sband->n_channels))
+			return -EINVAL;
+		/*
+		 * on 60gHz band, there are no legacy rates, so
+		 * n_bitrates is 0
+		 */
+		if (WARN_ON(band != IEEE80211_BAND_60GHZ &&
+			    !sband->n_bitrates))
 			return -EINVAL;
 			return -EINVAL;
 
 
 		/*
 		/*

+ 27 - 8
net/wireless/util.c

@@ -35,19 +35,29 @@ int ieee80211_channel_to_frequency(int chan, enum ieee80211_band band)
 {
 {
 	/* see 802.11 17.3.8.3.2 and Annex J
 	/* see 802.11 17.3.8.3.2 and Annex J
 	 * there are overlapping channel numbers in 5GHz and 2GHz bands */
 	 * there are overlapping channel numbers in 5GHz and 2GHz bands */
-	if (band == IEEE80211_BAND_5GHZ) {
-		if (chan >= 182 && chan <= 196)
-			return 4000 + chan * 5;
-		else
-			return 5000 + chan * 5;
-	} else { /* IEEE80211_BAND_2GHZ */
+	if (chan <= 0)
+		return 0; /* not supported */
+	switch (band) {
+	case IEEE80211_BAND_2GHZ:
 		if (chan == 14)
 		if (chan == 14)
 			return 2484;
 			return 2484;
 		else if (chan < 14)
 		else if (chan < 14)
 			return 2407 + chan * 5;
 			return 2407 + chan * 5;
+		break;
+	case IEEE80211_BAND_5GHZ:
+		if (chan >= 182 && chan <= 196)
+			return 4000 + chan * 5;
 		else
 		else
-			return 0; /* not supported */
+			return 5000 + chan * 5;
+		break;
+	case IEEE80211_BAND_60GHZ:
+		if (chan < 5)
+			return 56160 + chan * 2160;
+		break;
+	default:
+		;
 	}
 	}
+	return 0; /* not supported */
 }
 }
 EXPORT_SYMBOL(ieee80211_channel_to_frequency);
 EXPORT_SYMBOL(ieee80211_channel_to_frequency);
 
 
@@ -60,8 +70,12 @@ int ieee80211_frequency_to_channel(int freq)
 		return (freq - 2407) / 5;
 		return (freq - 2407) / 5;
 	else if (freq >= 4910 && freq <= 4980)
 	else if (freq >= 4910 && freq <= 4980)
 		return (freq - 4000) / 5;
 		return (freq - 4000) / 5;
-	else
+	else if (freq <= 45000) /* DMG band lower limit */
 		return (freq - 5000) / 5;
 		return (freq - 5000) / 5;
+	else if (freq >= 58320 && freq <= 64800)
+		return (freq - 56160) / 2160;
+	else
+		return 0;
 }
 }
 EXPORT_SYMBOL(ieee80211_frequency_to_channel);
 EXPORT_SYMBOL(ieee80211_frequency_to_channel);
 
 
@@ -137,6 +151,11 @@ static void set_mandatory_flags_band(struct ieee80211_supported_band *sband,
 		}
 		}
 		WARN_ON(want != 0 && want != 3 && want != 6);
 		WARN_ON(want != 0 && want != 3 && want != 6);
 		break;
 		break;
+	case IEEE80211_BAND_60GHZ:
+		/* check for mandatory HT MCS 1..4 */
+		WARN_ON(!sband->ht_cap.ht_supported);
+		WARN_ON((sband->ht_cap.mcs.rx_mask[0] & 0x1e) != 0x1e);
+		break;
 	case IEEE80211_NUM_BANDS:
 	case IEEE80211_NUM_BANDS:
 		WARN_ON(1);
 		WARN_ON(1);
 		break;
 		break;