cfg80211 API for channels/bitrates, mac80211 and driver conversion

This patch creates new cfg80211 wiphy API for channel and bitrate
registration and converts mac80211 and drivers to the new API. The
old mac80211 API is completely ripped out. All drivers (except ath5k)
are updated to the new API, in many cases I expect that optimisations
can be done.

Along with the regulatory code I've also ripped out the
IEEE80211_HW_DEFAULT_REG_DOMAIN_CONFIGURED flag, I believe it to be
unnecessary if the hardware simply gives us whatever channels it wants
to support and we then enable/disable them as required, which is pretty
much required for travelling.

Additionally, the patch adds proper "basic" rate handling for STA
mode interface, AP mode interface will have to have new API added
to allow userspace to set the basic rate set, currently it'll be
empty... However, the basic rate handling will need to be moved to
the BSS conf stuff.

I do expect there to be bugs in this, especially wrt. transmit
power handling where I'm basically clueless about how it should work.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
diff --git a/drivers/net/wireless/b43legacy/xmit.c b/drivers/net/wireless/b43legacy/xmit.c
index d84408a..47e130e 100644
--- a/drivers/net/wireless/b43legacy/xmit.c
+++ b/drivers/net/wireless/b43legacy/xmit.c
@@ -37,45 +37,48 @@
 
 
 /* Extract the bitrate out of a CCK PLCP header. */
-static u8 b43legacy_plcp_get_bitrate_cck(struct b43legacy_plcp_hdr6 *plcp)
+static u8 b43legacy_plcp_get_bitrate_idx_cck(struct b43legacy_plcp_hdr6 *plcp)
 {
 	switch (plcp->raw[0]) {
 	case 0x0A:
-		return B43legacy_CCK_RATE_1MB;
+		return 0;
 	case 0x14:
-		return B43legacy_CCK_RATE_2MB;
+		return 1;
 	case 0x37:
-		return B43legacy_CCK_RATE_5MB;
+		return 2;
 	case 0x6E:
-		return B43legacy_CCK_RATE_11MB;
+		return 3;
 	}
 	B43legacy_BUG_ON(1);
-	return 0;
+	return -1;
 }
 
 /* Extract the bitrate out of an OFDM PLCP header. */
-static u8 b43legacy_plcp_get_bitrate_ofdm(struct b43legacy_plcp_hdr6 *plcp)
+static u8 b43legacy_plcp_get_bitrate_idx_ofdm(struct b43legacy_plcp_hdr6 *plcp,
+					      bool aphy)
 {
+	int base = aphy ? 0 : 4;
+
 	switch (plcp->raw[0] & 0xF) {
 	case 0xB:
-		return B43legacy_OFDM_RATE_6MB;
+		return base + 0;
 	case 0xF:
-		return B43legacy_OFDM_RATE_9MB;
+		return base + 1;
 	case 0xA:
-		return B43legacy_OFDM_RATE_12MB;
+		return base + 2;
 	case 0xE:
-		return B43legacy_OFDM_RATE_18MB;
+		return base + 3;
 	case 0x9:
-		return B43legacy_OFDM_RATE_24MB;
+		return base + 4;
 	case 0xD:
-		return B43legacy_OFDM_RATE_36MB;
+		return base + 5;
 	case 0x8:
-		return B43legacy_OFDM_RATE_48MB;
+		return base + 6;
 	case 0xC:
-		return B43legacy_OFDM_RATE_54MB;
+		return base + 7;
 	}
 	B43legacy_BUG_ON(1);
-	return 0;
+	return -1;
 }
 
 u8 b43legacy_plcp_get_ratecode_cck(const u8 bitrate)
@@ -192,7 +195,7 @@
 	int use_encryption = (!(txctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT));
 	u16 fctl;
 	u8 rate;
-	u8 rate_fb;
+	struct ieee80211_rate *rate_fb;
 	int rate_ofdm;
 	int rate_fb_ofdm;
 	unsigned int plcp_fragment_len;
@@ -204,16 +207,16 @@
 
 	memset(txhdr, 0, sizeof(*txhdr));
 
