diff options
Diffstat (limited to 'drivers/net/wireless/rsi/rsi_91x_mgmt.c')
-rw-r--r-- | drivers/net/wireless/rsi/rsi_91x_mgmt.c | 111 |
1 files changed, 82 insertions, 29 deletions
diff --git a/drivers/net/wireless/rsi/rsi_91x_mgmt.c b/drivers/net/wireless/rsi/rsi_91x_mgmt.c index f7b550f900c4..46c9d5470dfb 100644 --- a/drivers/net/wireless/rsi/rsi_91x_mgmt.c +++ b/drivers/net/wireless/rsi/rsi_91x_mgmt.c @@ -460,12 +460,12 @@ static int rsi_hal_send_sta_notify_frame(struct rsi_common *common, const unsigned char *bssid, u8 qos_enable, u16 aid, - u16 sta_id) + u16 sta_id, + struct ieee80211_vif *vif) { - struct ieee80211_vif *vif = common->priv->vifs[0]; struct sk_buff *skb = NULL; struct rsi_peer_notify *peer_notify; - u16 vap_id = 0; + u16 vap_id = ((struct vif_priv *)vif->drv_priv)->vap_id; int status; u16 frame_len = sizeof(struct rsi_peer_notify); @@ -482,9 +482,9 @@ static int rsi_hal_send_sta_notify_frame(struct rsi_common *common, memset(skb->data, 0, frame_len); peer_notify = (struct rsi_peer_notify *)skb->data; - if (opmode == STA_OPMODE) + if (opmode == RSI_OPMODE_STA) peer_notify->command = cpu_to_le16(PEER_TYPE_AP << 1); - else if (opmode == AP_OPMODE) + else if (opmode == RSI_OPMODE_AP) peer_notify->command = cpu_to_le16(PEER_TYPE_STA << 1); switch (notify_event) { @@ -716,9 +716,9 @@ int rsi_hal_load_key(struct rsi_common *common, u8 key_type, u8 key_id, u32 cipher, - s16 sta_id) + s16 sta_id, + struct ieee80211_vif *vif) { - struct ieee80211_vif *vif = common->priv->vifs[0]; struct sk_buff *skb = NULL; struct rsi_set_key *set_key; u16 key_descriptor = 0; @@ -926,13 +926,13 @@ static int rsi_send_reset_mac(struct rsi_common *common) * * Return: 0 on success, corresponding error code on failure. */ -int rsi_band_check(struct rsi_common *common) +int rsi_band_check(struct rsi_common *common, + struct ieee80211_channel *curchan) { struct rsi_hw *adapter = common->priv; struct ieee80211_hw *hw = adapter->hw; u8 prev_bw = common->channel_width; u8 prev_ep = common->endpoint; - struct ieee80211_channel *curchan = hw->conf.chandef.chan; int status = 0; if (common->band != curchan->band) { @@ -1094,9 +1094,18 @@ int rsi_send_vap_dynamic_update(struct rsi_common *common) dynamic_frame->desc_dword0.frame_type = VAP_DYNAMIC_UPDATE; dynamic_frame->desc_dword2.pkt_info = cpu_to_le32(common->rts_threshold); - /* Beacon miss threshold */ - dynamic_frame->frame_body.keep_alive_period = + + if (common->wow_flags & RSI_WOW_ENABLED) { + /* Beacon miss threshold */ + dynamic_frame->desc_dword3.token = + cpu_to_le16(RSI_BCN_MISS_THRESHOLD); + dynamic_frame->frame_body.keep_alive_period = + cpu_to_le16(RSI_WOW_KEEPALIVE); + } else { + dynamic_frame->frame_body.keep_alive_period = cpu_to_le16(RSI_DEF_KEEPALIVE); + } + dynamic_frame->desc_dword3.sta_id = 0; /* vap id */ skb_put(skb, sizeof(struct rsi_dynamic_s)); @@ -1160,9 +1169,9 @@ static bool rsi_map_rates(u16 rate, int *offset) */ static int rsi_send_auto_rate_request(struct rsi_common *common, struct ieee80211_sta *sta, - u16 sta_id) + u16 sta_id, + struct ieee80211_vif *vif) { - 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; @@ -1318,33 +1327,35 @@ void rsi_inform_bss_status(struct rsi_common *common, u8 qos_enable, u16 aid, struct ieee80211_sta *sta, - u16 sta_id) + u16 sta_id, + struct ieee80211_vif *vif) { if (status) { - if (opmode == STA_OPMODE) + if (opmode == RSI_OPMODE_STA) common->hw_data_qs_blocked = true; rsi_hal_send_sta_notify_frame(common, opmode, STA_CONNECTED, addr, qos_enable, - aid, sta_id); + aid, sta_id, + vif); if (common->min_rate == 0xffff) - rsi_send_auto_rate_request(common, sta, sta_id); - if (opmode == STA_OPMODE) { + rsi_send_auto_rate_request(common, sta, sta_id, vif); + if (opmode == RSI_OPMODE_STA) { if (!rsi_send_block_unblock_frame(common, false)) common->hw_data_qs_blocked = false; } } else { - if (opmode == STA_OPMODE) + if (opmode == RSI_OPMODE_STA) common->hw_data_qs_blocked = true; - rsi_hal_send_sta_notify_frame(common, - opmode, - STA_DISCONNECTED, - addr, - qos_enable, - aid, sta_id); - if (opmode == STA_OPMODE) + + if (!(common->wow_flags & RSI_WOW_ENABLED)) + rsi_hal_send_sta_notify_frame(common, opmode, + STA_DISCONNECTED, addr, + qos_enable, aid, sta_id, + vif); + if (opmode == RSI_OPMODE_STA) rsi_send_block_unblock_frame(common, true); } } @@ -1471,10 +1482,11 @@ int rsi_send_rx_filter_frame(struct rsi_common *common, u16 rx_filter_word) return rsi_send_internal_mgmt_frame(common, skb); } -int rsi_send_ps_request(struct rsi_hw *adapter, bool enable) +int rsi_send_ps_request(struct rsi_hw *adapter, bool enable, + struct ieee80211_vif *vif) { struct rsi_common *common = adapter->priv; - struct ieee80211_bss_conf *bss = &adapter->vifs[0]->bss_conf; + struct ieee80211_bss_conf *bss = &vif->bss_conf; struct rsi_request_ps *ps; struct rsi_ps_info *ps_info; struct sk_buff *skb; @@ -1585,6 +1597,42 @@ static int rsi_send_beacon(struct rsi_common *common) return 0; } +#ifdef CONFIG_PM +int rsi_send_wowlan_request(struct rsi_common *common, u16 flags, + u16 sleep_status) +{ + struct rsi_wowlan_req *cmd_frame; + struct sk_buff *skb; + u8 length; + + rsi_dbg(ERR_ZONE, "%s: Sending wowlan request frame\n", __func__); + + length = sizeof(*cmd_frame); + skb = dev_alloc_skb(length); + if (!skb) + return -ENOMEM; + memset(skb->data, 0, length); + cmd_frame = (struct rsi_wowlan_req *)skb->data; + + rsi_set_len_qno(&cmd_frame->desc.desc_dword0.len_qno, + (length - FRAME_DESC_SZ), + RSI_WIFI_MGMT_Q); + cmd_frame->desc.desc_dword0.frame_type = WOWLAN_CONFIG_PARAMS; + cmd_frame->host_sleep_status = sleep_status; + if (common->secinfo.security_enable && + common->secinfo.gtk_cipher) + flags |= RSI_WOW_GTK_REKEY; + if (sleep_status) + cmd_frame->wow_flags = flags; + rsi_dbg(INFO_ZONE, "Host_Sleep_Status : %d Flags : %d\n", + cmd_frame->host_sleep_status, cmd_frame->wow_flags); + + skb_put(skb, length); + + return rsi_send_internal_mgmt_frame(common, skb); +} +#endif + /** * rsi_handle_ta_confirm_type() - This function handles the confirm frames. * @common: Pointer to the driver private structure. @@ -1715,7 +1763,11 @@ static int rsi_handle_ta_confirm_type(struct rsi_common *common, common->bb_rf_prog_count--; if (!common->bb_rf_prog_count) { common->fsm_state = FSM_MAC_INIT_DONE; - return rsi_mac80211_attach(common); + if (common->reinit_hw) { + complete(&common->wlan_init_completion); + } else { + return rsi_mac80211_attach(common); + } } } else { rsi_dbg(INFO_ZONE, @@ -1793,6 +1845,7 @@ int rsi_mgmt_pkt_recv(struct rsi_common *common, u8 *msg) case TA_CONFIRM_TYPE: return rsi_handle_ta_confirm_type(common, msg); case CARD_READY_IND: + common->hibernate_resume = false; rsi_dbg(FSM_ZONE, "%s: Card ready indication received\n", __func__); return rsi_handle_card_ready(common, msg); |