Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

rsi: Add support for 802.11d

Transmit power level in a channel is determined based on the dfs region.
To support regulatory rules dfs region should be configured to device during
set channel request. Also antenna gain values are taken from the mac80211
channel parameters instead of fixed values.

Signed-off-by: Prameela Rani Garnepudi <prameela.j04cs@gmail.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>

authored by

Prameela Rani Garnepudi and committed by
Kalle Valo
61d10842 4edbcd1a

+53 -7
+29 -1
drivers/net/wireless/rsi/rsi_91x_mac80211.c
··· 390 390 391 391 status = rsi_band_check(common); 392 392 if (!status) 393 - status = rsi_set_channel(adapter->priv, channel); 393 + status = rsi_set_channel(adapter->priv, curchan); 394 394 395 395 if (bss->assoc) { 396 396 if (common->hw_data_qs_blocked && ··· 1151 1151 return 0; 1152 1152 } 1153 1153 1154 + static void rsi_reg_notify(struct wiphy *wiphy, 1155 + struct regulatory_request *request) 1156 + { 1157 + struct ieee80211_supported_band *sband; 1158 + struct ieee80211_channel *ch; 1159 + struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); 1160 + struct rsi_hw * adapter = hw->priv; 1161 + int i; 1162 + 1163 + sband = wiphy->bands[NL80211_BAND_5GHZ]; 1164 + 1165 + for (i = 0; i < sband->n_channels; i++) { 1166 + ch = &sband->channels[i]; 1167 + if (ch->flags & IEEE80211_CHAN_DISABLED) 1168 + continue; 1169 + 1170 + if (ch->flags & IEEE80211_CHAN_RADAR) 1171 + ch->flags |= IEEE80211_CHAN_NO_IR; 1172 + } 1173 + 1174 + rsi_dbg(INFO_ZONE, 1175 + "country = %s dfs_region = %d\n", 1176 + request->alpha2, request->dfs_region); 1177 + adapter->dfs_region = request->dfs_region; 1178 + } 1179 + 1154 1180 static struct ieee80211_ops mac80211_ops = { 1155 1181 .tx = rsi_mac80211_tx, 1156 1182 .start = rsi_mac80211_start, ··· 1258 1232 &adapter->sbands[NL80211_BAND_2GHZ]; 1259 1233 wiphy->bands[NL80211_BAND_5GHZ] = 1260 1234 &adapter->sbands[NL80211_BAND_5GHZ]; 1235 + 1236 + wiphy->reg_notifier = rsi_reg_notify; 1261 1237 1262 1238 status = ieee80211_register_hw(hw); 1263 1239 if (status)
+21 -5
drivers/net/wireless/rsi/rsi_91x_mgmt.c
··· 913 913 * 914 914 * Return: 0 on success, corresponding error code on failure. 915 915 */ 916 - int rsi_set_channel(struct rsi_common *common, u16 channel) 916 + int rsi_set_channel(struct rsi_common *common, 917 + struct ieee80211_channel *channel) 917 918 { 918 919 struct sk_buff *skb = NULL; 919 920 struct rsi_mac_frame *mgmt_frame; ··· 929 928 return -ENOMEM; 930 929 } 931 930 931 + if (!channel) { 932 + dev_kfree_skb(skb); 933 + return 0; 934 + } 932 935 memset(skb->data, 0, FRAME_DESC_SZ); 933 936 mgmt_frame = (struct rsi_mac_frame *)skb->data; 934 937 935 938 mgmt_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12); 936 939 mgmt_frame->desc_word[1] = cpu_to_le16(SCAN_REQUEST); 937 - mgmt_frame->desc_word[4] = cpu_to_le16(channel); 940 + mgmt_frame->desc_word[4] = cpu_to_le16(channel->hw_value); 941 + 942 + mgmt_frame->desc_word[4] |= 943 + cpu_to_le16(((char)(channel->max_antenna_gain)) << 8); 944 + mgmt_frame->desc_word[5] = 945 + cpu_to_le16((char)(channel->max_antenna_gain)); 938 946 939 947 mgmt_frame->desc_word[7] = cpu_to_le16(PUT_BBP_RESET | 940 948 BBP_REG_WRITE | 941 949 (RSI_RF_TYPE << 4)); 942 950 943 - mgmt_frame->desc_word[5] = cpu_to_le16(0x01); 944 - mgmt_frame->desc_word[6] = cpu_to_le16(0x12); 951 + if (!(channel->flags & IEEE80211_CHAN_NO_IR) && 952 + !(channel->flags & IEEE80211_CHAN_RADAR)) { 953 + if (common->tx_power < channel->max_power) 954 + mgmt_frame->desc_word[6] = cpu_to_le16(common->tx_power); 955 + else 956 + mgmt_frame->desc_word[6] = cpu_to_le16(channel->max_power); 957 + } 958 + mgmt_frame->desc_word[7] = cpu_to_le16(common->priv->dfs_region); 945 959 946 960 if (common->channel_width == BW_40MHZ) 947 961 mgmt_frame->desc_word[5] |= cpu_to_le16(0x1 << 8); 948 962 949 - common->channel = channel; 963 + common->channel = channel->hw_value; 950 964 951 965 skb_put(skb, FRAME_DESC_SZ); 952 966
+1
drivers/net/wireless/rsi/rsi_main.h
··· 223 223 struct rsi_debugfs *dfsentry; 224 224 u8 num_debugfs_entries; 225 225 #endif 226 + u8 dfs_region; 226 227 void *rsi_dev; 227 228 int (*host_intf_read_pkt)(struct rsi_hw *adapter, u8 *pkt, u32 len); 228 229 int (*host_intf_write_pkt)(struct rsi_hw *adapter, u8 *pkt, u32 len);
+2 -1
drivers/net/wireless/rsi/rsi_mgmt.h
··· 314 314 u16 ssn, u8 buf_size, u8 event); 315 315 int rsi_hal_load_key(struct rsi_common *common, u8 *data, u16 key_len, 316 316 u8 key_type, u8 key_id, u32 cipher); 317 - int rsi_set_channel(struct rsi_common *common, u16 chno); 317 + int rsi_set_channel(struct rsi_common *common, 318 + struct ieee80211_channel *channel); 318 319 int rsi_send_block_unblock_frame(struct rsi_common *common, bool event); 319 320 void rsi_inform_bss_status(struct rsi_common *common, u8 status, 320 321 const u8 *bssid, u8 qos_enable, u16 aid);