[PATCH] [Xenial][SRU] UBUNTU: SAUCE: Redpine driver to support Host AP mode

Shrirang Bagul shrirang.bagul at canonical.com
Thu Feb 16 11:35:10 UTC 2017


Please ignore this patch as of now, we might have a newer version for the driver
from the vendor which will replace this patch.

Thanks,
Shrirang

On Thu, 2017-02-16 at 13:05 +0800, Shrirang Bagul wrote:
> BugLink: http://bugs.launchpad.net/bugs/1665211
> 
> Dell Caracalla IoT gateways sport a Redpine RS9113 WLAN-BT combo card.
> This patch adds Host AP mode support to the Redpine RS9113 driver.
> Vendor release version: 0.9.8.2 (Beta)
> 
> Signed-off-by: Shrirang Bagul <shrirang.bagul at canonical.com>
> ---
>  ubuntu/rsi/Makefile           |   2 +-
>  ubuntu/rsi/rsi_91x_core.c     |  49 +++++++++--
>  ubuntu/rsi/rsi_91x_debugfs.c  |  35 ++++++--
>  ubuntu/rsi/rsi_91x_hal.c      |  78 +++++++++++-------
>  ubuntu/rsi/rsi_91x_hci.c      |  44 +---------
>  ubuntu/rsi/rsi_91x_mac80211.c | 146 ++++++++++++++++++++++++--------
>  ubuntu/rsi/rsi_91x_main.c     |  96 +++++++++++++++++++++
>  ubuntu/rsi/rsi_91x_mgmt.c     | 188 +++++++++++++++++++++++++++------------
> ---
>  ubuntu/rsi/rsi_91x_sdio.c     |  88 ++++++++------------
>  ubuntu/rsi/rsi_91x_sdio_ops.c |  11 ++-
>  ubuntu/rsi/rsi_coex.h         |   2 +-
>  ubuntu/rsi/rsi_common.h       |   6 ++
>  ubuntu/rsi/rsi_main.h         |  15 +++-
>  ubuntu/rsi/rsi_mgmt.h         |  14 ++--
>  14 files changed, 521 insertions(+), 253 deletions(-)
> 
> diff --git a/ubuntu/rsi/Makefile b/ubuntu/rsi/Makefile
> index 941848c..a7db51c 100644
> --- a/ubuntu/rsi/Makefile
> +++ b/ubuntu/rsi/Makefile
> @@ -1,4 +1,4 @@
> -EXTRA_CFLAGS += -DCONFIG_DELL_BOARD -DCONFIG_VEN_RSI_COEX -DLINUX -Wimplicit
> -Wstrict-prototypes -DCONFIG_VEN_RSI_DEBUGFS -DPLATFORM_X86
> +EXTRA_CFLAGS += -DCONFIG_CARACALLA_BOARD -DCONFIG_VEN_RSI_COEX -DLINUX
> -Wimplicit -Wstrict-prototypes -DCONFIG_VEN_RSI_DEBUGFS -DPLATFORM_X86
> -DCONFIG_RSI_WOW
>  
>  ven_rsi_91x-y			+= rsi_91x_main.o
>  ven_rsi_91x-y			+= rsi_91x_core.o
> diff --git a/ubuntu/rsi/rsi_91x_core.c b/ubuntu/rsi/rsi_91x_core.c
> index eaf0e29..ac55ce1 100644
> --- a/ubuntu/rsi/rsi_91x_core.c
> +++ b/ubuntu/rsi/rsi_91x_core.c
> @@ -270,15 +270,13 @@ void rsi_core_qos_processor(struct rsi_common *common)
>  		ven_rsi_dbg(DATA_TX_ZONE,
>  			"%s: Queue number = %d\n", __func__, q_num);
>  
> -		if (q_num == INVALID_QUEUE) {
> -			ven_rsi_dbg(DATA_TX_ZONE, "%s: No More Pkt\n",
> __func__);
> +		if (q_num == INVALID_QUEUE)
>  			break;
> -		}
>  
>  		mutex_lock(&common->tx_lock);
>  
>  		status = adapter->check_hw_queue_status(adapter, q_num);
> -		if ((status <= 0)) {
> +		if (status <= 0) {
>  			mutex_unlock(&common->tx_lock);
>  			break;
>  		}
> @@ -286,6 +284,8 @@ void rsi_core_qos_processor(struct rsi_common *common)
>  		if ((q_num < MGMT_SOFT_Q) &&
>  		    ((skb_queue_len(&common->tx_queue[q_num])) <=
>  		      MIN_DATA_QUEUE_WATER_MARK)) {
> +			if (!adapter->hw)
> +				break;
>  			if (ieee80211_queue_stopped(adapter->hw,
> WME_AC(q_num)))
>  				ieee80211_wake_queue(adapter->hw,
>  						     WME_AC(q_num));
> @@ -368,7 +368,9 @@ struct rsi_sta *rsi_find_sta(struct rsi_common *common, u8
> *mac_addr)
>  {
>  	int i;
>  
> -	for (i = 0; i < common->num_stations; i++) {
> +	for (i = 0; i < RSI_MAX_ASSOC_STAS; i++) {
> +		if (!common->stations[i].sta)
> +			continue;
>  		if (!(memcmp(common->stations[i].sta->addr,
>  			     mac_addr, ETH_ALEN)))
>  			return &common->stations[i];
> @@ -397,7 +399,12 @@ void rsi_core_xmit(struct rsi_common *common, struct
> sk_buff *skb)
>  			__func__);
>  		goto xmit_fail;
>  	}
> -
> +#ifdef CONFIG_RSI_WOW
> +	if(common->suspend_flag) {
> +		ven_rsi_dbg(ERR_ZONE, "%s: Blocking Tx_packets when WOWLAN is
> enabled\n", __func__);
> +		goto xmit_fail;
> +	}
> +#endif
>  	if (common->fsm_state != FSM_MAC_INIT_DONE) {
>  		ven_rsi_dbg(ERR_ZONE, "%s: FSM state not open\n", __func__);
>  		goto xmit_fail;
> @@ -410,9 +417,23 @@ void rsi_core_xmit(struct rsi_common *common, struct
> sk_buff *skb)
>  	if ((ieee80211_is_mgmt(wlh->frame_control)) ||
>  	    (ieee80211_is_ctl(wlh->frame_control)) ||
>  	    (ieee80211_is_qos_nullfunc(wlh->frame_control))) {
> +		if ((ieee80211_is_assoc_req(wlh->frame_control)) ||
> +	 	    (ieee80211_is_reassoc_req(wlh->frame_control))) {
> +			struct ieee80211_bss_conf *bss = NULL;
> +
> +			bss = &adapter->vifs[0]->bss_conf;
> +			rsi_inform_bss_status(common, STA_OPMODE,1 ,
> +					      bss->bssid, bss->qos,
> +					      bss->aid, NULL, 0);
> +		}
>  		q_num = MGMT_SOFT_Q;
>  		skb->priority = q_num;
> -
> +#ifdef CONFIG_RSI_WOW          
> +		if ((ieee80211_is_deauth(wlh->frame_control)) && (common-
> >suspend_flag)) {
> +			ven_rsi_dbg(ERR_ZONE, "%s: Discarding Deauth when
> WOWLAN is enabled\n", __func__);
> +			goto xmit_fail; 
> +		}
> +#endif
>  		ven_rsi_dbg(INFO_ZONE, "Core: TX Dot11 Mgmt Pkt Type: %s\n",
>  			dot11_pkt_type(wlh->frame_control));
>  		if (ieee80211_is_probe_req(wlh->frame_control)) {
> @@ -434,9 +455,19 @@ void rsi_core_xmit(struct rsi_common *common, struct
> sk_buff *skb)
>  		rsi_hex_dump(DATA_TX_ZONE, "TX Data Packet",
>  			     skb->data, skb->len);
>  
> +		/* Drop the null packets if bgscan is enabled
> + 		 * as it is already handled in firmware */
> +		if ((vif->type == NL80211_IFTYPE_STATION) && (common-
> >bgscan_en)) {
> +			if (ieee80211_is_qos_nullfunc(wlh->frame_control)) {
> +				++common->tx_stats.total_tx_pkt_freed[skb-
> >priority];
> +				rsi_indicate_tx_status(adapter, skb, 0);
> +				return;
> +			}
> +		}
> +
>  		if (ieee80211_is_data_qos(wlh->frame_control)) {
>  			u8 *qos = ieee80211_get_qos_ctl(wlh);
> -
> +			
>  			tid = *qos & IEEE80211_QOS_CTL_TID_MASK;
>  			skb->priority = TID_TO_WME_AC(tid);
>  
> @@ -450,7 +481,7 @@ void rsi_core_xmit(struct rsi_common *common, struct
> sk_buff *skb)
>  		} else {
>  			tid = IEEE80211_NONQOS_TID;
>  			skb->priority = BE_Q;
> -
> +		
>  			if ((!is_broadcast_ether_addr(wlh->addr1)) &&
>  			    (!is_multicast_ether_addr(wlh->addr1)) &&
>  			    (vif->type == NL80211_IFTYPE_AP)) {
> diff --git a/ubuntu/rsi/rsi_91x_debugfs.c b/ubuntu/rsi/rsi_91x_debugfs.c
> index aeb0834..be4aec2 100644
> --- a/ubuntu/rsi/rsi_91x_debugfs.c
> +++ b/ubuntu/rsi/rsi_91x_debugfs.c
> @@ -267,9 +267,19 @@ static ssize_t rsi_debug_zone_write(struct file *filp,
>  static int rsi_bgscan_int_read(struct seq_file *file, void *data)
>  {
>  	struct rsi_common *common = file->private;
> -	struct bgscan_config_params *params = &common->bgscan_info;
> +	struct bgscan_config_params *params = NULL;
>  	int cnt;
>  
> +	if (!common) {
> +		ven_rsi_dbg(ERR_ZONE, "No Interface\n");
> +		return -ENODEV;
> +	}
> +	if (common->iface_down) {
> +		ven_rsi_dbg(ERR_ZONE, "Interface Down\n");
> +		return -ENODEV;
> +	}
> +	params = &common->bgscan_info;
> +
>  	seq_printf(file, "%d %d %d %d %d %d %d %d\n",
>  		   common->bgscan_en,
>  		   params->bgscan_threshold,
> @@ -314,14 +324,25 @@ static ssize_t rsi_bgscan_write(struct file *file,
>  
>  {
>  	struct rsi_common *common = file->f_inode->i_private;
> -	struct rsi_hw *adapter = common->priv;
> -	struct ieee80211_bss_conf *bss = &adapter->vifs[0]->bss_conf;
> +	struct rsi_hw *adapter = NULL;
> +	struct ieee80211_bss_conf *bss = NULL;
>  	char bgscan_buf[200];
>  	int bgscan_vals[64] = { 0 };
>  	int total_bytes, cnt = 0;
>  	int bytes_read = 0, t_bytes;
>  	int ret;
>  
> +	if (!common) {
> +		ven_rsi_dbg(ERR_ZONE, "No Interface\n");
> +		return -ENODEV;
> +	}
> +	if (common->iface_down) {
> +		ven_rsi_dbg(ERR_ZONE, "Interface Down\n");
> +		return -ENODEV;
> +	}
> +	adapter = common->priv;
> +	bss = &adapter->vifs[0]->bss_conf;
> +
>  	total_bytes = simple_write_to_buffer(bgscan_buf,
>  					     sizeof(bgscan_buf) - 1,
>  					     ppos, user_buff, count);
> @@ -387,10 +408,10 @@ static ssize_t rsi_bgscan_write(struct file *file,
>  	common->bgscan_info.num_user_channels = bgscan_vals[6];
>  	memset(&common->bgscan_info.user_channels, 0,
>  	       (MAX_BGSCAN_CHANNELS * 2));
> -	common->bgscan_info.num_user_channels =
> +	common->bgscan_info.num_user_channels = 
>  		((bgscan_vals[6] > MAX_BGSCAN_CHANNELS) ?
> -		 MAX_BGSCAN_CHANNELS : bgscan_vals[6]);
> -
> +		 MAX_BGSCAN_CHANNELS : bgscan_vals[6]); 
> +	
>  	for (cnt = 0; cnt < common->bgscan_info.num_user_channels; cnt++)
>  		common->bgscan_info.user_channels[cnt] = bgscan_vals[7 +
> cnt];
>  
> @@ -435,7 +456,7 @@ static ssize_t rsi_bgscan_write(struct file *file,
>  			common->bgscan_en = 0;
>  			g_bgscan_enable = 0;
>  		}
> -
> +	
>  } else {
>  #ifdef PLATFORM_X86
>  		ven_rsi_dbg(ERR_ZONE, "Failed sending bgscan params req\n");
> diff --git a/ubuntu/rsi/rsi_91x_hal.c b/ubuntu/rsi/rsi_91x_hal.c
> index 45f83e9..9181b54 100644
> --- a/ubuntu/rsi/rsi_91x_hal.c
> +++ b/ubuntu/rsi/rsi_91x_hal.c
> @@ -160,11 +160,27 @@ int rsi_prepare_data_desc(struct rsi_common *common,
> struct sk_buff *skb)
>  
>  	if (skb->protocol == cpu_to_be16(ETH_P_PAE)) {
>  		ven_rsi_dbg(INFO_ZONE, "*** Tx EAPOL ***\n");
> +		
> +		frame_desc[3] = cpu_to_le16(RATE_INFO_ENABLE);
> +		if (common->band == NL80211_BAND_5GHZ)
> +				frame_desc[4] = cpu_to_le16(RSI_RATE_6);
> +			else
> +				frame_desc[4] = cpu_to_le16(RSI_RATE_1);
>  		frame_desc[6] |= cpu_to_le16(BIT(13));
>  		frame_desc[1] |= cpu_to_le16(BIT(12));
> +		if (vif->type == NL80211_IFTYPE_STATION) {
> +			frame_desc[0] = cpu_to_le16((skb->len -
> FRAME_DESC_SZ) |
> +					(RSI_WIFI_MGMT_Q << 12));
> +			if ((skb->len - header_size) == 133) {
> +				ven_rsi_dbg(INFO_ZONE, "*** Tx EAPOL
> 4*****\n");
> +				frame_desc[1] |=
> +					cpu_to_le16(RSI_DESC_REQUIRE_CFM_TO_H
> OST);
> +				xtend_desc->confirm_frame_type =
> EAPOL4_CONFIRM;
> +			}
> +		}
>  #define EAPOL_RETRY_CNT 15
>  		xtend_desc->retry_cnt = EAPOL_RETRY_CNT;
> -#ifdef EAPOL_IN_MGMT_Q
> +#if 0 
>  		skb->priority = VO_Q;
>  #endif
>  	}
> @@ -178,14 +194,12 @@ int rsi_prepare_data_desc(struct rsi_common *common,
> struct sk_buff *skb)
>  	    (is_multicast_ether_addr(wh->addr1))) {
>  		frame_desc[3] = cpu_to_le16(RATE_INFO_ENABLE);
>  		frame_desc[3] |= cpu_to_le16(RSI_BROADCAST_PKT);
> -#if 0
> -		if (common->min_rate == 0xffff) {
> +		if (vif->type == NL80211_IFTYPE_AP) {
>  			if (common->band == NL80211_BAND_5GHZ)
>  				frame_desc[4] = cpu_to_le16(RSI_RATE_6);
>  			else
>  				frame_desc[4] = cpu_to_le16(RSI_RATE_1);
>  		}
> -#endif
>  	}
>  
>  	if ((vif->type == NL80211_IFTYPE_AP) &&
> @@ -196,7 +210,7 @@ int rsi_prepare_data_desc(struct rsi_common *common,
> struct sk_buff *skb)
>  
>  err:
>  	++common->tx_stats.total_tx_pkt_freed[skb->priority];
> -	rsi_indicate_tx_status(common->priv, skb, status);
> +	rsi_indicate_tx_status(adapter, skb, status);
>  	return status;
>  }
>  
> @@ -323,6 +337,8 @@ int rsi_send_data_pkt(struct rsi_common *common, struct
> sk_buff *skb)
>  	u8 header_size = 0;
>  
>  	info = IEEE80211_SKB_CB(skb);
> +	if (!info->control.vif)
> +		goto err;
>  	bss = &info->control.vif->bss_conf;
>  	tx_params = (struct skb_info *)info->driver_data;
>  
> @@ -381,7 +397,6 @@ int rsi_send_mgmt_pkt(struct rsi_common *common, struct
> sk_buff *skb)
>  			     skb->data, skb->len);
>  
>  		status = rsi_send_pkt(common, skb);
> -
>  		if (status) {
>  			ven_rsi_dbg(ERR_ZONE,
>  				"%s: Failed to write the packet\n",
> @@ -391,6 +406,8 @@ int rsi_send_mgmt_pkt(struct rsi_common *common, struct
> sk_buff *skb)
>  		return status;
>  	}
>  
> +	if (!info->control.vif)
> +		goto out;
>  	bss = &info->control.vif->bss_conf;
>  	wh = (struct ieee80211_hdr *)&skb->data[header_size];
>  
> @@ -398,23 +415,24 @@ int rsi_send_mgmt_pkt(struct rsi_common *common, struct
> sk_buff *skb)
>  	xtend_desc = (struct xtended_desc *)&skb->data[FRAME_DESC_SZ];
>  
>  	/* Indicate to firmware to give cfm */
> -	if (ieee80211_is_probe_req(wh->frame_control)) { // && (!bss->assoc)) 
> {
> +	if (ieee80211_is_probe_req(wh->frame_control)) {
>  		if (!bss->assoc) {
> -			ven_rsi_dbg(INFO_ZONE, "%s: blocking mgmt queue\n",
> __func__);
> +			ven_rsi_dbg(INFO_ZONE,
> +				"%s: blocking mgmt queue\n", __func__);
>  			desc[1] |= cpu_to_le16(RSI_DESC_REQUIRE_CFM_TO_HOST);
>  			xtend_desc->confirm_frame_type = PROBEREQ_CONFIRM;
>  			common->mgmt_q_block = true;
>  			ven_rsi_dbg(INFO_ZONE, "Mgmt queue blocked\n");
>  		} else if (common->bgscan_en) {
> -			/* Drop off channel probe request */
>  			if (common->mac80211_cur_channel !=
>  			    rsi_get_connected_channel(adapter)) { 
> -				dev_kfree_skb(skb);
> -				return 0;
> +				/* Drop off channel probe request */
> +				status = 0;
> +				goto out;
>  			} else if (wh->addr1[0] == 0xff) {
>  				/* Drop broadcast probe in connected
> channel*/
> -				dev_kfree_skb(skb);
> -				return 0;
> +				status = 0;
> +				goto out;
>  			}
>  		}
>  		ven_rsi_dbg(MGMT_TX_ZONE, "Sending PROBE REQUEST =====>\n");
> @@ -433,6 +451,7 @@ int rsi_send_mgmt_pkt(struct rsi_common *common, struct
> sk_buff *skb)
>  			__func__);
>  	}
>  
> +out:
>  	rsi_indicate_tx_status(common->priv, skb, status);
>  	return status;
>  }
> @@ -472,7 +491,6 @@ err:
>  
>  int rsi_send_beacon(struct rsi_common *common)
>  {
> -	struct rsi_hw *adapter = common->priv;
>  	struct rsi_mac_frame *bcn_frm = NULL;
>  	u16 bcn_len = common->beacon_frame_len;
>  	struct sk_buff *skb = NULL;
> @@ -481,16 +499,18 @@ int rsi_send_beacon(struct rsi_common *common)
>  	u8 vap_id = 0;
>  	u8 dword_align_bytes = 0;
>  	u8 header_size = 0;
> +	int status = 0;
>  
> -	skb = dev_alloc_skb(FRAME_DESC_SZ + bcn_len + 64);
> +	skb = dev_alloc_skb(MAX_MGMT_PKT_SIZE);
>  	if (!skb)
>  		return -ENOMEM;
>  
>  	dword_align_bytes = ((unsigned long)skb->data & 0x3f);
> -	printk("%s: dword_bytes = %d\n", __func__, dword_align_bytes);
> -	header_size = dword_align_bytes + FRAME_DESC_SZ;
> -	printk("header_size = %d\n", header_size);
> -	memset(skb->data, 0, header_size + bcn_len + 64);
> +	if (dword_align_bytes) {
> +		skb_pull(skb, (64 - dword_align_bytes));
> +	}
> +	header_size = FRAME_DESC_SZ;
> +	memset(skb->data, 0, MAX_MGMT_PKT_SIZE);
>  
>  	common->beacon_cnt++;
>  	bcn_frm = (struct rsi_mac_frame *)skb->data;
> @@ -504,7 +524,7 @@ int rsi_send_beacon(struct rsi_common *common)
>  	bcn_frm->desc_word[3] |= cpu_to_le16(RATE_INFO_ENABLE);
>  	bcn_frm->desc_word[4] = cpu_to_le16(vap_id << 14);
>  	bcn_frm->desc_word[7] = cpu_to_le16(BEACON_HW_Q);
> -
> +	
>  	if (conf_is_ht40_plus(conf)) {
>  		bcn_frm->desc_word[5] = cpu_to_le16(LOWER_20_ENABLE);
>  		bcn_frm->desc_word[5] |= cpu_to_le16(LOWER_20_ENABLE >> 12);
> @@ -514,29 +534,31 @@ int rsi_send_beacon(struct rsi_common *common)
>  	}
>  
>  	if (common->band == NL80211_BAND_2GHZ)
> -		bcn_frm->desc_word[4] |= cpu_to_le16(0xB | RSI_11G_MODE);
> +		bcn_frm->desc_word[4] |= cpu_to_le16(RSI_RATE_1);
>  	else
> -		bcn_frm->desc_word[4] |= cpu_to_le16(RSI_11B_MODE);
> +		bcn_frm->desc_word[4] |= cpu_to_le16(RSI_RATE_6);
>  
>  	//if (!(common->beacon_cnt % common->dtim_cnt))
>  	if (1) //FIXME check this
>  		bcn_frm->desc_word[3] |= cpu_to_le16(DTIM_BEACON);
>  
> +	//mutex_lock(&common->mutex);
>  	memcpy(&skb->data[header_size], common->beacon_frame, bcn_len);
> +	//mutex_unlock(&common->mutex);
>  
>  	skb_put(skb, bcn_len + header_size);
>  
> -	rsi_hex_dump(MGMT_TX_ZONE, "Beacon Frame", skb->data, skb->len);
> +	rsi_hex_dump(MGMT_TX_ZONE, "Beacon Frame", skb->data, skb->len);	
>  
> -	if (adapter->host_intf_ops->write_pkt(adapter, skb->data, skb->len) <
> 0) {
> +	mutex_lock(&common->tx_lock);
> +	if (rsi_send_pkt(common, skb)) {
>  		ven_rsi_dbg(ERR_ZONE, "Failed to send Beacon\n");
> -		goto err;
> +		status = -EINVAL;
>  	}
> -	return 0;
> +	mutex_unlock(&common->tx_lock);
>  
> -err:
>  	dev_kfree_skb(skb);
> -	return -1;
> +	return status;
>  }
>  
>  /**
> diff --git a/ubuntu/rsi/rsi_91x_hci.c b/ubuntu/rsi/rsi_91x_hci.c
> index 773e216..4442651 100644
> --- a/ubuntu/rsi/rsi_91x_hci.c
> +++ b/ubuntu/rsi/rsi_91x_hci.c
> @@ -198,21 +198,6 @@ fail:
>  	return status;
>  }
>  
> -void rsi_hci_scheduler_thread(struct rsi_common *common)
> -{
> -	struct rsi_hw *adapter = common->priv;
> -	int status = 0;
> -
> -	do {
> -		status = adapter->check_intr_status_reg(adapter);
> -		if (adapter->isr_pending)
> -			adapter->isr_pending = 0;
> -		msleep(20);
> -
> -	} while (atomic_read(&common->hci_thread.thread_done) == 0);
> -	complete_and_exit(&common->hci_thread.completion, 0);
> -}
> -
>  int rsi_hci_recv_pkt(struct rsi_common *common, u8 *pkt)
>  {
>  	struct rsi_hci_adapter *h_adapter =
> @@ -234,34 +219,9 @@ int rsi_hci_recv_pkt(struct rsi_common *common, u8 *pkt)
>  			return 0;
>  		}
>  
> -		/* TODO: Work aroud for Dell; move this to module_param */
> -#if (defined(CONFIG_DELL_BOARD) &&  defined(CONFIG_VEN_RSI_HCI))
> -		if (rsi_set_antenna(common, ANTENNA_SEL_UFL)) {
> -			ven_rsi_dbg(ERR_ZONE,
> -				"%s: Failed to configure external antenna\n",
> -				__func__);
> -		} else
> -			ven_rsi_dbg(INFO_ZONE, "***** UFL antenna is
> configured\n");
> -
> -#endif
> -
> -#if (defined(CONFIG_VEN_RSI_HCI) || defined(CONFIG_VEN_RSI_COEX))
> -#if defined(CONFIG_DELL_BOARD)
> -	if (common->priv->rsi_host_intf == RSI_HOST_INTF_SDIO) {
> -		rsi_init_event(&common->hci_thread.event);
> -		if (rsi_create_kthread(common,
> -					&common->hci_thread,
> -					rsi_hci_scheduler_thread,
> -					"hci-Thread")) {
> -			ven_rsi_dbg(ERR_ZONE, "%s: Unable to init hci
> thrd\n",
> -				__func__);
> -		}
> -	}
> -#endif
> -#endif
>  		return 0;
>  	}
> -
>>  	if (common->bt_fsm_state != BT_DEVICE_READY) {
>  		ven_rsi_dbg(INFO_ZONE, "BT Device not ready\n");
>  		return 0;
> @@ -504,6 +464,7 @@ err:
>  #if LINUX_VERSION_CODE <= KERNEL_VERSION(3, 12, 34)
>  		genl_unregister_ops(gcb->gc_family, gcb->gc_ops);
>  #endif
> +		kfree(gcb);
>  	}
>  	h_adapter->gcb = NULL;
>  	kfree(h_adapter);
> @@ -547,6 +508,7 @@ void rsi_hci_detach(struct rsi_common *common)
>  		genl_unregister_ops(gcb->gc_family, gcb->gc_ops);
>  #endif
>  		h_adapter->gcb = NULL;
> +		kfree(gcb);
>  	}
>  	kfree(h_adapter);
>  
> diff --git a/ubuntu/rsi/rsi_91x_mac80211.c b/ubuntu/rsi/rsi_91x_mac80211.c
> index 1d18b10..8cf3a47 100644
> --- a/ubuntu/rsi/rsi_91x_mac80211.c
> +++ b/ubuntu/rsi/rsi_91x_mac80211.c
> @@ -419,10 +419,10 @@ static int rsi_mac80211_add_interface(struct
> ieee80211_hw *hw,
>  
>  	mutex_lock(&common->mutex);
>  
> -	/* Not supporting concurrent mode now */
> +	/* Not supporting concurrent mode now */	
>  	if (adapter->sc_nvifs > 0)
>  		return -1;
> -
> +	
>  	adapter->vifs[adapter->sc_nvifs++] = vif;
>  
>  	switch (vif->type) {
> @@ -442,9 +442,15 @@ static int rsi_mac80211_add_interface(struct ieee80211_hw
> *hw,
>  	}
>  
>  	if (vif->type == NL80211_IFTYPE_AP) {
> +		int i;
> +
>  		common->bc_mc_seqno = 1;
>  		rsi_send_rx_filter_frame(common, DISALLOW_BEACONS);
> -		rsi_set_min_rate(hw, NULL, common);
> +		common->min_rate = 0xffff;
> +		//common->bitrate_mask[NL80211_BAND_2GHZ] = 0xfff;
> +		//common->bitrate_mask[NL80211_BAND_5GHZ] = 0xfff;
> +		for (i = 0; i < RSI_MAX_ASSOC_STAS; i++)
> +			common->stations[i].sta = NULL;
>  	}
>  
>  	mutex_unlock(&common->mutex);
> @@ -762,7 +768,7 @@ static void rsi_mac80211_bss_info_changed(struct
> ieee80211_hw *hw,
>  					  ALLOW_CTRL_ASSOC_PEER |
>  					  ALLOW_MGMT_ASSOC_PEER |
>  #ifdef RSI_HW_CONN_MONITOR
> -					  DISALLOW_BEACONS |
> +					  //DISALLOW_BEACONS |
>  #endif
>  					0);
>  			rsi_send_rx_filter_frame(common, rx_filter_word);
> @@ -778,7 +784,7 @@ static void rsi_mac80211_bss_info_changed(struct
> ieee80211_hw *hw,
>  		/* Send peer notify to device */
>  		ven_rsi_dbg(INFO_ZONE, "Indicate bss status to device\n");
>  		rsi_inform_bss_status(common, STA_OPMODE, bss->assoc,
> -				      bss->bssid, bss->qos, bss->aid, 0);
> +				      bss->bssid, bss->qos, bss->aid, NULL,
> 0);
>  
>  		adapter->ps_info.listen_interval =
>  			bss->beacon_int * adapter-
> >ps_info.num_bcns_per_lis_int;
> @@ -810,6 +816,7 @@ static void rsi_mac80211_bss_info_changed(struct
> ieee80211_hw *hw,
>  	if (changed & BSS_CHANGED_BEACON_INT) {
>  		ven_rsi_dbg(INFO_ZONE, "%s: Changed Beacon interval: %d\n",
>  			__func__, bss_conf->beacon_int);
> +		common->beacon_interval = bss->beacon_int; 
>  		adapter->ps_info.listen_interval =
>  			bss->beacon_int * adapter-
> >ps_info.num_bcns_per_lis_int;
>  	}
> @@ -822,10 +829,19 @@ static void rsi_mac80211_bss_info_changed(struct
> ieee80211_hw *hw,
>  
>  	if ((changed & BSS_CHANGED_BEACON_ENABLED) &&
>  	    (vif->type == NL80211_IFTYPE_AP)) {
> -		if (bss->enable_beacon)
> +		if (bss->enable_beacon) {
>  			ven_rsi_dbg(INFO_ZONE, "===> BEACON ENABLED <===\n");
> -		else
> +			common->beacon_enabled = 1;
> +#ifdef CONFIG_CARACALLA_BOARD
> +			rsi_init_bcn_timer(common);
> +#endif
> +		} else {
>  			ven_rsi_dbg(INFO_ZONE, "===> BEACON DISABLED
> <===\n");
> +			common->beacon_enabled = 0;
> +#ifdef CONFIG_CARACALLA_BOARD
> +			rsi_del_bcn_timer(common);
> +#endif
> +		}
>  	}
>  
>  	mutex_unlock(&common->mutex);
> @@ -1073,6 +1089,7 @@ static int rsi_mac80211_ampdu_action(struct ieee80211_hw
> *hw,
>  	struct rsi_common *common = adapter->priv;
>  	u16 seq_no = 0;
>  	u8 ii = 0;
> +	u8 sta_id = 0;
>  
>  #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0))
>  	u16 tid = params->tid;
> @@ -1094,6 +1111,15 @@ static int rsi_mac80211_ampdu_action(struct
> ieee80211_hw *hw,
>  #else
>  	seq_no = params->ssn;
>  #endif
> +	if (vif->type == NL80211_IFTYPE_AP) {
> +		struct rsi_sta *rsta = rsi_find_sta(common, sta->addr);
> +
> +		if (!rsta) {
> +			ven_rsi_dbg(ERR_ZONE, "No station mapped\n");
> +			return 0;
> +		}
> +		sta_id = rsta->sta_id;
> +	}
>  
>  	ven_rsi_dbg(INFO_ZONE,
>  		"%s: AMPDU action tid=%d ssn=0x%x, buf_size=%d\n",
> @@ -1106,7 +1132,8 @@ static int rsi_mac80211_ampdu_action(struct ieee80211_hw
> *hw,
>  						    tid,
>  						    seq_no,
>  						    buf_size,
> -						    STA_RX_ADDBA_DONE);
> +						    STA_RX_ADDBA_DONE,
> +						    sta_id);
>  		break;
>  
>  	case IEEE80211_AMPDU_RX_STOP:
> @@ -1116,7 +1143,8 @@ static int rsi_mac80211_ampdu_action(struct ieee80211_hw
> *hw,
>  						    tid,
>  						    0,
>  						    buf_size,
> -						    STA_RX_DELBA);
> +						    STA_RX_DELBA,
> +						    sta_id);
>  		break;
>  
>  	case IEEE80211_AMPDU_TX_START:
> @@ -1137,7 +1165,8 @@ static int rsi_mac80211_ampdu_action(struct ieee80211_hw
> *hw,
>  						    tid,
>  						    seq_no,
>  						    buf_size,
> -						    STA_TX_DELBA);
> +						    STA_TX_DELBA,
> +						    sta_id);
>  		if (!status)
>  			ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
>  		break;
> @@ -1150,7 +1179,8 @@ static int rsi_mac80211_ampdu_action(struct ieee80211_hw
> *hw,
>  						tid,
>  						common-
> >vif_info[ii].seq_start,
>  						buf_size,
> -						STA_TX_ADDBA_DONE);
> +						STA_TX_ADDBA_DONE,
> +						sta_id);
>  		break;
>  
>  	default:
> @@ -1332,6 +1362,8 @@ void rsi_indicate_pkt_to_os(struct rsi_common *common,
>  	/* filling in the ieee80211_rx_status flags */
>  	rsi_fill_rx_status(hw, skb, common, rx_status);
>  
> +	ven_rsi_dbg(INFO_ZONE, "RX Packet Type: %s\n",
> +		dot11_pkt_type(skb->data[0]));
>  	rsi_hex_dump(DATA_RX_ZONE, "802.11 RX packet", skb->data, skb->len);
>  	ieee80211_rx_irqsafe(hw, skb);
>  }
> @@ -1359,10 +1391,22 @@ static int rsi_mac80211_sta_add(struct ieee80211_hw
> *hw,
>  
>  	if (vif->type == NL80211_IFTYPE_AP) {
>  		u8 i, j;
> +		int free_index = -1;
> +
> +		/* Check if max stations reached */
> +		if (common->num_stations >= RSI_MAX_ASSOC_STAS) {
> +			ven_rsi_dbg(ERR_ZONE, "Reject: Max Stations
> exists\n");
> +			return -EINVAL;
> +		}
>  
>  		/* Send peer notify to device */
>  		ven_rsi_dbg(INFO_ZONE, "Indicate bss status to device\n");
> -		for (i = 0; i < common->num_stations; i++) {
> +		for (i = 0; i < RSI_MAX_ASSOC_STAS; i++) {
> +			if (!common->stations[i].sta) {
> +				if (free_index < 0)
> +					free_index = i;
> +				continue; 
> +			}
>  			if (!memcmp(common->stations[i].sta->addr,
>  				    sta->addr, ETH_ALEN)) {
>  				ven_rsi_dbg(INFO_ZONE, "Station exists\n");
> @@ -1372,15 +1416,18 @@ static int rsi_mac80211_sta_add(struct ieee80211_hw
> *hw,
>  		}
>  		if (!sta_exist) {
>  			ven_rsi_dbg(INFO_ZONE, "New Station\n");
> -			rsi_inform_bss_status(common, AP_OPMODE, 1, sta-
> >addr,
> -					      sta->wme, sta->aid, i);
> +			if (free_index >= 0)
> +				i = free_index;
>  			common->stations[i].sta = sta;
>  			common->stations[i].sta_id = i;
> +			rsi_inform_bss_status(common, AP_OPMODE, 1, sta-
> >addr,
> +					      sta->wme, sta->aid, sta, i);
>  			for (j = 0; j < IEEE80211_NUM_ACS; j++)
>  				common->stations[i].seq_no[j] = 1;
>  			common->num_stations++;
>  		} else {
>  			common->stations[i].sta = sta;
> +			common->stations[i].sta_id = i;
>  			for (j = 0; j < IEEE80211_NUM_ACS; j++)
>  				common->stations[i].seq_no[j] = 1;
>  		}
> @@ -1403,8 +1450,11 @@ static int rsi_mac80211_sta_add(struct ieee80211_hw
> *hw,
>  		}
>  	}
>  
> +#if 0
>  	if ((vif->type == NL80211_IFTYPE_STATION) &&
>  	    sta->ht_cap.ht_supported)
> +#endif
> +	if (sta->ht_cap.ht_supported)
>  		ieee80211_start_tx_ba_session(sta, 0, 0);
>  
>  	mutex_unlock(&common->mutex);
> @@ -1431,22 +1481,27 @@ static int rsi_mac80211_sta_remove(struct ieee80211_hw
> *hw,
>  
>  	rsi_hex_dump(INFO_ZONE, "Station Removed: ", sta->addr, ETH_ALEN);
>  
> +	mutex_lock(&common->mutex);
>  	if (vif->type == NL80211_IFTYPE_AP) {
>  		u8 i, j;
>  
>  		/* Send peer notify to device */
>  		ven_rsi_dbg(INFO_ZONE, "Indicate bss status to device\n");
> -		for (i = 0; i < common->num_stations; i++) {
> +		for (i = 0; i < RSI_MAX_ASSOC_STAS; i++) {
> +			if (!common->stations[i].sta)
> +				continue;
>  			if (!memcmp(common->stations[i].sta->addr,
>  				    sta->addr, ETH_ALEN)) {
>  				rsi_inform_bss_status(common, AP_OPMODE, 0,
>  						      sta->addr, sta->wme,
> -						      sta->aid, i);
> +						      sta->aid, sta, i);
>  				common->stations[i].sta = NULL;
>  				common->stations[i].sta_id = -1;
>  				for (j = 0; j < IEEE80211_NUM_ACS; j++)
>  					common->stations[i].seq_no[j] = 0;
>  				common->num_stations--;
> +				if (common->num_stations < 0)
> +					common->num_stations = 0;
>  				break;
>  			}
>  		}
> @@ -1456,7 +1511,6 @@ static int rsi_mac80211_sta_remove(struct ieee80211_hw
> *hw,
>  
>  	if (vif->type == NL80211_IFTYPE_STATION) {
>  		/* Resetting all the fields to default values */
> -		mutex_lock(&common->mutex);
>  		memcpy((u8 *)bss->bssid, (u8 *)sta->addr, ETH_ALEN);
>  		bss->qos = sta->wme;
>  		common->bitrate_mask[NL80211_BAND_2GHZ] = 0;
> @@ -1469,11 +1523,11 @@ static int rsi_mac80211_sta_remove(struct ieee80211_hw
> *hw,
>  		common->secinfo.gtk_cipher = 0;
>  		if (common->bgscan_en)
>  			common->bgscan_en = 0;
> -		mutex_unlock(&common->mutex);
>  
>  		if (!common->iface_down)
>  			rsi_send_rx_filter_frame(common, 0);
>  	}
> +	mutex_unlock(&common->mutex);
>  	return 0;
>  }
>  #if 0
> @@ -1655,7 +1709,7 @@ static void rsi_reg_notify(struct wiphy *wiphy,
>  			common->bgscan_en = 1;
>  		}
>  	}
> -
> +	
>  	adapter->dfs_region = request->dfs_region;
>  	adapter->country[0] = request->alpha2[0];
>  	adapter->country[1] = request->alpha2[1];
> @@ -1679,13 +1733,13 @@ void rsi_mac80211_rfkill_poll(struct ieee80211_hw *hw)
>  
>  #ifdef CONFIG_RSI_WOW
>  static const struct wiphy_wowlan_support rsi_wowlan_support = {
> -	.flags =WIPHY_WOWLAN_ANY |
> -		WIPHY_WOWLAN_MAGIC_PKT |
> -		WIPHY_WOWLAN_DISCONNECT |
> -		WIPHY_WOWLAN_GTK_REKEY_FAILURE  |
> -		WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
> -		WIPHY_WOWLAN_EAP_IDENTITY_REQ   |
> -		WIPHY_WOWLAN_4WAY_HANDSHAKE,
> +	.flags = WIPHY_WOWLAN_ANY |
> +		 WIPHY_WOWLAN_MAGIC_PKT |
> +		 WIPHY_WOWLAN_DISCONNECT |
> +		 WIPHY_WOWLAN_GTK_REKEY_FAILURE  |
> +		 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
> +		 WIPHY_WOWLAN_EAP_IDENTITY_REQ   |
> +		 WIPHY_WOWLAN_4WAY_HANDSHAKE,
>  	.n_patterns = 0,
>  	.pattern_min_len = 1,
>  	.pattern_max_len = 0,
> @@ -1707,7 +1761,7 @@ static u16 rsi_wow_map_triggers(struct rsi_common
> *common,
>  	if (wowlan->gtk_rekey_failure || wowlan->eap_identity_req ||
>  	    wowlan->four_way_handshake)
>  		wow_triggers |= RSI_WOW_SUPPORTS_GTK_REKEY;
> -
> +	
>  	return wow_triggers;
>  }
>  #endif
> @@ -1719,7 +1773,7 @@ int rsi_mac80211_suspend(struct ieee80211_hw *hw,
>  #ifdef CONFIG_RSI_WOW
>  	struct rsi_hw *adapter = hw->priv;
>  	struct rsi_common *common = adapter->priv;
> -	u16 triggers;
> +	u16 triggers, rx_filter_word = 0;
>  #endif
>  	int ret = 0;
>  
> @@ -1736,22 +1790,45 @@ int rsi_mac80211_suspend(struct ieee80211_hw *hw,
>  	triggers = rsi_wow_map_triggers(common, wowlan);
>  	if (!triggers) {
>  		ven_rsi_dbg(ERR_ZONE, "%s:No valid WoW triggers\n",__func__);
> -		ret = 1;
> +		ret = -EINVAL;
>  		goto fail_wow;
>  	}
>  	ven_rsi_dbg(INFO_ZONE, "TRIGGERS %x\n", triggers);
>  
> -	 rsi_send_wowlan_request(common, triggers, wowlan);
> +	rsi_send_wowlan_request(common, triggers, 1);
>  
> + 	 rx_filter_word = (ALLOW_DATA_ASSOC_PEER |
> +			   ALLOW_CTRL_ASSOC_PEER |
> +			   ALLOW_MGMT_ASSOC_PEER |
> +			   DISALLOW_BEACONS |
> +			   0);
> +	rsi_send_rx_filter_frame(common, rx_filter_word);
> +        common->suspend_flag = 1;
>  fail_wow:
>  #endif
> -	return ret;
> +        return ret;
>  }
>  
>  static int rsi_mac80211_resume(struct ieee80211_hw *hw)
>  {
> +#ifdef CONFIG_RSI_WOW
> +	struct rsi_hw *adapter = hw->priv;
> +	struct rsi_common *common = adapter->priv;
> +	u16 rx_filter_word = 0;
> +#endif
> +	
>  	ven_rsi_dbg(INFO_ZONE, "%s: mac80211 resume\n", __func__);
>  
> +#ifdef CONFIG_RSI_WOW
> +	rsi_send_wowlan_request(common, 0, 0);
> +	//rx_filter_word = 0xE ;
> +
> +	rx_filter_word = (ALLOW_DATA_ASSOC_PEER |
> +			  ALLOW_CTRL_ASSOC_PEER |
> +			  ALLOW_MGMT_ASSOC_PEER |
> +			  0);
> +	rsi_send_rx_filter_frame(common, rx_filter_word);
> +#endif
>  	return 0;
>  }
>  #endif
> @@ -1774,8 +1851,8 @@ static struct ieee80211_ops mac80211_ops = {
>  	.sta_remove = rsi_mac80211_sta_remove,
>  	.set_antenna = rsi_mac80211_set_antenna,
>  	.get_antenna = rsi_mac80211_get_antenna,
> -	.rfkill_poll = rsi_mac80211_rfkill_poll,
> -#ifdef CONFIG_PM
> +        .rfkill_poll = rsi_mac80211_rfkill_poll,
> +#ifdef CONFIG_PM 
>  	.suspend = rsi_mac80211_suspend,
>  	.resume  = rsi_mac80211_resume,
>  #endif
> @@ -1842,7 +1919,8 @@ int rsi_mac80211_attach(struct rsi_common *common)
>  	hw->max_rate_tries = MAX_RETRIES;
>  	hw->uapsd_queues = IEEE80211_MARKALL_UAPSD_QUEUES;
>  	hw->uapsd_max_sp_len = IEEE80211_STA_SP_ALL_PKTS;
> -	hw->max_tx_aggregation_subframes = 6;
> +//	hw->max_tx_aggregation_subframes = 6;
> +	hw->max_tx_aggregation_subframes = 4;
>  
>  	rsi_register_rates_channels(adapter, NL80211_BAND_2GHZ);
>  	rsi_register_rates_channels(adapter, NL80211_BAND_5GHZ);
> diff --git a/ubuntu/rsi/rsi_91x_main.c b/ubuntu/rsi/rsi_91x_main.c
> index 006dbd9..1c7a374 100644
> --- a/ubuntu/rsi/rsi_91x_main.c
> +++ b/ubuntu/rsi/rsi_91x_main.c
> @@ -226,6 +226,54 @@ fail:
>  }
>  EXPORT_SYMBOL_GPL(ven_rsi_read_pkt);
>  
> +#ifdef CONFIG_CARACALLA_BOARD
> +static void rsi_bcn_sched(unsigned long data)
> +{
> +	struct rsi_common *common = (struct rsi_common *)data;
> +
> +	rsi_set_event(&common->bcn_thread.event);
> +
> +	common->bcn_timer.expires =
> +		msecs_to_jiffies(common->beacon_interval) + jiffies;
> +	add_timer(&common->bcn_timer);
> +}
> +
> +void rsi_init_bcn_timer(struct rsi_common *common)
> +{
> +	init_timer(&common->bcn_timer);
> +
> +	common->bcn_timer.data = (unsigned long)common;
> +	common->bcn_timer.expires =
> +		msecs_to_jiffies(common->beacon_interval + 10) + jiffies;
> +	common->bcn_timer.function = (void *)rsi_bcn_sched;
> +
> +	add_timer(&common->bcn_timer);
> +}
> +
> +void rsi_del_bcn_timer(struct rsi_common *common)
> +{
> +	del_timer(&common->bcn_timer);
> +}
> +
> +void rsi_bcn_scheduler_thread(struct rsi_common *common)
> +{
> +	do {
> +		rsi_wait_event(&common->bcn_thread.event,
> +			       msecs_to_jiffies(common->beacon_interval));
> +		rsi_reset_event(&common->bcn_thread.event);
> +
> +		if (!common->beacon_enabled)
> +			continue;
> +		if (!common->init_done)
> +			continue;
> +		if (common->iface_down)
> +			continue;
> +		rsi_send_beacon(common);
> +	} while (atomic_read(&common->bcn_thread.thread_done) == 0);
> +	complete_and_exit(&common->bcn_thread.completion, 0);
> +}
> +#endif
> +
>  /**
>   * rsi_tx_scheduler_thread() - This function is a kernel thread to send the
>   *			       packets to the device.
> @@ -250,6 +298,38 @@ static void rsi_tx_scheduler_thread(struct rsi_common
> *common)
>  	complete_and_exit(&common->tx_thread.completion, 0);
>  }
>  
> +#ifdef CONFIG_SDIO_INTR_POLL
> +void rsi_sdio_intr_poll_scheduler_thread(struct rsi_common *common)
> +{
> +        struct rsi_hw *adapter = common->priv;
> +        int status = 0;
> +
> +        do {
> +                status = adapter->check_intr_status_reg(adapter);
> +                if (adapter->isr_pending)
> +                        adapter->isr_pending = 0;
> +                msleep(20);
> +
> +        } while (atomic_read(&common->sdio_intr_poll_thread.thread_done) ==
> 0);
> +        complete_and_exit(&common->sdio_intr_poll_thread.completion, 0);
> +}
> +
> +void init_sdio_intr_status_poll_thread(struct rsi_common *common)
> +{
> +	if (common->priv->rsi_host_intf == RSI_HOST_INTF_SDIO) {
> +		rsi_init_event(&common->sdio_intr_poll_thread.event);
> +		if (rsi_create_kthread(common,
> +					&common->sdio_intr_poll_thread,
> +					rsi_sdio_intr_poll_scheduler_thread,
> +					"Sdio Intr poll-Thread")) {
> +			ven_rsi_dbg(ERR_ZONE, "%s: Unable to init sdio intr
> poll thrd\n",
> +					__func__);
> +		}
> +	}
> +}
> +EXPORT_SYMBOL_GPL(init_sdio_intr_status_poll_thread);
> +#endif
> +
>  /**
>   * ven_rsi_91x_init() - This function initializes os interface operations.
>   * @void: Void.
> @@ -285,6 +365,7 @@ struct rsi_hw *ven_rsi_91x_init(void)
>  		skb_queue_head_init(&common->tx_queue[ii]);
>  
>  	rsi_init_event(&common->tx_thread.event);
> +	rsi_init_event(&common->bcn_thread.event);
>  	mutex_init(&common->mutex);
>  	mutex_init(&common->tx_lock);
>  	mutex_init(&common->rx_lock);
> @@ -297,6 +378,16 @@ struct rsi_hw *ven_rsi_91x_init(void)
>  		goto err;
>  	}
>  
> +#ifdef CONFIG_CARACALLA_BOARD
> +	if (rsi_create_kthread(common,
> +			       &common->bcn_thread,
> +			       rsi_bcn_scheduler_thread,
> +			       "Beacon-Thread")) {
> +		ven_rsi_dbg(ERR_ZONE, "%s: Unable to init bcn thrd\n",
> __func__);
> +		goto err;
> +	}
> +#endif
> +
>  #ifdef CONFIG_VEN_RSI_COEX
>  	if (rsi_coex_init(common)) {
>  		ven_rsi_dbg(ERR_ZONE, "Failed to init COEX module\n");
> @@ -332,6 +423,9 @@ void ven_rsi_91x_deinit(struct rsi_hw *adapter)
>  	ven_rsi_dbg(INFO_ZONE, "%s: Deinit core module...\n", __func__);
>  
>  	rsi_kill_thread(&common->tx_thread);
> +#ifdef CONFIG_CARACALLA_BOARD
> +	rsi_kill_thread(&common->bcn_thread);
> +#endif
>  
>  	for (ii = 0; ii < NUM_SOFT_QUEUES; ii++)
>  		skb_queue_purge(&common->tx_queue[ii]);
> @@ -341,6 +435,8 @@ void ven_rsi_91x_deinit(struct rsi_hw *adapter)
>  #endif
>  	common->init_done = false;
>  
> +	kfree(common->beacon_frame);
> +	common->beacon_frame = NULL;
>  	kfree(common);
>  	kfree(adapter->rsi_dev);
>  	kfree(adapter);
> diff --git a/ubuntu/rsi/rsi_91x_mgmt.c b/ubuntu/rsi/rsi_91x_mgmt.c
> index 3329204..ca6151e 100644
> --- a/ubuntu/rsi/rsi_91x_mgmt.c
> +++ b/ubuntu/rsi/rsi_91x_mgmt.c
> @@ -341,6 +341,7 @@ static void rsi_set_default_parameters(struct rsi_common
> *common)
>  	common->antenna_diversity = 0;
>  	common->tx_power = RSI_TXPOWER_MAX;
>  	common->dtim_cnt = 2;
> +	common->beacon_interval = 100;
>  }
>  
>  void init_bgscan_params(struct rsi_common *common)
> @@ -685,7 +686,8 @@ int rsi_send_aggr_params_frame(struct rsi_common *common,
>  			       u16 tid,
>  			       u16 ssn,
>  			       u8 buf_size,
> -			       u8 event)
> +			       u8 event,
> +			       u8 sta_id)
>  {
>  	struct sk_buff *skb = NULL;
>  	struct rsi_mac_frame *mgmt_frame;
> @@ -868,7 +870,7 @@ int rsi_set_vap_capabilities(struct rsi_common *common,
>  #endif
>  
>  	vap_caps->default_data_rate = 0;
> -	vap_caps->beacon_interval = cpu_to_le16(200);
> +	vap_caps->beacon_interval = cpu_to_le16(common->beacon_interval);
>  	vap_caps->dtim_period = cpu_to_le16(common->dtim_cnt);
>  //	vap_caps->beacon_miss_threshold = cpu_to_le16(10);
>  	if (mode == AP_OPMODE)
> @@ -972,22 +974,18 @@ int rsi_load_key(struct rsi_common *common,
>  	set_key->desc_word[4] = cpu_to_le16(key_descriptor);
>  	set_key->desc_word[7] = cpu_to_le16(sta_id | (vap_id << 8));
>  
> -#if 0
> -	if ((cipher == WLAN_CIPHER_SUITE_WEP40) ||
> -	    (cipher == WLAN_CIPHER_SUITE_WEP104)) {
> -		memcpy(&set_key->key[key_id][1], data, key_len * 2);
> -	} else {
> -		memcpy(&set_key->key[0][0], data, key_len);
> -	}
> -#endif
>  	if (data) {
> -		memcpy(&set_key->key[0][0], data, key_len);
> -		//memcpy(&set_key->key, data, 4 * 32);
> +		if ((cipher == WLAN_CIPHER_SUITE_WEP40) ||
> +		    (cipher == WLAN_CIPHER_SUITE_WEP104)) {
> +			memcpy(&set_key->key[key_id][1], data, key_len * 2);
> +		} else {
> +			memcpy(&set_key->key[0][0], data, key_len);
> +		}
>  		memcpy(set_key->tx_mic_key, &data[16], 8);
>  		memcpy(set_key->rx_mic_key, &data[24], 8);
>  	} else {
>  		memset(&set_key[FRAME_DESC_SZ], 0,
> -		       sizeof(struct rsi_set_key) - FRAME_DESC_SZ);
> +		       sizeof(struct rsi_set_key) - FRAME_DESC_SZ);		
> 		
>  	}
>  
>  	skb_put(skb, sizeof(struct rsi_set_key));
> @@ -1401,8 +1399,13 @@ int rsi_send_vap_dynamic_update(struct rsi_common
> *common)
>  	dynamic_frame->desc_word[5] = cpu_to_le16(common->frag_threshold);
>  	dynamic_frame->desc_word[5] = cpu_to_le16(2352);
>  #endif
> -//	dynamic_frame->desc_word[6] = cpu_to_le16(10); /* bmiss_threshold
> */
> +
> +#ifdef CONFIG_RSI_WOW
> +	dynamic_frame->desc_word[6] = cpu_to_le16(24); /* bmiss_threshold */
> +	dynamic_frame->frame_body.keep_alive_period = cpu_to_le16(10);
> +#else
>  	dynamic_frame->frame_body.keep_alive_period = cpu_to_le16(90);
> +#endif
>  
>  #if 0
>  	dynamic_frame->frame_body.mgmt_rate = cpu_to_le32(RSI_RATE_6);
> @@ -1526,8 +1529,10 @@ static bool rsi_map_rates(u16 rate, int *offset)
>   * Return: 0 on success, corresponding error code on failure.
>   */
>  static int rsi_send_auto_rate_request(struct rsi_common *common,
> +				      struct ieee80211_sta *sta,
>  				      u16 sta_id)
>  {
> +	struct ieee80211_vif *vif = common->priv->vifs[0];
>  	struct sk_buff *skb;
>  	struct rsi_auto_rate *auto_rate;
>  	int ii = 0, jj = 0, kk = 0;
> @@ -1535,8 +1540,9 @@ static int rsi_send_auto_rate_request(struct rsi_common
> *common,
>  	u8 band = hw->conf.chandef.chan->band;
>  	u8 num_supported_rates = 0;
>  	u8 rate_table_offset, rate_offset = 0;
> -	u32 rate_bitmap = common->bitrate_mask[band];
> +	u32 rate_bitmap = 0;
>  	u16 *selected_rates, min_rate;
> +	bool is_ht = false, is_sgi = false;
>  
>  	ven_rsi_dbg(MGMT_TX_ZONE,
>  		"%s: Sending auto rate request frame\n", __func__);
> @@ -1548,6 +1554,8 @@ static int rsi_send_auto_rate_request(struct rsi_common
> *common,
>  		return -ENOMEM;
>  	}
>  
> +	memset(skb->data, 0, MAX_MGMT_PKT_SIZE);
> +
>  	selected_rates = kzalloc(2 * RSI_TBL_SZ, GFP_KERNEL);
>  	if (!selected_rates) {
>  		ven_rsi_dbg(ERR_ZONE, "%s: Failed in allocation of mem\n",
> @@ -1555,8 +1563,6 @@ static int rsi_send_auto_rate_request(struct rsi_common
> *common,
>  		dev_kfree_skb(skb);
>  		return -ENOMEM;
>  	}
> -
> -	memset(skb->data, 0, sizeof(struct rsi_auto_rate));
>  	memset(selected_rates, 0, 2 * RSI_TBL_SZ);
>  
>  	auto_rate = (struct rsi_auto_rate *)skb->data;
> @@ -1573,11 +1579,31 @@ static int rsi_send_auto_rate_request(struct
> rsi_common *common,
>  		auto_rate->desc_word[7] = cpu_to_le16(1);
>  	auto_rate->desc_word[7] |= cpu_to_le16(sta_id << 8);
>  
> +	if (vif->type == NL80211_IFTYPE_STATION) {
> +		rate_bitmap = common->bitrate_mask[band];
> +		is_ht = common->vif_info[0].is_ht;
> +		is_sgi = common->vif_info[0].sgi;
> +	} else {
> +		rate_bitmap = sta->supp_rates[band];
> +		is_ht = sta->ht_cap.ht_supported;
> +		if ((sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ||
> +		    (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40))
> +			is_sgi = true;
> +	}
> +	printk("rate_bitmap = %x\n", rate_bitmap);
> +	printk("is_ht = %d\n", is_ht);
> +
>  	if (band == NL80211_BAND_2GHZ) {
> -		min_rate = RSI_RATE_1;
> +		if ((rate_bitmap == 0) && (is_ht))
> +			min_rate = RSI_RATE_MCS0;
> +		else
> +			min_rate = RSI_RATE_1;
>  		rate_table_offset = 0;
>  	} else {
> -		min_rate = RSI_RATE_6;
> +		if ((rate_bitmap == 0) && (is_ht))
> +			min_rate = RSI_RATE_MCS0;
> +		else
> +			min_rate = RSI_RATE_6;
>  		rate_table_offset = 4;
>  	}
>  
> @@ -1591,7 +1617,7 @@ static int rsi_send_auto_rate_request(struct rsi_common
> *common,
>  	}
>  	num_supported_rates = jj;
>  
> -	if (common->vif_info[0].is_ht) {
> +	if (is_ht) {
>  		for (ii = 0; ii < ARRAY_SIZE(mcs); ii++)
>  			selected_rates[jj++] = mcs[ii];
>  		num_supported_rates += ARRAY_SIZE(mcs);
> @@ -1612,13 +1638,16 @@ static int rsi_send_auto_rate_request(struct
> rsi_common *common,
>  	}
>  
>  	/* loading HT rates in the bottom half of the auto rate table */
> -	if (common->vif_info[0].is_ht) {
> +	if (is_ht) {
>  		for (ii = rate_offset, kk = ARRAY_SIZE(rsi_mcsrates) - 1;
>  		     ii < rate_offset + 2 * ARRAY_SIZE(rsi_mcsrates); ii++) {
> -			if (common->vif_info[0].sgi ||
> -			    conf_is_ht40(&common->priv->hw->conf))
> +			if (is_sgi || conf_is_ht40(&common->priv->hw->conf))
> {
>  				auto_rate->supported_rates[ii++] =
>  					cpu_to_le16(rsi_mcsrates[kk] |
> BIT(9));
> +			} else {
> +				auto_rate->supported_rates[ii++] =
> +					cpu_to_le16(rsi_mcsrates[kk]);
> +			}
>  			auto_rate->supported_rates[ii] =
>  				cpu_to_le16(rsi_mcsrates[kk--]);
>  		}
> @@ -1637,8 +1666,8 @@ static int rsi_send_auto_rate_request(struct rsi_common
> *common,
>  	num_supported_rates *= 2;
>  
>  	auto_rate->desc_word[0] = cpu_to_le16((sizeof(*auto_rate) -
> -					       FRAME_DESC_SZ) |
> -					       (RSI_WIFI_MGMT_Q << 12));
> +					      FRAME_DESC_SZ) |
> +					      (RSI_WIFI_MGMT_Q << 12));
>  
>  	skb_put(skb, sizeof(struct rsi_auto_rate));
>  	kfree(selected_rates);
> @@ -1659,7 +1688,7 @@ static void rsi_validate_bgscan_channels(struct rsi_hw
> *adapter,
>  {
>  	struct ieee80211_supported_band *sband;
>  	struct ieee80211_channel *ch;
> -	struct wiphy *wiphy = adapter->hw->wiphy;
> +	struct wiphy *wiphy = adapter->hw->wiphy; 
>  	u16 bgscan_channels[MAX_BGSCAN_CHANNELS] = {1, 2, 3, 4, 5, 6, 7, 8,
> 9,
>  						    10, 11, 12, 13, 14, 36,
> 40,
>  						    44, 48, 52, 56, 60, 64,
> 100,
> @@ -1745,7 +1774,7 @@ int rsi_send_bgscan_params(struct rsi_common *common,
> int enable)
>  		ven_rsi_dbg(ERR_ZONE, "##### No valid bgscan channels
> #####\n");
>  		return -1;
>  	}
> -
> +	
>  	skb = dev_alloc_skb(frame_len);
>  	if (!skb)
>  		return -ENOMEM;
> @@ -1849,6 +1878,7 @@ void rsi_inform_bss_status(struct rsi_common *common,
>  			   u8 *bssid,
>  			   u8 qos_enable,
>  			   u16 aid,
> +			   struct ieee80211_sta *sta,
>  			   u16 sta_id)
>  {
>  	if (status) {
> @@ -1863,15 +1893,21 @@ void rsi_inform_bss_status(struct rsi_common *common,
>  					  sta_id);
>  		if (common->min_rate == 0xffff) {
>  			ven_rsi_dbg(INFO_ZONE, "Send auto rate request\n");
> -			rsi_send_auto_rate_request(common, sta_id);
> +			rsi_send_auto_rate_request(common, sta, sta_id);
>  		}
>  		if (opmode == STA_OPMODE) {
> -			if (!rsi_send_block_unblock_frame(common, false))
> -				common->hw_data_qs_blocked = false;
> +			if ((!common->secinfo.security_enable) ||
> +			    (rsi_is_cipher_wep(common))) {
> +				if (!rsi_send_block_unblock_frame(common,
> false))
> +					common->hw_data_qs_blocked = false;
> +			}
>  		}
>  	} else {
>  		if (opmode == STA_OPMODE)
>  			common->hw_data_qs_blocked = true;
> +#ifdef CONFIG_RSI_WOW
> +		if (!common->suspend_flag) {
> +#endif
>  		rsi_send_sta_notify_frame(common,
>  					  opmode,
>  					  STA_DISCONNECTED,
> @@ -1879,6 +1915,9 @@ void rsi_inform_bss_status(struct rsi_common *common,
>  					  qos_enable,
>  					  aid,
>  					  sta_id);
> +#ifdef CONFIG_RSI_WOW
> +		}
> +#endif
>  		if (opmode == STA_OPMODE)
>  			rsi_send_block_unblock_frame(common, true);
>  	}
> @@ -2004,6 +2043,7 @@ int rsi_send_rx_filter_frame(struct rsi_common *common,
> u16 rx_filter_word)
>  
>  	return rsi_send_internal_mgmt_frame(common, skb);
>  }
> +EXPORT_SYMBOL_GPL(rsi_send_rx_filter_frame); 
>  
>  /**
>   * rsi_send_ps_request() - Sends power save request.
> @@ -2352,42 +2392,45 @@ int rsi_handle_card_ready(struct rsi_common *common)
>  	return 0;
>  }
>  
> -#ifdef CONFIG_RSI_WOW
> +#ifdef CONFIG_RSI_WOW 
>  int rsi_send_wowlan_request(struct rsi_common *common, u16 flags,
> -			    struct cfg80211_wowlan *wowlan)
> +		            u16 sleep_status)
>  {
> -	struct rsi_wowlan_req *cmd_frame;
> -	struct sk_buff *skb;
> -	u8 length;
> -	u8 sourceid[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
> -
> -	ven_rsi_dbg(ERR_ZONE, "%s: Sending wowlan request frame\n",
> __func__);
> -
> -	skb = dev_alloc_skb(sizeof(*cmd_frame));
> -	if (!skb) {
> -		ven_rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
> -				__func__);
> -		return -ENOMEM;
> -	}
> -	memset(skb->data, 0, sizeof(*cmd_frame));
> -	cmd_frame = (struct rsi_wowlan_req *)skb->data;
> -
> -	cmd_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12);
> -	cmd_frame->desc_word[1] |= cpu_to_le16(WOWLAN_CONFIG_PARAMS);
> -
> -	memcpy(cmd_frame->sourceid, &sourceid, IEEE80211_ADDR_LEN);
> -
> -	cmd_frame->wow_flags = flags; /* TODO: check for the magic packet */
> -	cmd_frame->host_sleep_status = 1; /* TODO: check for the host status
> */
> -
> -	length = FRAME_DESC_SZ + IEEE80211_ADDR_LEN + 2 + 2;
> -
> -	cmd_frame->desc_word[0] |= cpu_to_le16(length - FRAME_DESC_SZ);
> -	cmd_frame->desc_word[2] |= cpu_to_le16(0);
> +        struct rsi_wowlan_req *cmd_frame;
> +        struct sk_buff *skb;
> +        u8 length;
> +        u8 sourceid[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
> +
> +        ven_rsi_dbg(ERR_ZONE, "%s: Sending wowlan request frame\n",
> __func__);
> +
> +        skb = dev_alloc_skb(sizeof(*cmd_frame));
> +        if (!skb) {
> +                ven_rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
> +                                __func__);
> +                return -ENOMEM;
> +        }
> +        memset(skb->data, 0, sizeof(*cmd_frame));
> +        cmd_frame = (struct rsi_wowlan_req *)skb->data;
> +
> +        cmd_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12);
> +        cmd_frame->desc_word[1] |= cpu_to_le16(WOWLAN_CONFIG_PARAMS);
>> +        memcpy(cmd_frame->sourceid, &sourceid, IEEE80211_ADDR_LEN);
> +	
> +        cmd_frame->host_sleep_status = sleep_status;
> +	if (sleep_status)
> +		cmd_frame->wow_flags = flags; /* TODO: check for magic packet
> */
> +        ven_rsi_dbg(INFO_ZONE, "Host_Sleep_Status : %d Flags : %d\n",
> +		cmd_frame->host_sleep_status, cmd_frame->wow_flags );
> +	
> +        length = FRAME_DESC_SZ + IEEE80211_ADDR_LEN + 2 + 2;
>  
> -	skb_put(skb, length);
> +        cmd_frame->desc_word[0] |= cpu_to_le16(length - FRAME_DESC_SZ);
> +        cmd_frame->desc_word[2] |= cpu_to_le16(0);
> +  
> +  	skb_put(skb, length);
>  
> -	return rsi_send_internal_mgmt_frame(common, skb);
> +        return rsi_send_internal_mgmt_frame(common, skb);
>  }
>  #endif
>  
> @@ -2403,6 +2446,7 @@ int rsi_mgmt_pkt_recv(struct rsi_common *common, u8
> *msg)
>  {
>  	s32 msg_len = (le16_to_cpu(*(__le16 *)&msg[0]) & 0x0fff);
>  	u16 msg_type = msg[2];
> +	struct ieee80211_vif *vif = common->priv->vifs[0];
>  
>  	switch (msg_type) {
>  	case TA_CONFIRM_TYPE:
> @@ -2417,6 +2461,18 @@ int rsi_mgmt_pkt_recv(struct rsi_common *common, u8
> *msg)
>  			common->mgmt_q_block = false;
>  			ven_rsi_dbg(INFO_ZONE, "Mgmt queue unblocked\n");
>  		}
> +		if ((msg[15] & 0xff) == EAPOL4_CONFIRM) {
> +			u8 status = msg[12];
> +
> +			if (status) {	
> +				if(vif->type == NL80211_IFTYPE_STATION) {
> +					ven_rsi_dbg(ERR_ZONE, "EAPOL 4
> confirm\n");
> +					common->eapol4_confirm = 1;
> +					if
> (!rsi_send_block_unblock_frame(common, false))
> +						common->hw_data_qs_blocked =
> false;
> +				}
> +			}
> +		}
>  		break;
>  
>  	case PS_NOTIFY_IND:
> @@ -2447,13 +2503,15 @@ int rsi_mgmt_pkt_recv(struct rsi_common *common, u8
> *msg)
>  
>  	case BEACON_EVENT_IND:
>  		ven_rsi_dbg(INFO_ZONE, "Beacon event\n");
> -		if (common->fsm_state != FSM_MAC_INIT_DONE)
> +#ifndef CONFIG_CARACALLA_BOARD
> +		if (!common->init_done)
>  			return -1;
>  		if (common->iface_down)
>  			return -1;
> -		mutex_lock(&common->mutex);
> +		if (!common->beacon_enabled)
> +			return -1;
>  		rsi_send_beacon(common);
> -		mutex_unlock(&common->mutex);
> +#endif
>  		break;
>  
>  	case RX_DOT11_MGMT:
> diff --git a/ubuntu/rsi/rsi_91x_sdio.c b/ubuntu/rsi/rsi_91x_sdio.c
> index 15083e5..9378b36 100644
> --- a/ubuntu/rsi/rsi_91x_sdio.c
> +++ b/ubuntu/rsi/rsi_91x_sdio.c
> @@ -276,7 +276,7 @@ static void rsi_reset_card(struct sdio_func *pfunction)
>  	u16 rca;
>  	u32 cmd_delay = 0;
>  
> -#ifdef CONFIG_DELL_BOARD
> +#ifdef CONFIG_CARACALLA_BOARD
>  	/* Reset 9110 chip */
>  	err = rsi_cmd52writebyte(pfunction->card,
>  				 SDIO_CCCR_ABORT,
> @@ -338,7 +338,7 @@ static void rsi_reset_card(struct sdio_func *pfunction)
>  	if (err)
>  		ven_rsi_dbg(ERR_ZONE, "%s: CMD0 failed : %d\n", __func__,
> err);
>  
> -#ifdef CONFIG_DELL_BOARD
> +#ifdef CONFIG_CARACALLA_BOARD
>  	if (!host->ocr_avail) {
>  #else
>  	if (1) {
> @@ -352,7 +352,7 @@ static void rsi_reset_card(struct sdio_func *pfunction)
>  		if (err)
>  			ven_rsi_dbg(ERR_ZONE, "%s: CMD5 failed : %d\n",
>  				__func__, err);
> -#ifdef CONFIG_DELL_BOARD
> +#ifdef CONFIG_CARACALLA_BOARD
>  		host->ocr_avail = resp;
>  #else
>  		card->ocr = resp;
> @@ -363,7 +363,7 @@ static void rsi_reset_card(struct sdio_func *pfunction)
>  	for (i = 0; i < 100; i++) {
>  		err = rsi_issue_sdiocommand(pfunction,
>  					    SD_IO_SEND_OP_COND,
> -#ifdef CONFIG_DELL_BOARD
> +#ifdef CONFIG_CARACALLA_BOARD
>  					    host->ocr_avail,
>  #else
>  					    card->ocr,
> @@ -997,7 +997,7 @@ static int rsi_init_sdio_interface(struct rsi_hw *adapter,
>  	adapter->check_hw_queue_status =
> rsi_sdio_read_buffer_status_register;
>  	adapter->process_isr_hci = rsi_interrupt_handler;
>  	adapter->check_intr_status_reg = rsi_read_intr_status_reg;
> -
> +	
>  #ifdef CONFIG_VEN_RSI_DEBUGFS
>  	adapter->num_debugfs_entries = MAX_DEBUGFS_ENTRIES;
>  #endif
> @@ -1049,7 +1049,9 @@ static int rsi_probe(struct sdio_func *pfunction,
>  			__func__);
>  		goto fail;
>  	}
> -
> +#ifdef CONFIG_SDIO_INTR_POLL
> +	init_sdio_intr_status_poll_thread(adapter->priv);
> +#endif
>  	sdio_claim_host(pfunction);
>  //	if (sdio_claim_irq(pfunction, rsi_handle_interrupt)) {
>  	if (sdio_claim_irq(pfunction, rsi_dummy_isr)) {
> @@ -1110,12 +1112,14 @@ static void rsi_disconnect(struct sdio_func
> *pfunction)
>  
>  	dev = (struct rsi_91x_sdiodev *)adapter->rsi_dev;
>  
> -#if defined(CONFIG_VEN_RSI_HCI) || defined(CONFIG_VEN_RSI_COEX)
> -#if defined(CONFIG_DELL_BOARD)
> +#ifdef CONFIG_SDIO_INTR_POLL
>  	if (adapter->rsi_host_intf == RSI_HOST_INTF_SDIO)
> -		rsi_kill_thread(&adapter->priv->hci_thread);
> -#endif
> +		rsi_kill_thread(&adapter->priv->sdio_intr_poll_thread);
>  #endif
> +	sdio_claim_host(pfunction);
> +	sdio_release_irq(pfunction);
> +	sdio_release_host(pfunction);
> +	mdelay(10);
>  
>  	ven_rsi_mac80211_detach(adapter);
>  	mdelay(10);
> @@ -1124,10 +1128,6 @@ static void rsi_disconnect(struct sdio_func *pfunction)
>  	rsi_hci_detach(adapter->priv);
>  	mdelay(10);
>  #endif
> -	sdio_claim_host(pfunction);
> -	sdio_release_irq(pfunction);
> -	sdio_release_host(pfunction);
> -	mdelay(10);
>  
>  	/* Reset Chip */
>  	rsi_reset_chip(adapter);
> @@ -1148,16 +1148,8 @@ int rsi_set_sdio_pm_caps(struct rsi_hw *adapter)
>  	struct rsi_91x_sdiodev *dev =
>  		(struct rsi_91x_sdiodev *)adapter->rsi_dev;
>  	struct sdio_func *func = dev->pfunction;
> -	mmc_pm_flag_t flags;
>  	int ret;
>  
> -	/*Getting the host power management capabilities*/
> -	flags = sdio_get_host_pm_caps(func);
> -	ven_rsi_dbg(INFO_ZONE, "sdio suspend pm_caps 0x%x\n", flags);
> -	if ((!(flags & MMC_PM_WAKE_SDIO_IRQ)) ||
> -	    (!(flags & MMC_PM_KEEP_POWER)))
> -		return -EINVAL;
> -
>  	/* Keep Power to the MMC while suspend*/
>  	ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
>  	if (ret) {
> @@ -1165,53 +1157,45 @@ int rsi_set_sdio_pm_caps(struct rsi_hw *adapter)
>  		return ret;
>  	}
>  
> -	/* sdio irq wakes up host */
> -	ret = sdio_set_host_pm_flags(func, MMC_PM_WAKE_SDIO_IRQ);
> -	if (ret)
> -		ven_rsi_dbg(ERR_ZONE,"set sdio wake irq flag failed: %d\n",
> ret);
> -
>  	return ret;
>  }
>  
> -int rsi_sdio_suspend(struct rsi_hw *adapter)
> -{
> -	struct rsi_91x_sdiodev *dev =
> -		(struct rsi_91x_sdiodev *)adapter->rsi_dev;
> -
> -	ven_rsi_dbg(INFO_ZONE,"Suspend SDIO\n");
> -
> -	sdio_claim_host(dev->pfunction);
> -	sdio_release_irq(dev->pfunction);
> -	sdio_release_host(dev->pfunction);
> -
> -	return 0;
> -}
> -
>  static int rsi_suspend(struct device *dev)
>  {
>  	int ret = 0;
>  	struct sdio_func *pfunction = dev_to_sdio_func(dev);
>  	struct rsi_hw *adapter = sdio_get_drvdata(pfunction);
> +	u8 isr_status = 0;
>  
> -	ven_rsi_dbg(INFO_ZONE,"***** SUSPEND CALLED ******\n");
> -
> -	ret = rsi_set_sdio_pm_caps(adapter);
> -	if (ret){
> -		ven_rsi_dbg(INFO_ZONE,"failed %s:%d\n",__func__,__LINE__);
> -	}
> -	ret = rsi_sdio_suspend(adapter);
> +	ven_rsi_dbg(INFO_ZONE,"%s : ***** BUS SUSPEND  ******\n",__func__);
>  
> -	if (ret && ret != -ENOTCONN)
> -		ven_rsi_dbg(ERR_ZONE,"wow suspend failed: %d\n", ret);
> +	ven_rsi_dbg(INFO_ZONE, "Waiting for interrupts to be cleared..");
> +	do {
> +		rsi_sdio_read_register(adapter,
> +				       RSI_FN1_INT_REGISTER,
> +				       &isr_status);
> +		printk(".");
> +	} while (isr_status); 
> +	printk("\n");
>  
> +	ret = rsi_set_sdio_pm_caps(adapter);
> +	if (ret)
> +		ven_rsi_dbg(INFO_ZONE, "Setting power management caps
> failed\n");
>  	return 0;
>  }
>  
>  int rsi_resume(struct device *dev)
>  {
> -	ven_rsi_dbg(INFO_ZONE,"rsi_sdio_resume returning\n");
> -	return 0;
> +#ifdef CONFIG_RSI_WOW
> +	struct sdio_func *pfunction = dev_to_sdio_func(dev);
> +	struct rsi_hw *adapter = sdio_get_drvdata(pfunction);
> +        
> +	ven_rsi_dbg(INFO_ZONE,"%s: ***** BUS RESUME ******\n",__func__);
> +        adapter->priv->suspend_flag = 0;
> +#endif
>  
> +	ven_rsi_dbg(INFO_ZONE, "RSI module resumed\n");
> +	return 0;
>  }
>  
>  static const struct dev_pm_ops rsi_pm_ops = {
> diff --git a/ubuntu/rsi/rsi_91x_sdio_ops.c b/ubuntu/rsi/rsi_91x_sdio_ops.c
> index be62d42..7d412f0 100644
> --- a/ubuntu/rsi/rsi_91x_sdio_ops.c
> +++ b/ubuntu/rsi/rsi_91x_sdio_ops.c
> @@ -235,7 +235,7 @@ int rsi_read_intr_status_reg(struct rsi_hw *adapter)
>  						RSI_FN1_INT_REGISTER,
>  						&isr_status);
>  	isr_status &= 0xE;
> -
> +	
>  	if(isr_status & BIT(MSDU_PKT_PENDING))
>  		adapter->isr_pending = 1;
>  	return 0;
> @@ -376,9 +376,9 @@ int rsi_sdio_read_buffer_status_register(struct rsi_hw
> *adapter, u8 q_num)
>  		(struct rsi_91x_sdiodev *)adapter->rsi_dev;
>  	u8 buf_status = 0;
>  	int status = 0;
> -#if 0
> -	static int counter = 4;
> +//	static int counter = 4;
>  
> +#if 0
>  	if ((!dev->buff_status_updated) && counter) {
>  		counter--;
>  		goto out;
> @@ -389,7 +389,6 @@ int rsi_sdio_read_buffer_status_register(struct rsi_hw
> *adapter, u8 q_num)
>  	status = rsi_sdio_read_register(common->priv,
>  					RSI_DEVICE_BUFFER_STATUS_REGISTER,
>  					&buf_status);
> -
>  	if (status) {
>  		ven_rsi_dbg(ERR_ZONE,
>  			"%s: Failed to read status register\n", __func__);
> @@ -421,11 +420,11 @@ int rsi_sdio_read_buffer_status_register(struct rsi_hw
> *adapter, u8 q_num)
>  	}
>  //	(dev->rx_info.semi_buffer_full ? (counter = 4) : (counter = 1));
>  
> -out:
> +//out:
>  	if ((q_num == MGMT_SOFT_Q) && (dev->rx_info.mgmt_buffer_full))
>  		return QUEUE_FULL;
>  
> -	if (dev->rx_info.buffer_full)
> +	if ((q_num < MGMT_SOFT_Q) && (dev->rx_info.buffer_full))
>  		return QUEUE_FULL;
>  
>  	return QUEUE_NOT_FULL;
> diff --git a/ubuntu/rsi/rsi_coex.h b/ubuntu/rsi/rsi_coex.h
> index 027bc77..24b8688 100644
> --- a/ubuntu/rsi/rsi_coex.h
> +++ b/ubuntu/rsi/rsi_coex.h
> @@ -40,7 +40,7 @@ enum rsi_proto {
>  struct rsi_coex_ctrl_block {
>  	struct rsi_common *priv;
>  	struct sk_buff_head coex_tx_qs[NUM_COEX_TX_QUEUES];
> -	struct semaphore tx_bus_lock;
> +        struct semaphore tx_bus_lock;
>  	struct rsi_thread coex_tx_thread;
>  };
>  
> diff --git a/ubuntu/rsi/rsi_common.h b/ubuntu/rsi/rsi_common.h
> index 5067af9..47951cf 100644
> --- a/ubuntu/rsi/rsi_common.h
> +++ b/ubuntu/rsi/rsi_common.h
> @@ -90,4 +90,10 @@ void rsi_resume_conn_channel(struct rsi_hw *adapter);
>  void rsi_hci_detach(struct rsi_common *common);
>  inline char *dot11_pkt_type(__le16 frame_control);
>  struct rsi_sta *rsi_find_sta(struct rsi_common *common, u8 *mac_addr);
> +void rsi_init_bcn_timer(struct rsi_common *common);
> +void rsi_del_bcn_timer(struct rsi_common *common);
> +void rsi_bcn_scheduler_thread(struct rsi_common *common);
> +#ifdef CONFIG_SDIO_INTR_POLL
> +void init_sdio_intr_status_poll_thread(struct rsi_common *common);
> +#endif
>  #endif
> diff --git a/ubuntu/rsi/rsi_main.h b/ubuntu/rsi/rsi_main.h
> index 09b9c82..2edb661 100644
> --- a/ubuntu/rsi/rsi_main.h
> +++ b/ubuntu/rsi/rsi_main.h
> @@ -210,7 +210,9 @@ struct rsi_common {
>  	struct version_info fw_ver;
>  
>  	struct rsi_thread tx_thread;
> -	struct rsi_thread hci_thread;
> +#ifdef CONFIG_SDIO_INTR_POLL
> +	struct rsi_thread sdio_intr_poll_thread;
> +#endif
>  	struct sk_buff_head tx_queue[NUM_EDCA_QUEUES + 1];
>  	/* Mutex declaration */
>  	struct mutex mutex;
> @@ -287,6 +289,9 @@ struct rsi_common {
>  	u8 host_wakeup_intr_active_high;
>  	int tx_power;
>  	u8 ant_in_use;
> +#ifdef CONFIG_RSI_WOW
> +	u8 suspend_flag;
> +#endif
>  
>  #if defined (CONFIG_VEN_RSI_HCI) || defined(CONFIG_VEN_RSI_COEX)
>  	void *hci_adapter;
> @@ -297,14 +302,20 @@ struct rsi_common {
>  #endif
>  
>  	/* AP mode related */
> +	u8 beacon_enabled;
> +	u16 beacon_interval;
>  	u8 *beacon_frame;
>  	u16 beacon_frame_len;
>  	u16 beacon_cnt;
>  	u8 dtim_cnt;
>  	u16 bc_mc_seqno;
>  	struct rsi_sta stations[RSI_MAX_ASSOC_STAS + 1];
> -	u8 num_stations;
> +	int num_stations;
>  	struct ieee80211_channel *ap_channel;
> +	struct rsi_thread bcn_thread;
> +	struct timer_list bcn_timer;
> +	struct ieee80211_key_conf *key;
> +	u8 eapol4_confirm;
>  };
>  
>  enum host_intf {
> diff --git a/ubuntu/rsi/rsi_mgmt.h b/ubuntu/rsi/rsi_mgmt.h
> index ece9b40..987f9dc 100644
> --- a/ubuntu/rsi/rsi_mgmt.h
> +++ b/ubuntu/rsi/rsi_mgmt.h
> @@ -66,7 +66,7 @@ enum rx_cmd_type {
>  	ANTENNA_SELECT = 0xf,
>  };
>  
> -#ifdef RSI_ENABLE_WOW
> +#ifdef CONFIG_RSI_WOW
>  #define WOW_MAX_FILTERS_PER_LIST 16
>  #define WOW_PATTERN_SIZE 256
>  #endif
> @@ -210,12 +210,12 @@ enum rx_cmd_type {
>  #define IEEE80211_STA_SP_ALL_PKTS	0x00
>  
>  /* Tx data frame format */
> -#define MAC_BBP_INFO			BIT(0)
> +#define MAC_BBP_INFO			BIT(0) 
>  #define NO_ACK_IND			BIT(9)
>  #define QOS_EN				BIT(12)
>  /* frame type bit{11:10} */
>  #define NORMAL_FRAME			0x00
> -#define DTIM_BEACON_GATED_FRAME		BIT(10)
> +#define DTIM_BEACON_GATED_FRAME		BIT(10) 
>  #define BEACON_FRAME			BIT(11)
>  #define DTIM_BEACON			BIT(10) | BIT(11)
>  #define INSERT_TSF			BIT(15)
> @@ -490,7 +490,7 @@ struct rsi_request_ps {
>  	u16 ps_num_dtim_intervals;
>  } __packed;
>  
> -struct rsi_wowlan_req {
> +struct rsi_wowlan_req { 
>  	__le16 desc_word[8];
>  	u8 sourceid[ETH_ALEN];
>  	u16 wow_flags;
> @@ -527,7 +527,7 @@ int rsi_mgmt_pkt_recv(struct rsi_common *common, u8 *msg);
>  int rsi_set_vap_capabilities(struct rsi_common *common, enum opmode mode,
>  			     u8 vap_status);
>  int rsi_send_aggr_params_frame(struct rsi_common *common, u16 tid,
> -			       u16 ssn, u8 buf_size, u8 event);
> +			       u16 ssn, u8 buf_size, u8 event, u8 sta_id);
>  int rsi_load_key(struct rsi_common *common, u8 *data, u16 key_len,
>  		 u8 key_type, u8 key_id, u32 cipher, s16 sta_id);
>  int rsi_set_channel(struct rsi_common *common,
> @@ -536,7 +536,7 @@ int rsi_send_vap_dynamic_update(struct rsi_common
> *common);
>  int rsi_send_block_unblock_frame(struct rsi_common *common, bool event);
>  void rsi_inform_bss_status(struct rsi_common *common, enum opmode opmode,
>  			   u8 status, u8 *bssid, u8 qos_enable, u16 aid,
> -			   u16 sta_id);
> +			   struct ieee80211_sta *sta, u16 sta_id);
>  void rsi_indicate_pkt_to_os(struct rsi_common *common, struct sk_buff *skb);
>  int rsi_mac80211_attach(struct rsi_common *common);
>  int rsi_send_bgscan_params(struct rsi_common *common, int enable);
> @@ -559,6 +559,6 @@ int rsi_hci_attach(struct rsi_common *common);
>  int rsi_handle_card_ready(struct rsi_common *common);
>  #ifdef CONFIG_RSI_WOW
>  int rsi_send_wowlan_request(struct rsi_common *common, u16 flags,
> -			    struct cfg80211_wowlan *wowlan);
> +			    u16 sleep_status);
>  #endif
>  #endif
> -- 
> 2.9.3
> 
> 




More information about the kernel-team mailing list