Linux Audio

Check our new training course

Yocto distribution development and maintenance

Need a Yocto distribution for your embedded project?
Loading...
Note: File does not exist in v3.1.
   1/**
   2 * Copyright (c) 2014 Redpine Signals Inc.
   3 *
   4 * Permission to use, copy, modify, and/or distribute this software for any
   5 * purpose with or without fee is hereby granted, provided that the above
   6 * copyright notice and this permission notice appear in all copies.
   7 *
   8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15 */
  16
  17#include <linux/etherdevice.h>
  18#include "rsi_debugfs.h"
  19#include "rsi_mgmt.h"
  20#include "rsi_common.h"
  21
  22static const struct ieee80211_channel rsi_2ghz_channels[] = {
  23	{ .band = NL80211_BAND_2GHZ, .center_freq = 2412,
  24	  .hw_value = 1 }, /* Channel 1 */
  25	{ .band = NL80211_BAND_2GHZ, .center_freq = 2417,
  26	  .hw_value = 2 }, /* Channel 2 */
  27	{ .band = NL80211_BAND_2GHZ, .center_freq = 2422,
  28	  .hw_value = 3 }, /* Channel 3 */
  29	{ .band = NL80211_BAND_2GHZ, .center_freq = 2427,
  30	  .hw_value = 4 }, /* Channel 4 */
  31	{ .band = NL80211_BAND_2GHZ, .center_freq = 2432,
  32	  .hw_value = 5 }, /* Channel 5 */
  33	{ .band = NL80211_BAND_2GHZ, .center_freq = 2437,
  34	  .hw_value = 6 }, /* Channel 6 */
  35	{ .band = NL80211_BAND_2GHZ, .center_freq = 2442,
  36	  .hw_value = 7 }, /* Channel 7 */
  37	{ .band = NL80211_BAND_2GHZ, .center_freq = 2447,
  38	  .hw_value = 8 }, /* Channel 8 */
  39	{ .band = NL80211_BAND_2GHZ, .center_freq = 2452,
  40	  .hw_value = 9 }, /* Channel 9 */
  41	{ .band = NL80211_BAND_2GHZ, .center_freq = 2457,
  42	  .hw_value = 10 }, /* Channel 10 */
  43	{ .band = NL80211_BAND_2GHZ, .center_freq = 2462,
  44	  .hw_value = 11 }, /* Channel 11 */
  45	{ .band = NL80211_BAND_2GHZ, .center_freq = 2467,
  46	  .hw_value = 12 }, /* Channel 12 */
  47	{ .band = NL80211_BAND_2GHZ, .center_freq = 2472,
  48	  .hw_value = 13 }, /* Channel 13 */
  49	{ .band = NL80211_BAND_2GHZ, .center_freq = 2484,
  50	  .hw_value = 14 }, /* Channel 14 */
  51};
  52
  53static const struct ieee80211_channel rsi_5ghz_channels[] = {
  54	{ .band = NL80211_BAND_5GHZ, .center_freq = 5180,
  55	  .hw_value = 36,  }, /* Channel 36 */
  56	{ .band = NL80211_BAND_5GHZ, .center_freq = 5200,
  57	  .hw_value = 40, }, /* Channel 40 */
  58	{ .band = NL80211_BAND_5GHZ, .center_freq = 5220,
  59	  .hw_value = 44, }, /* Channel 44 */
  60	{ .band = NL80211_BAND_5GHZ, .center_freq = 5240,
  61	  .hw_value = 48, }, /* Channel 48 */
  62	{ .band = NL80211_BAND_5GHZ, .center_freq = 5260,
  63	  .hw_value = 52, }, /* Channel 52 */
  64	{ .band = NL80211_BAND_5GHZ, .center_freq = 5280,
  65	  .hw_value = 56, }, /* Channel 56 */
  66	{ .band = NL80211_BAND_5GHZ, .center_freq = 5300,
  67	  .hw_value = 60, }, /* Channel 60 */
  68	{ .band = NL80211_BAND_5GHZ, .center_freq = 5320,
  69	  .hw_value = 64, }, /* Channel 64 */
  70	{ .band = NL80211_BAND_5GHZ, .center_freq = 5500,
  71	  .hw_value = 100, }, /* Channel 100 */
  72	{ .band = NL80211_BAND_5GHZ, .center_freq = 5520,
  73	  .hw_value = 104, }, /* Channel 104 */
  74	{ .band = NL80211_BAND_5GHZ, .center_freq = 5540,
  75	  .hw_value = 108, }, /* Channel 108 */
  76	{ .band = NL80211_BAND_5GHZ, .center_freq = 5560,
  77	  .hw_value = 112, }, /* Channel 112 */
  78	{ .band = NL80211_BAND_5GHZ, .center_freq = 5580,
  79	  .hw_value = 116, }, /* Channel 116 */
  80	{ .band = NL80211_BAND_5GHZ, .center_freq = 5600,
  81	  .hw_value = 120, }, /* Channel 120 */
  82	{ .band = NL80211_BAND_5GHZ, .center_freq = 5620,
  83	  .hw_value = 124, }, /* Channel 124 */
  84	{ .band = NL80211_BAND_5GHZ, .center_freq = 5640,
  85	  .hw_value = 128, }, /* Channel 128 */
  86	{ .band = NL80211_BAND_5GHZ, .center_freq = 5660,
  87	  .hw_value = 132, }, /* Channel 132 */
  88	{ .band = NL80211_BAND_5GHZ, .center_freq = 5680,
  89	  .hw_value = 136, }, /* Channel 136 */
  90	{ .band = NL80211_BAND_5GHZ, .center_freq = 5700,
  91	  .hw_value = 140, }, /* Channel 140 */
  92	{ .band = NL80211_BAND_5GHZ, .center_freq = 5745,
  93	  .hw_value = 149, }, /* Channel 149 */
  94	{ .band = NL80211_BAND_5GHZ, .center_freq = 5765,
  95	  .hw_value = 153, }, /* Channel 153 */
  96	{ .band = NL80211_BAND_5GHZ, .center_freq = 5785,
  97	  .hw_value = 157, }, /* Channel 157 */
  98	{ .band = NL80211_BAND_5GHZ, .center_freq = 5805,
  99	  .hw_value = 161, }, /* Channel 161 */
 100	{ .band = NL80211_BAND_5GHZ, .center_freq = 5825,
 101	  .hw_value = 165, }, /* Channel 165 */
 102};
 103
 104struct ieee80211_rate rsi_rates[12] = {
 105	{ .bitrate = STD_RATE_01  * 5, .hw_value = RSI_RATE_1 },
 106	{ .bitrate = STD_RATE_02  * 5, .hw_value = RSI_RATE_2 },
 107	{ .bitrate = STD_RATE_5_5 * 5, .hw_value = RSI_RATE_5_5 },
 108	{ .bitrate = STD_RATE_11  * 5, .hw_value = RSI_RATE_11 },
 109	{ .bitrate = STD_RATE_06  * 5, .hw_value = RSI_RATE_6 },
 110	{ .bitrate = STD_RATE_09  * 5, .hw_value = RSI_RATE_9 },
 111	{ .bitrate = STD_RATE_12  * 5, .hw_value = RSI_RATE_12 },
 112	{ .bitrate = STD_RATE_18  * 5, .hw_value = RSI_RATE_18 },
 113	{ .bitrate = STD_RATE_24  * 5, .hw_value = RSI_RATE_24 },
 114	{ .bitrate = STD_RATE_36  * 5, .hw_value = RSI_RATE_36 },
 115	{ .bitrate = STD_RATE_48  * 5, .hw_value = RSI_RATE_48 },
 116	{ .bitrate = STD_RATE_54  * 5, .hw_value = RSI_RATE_54 },
 117};
 118
 119const u16 rsi_mcsrates[8] = {
 120	RSI_RATE_MCS0, RSI_RATE_MCS1, RSI_RATE_MCS2, RSI_RATE_MCS3,
 121	RSI_RATE_MCS4, RSI_RATE_MCS5, RSI_RATE_MCS6, RSI_RATE_MCS7
 122};
 123
 124/**
 125 * rsi_is_cipher_wep() -  This function determines if the cipher is WEP or not.
 126 * @common: Pointer to the driver private structure.
 127 *
 128 * Return: If cipher type is WEP, a value of 1 is returned, else 0.
 129 */
 130
 131bool rsi_is_cipher_wep(struct rsi_common *common)
 132{
 133	if (((common->secinfo.gtk_cipher == WLAN_CIPHER_SUITE_WEP104) ||
 134	     (common->secinfo.gtk_cipher == WLAN_CIPHER_SUITE_WEP40)) &&
 135	    (!common->secinfo.ptk_cipher))
 136		return true;
 137	else
 138		return false;
 139}
 140
 141/**
 142 * rsi_register_rates_channels() - This function registers channels and rates.
 143 * @adapter: Pointer to the adapter structure.
 144 * @band: Operating band to be set.
 145 *
 146 * Return: None.
 147 */
 148static void rsi_register_rates_channels(struct rsi_hw *adapter, int band)
 149{
 150	struct ieee80211_supported_band *sbands = &adapter->sbands[band];
 151	void *channels = NULL;
 152
 153	if (band == NL80211_BAND_2GHZ) {
 154		channels = kmalloc(sizeof(rsi_2ghz_channels), GFP_KERNEL);
 155		memcpy(channels,
 156		       rsi_2ghz_channels,
 157		       sizeof(rsi_2ghz_channels));
 158		sbands->band = NL80211_BAND_2GHZ;
 159		sbands->n_channels = ARRAY_SIZE(rsi_2ghz_channels);
 160		sbands->bitrates = rsi_rates;
 161		sbands->n_bitrates = ARRAY_SIZE(rsi_rates);
 162	} else {
 163		channels = kmalloc(sizeof(rsi_5ghz_channels), GFP_KERNEL);
 164		memcpy(channels,
 165		       rsi_5ghz_channels,
 166		       sizeof(rsi_5ghz_channels));
 167		sbands->band = NL80211_BAND_5GHZ;
 168		sbands->n_channels = ARRAY_SIZE(rsi_5ghz_channels);
 169		sbands->bitrates = &rsi_rates[4];
 170		sbands->n_bitrates = ARRAY_SIZE(rsi_rates) - 4;
 171	}
 172
 173	sbands->channels = channels;
 174
 175	memset(&sbands->ht_cap, 0, sizeof(struct ieee80211_sta_ht_cap));
 176	sbands->ht_cap.ht_supported = true;
 177	sbands->ht_cap.cap = (IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
 178			      IEEE80211_HT_CAP_SGI_20 |
 179			      IEEE80211_HT_CAP_SGI_40);
 180	sbands->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K;
 181	sbands->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
 182	sbands->ht_cap.mcs.rx_mask[0] = 0xff;
 183	sbands->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
 184	/* sbands->ht_cap.mcs.rx_highest = 0x82; */
 185}
 186
 187/**
 188 * rsi_mac80211_detach() - This function is used to de-initialize the
 189 *			   Mac80211 stack.
 190 * @adapter: Pointer to the adapter structure.
 191 *
 192 * Return: None.
 193 */
 194void rsi_mac80211_detach(struct rsi_hw *adapter)
 195{
 196	struct ieee80211_hw *hw = adapter->hw;
 197	enum nl80211_band band;
 198
 199	if (hw) {
 200		ieee80211_stop_queues(hw);
 201		ieee80211_unregister_hw(hw);
 202		ieee80211_free_hw(hw);
 203	}
 204
 205	for (band = 0; band < NUM_NL80211_BANDS; band++) {
 206		struct ieee80211_supported_band *sband =
 207					&adapter->sbands[band];
 208
 209		kfree(sband->channels);
 210	}
 211
 212#ifdef CONFIG_RSI_DEBUGFS
 213	rsi_remove_dbgfs(adapter);
 214	kfree(adapter->dfsentry);
 215#endif
 216}
 217EXPORT_SYMBOL_GPL(rsi_mac80211_detach);
 218
 219/**
 220 * rsi_indicate_tx_status() - This function indicates the transmit status.
 221 * @adapter: Pointer to the adapter structure.
 222 * @skb: Pointer to the socket buffer structure.
 223 * @status: Status
 224 *
 225 * Return: None.
 226 */
 227void rsi_indicate_tx_status(struct rsi_hw *adapter,
 228			    struct sk_buff *skb,
 229			    int status)
 230{
 231	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 232
 233	memset(info->driver_data, 0, IEEE80211_TX_INFO_DRIVER_DATA_SIZE);
 234
 235	if (!status)
 236		info->flags |= IEEE80211_TX_STAT_ACK;
 237
 238	ieee80211_tx_status_irqsafe(adapter->hw, skb);
 239}
 240
 241/**
 242 * rsi_mac80211_tx() - This is the handler that 802.11 module calls for each
 243 *		       transmitted frame.SKB contains the buffer starting
 244 *		       from the IEEE 802.11 header.
 245 * @hw: Pointer to the ieee80211_hw structure.
 246 * @control: Pointer to the ieee80211_tx_control structure
 247 * @skb: Pointer to the socket buffer structure.
 248 *
 249 * Return: None
 250 */
 251static void rsi_mac80211_tx(struct ieee80211_hw *hw,
 252			    struct ieee80211_tx_control *control,
 253			    struct sk_buff *skb)
 254{
 255	struct rsi_hw *adapter = hw->priv;
 256	struct rsi_common *common = adapter->priv;
 257
 258	rsi_core_xmit(common, skb);
 259}
 260
 261/**
 262 * rsi_mac80211_start() - This is first handler that 802.11 module calls, since
 263 *			  the driver init is complete by then, just
 264 *			  returns success.
 265 * @hw: Pointer to the ieee80211_hw structure.
 266 *
 267 * Return: 0 as success.
 268 */
 269static int rsi_mac80211_start(struct ieee80211_hw *hw)
 270{
 271	struct rsi_hw *adapter = hw->priv;
 272	struct rsi_common *common = adapter->priv;
 273
 274	mutex_lock(&common->mutex);
 275	common->iface_down = false;
 276	mutex_unlock(&common->mutex);
 277
 278	rsi_send_rx_filter_frame(common, 0);
 279
 280	return 0;
 281}
 282
 283/**
 284 * rsi_mac80211_stop() - This is the last handler that 802.11 module calls.
 285 * @hw: Pointer to the ieee80211_hw structure.
 286 *
 287 * Return: None.
 288 */
 289static void rsi_mac80211_stop(struct ieee80211_hw *hw)
 290{
 291	struct rsi_hw *adapter = hw->priv;
 292	struct rsi_common *common = adapter->priv;
 293
 294	mutex_lock(&common->mutex);
 295	common->iface_down = true;
 296	mutex_unlock(&common->mutex);
 297}
 298
 299/**
 300 * rsi_mac80211_add_interface() - This function is called when a netdevice
 301 *				  attached to the hardware is enabled.
 302 * @hw: Pointer to the ieee80211_hw structure.
 303 * @vif: Pointer to the ieee80211_vif structure.
 304 *
 305 * Return: ret: 0 on success, negative error code on failure.
 306 */
 307static int rsi_mac80211_add_interface(struct ieee80211_hw *hw,
 308				      struct ieee80211_vif *vif)
 309{
 310	struct rsi_hw *adapter = hw->priv;
 311	struct rsi_common *common = adapter->priv;
 312	int ret = -EOPNOTSUPP;
 313
 314	mutex_lock(&common->mutex);
 315	switch (vif->type) {
 316	case NL80211_IFTYPE_STATION:
 317		if (!adapter->sc_nvifs) {
 318			++adapter->sc_nvifs;
 319			adapter->vifs[0] = vif;
 320			ret = rsi_set_vap_capabilities(common,
 321						       STA_OPMODE,
 322						       VAP_ADD);
 323		}
 324		break;
 325	default:
 326		rsi_dbg(ERR_ZONE,
 327			"%s: Interface type %d not supported\n", __func__,
 328			vif->type);
 329	}
 330	mutex_unlock(&common->mutex);
 331
 332	return ret;
 333}
 334
 335/**
 336 * rsi_mac80211_remove_interface() - This function notifies driver that an
 337 *				     interface is going down.
 338 * @hw: Pointer to the ieee80211_hw structure.
 339 * @vif: Pointer to the ieee80211_vif structure.
 340 *
 341 * Return: None.
 342 */
 343static void rsi_mac80211_remove_interface(struct ieee80211_hw *hw,
 344					  struct ieee80211_vif *vif)
 345{
 346	struct rsi_hw *adapter = hw->priv;
 347	struct rsi_common *common = adapter->priv;
 348
 349	mutex_lock(&common->mutex);
 350	if (vif->type == NL80211_IFTYPE_STATION) {
 351		adapter->sc_nvifs--;
 352		rsi_set_vap_capabilities(common, STA_OPMODE, VAP_DELETE);
 353	}
 354
 355	if (!memcmp(adapter->vifs[0], vif, sizeof(struct ieee80211_vif)))
 356		adapter->vifs[0] = NULL;
 357	mutex_unlock(&common->mutex);
 358}
 359
 360/**
 361 * rsi_channel_change() - This function is a performs the checks
 362 *			  required for changing a channel and sets
 363 *			  the channel accordingly.
 364 * @hw: Pointer to the ieee80211_hw structure.
 365 *
 366 * Return: 0 on success, negative error code on failure.
 367 */
 368static int rsi_channel_change(struct ieee80211_hw *hw)
 369{
 370	struct rsi_hw *adapter = hw->priv;
 371	struct rsi_common *common = adapter->priv;
 372	int status = -EOPNOTSUPP;
 373	struct ieee80211_channel *curchan = hw->conf.chandef.chan;
 374	u16 channel = curchan->hw_value;
 375	struct ieee80211_bss_conf *bss = &adapter->vifs[0]->bss_conf;
 376
 377	rsi_dbg(INFO_ZONE,
 378		"%s: Set channel: %d MHz type: %d channel_no %d\n",
 379		__func__, curchan->center_freq,
 380		curchan->flags, channel);
 381
 382	if (bss->assoc) {
 383		if (!common->hw_data_qs_blocked &&
 384		    (rsi_get_connected_channel(adapter) != channel)) {
 385			rsi_dbg(INFO_ZONE, "blk data q %d\n", channel);
 386			if (!rsi_send_block_unblock_frame(common, true))
 387				common->hw_data_qs_blocked = true;
 388		}
 389	}
 390
 391	status = rsi_band_check(common);
 392	if (!status)
 393		status = rsi_set_channel(adapter->priv, curchan);
 394
 395	if (bss->assoc) {
 396		if (common->hw_data_qs_blocked &&
 397		    (rsi_get_connected_channel(adapter) == channel)) {
 398			rsi_dbg(INFO_ZONE, "unblk data q %d\n", channel);
 399			if (!rsi_send_block_unblock_frame(common, false))
 400				common->hw_data_qs_blocked = false;
 401		}
 402	} else {
 403		if (common->hw_data_qs_blocked) {
 404			rsi_dbg(INFO_ZONE, "unblk data q %d\n", channel);
 405			if (!rsi_send_block_unblock_frame(common, false))
 406				common->hw_data_qs_blocked = false;
 407		}
 408	}
 409
 410	return status;
 411}
 412
 413/**
 414 * rsi_config_power() - This function configures tx power to device
 415 * @hw: Pointer to the ieee80211_hw structure.
 416 *
 417 * Return: 0 on success, negative error code on failure.
 418 */
 419static int rsi_config_power(struct ieee80211_hw *hw)
 420{
 421	struct rsi_hw *adapter = hw->priv;
 422	struct rsi_common *common = adapter->priv;
 423	struct ieee80211_conf *conf = &hw->conf;
 424
 425	if (adapter->sc_nvifs <= 0) {
 426		rsi_dbg(ERR_ZONE, "%s: No virtual interface found\n", __func__);
 427		return -EINVAL;
 428	}
 429
 430	rsi_dbg(INFO_ZONE,
 431		"%s: Set tx power: %d dBM\n", __func__, conf->power_level);
 432
 433	if (conf->power_level == common->tx_power)
 434		return 0;
 435
 436	common->tx_power = conf->power_level;
 437
 438	return rsi_send_radio_params_update(common);
 439}
 440
 441/**
 442 * rsi_mac80211_config() - This function is a handler for configuration
 443 *			   requests. The stack calls this function to
 444 *			   change hardware configuration, e.g., channel.
 445 * @hw: Pointer to the ieee80211_hw structure.
 446 * @changed: Changed flags set.
 447 *
 448 * Return: 0 on success, negative error code on failure.
 449 */
 450static int rsi_mac80211_config(struct ieee80211_hw *hw,
 451			       u32 changed)
 452{
 453	struct rsi_hw *adapter = hw->priv;
 454	struct rsi_common *common = adapter->priv;
 455	int status = -EOPNOTSUPP;
 456
 457	mutex_lock(&common->mutex);
 458
 459	if (changed & IEEE80211_CONF_CHANGE_CHANNEL)
 460		status = rsi_channel_change(hw);
 461
 462	/* tx power */
 463	if (changed & IEEE80211_CONF_CHANGE_POWER) {
 464		rsi_dbg(INFO_ZONE, "%s: Configuring Power\n", __func__);
 465		status = rsi_config_power(hw);
 466	}
 467
 468	mutex_unlock(&common->mutex);
 469
 470	return status;
 471}
 472
 473/**
 474 * rsi_get_connected_channel() - This function is used to get the current
 475 *				 connected channel number.
 476 * @adapter: Pointer to the adapter structure.
 477 *
 478 * Return: Current connected AP's channel number is returned.
 479 */
 480u16 rsi_get_connected_channel(struct rsi_hw *adapter)
 481{
 482	struct ieee80211_vif *vif = adapter->vifs[0];
 483	if (vif) {
 484		struct ieee80211_bss_conf *bss = &vif->bss_conf;
 485		struct ieee80211_channel *channel = bss->chandef.chan;
 486		return channel->hw_value;
 487	}
 488
 489	return 0;
 490}
 491
 492/**
 493 * rsi_mac80211_bss_info_changed() - This function is a handler for config
 494 *				     requests related to BSS parameters that
 495 *				     may vary during BSS's lifespan.
 496 * @hw: Pointer to the ieee80211_hw structure.
 497 * @vif: Pointer to the ieee80211_vif structure.
 498 * @bss_conf: Pointer to the ieee80211_bss_conf structure.
 499 * @changed: Changed flags set.
 500 *
 501 * Return: None.
 502 */
 503static void rsi_mac80211_bss_info_changed(struct ieee80211_hw *hw,
 504					  struct ieee80211_vif *vif,
 505					  struct ieee80211_bss_conf *bss_conf,
 506					  u32 changed)
 507{
 508	struct rsi_hw *adapter = hw->priv;
 509	struct rsi_common *common = adapter->priv;
 510	u16 rx_filter_word = 0;
 511
 512	mutex_lock(&common->mutex);
 513	if (changed & BSS_CHANGED_ASSOC) {
 514		rsi_dbg(INFO_ZONE, "%s: Changed Association status: %d\n",
 515			__func__, bss_conf->assoc);
 516		if (bss_conf->assoc) {
 517			/* Send the RX filter frame */
 518			rx_filter_word = (ALLOW_DATA_ASSOC_PEER |
 519					  ALLOW_CTRL_ASSOC_PEER |
 520					  ALLOW_MGMT_ASSOC_PEER);
 521			rsi_send_rx_filter_frame(common, rx_filter_word);
 522		}
 523		rsi_inform_bss_status(common,
 524				      bss_conf->assoc,
 525				      bss_conf->bssid,
 526				      bss_conf->qos,
 527				      bss_conf->aid);
 528	}
 529
 530	if (changed & BSS_CHANGED_CQM) {
 531		common->cqm_info.last_cqm_event_rssi = 0;
 532		common->cqm_info.rssi_thold = bss_conf->cqm_rssi_thold;
 533		common->cqm_info.rssi_hyst = bss_conf->cqm_rssi_hyst;
 534		rsi_dbg(INFO_ZONE, "RSSI throld & hysteresis are: %d %d\n",
 535			common->cqm_info.rssi_thold,
 536			common->cqm_info.rssi_hyst);
 537	}
 538	mutex_unlock(&common->mutex);
 539}
 540
 541/**
 542 * rsi_mac80211_conf_filter() - This function configure the device's RX filter.
 543 * @hw: Pointer to the ieee80211_hw structure.
 544 * @changed: Changed flags set.
 545 * @total_flags: Total initial flags set.
 546 * @multicast: Multicast.
 547 *
 548 * Return: None.
 549 */
 550static void rsi_mac80211_conf_filter(struct ieee80211_hw *hw,
 551				     u32 changed_flags,
 552				     u32 *total_flags,
 553				     u64 multicast)
 554{
 555	/* Not doing much here as of now */
 556	*total_flags &= RSI_SUPP_FILTERS;
 557}
 558
 559/**
 560 * rsi_mac80211_conf_tx() - This function configures TX queue parameters
 561 *			    (EDCF (aifs, cw_min, cw_max), bursting)
 562 *			    for a hardware TX queue.
 563 * @hw: Pointer to the ieee80211_hw structure
 564 * @vif: Pointer to the ieee80211_vif structure.
 565 * @queue: Queue number.
 566 * @params: Pointer to ieee80211_tx_queue_params structure.
 567 *
 568 * Return: 0 on success, negative error code on failure.
 569 */
 570static int rsi_mac80211_conf_tx(struct ieee80211_hw *hw,
 571				struct ieee80211_vif *vif, u16 queue,
 572				const struct ieee80211_tx_queue_params *params)
 573{
 574	struct rsi_hw *adapter = hw->priv;
 575	struct rsi_common *common = adapter->priv;
 576	u8 idx = 0;
 577
 578	if (queue >= IEEE80211_NUM_ACS)
 579		return 0;
 580
 581	rsi_dbg(INFO_ZONE,
 582		"%s: Conf queue %d, aifs: %d, cwmin: %d cwmax: %d, txop: %d\n",
 583		__func__, queue, params->aifs,
 584		params->cw_min, params->cw_max, params->txop);
 585
 586	mutex_lock(&common->mutex);
 587	/* Map into the way the f/w expects */
 588	switch (queue) {
 589	case IEEE80211_AC_VO:
 590		idx = VO_Q;
 591		break;
 592	case IEEE80211_AC_VI:
 593		idx = VI_Q;
 594		break;
 595	case IEEE80211_AC_BE:
 596		idx = BE_Q;
 597		break;
 598	case IEEE80211_AC_BK:
 599		idx = BK_Q;
 600		break;
 601	default:
 602		idx = BE_Q;
 603		break;
 604	}
 605
 606	memcpy(&common->edca_params[idx],
 607	       params,
 608	       sizeof(struct ieee80211_tx_queue_params));
 609	mutex_unlock(&common->mutex);
 610
 611	return 0;
 612}
 613
 614/**
 615 * rsi_hal_key_config() - This function loads the keys into the firmware.
 616 * @hw: Pointer to the ieee80211_hw structure.
 617 * @vif: Pointer to the ieee80211_vif structure.
 618 * @key: Pointer to the ieee80211_key_conf structure.
 619 *
 620 * Return: status: 0 on success, -1 on failure.
 621 */
 622static int rsi_hal_key_config(struct ieee80211_hw *hw,
 623			      struct ieee80211_vif *vif,
 624			      struct ieee80211_key_conf *key)
 625{
 626	struct rsi_hw *adapter = hw->priv;
 627	int status;
 628	u8 key_type;
 629
 630	if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
 631		key_type = RSI_PAIRWISE_KEY;
 632	else
 633		key_type = RSI_GROUP_KEY;
 634
 635	rsi_dbg(ERR_ZONE, "%s: Cipher 0x%x key_type: %d key_len: %d\n",
 636		__func__, key->cipher, key_type, key->keylen);
 637
 638	if ((key->cipher == WLAN_CIPHER_SUITE_WEP104) ||
 639	    (key->cipher == WLAN_CIPHER_SUITE_WEP40)) {
 640		status = rsi_hal_load_key(adapter->priv,
 641					  key->key,
 642					  key->keylen,
 643					  RSI_PAIRWISE_KEY,
 644					  key->keyidx,
 645					  key->cipher);
 646		if (status)
 647			return status;
 648	}
 649	return rsi_hal_load_key(adapter->priv,
 650				key->key,
 651				key->keylen,
 652				key_type,
 653				key->keyidx,
 654				key->cipher);
 655}
 656
 657/**
 658 * rsi_mac80211_set_key() - This function sets type of key to be loaded.
 659 * @hw: Pointer to the ieee80211_hw structure.
 660 * @cmd: enum set_key_cmd.
 661 * @vif: Pointer to the ieee80211_vif structure.
 662 * @sta: Pointer to the ieee80211_sta structure.
 663 * @key: Pointer to the ieee80211_key_conf structure.
 664 *
 665 * Return: status: 0 on success, negative error code on failure.
 666 */
 667static int rsi_mac80211_set_key(struct ieee80211_hw *hw,
 668				enum set_key_cmd cmd,
 669				struct ieee80211_vif *vif,
 670				struct ieee80211_sta *sta,
 671				struct ieee80211_key_conf *key)
 672{
 673	struct rsi_hw *adapter = hw->priv;
 674	struct rsi_common *common = adapter->priv;
 675	struct security_info *secinfo = &common->secinfo;
 676	int status;
 677
 678	mutex_lock(&common->mutex);
 679	switch (cmd) {
 680	case SET_KEY:
 681		secinfo->security_enable = true;
 682		status = rsi_hal_key_config(hw, vif, key);
 683		if (status) {
 684			mutex_unlock(&common->mutex);
 685			return status;
 686		}
 687
 688		if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
 689			secinfo->ptk_cipher = key->cipher;
 690		else
 691			secinfo->gtk_cipher = key->cipher;
 692
 693		key->hw_key_idx = key->keyidx;
 694		key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
 695
 696		rsi_dbg(ERR_ZONE, "%s: RSI set_key\n", __func__);
 697		break;
 698
 699	case DISABLE_KEY:
 700		secinfo->security_enable = false;
 701		rsi_dbg(ERR_ZONE, "%s: RSI del key\n", __func__);
 702		memset(key, 0, sizeof(struct ieee80211_key_conf));
 703		status = rsi_hal_key_config(hw, vif, key);
 704		break;
 705
 706	default:
 707		status = -EOPNOTSUPP;
 708		break;
 709	}
 710
 711	mutex_unlock(&common->mutex);
 712	return status;
 713}
 714
 715/**
 716 * rsi_mac80211_ampdu_action() - This function selects the AMPDU action for
 717 *				 the corresponding mlme_action flag and
 718 *				 informs the f/w regarding this.
 719 * @hw: Pointer to the ieee80211_hw structure.
 720 * @vif: Pointer to the ieee80211_vif structure.
 721 * @params: Pointer to A-MPDU action parameters
 722 *
 723 * Return: status: 0 on success, negative error code on failure.
 724 */
 725static int rsi_mac80211_ampdu_action(struct ieee80211_hw *hw,
 726				     struct ieee80211_vif *vif,
 727				     struct ieee80211_ampdu_params *params)
 728{
 729	int status = -EOPNOTSUPP;
 730	struct rsi_hw *adapter = hw->priv;
 731	struct rsi_common *common = adapter->priv;
 732	u16 seq_no = 0;
 733	u8 ii = 0;
 734	struct ieee80211_sta *sta = params->sta;
 735	enum ieee80211_ampdu_mlme_action action = params->action;
 736	u16 tid = params->tid;
 737	u16 *ssn = &params->ssn;
 738	u8 buf_size = params->buf_size;
 739
 740	for (ii = 0; ii < RSI_MAX_VIFS; ii++) {
 741		if (vif == adapter->vifs[ii])
 742			break;
 743	}
 744
 745	mutex_lock(&common->mutex);
 746	rsi_dbg(INFO_ZONE, "%s: AMPDU action %d called\n", __func__, action);
 747	if (ssn != NULL)
 748		seq_no = *ssn;
 749
 750	switch (action) {
 751	case IEEE80211_AMPDU_RX_START:
 752		status = rsi_send_aggregation_params_frame(common,
 753							   tid,
 754							   seq_no,
 755							   buf_size,
 756							   STA_RX_ADDBA_DONE);
 757		break;
 758
 759	case IEEE80211_AMPDU_RX_STOP:
 760		status = rsi_send_aggregation_params_frame(common,
 761							   tid,
 762							   0,
 763							   buf_size,
 764							   STA_RX_DELBA);
 765		break;
 766
 767	case IEEE80211_AMPDU_TX_START:
 768		common->vif_info[ii].seq_start = seq_no;
 769		ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
 770		status = 0;
 771		break;
 772
 773	case IEEE80211_AMPDU_TX_STOP_CONT:
 774	case IEEE80211_AMPDU_TX_STOP_FLUSH:
 775	case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
 776		status = rsi_send_aggregation_params_frame(common,
 777							   tid,
 778							   seq_no,
 779							   buf_size,
 780							   STA_TX_DELBA);
 781		if (!status)
 782			ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
 783		break;
 784
 785	case IEEE80211_AMPDU_TX_OPERATIONAL:
 786		status = rsi_send_aggregation_params_frame(common,
 787							   tid,
 788							   common->vif_info[ii]
 789								.seq_start,
 790							   buf_size,
 791							   STA_TX_ADDBA_DONE);
 792		break;
 793
 794	default:
 795		rsi_dbg(ERR_ZONE, "%s: Uknown AMPDU action\n", __func__);
 796		break;
 797	}
 798
 799	mutex_unlock(&common->mutex);
 800	return status;
 801}
 802
 803/**
 804 * rsi_mac80211_set_rts_threshold() - This function sets rts threshold value.
 805 * @hw: Pointer to the ieee80211_hw structure.
 806 * @value: Rts threshold value.
 807 *
 808 * Return: 0 on success.
 809 */
 810static int rsi_mac80211_set_rts_threshold(struct ieee80211_hw *hw,
 811					  u32 value)
 812{
 813	struct rsi_hw *adapter = hw->priv;
 814	struct rsi_common *common = adapter->priv;
 815
 816	mutex_lock(&common->mutex);
 817	common->rts_threshold = value;
 818	mutex_unlock(&common->mutex);
 819
 820	return 0;
 821}
 822
 823/**
 824 * rsi_mac80211_set_rate_mask() - This function sets bitrate_mask to be used.
 825 * @hw: Pointer to the ieee80211_hw structure
 826 * @vif: Pointer to the ieee80211_vif structure.
 827 * @mask: Pointer to the cfg80211_bitrate_mask structure.
 828 *
 829 * Return: 0 on success.
 830 */
 831static int rsi_mac80211_set_rate_mask(struct ieee80211_hw *hw,
 832				      struct ieee80211_vif *vif,
 833				      const struct cfg80211_bitrate_mask *mask)
 834{
 835	struct rsi_hw *adapter = hw->priv;
 836	struct rsi_common *common = adapter->priv;
 837	enum nl80211_band band = hw->conf.chandef.chan->band;
 838
 839	mutex_lock(&common->mutex);
 840	common->fixedrate_mask[band] = 0;
 841
 842	if (mask->control[band].legacy == 0xfff) {
 843		common->fixedrate_mask[band] =
 844			(mask->control[band].ht_mcs[0] << 12);
 845	} else {
 846		common->fixedrate_mask[band] =
 847			mask->control[band].legacy;
 848	}
 849	mutex_unlock(&common->mutex);
 850
 851	return 0;
 852}
 853
 854/**
 855 * rsi_perform_cqm() - This function performs cqm.
 856 * @common: Pointer to the driver private structure.
 857 * @bssid: pointer to the bssid.
 858 * @rssi: RSSI value.
 859 */
 860static void rsi_perform_cqm(struct rsi_common *common,
 861			    u8 *bssid,
 862			    s8 rssi)
 863{
 864	struct rsi_hw *adapter = common->priv;
 865	s8 last_event = common->cqm_info.last_cqm_event_rssi;
 866	int thold = common->cqm_info.rssi_thold;
 867	u32 hyst = common->cqm_info.rssi_hyst;
 868	enum nl80211_cqm_rssi_threshold_event event;
 869
 870	if (rssi < thold && (last_event == 0 || rssi < (last_event - hyst)))
 871		event = NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW;
 872	else if (rssi > thold &&
 873		 (last_event == 0 || rssi > (last_event + hyst)))
 874		event = NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH;
 875	else
 876		return;
 877
 878	common->cqm_info.last_cqm_event_rssi = rssi;
 879	rsi_dbg(INFO_ZONE, "CQM: Notifying event: %d\n", event);
 880	ieee80211_cqm_rssi_notify(adapter->vifs[0], event, GFP_KERNEL);
 881
 882	return;
 883}
 884
 885/**
 886 * rsi_fill_rx_status() - This function fills rx status in
 887 *			  ieee80211_rx_status structure.
 888 * @hw: Pointer to the ieee80211_hw structure.
 889 * @skb: Pointer to the socket buffer structure.
 890 * @common: Pointer to the driver private structure.
 891 * @rxs: Pointer to the ieee80211_rx_status structure.
 892 *
 893 * Return: None.
 894 */
 895static void rsi_fill_rx_status(struct ieee80211_hw *hw,
 896			       struct sk_buff *skb,
 897			       struct rsi_common *common,
 898			       struct ieee80211_rx_status *rxs)
 899{
 900	struct ieee80211_bss_conf *bss = &common->priv->vifs[0]->bss_conf;
 901	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 902	struct skb_info *rx_params = (struct skb_info *)info->driver_data;
 903	struct ieee80211_hdr *hdr;
 904	char rssi = rx_params->rssi;
 905	u8 hdrlen = 0;
 906	u8 channel = rx_params->channel;
 907	s32 freq;
 908
 909	hdr = ((struct ieee80211_hdr *)(skb->data));
 910	hdrlen = ieee80211_hdrlen(hdr->frame_control);
 911
 912	memset(info, 0, sizeof(struct ieee80211_tx_info));
 913
 914	rxs->signal = -(rssi);
 915
 916	rxs->band = common->band;
 917
 918	freq = ieee80211_channel_to_frequency(channel, rxs->band);
 919
 920	if (freq)
 921		rxs->freq = freq;
 922
 923	if (ieee80211_has_protected(hdr->frame_control)) {
 924		if (rsi_is_cipher_wep(common)) {
 925			memmove(skb->data + 4, skb->data, hdrlen);
 926			skb_pull(skb, 4);
 927		} else {
 928			memmove(skb->data + 8, skb->data, hdrlen);
 929			skb_pull(skb, 8);
 930			rxs->flag |= RX_FLAG_MMIC_STRIPPED;
 931		}
 932		rxs->flag |= RX_FLAG_DECRYPTED;
 933		rxs->flag |= RX_FLAG_IV_STRIPPED;
 934	}
 935
 936	/* CQM only for connected AP beacons, the RSSI is a weighted avg */
 937	if (bss->assoc && !(memcmp(bss->bssid, hdr->addr2, ETH_ALEN))) {
 938		if (ieee80211_is_beacon(hdr->frame_control))
 939			rsi_perform_cqm(common, hdr->addr2, rxs->signal);
 940	}
 941
 942	return;
 943}
 944
 945/**
 946 * rsi_indicate_pkt_to_os() - This function sends recieved packet to mac80211.
 947 * @common: Pointer to the driver private structure.
 948 * @skb: Pointer to the socket buffer structure.
 949 *
 950 * Return: None.
 951 */
 952void rsi_indicate_pkt_to_os(struct rsi_common *common,
 953			    struct sk_buff *skb)
 954{
 955	struct rsi_hw *adapter = common->priv;
 956	struct ieee80211_hw *hw = adapter->hw;
 957	struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb);
 958
 959	if ((common->iface_down) || (!adapter->sc_nvifs)) {
 960		dev_kfree_skb(skb);
 961		return;
 962	}
 963
 964	/* filling in the ieee80211_rx_status flags */
 965	rsi_fill_rx_status(hw, skb, common, rx_status);
 966
 967	ieee80211_rx_irqsafe(hw, skb);
 968}
 969
 970static void rsi_set_min_rate(struct ieee80211_hw *hw,
 971			     struct ieee80211_sta *sta,
 972			     struct rsi_common *common)
 973{
 974	u8 band = hw->conf.chandef.chan->band;
 975	u8 ii;
 976	u32 rate_bitmap;
 977	bool matched = false;
 978
 979	common->bitrate_mask[band] = sta->supp_rates[band];
 980
 981	rate_bitmap = (common->fixedrate_mask[band] & sta->supp_rates[band]);
 982
 983	if (rate_bitmap & 0xfff) {
 984		/* Find out the min rate */
 985		for (ii = 0; ii < ARRAY_SIZE(rsi_rates); ii++) {
 986			if (rate_bitmap & BIT(ii)) {
 987				common->min_rate = rsi_rates[ii].hw_value;
 988				matched = true;
 989				break;
 990			}
 991		}
 992	}
 993
 994	common->vif_info[0].is_ht = sta->ht_cap.ht_supported;
 995
 996	if ((common->vif_info[0].is_ht) && (rate_bitmap >> 12)) {
 997		for (ii = 0; ii < ARRAY_SIZE(rsi_mcsrates); ii++) {
 998			if ((rate_bitmap >> 12) & BIT(ii)) {
 999				common->min_rate = rsi_mcsrates[ii];
1000				matched = true;
1001				break;
1002			}
1003		}
1004	}
1005
1006	if (!matched)
1007		common->min_rate = 0xffff;
1008}
1009
1010/**
1011 * rsi_mac80211_sta_add() - This function notifies driver about a peer getting
1012 *			    connected.
1013 * @hw: pointer to the ieee80211_hw structure.
1014 * @vif: Pointer to the ieee80211_vif structure.
1015 * @sta: Pointer to the ieee80211_sta structure.
1016 *
1017 * Return: 0 on success, -1 on failure.
1018 */
1019static int rsi_mac80211_sta_add(struct ieee80211_hw *hw,
1020				struct ieee80211_vif *vif,
1021				struct ieee80211_sta *sta)
1022{
1023	struct rsi_hw *adapter = hw->priv;
1024	struct rsi_common *common = adapter->priv;
1025
1026	mutex_lock(&common->mutex);
1027
1028	rsi_set_min_rate(hw, sta, common);
1029
1030	if ((sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ||
1031	    (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40)) {
1032		common->vif_info[0].sgi = true;
1033	}
1034
1035	if (sta->ht_cap.ht_supported)
1036		ieee80211_start_tx_ba_session(sta, 0, 0);
1037
1038	mutex_unlock(&common->mutex);
1039
1040	return 0;
1041}
1042
1043/**
1044 * rsi_mac80211_sta_remove() - This function notifies driver about a peer
1045 *			       getting disconnected.
1046 * @hw: Pointer to the ieee80211_hw structure.
1047 * @vif: Pointer to the ieee80211_vif structure.
1048 * @sta: Pointer to the ieee80211_sta structure.
1049 *
1050 * Return: 0 on success, -1 on failure.
1051 */
1052static int rsi_mac80211_sta_remove(struct ieee80211_hw *hw,
1053				   struct ieee80211_vif *vif,
1054				   struct ieee80211_sta *sta)
1055{
1056	struct rsi_hw *adapter = hw->priv;
1057	struct rsi_common *common = adapter->priv;
1058
1059	mutex_lock(&common->mutex);
1060
1061	/* Resetting all the fields to default values */
1062	common->bitrate_mask[NL80211_BAND_2GHZ] = 0;
1063	common->bitrate_mask[NL80211_BAND_5GHZ] = 0;
1064	common->min_rate = 0xffff;
1065	common->vif_info[0].is_ht = false;
1066	common->vif_info[0].sgi = false;
1067	common->vif_info[0].seq_start = 0;
1068	common->secinfo.ptk_cipher = 0;
1069	common->secinfo.gtk_cipher = 0;
1070
1071	rsi_send_rx_filter_frame(common, 0);
1072	
1073	mutex_unlock(&common->mutex);
1074	
1075	return 0;
1076}
1077
1078/**
1079 * rsi_mac80211_set_antenna() - This function is used to configure
1080 *				tx and rx antennas.
1081 * @hw: Pointer to the ieee80211_hw structure.
1082 * @tx_ant: Bitmap for tx antenna
1083 * @rx_ant: Bitmap for rx antenna
1084 *
1085 * Return: 0 on success, Negative error code on failure.
1086 */
1087static int rsi_mac80211_set_antenna(struct ieee80211_hw *hw,
1088				    u32 tx_ant, u32 rx_ant)
1089{
1090	struct rsi_hw *adapter = hw->priv;
1091	struct rsi_common *common = adapter->priv;
1092	u8 antenna = 0;
1093
1094	if (tx_ant > 1 || rx_ant > 1) {
1095		rsi_dbg(ERR_ZONE,
1096			"Invalid antenna selection (tx: %d, rx:%d)\n",
1097			tx_ant, rx_ant);
1098		rsi_dbg(ERR_ZONE,
1099			"Use 0 for int_ant, 1 for ext_ant\n");
1100		return -EINVAL; 
1101	}
1102
1103	rsi_dbg(INFO_ZONE, "%s: Antenna map Tx %x Rx %d\n",
1104			__func__, tx_ant, rx_ant);
1105
1106	mutex_lock(&common->mutex);
1107
1108	antenna = tx_ant ? ANTENNA_SEL_UFL : ANTENNA_SEL_INT;
1109	if (common->ant_in_use != antenna)
1110		if (rsi_set_antenna(common, antenna))
1111			goto fail_set_antenna;
1112
1113	rsi_dbg(INFO_ZONE, "(%s) Antenna path configured successfully\n",
1114		tx_ant ? "UFL" : "INT");
1115
1116	common->ant_in_use = antenna;
1117	
1118	mutex_unlock(&common->mutex);
1119	
1120	return 0;
1121
1122fail_set_antenna:
1123	rsi_dbg(ERR_ZONE, "%s: Failed.\n", __func__);
1124	mutex_unlock(&common->mutex);
1125	return -EINVAL;
1126}
1127
1128/**
1129 * rsi_mac80211_get_antenna() - This function is used to configure 
1130 * 				tx and rx antennas.
1131 *
1132 * @hw: Pointer to the ieee80211_hw structure.
1133 * @tx_ant: Bitmap for tx antenna
1134 * @rx_ant: Bitmap for rx antenna
1135 * 
1136 * Return: 0 on success, -1 on failure.
1137 */
1138static int rsi_mac80211_get_antenna(struct ieee80211_hw *hw,
1139				    u32 *tx_ant, u32 *rx_ant)
1140{
1141	struct rsi_hw *adapter = hw->priv;
1142	struct rsi_common *common = adapter->priv;
1143
1144	mutex_lock(&common->mutex);
1145
1146	*tx_ant = (common->ant_in_use == ANTENNA_SEL_UFL) ? 1 : 0;
1147	*rx_ant = 0;
1148
1149	mutex_unlock(&common->mutex);
1150	
1151	return 0;	
1152}
1153
1154static 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
1180static struct ieee80211_ops mac80211_ops = {
1181	.tx = rsi_mac80211_tx,
1182	.start = rsi_mac80211_start,
1183	.stop = rsi_mac80211_stop,
1184	.add_interface = rsi_mac80211_add_interface,
1185	.remove_interface = rsi_mac80211_remove_interface,
1186	.config = rsi_mac80211_config,
1187	.bss_info_changed = rsi_mac80211_bss_info_changed,
1188	.conf_tx = rsi_mac80211_conf_tx,
1189	.configure_filter = rsi_mac80211_conf_filter,
1190	.set_key = rsi_mac80211_set_key,
1191	.set_rts_threshold = rsi_mac80211_set_rts_threshold,
1192	.set_bitrate_mask = rsi_mac80211_set_rate_mask,
1193	.ampdu_action = rsi_mac80211_ampdu_action,
1194	.sta_add = rsi_mac80211_sta_add,
1195	.sta_remove = rsi_mac80211_sta_remove,
1196	.set_antenna = rsi_mac80211_set_antenna,
1197	.get_antenna = rsi_mac80211_get_antenna,
1198};
1199
1200/**
1201 * rsi_mac80211_attach() - This function is used to initialize Mac80211 stack.
1202 * @common: Pointer to the driver private structure.
1203 *
1204 * Return: 0 on success, -1 on failure.
1205 */
1206int rsi_mac80211_attach(struct rsi_common *common)
1207{
1208	int status = 0;
1209	struct ieee80211_hw *hw = NULL;
1210	struct wiphy *wiphy = NULL;
1211	struct rsi_hw *adapter = common->priv;
1212	u8 addr_mask[ETH_ALEN] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x3};
1213
1214	rsi_dbg(INIT_ZONE, "%s: Performing mac80211 attach\n", __func__);
1215
1216	hw = ieee80211_alloc_hw(sizeof(struct rsi_hw), &mac80211_ops);
1217	if (!hw) {
1218		rsi_dbg(ERR_ZONE, "%s: ieee80211 hw alloc failed\n", __func__);
1219		return -ENOMEM;
1220	}
1221
1222	wiphy = hw->wiphy;
1223
1224	SET_IEEE80211_DEV(hw, adapter->device);
1225
1226	hw->priv = adapter;
1227	adapter->hw = hw;
1228
1229	ieee80211_hw_set(hw, SIGNAL_DBM);
1230	ieee80211_hw_set(hw, HAS_RATE_CONTROL);
1231	ieee80211_hw_set(hw, AMPDU_AGGREGATION);
1232
1233	hw->queues = MAX_HW_QUEUES;
1234	hw->extra_tx_headroom = RSI_NEEDED_HEADROOM;
1235
1236	hw->max_rates = 1;
1237	hw->max_rate_tries = MAX_RETRIES;
1238
1239	hw->max_tx_aggregation_subframes = 6;
1240	rsi_register_rates_channels(adapter, NL80211_BAND_2GHZ);
1241	rsi_register_rates_channels(adapter, NL80211_BAND_5GHZ);
1242	hw->rate_control_algorithm = "AARF";
1243
1244	SET_IEEE80211_PERM_ADDR(hw, common->mac_addr);
1245	ether_addr_copy(hw->wiphy->addr_mask, addr_mask);
1246
1247	wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
1248	wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
1249	wiphy->retry_short = RETRY_SHORT;
1250	wiphy->retry_long  = RETRY_LONG;
1251	wiphy->frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD;
1252	wiphy->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
1253	wiphy->flags = 0;
1254
1255	wiphy->available_antennas_rx = 1;
1256	wiphy->available_antennas_tx = 1;
1257	wiphy->bands[NL80211_BAND_2GHZ] =
1258		&adapter->sbands[NL80211_BAND_2GHZ];
1259	wiphy->bands[NL80211_BAND_5GHZ] =
1260		&adapter->sbands[NL80211_BAND_5GHZ];
1261
1262	wiphy->reg_notifier = rsi_reg_notify;
1263
1264	status = ieee80211_register_hw(hw);
1265	if (status)
1266		return status;
1267
1268	return rsi_init_dbgfs(adapter);
1269}