-	rate = txctl->tx_rate;
+	rate = txctl->tx_rate->hw_value;
 	rate_ofdm = b43legacy_is_ofdm_rate(rate);
-	rate_fb = (txctl->alt_retry_rate == -1) ? rate : txctl->alt_retry_rate;
-	rate_fb_ofdm = b43legacy_is_ofdm_rate(rate_fb);
+	rate_fb = txctl->alt_retry_rate ? : txctl->tx_rate;
+	rate_fb_ofdm = b43legacy_is_ofdm_rate(rate_fb->hw_value);
 
 	txhdr->mac_frame_ctl = wlhdr->frame_control;
 	memcpy(txhdr->tx_receiver, wlhdr->addr1, 6);
 
 	/* Calculate duration for fallback rate */
-	if ((rate_fb == rate) ||
+	if ((rate_fb->hw_value == rate) ||
 	    (wlhdr->duration_id & cpu_to_le16(0x8000)) ||
 	    (wlhdr->duration_id == cpu_to_le16(0))) {
 		/* If the fallback rate equals the normal rate or the
@@ -221,11 +224,10 @@
 		 * use the original dur_id field. */
 		txhdr->dur_fb = wlhdr->duration_id;
 	} else {
-		int fbrate_base100kbps = B43legacy_RATE_TO_100KBPS(rate_fb);
 		txhdr->dur_fb = ieee80211_generic_frame_duration(dev->wl->hw,
 							 txctl->vif,
 							 fragment_len,
-							 fbrate_base100kbps);
+							 rate_fb);
 	}
 
 	plcp_fragment_len = fragment_len + FCS_LEN;
@@ -266,7 +268,7 @@
 				    rate);
 	b43legacy_generate_plcp_hdr((struct b43legacy_plcp_hdr4 *)
 				    (&txhdr->plcp_fb), plcp_fragment_len,
-				    rate_fb);
+				    rate_fb->hw_value);
 
 	/* PHY TX Control word */
 	if (rate_ofdm)
@@ -310,7 +312,7 @@
 		int rts_rate_ofdm;
 		int rts_rate_fb_ofdm;
 
-		rts_rate = txctl->rts_cts_rate;
+		rts_rate = txctl->rts_cts_rate->hw_value;
 		rts_rate_ofdm = b43legacy_is_ofdm_rate(rts_rate);
 		rts_rate_fb = b43legacy_calc_fallback_rate(rts_rate);
 		rts_rate_fb_ofdm = b43legacy_is_ofdm_rate(rts_rate_fb);
@@ -536,10 +538,11 @@
 				      (phystat3 & B43legacy_RX_PHYST3_TRSTATE));
 	status.noise = dev->stats.link_noise;
 	status.signal = (jssi * 100) / B43legacy_RX_MAX_SSI;
+	/* change to support A PHY */
 	if (phystat0 & B43legacy_RX_PHYST0_OFDM)
-		status.rate = b43legacy_plcp_get_bitrate_ofdm(plcp);
+		status.rate_idx = b43legacy_plcp_get_bitrate_idx_ofdm(plcp, false);
 	else
-		status.rate = b43legacy_plcp_get_bitrate_cck(plcp);
+		status.rate_idx = b43legacy_plcp_get_bitrate_idx_cck(plcp);
 	status.antenna = !!(phystat0 & B43legacy_RX_PHYST0_ANT);
 
 	/*
@@ -564,14 +567,9 @@
 		  B43legacy_RX_CHAN_ID_SHIFT;
 	switch (chanstat & B43legacy_RX_CHAN_PHYTYPE) {
 	case B43legacy_PHYTYPE_B:
-		status.phymode = MODE_IEEE80211B;
-		status.freq = chanid + 2400;
-		status.channel = b43legacy_freq_to_channel_bg(chanid + 2400);
-		break;
 	case B43legacy_PHYTYPE_G:
-		status.phymode = MODE_IEEE80211G;
+		status.band = IEEE80211_BAND_2GHZ;
 		status.freq = chanid + 2400;
-		status.channel = b43legacy_freq_to_channel_bg(chanid + 2400);
 		break;
 	default:
 		b43legacywarn(dev->wl, "Unexpected value for chanstat (0x%X)\n",