2013-05-08 21:45:39 +00:00
/******************************************************************************
*
* Copyright ( c ) 2007 - 2012 Realtek Corporation . All rights reserved .
2014-12-19 06:59:46 +00:00
*
2013-05-08 21:45:39 +00:00
* This program is free software ; you can redistribute it and / or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation .
*
* This program is distributed in the hope that it will be useful , but WITHOUT
* ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE . See the GNU General Public License for
* more details .
*
* You should have received a copy of the GNU General Public License along with
* this program ; if not , write to the Free Software Foundation , Inc . ,
* 51 Franklin Street , Fifth Floor , Boston , MA 02110 , USA
*
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# define _RTW_MLME_EXT_C_
2014-12-11 21:15:04 +00:00
# include <drv_conf.h>
2013-05-08 21:45:39 +00:00
# include <osdep_service.h>
# include <drv_types.h>
# include <wifi.h>
# include <rtw_mlme_ext.h>
# include <wlan_bssdef.h>
# include <mlme_osdep.h>
# include <recv_osdep.h>
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_BT_COEXIST
# include <rtl8723a_hal.h>
# endif
2014-12-19 04:28:04 +00:00
static void issue_action_BA ( struct adapter * padapter , unsigned char * raddr ,
unsigned char action , u16 status ) ;
static struct mlme_handler mlme_sta_tbl [ ] = {
2013-05-08 21:45:39 +00:00
{ WIFI_ASSOCREQ , " OnAssocReq " , & OnAssocReq } ,
{ WIFI_ASSOCRSP , " OnAssocRsp " , & OnAssocRsp } ,
{ WIFI_REASSOCREQ , " OnReAssocReq " , & OnAssocReq } ,
{ WIFI_REASSOCRSP , " OnReAssocRsp " , & OnAssocRsp } ,
{ WIFI_PROBEREQ , " OnProbeReq " , & OnProbeReq } ,
{ WIFI_PROBERSP , " OnProbeRsp " , & OnProbeRsp } ,
/*----------------------------------------------------------
below 2 are reserved
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
{ 0 , " DoReserved " , & DoReserved } ,
{ 0 , " DoReserved " , & DoReserved } ,
{ WIFI_BEACON , " OnBeacon " , & OnBeacon } ,
{ WIFI_ATIM , " OnATIM " , & OnAtim } ,
{ WIFI_DISASSOC , " OnDisassoc " , & OnDisassoc } ,
{ WIFI_AUTH , " OnAuth " , & OnAuthClient } ,
{ WIFI_DEAUTH , " OnDeAuth " , & OnDeAuth } ,
{ WIFI_ACTION , " OnAction " , & OnAction } ,
} ;
2014-12-19 04:28:04 +00:00
static struct action_handler OnAction_tbl [ ] = {
2013-05-08 21:45:39 +00:00
{ RTW_WLAN_CATEGORY_SPECTRUM_MGMT , " ACTION_SPECTRUM_MGMT " , on_action_spct } ,
{ RTW_WLAN_CATEGORY_QOS , " ACTION_QOS " , & OnAction_qos } ,
{ RTW_WLAN_CATEGORY_DLS , " ACTION_DLS " , & OnAction_dls } ,
{ RTW_WLAN_CATEGORY_BACK , " ACTION_BACK " , & OnAction_back } ,
{ RTW_WLAN_CATEGORY_PUBLIC , " ACTION_PUBLIC " , on_action_public } ,
{ RTW_WLAN_CATEGORY_RADIO_MEASUREMENT , " ACTION_RADIO_MEASUREMENT " , & DoReserved } ,
{ RTW_WLAN_CATEGORY_FT , " ACTION_FT " , & DoReserved } ,
{ RTW_WLAN_CATEGORY_HT , " ACTION_HT " , & OnAction_ht } ,
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_IEEE80211W
{ RTW_WLAN_CATEGORY_SA_QUERY , " ACTION_SA_QUERY " , & OnAction_sa_query } ,
# else
2013-05-08 21:45:39 +00:00
{ RTW_WLAN_CATEGORY_SA_QUERY , " ACTION_SA_QUERY " , & DoReserved } ,
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_IEEE80211W */
/* add for CONFIG_IEEE80211W */
2014-12-11 21:15:04 +00:00
{ RTW_WLAN_CATEGORY_UNPROTECTED_WNM , " ACTION_UNPROTECTED_WNM " , & DoReserved } ,
{ RTW_WLAN_CATEGORY_SELF_PROTECTED , " ACTION_SELF_PROTECTED " , & DoReserved } ,
2014-12-19 06:59:46 +00:00
{ RTW_WLAN_CATEGORY_WMM , " ACTION_WMM " , & OnAction_wmm } ,
{ RTW_WLAN_CATEGORY_P2P , " ACTION_P2P " , & OnAction_p2p } ,
2013-05-08 21:45:39 +00:00
} ;
2014-12-11 21:15:04 +00:00
2014-12-19 04:28:04 +00:00
static u8 null_addr [ ETH_ALEN ] = { 0 , 0 , 0 , 0 , 0 , 0 } ;
2013-05-08 21:45:39 +00:00
/**************************************************
OUI definitions for the vendor specific IE
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
unsigned char RTW_WPA_OUI [ ] = { 0x00 , 0x50 , 0xf2 , 0x01 } ;
unsigned char WMM_OUI [ ] = { 0x00 , 0x50 , 0xf2 , 0x02 } ;
unsigned char WPS_OUI [ ] = { 0x00 , 0x50 , 0xf2 , 0x04 } ;
2014-12-11 21:15:04 +00:00
unsigned char P2P_OUI [ ] = { 0x50 , 0x6F , 0x9A , 0x09 } ;
unsigned char WFD_OUI [ ] = { 0x50 , 0x6F , 0x9A , 0x0A } ;
2013-05-08 21:45:39 +00:00
unsigned char WMM_INFO_OUI [ ] = { 0x00 , 0x50 , 0xf2 , 0x02 , 0x00 , 0x01 } ;
unsigned char WMM_PARA_OUI [ ] = { 0x00 , 0x50 , 0xf2 , 0x02 , 0x01 , 0x01 } ;
unsigned char WPA_TKIP_CIPHER [ 4 ] = { 0x00 , 0x50 , 0xf2 , 0x02 } ;
unsigned char RSN_TKIP_CIPHER [ 4 ] = { 0x00 , 0x0f , 0xac , 0x02 } ;
/********************************************************
MCS rate definitions
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_DISABLE_MCS13TO15
unsigned char MCS_rate_2R_MCS13TO15_OFF [ 16 ] = { 0xff , 0x1f , 0x0 , 0x0 , 0x01 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 } ;
unsigned char MCS_rate_2R [ 16 ] = { 0xff , 0xff , 0x0 , 0x0 , 0x01 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 } ;
2015-02-19 21:34:32 +00:00
# else /* CONFIG_DISABLE_MCS13TO15 */
2013-05-08 21:45:39 +00:00
unsigned char MCS_rate_2R [ 16 ] = { 0xff , 0xff , 0x0 , 0x0 , 0x01 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 } ;
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_DISABLE_MCS13TO15 */
2013-05-08 21:45:39 +00:00
unsigned char MCS_rate_1R [ 16 ] = { 0xff , 0x00 , 0x0 , 0x0 , 0x01 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 } ;
/********************************************************
ChannelPlan definitions
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2014-12-11 21:15:04 +00:00
static RT_CHANNEL_PLAN_2G RTW_ChannelPlan2G [ RT_CHANNEL_DOMAIN_2G_MAX ] = {
2015-02-19 21:34:32 +00:00
{ { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 } , 13 } , /* 0x00, RT_CHANNEL_DOMAIN_2G_WORLD , Passive scan CH 12, 13 */
{ { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 } , 13 } , /* 0x01, RT_CHANNEL_DOMAIN_2G_ETSI1 */
{ { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 } , 11 } , /* 0x02, RT_CHANNEL_DOMAIN_2G_FCC1 */
{ { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 } , 14 } , /* 0x03, RT_CHANNEL_DOMAIN_2G_MIKK1 */
{ { 10 , 11 , 12 , 13 } , 4 } , /* 0x04, RT_CHANNEL_DOMAIN_2G_ETSI2 */
{ { } , 0 } , /* 0x05, RT_CHANNEL_DOMAIN_2G_NULL */
2014-12-11 21:15:04 +00:00
} ;
static RT_CHANNEL_PLAN_5G RTW_ChannelPlan5G [ RT_CHANNEL_DOMAIN_5G_MAX ] = {
2015-02-19 21:34:32 +00:00
{ { } , 0 } , /* 0x00, RT_CHANNEL_DOMAIN_5G_NULL */
{ { 36 , 40 , 44 , 48 , 52 , 56 , 60 , 64 , 100 , 104 , 108 , 112 , 116 , 120 , 124 , 128 , 132 , 136 , 140 } , 19 } , /* 0x01, RT_CHANNEL_DOMAIN_5G_ETSI1 */
{ { 36 , 40 , 44 , 48 , 52 , 56 , 60 , 64 , 100 , 104 , 108 , 112 , 116 , 120 , 124 , 128 , 132 , 136 , 140 , 149 , 153 , 157 , 161 , 165 } , 24 } , /* 0x02, RT_CHANNEL_DOMAIN_5G_ETSI2 */
{ { 36 , 40 , 44 , 48 , 52 , 56 , 60 , 64 , 100 , 104 , 108 , 112 , 116 , 120 , 124 , 128 , 132 , 149 , 153 , 157 , 161 , 165 } , 22 } , /* 0x03, RT_CHANNEL_DOMAIN_5G_ETSI3 */
{ { 36 , 40 , 44 , 48 , 52 , 56 , 60 , 64 , 100 , 104 , 108 , 112 , 116 , 120 , 124 , 128 , 132 , 136 , 140 , 149 , 153 , 157 , 161 , 165 } , 24 } , /* 0x04, RT_CHANNEL_DOMAIN_5G_FCC1 */
{ { 36 , 40 , 44 , 48 , 149 , 153 , 157 , 161 , 165 } , 9 } , /* 0x05, RT_CHANNEL_DOMAIN_5G_FCC2 */
{ { 36 , 40 , 44 , 48 , 52 , 56 , 60 , 64 , 149 , 153 , 157 , 161 , 165 } , 13 } , /* 0x06, RT_CHANNEL_DOMAIN_5G_FCC3 */
{ { 36 , 40 , 44 , 48 , 52 , 56 , 60 , 64 , 149 , 153 , 157 , 161 } , 12 } , /* 0x07, RT_CHANNEL_DOMAIN_5G_FCC4 */
{ { 149 , 153 , 157 , 161 , 165 } , 5 } , /* 0x08, RT_CHANNEL_DOMAIN_5G_FCC5 */
{ { 36 , 40 , 44 , 48 , 52 , 56 , 60 , 64 } , 8 } , /* 0x09, RT_CHANNEL_DOMAIN_5G_FCC6 */
{ { 36 , 40 , 44 , 48 , 52 , 56 , 60 , 64 , 100 , 104 , 108 , 112 , 116 , 136 , 140 , 149 , 153 , 157 , 161 , 165 } , 20 } , /* 0x0A, RT_CHANNEL_DOMAIN_5G_FCC7_IC1 */
{ { 36 , 40 , 44 , 48 , 52 , 56 , 60 , 64 , 100 , 104 , 108 , 112 , 116 , 120 , 124 , 149 , 153 , 157 , 161 , 165 } , 20 } , /* 0x0B, RT_CHANNEL_DOMAIN_5G_KCC1 */
{ { 36 , 40 , 44 , 48 , 52 , 56 , 60 , 64 , 100 , 104 , 108 , 112 , 116 , 120 , 124 , 128 , 132 , 136 , 140 } , 19 } , /* 0x0C, RT_CHANNEL_DOMAIN_5G_MKK1 */
{ { 36 , 40 , 44 , 48 , 52 , 56 , 60 , 64 } , 8 } , /* 0x0D, RT_CHANNEL_DOMAIN_5G_MKK2 */
{ { 100 , 104 , 108 , 112 , 116 , 120 , 124 , 128 , 132 , 136 , 140 } , 11 } , /* 0x0E, RT_CHANNEL_DOMAIN_5G_MKK3 */
{ { 56 , 60 , 64 , 100 , 104 , 108 , 112 , 116 , 136 , 140 , 149 , 153 , 157 , 161 , 165 } , 15 } , /* 0x0F, RT_CHANNEL_DOMAIN_5G_NCC1 */
{ { 56 , 60 , 64 , 149 , 153 , 157 , 161 , 165 } , 8 } , /* 0x10, RT_CHANNEL_DOMAIN_5G_NCC2 */
/* Driver self defined for old channel plan Compatible ,Remember to modify if have new channel plan definition ===== */
{ { 36 , 40 , 44 , 48 , 52 , 56 , 60 , 64 , 100 , 104 , 108 , 112 , 116 , 132 , 136 , 140 , 149 , 153 , 157 , 161 , 165 } , 21 } , /* 0x11, RT_CHANNEL_DOMAIN_5G_FCC */
{ { 36 , 40 , 44 , 48 } , 4 } , /* 0x12, RT_CHANNEL_DOMAIN_5G_JAPAN_NO_DFS */
{ { 36 , 40 , 44 , 48 , 149 , 153 , 157 , 161 } , 8 } , /* 0x13, RT_CHANNEL_DOMAIN_5G_FCC4_NO_DFS */
2013-05-08 21:45:39 +00:00
} ;
2014-12-11 21:15:04 +00:00
static RT_CHANNEL_PLAN_MAP RTW_ChannelPlanMap [ RT_CHANNEL_DOMAIN_MAX ] = {
2015-02-19 21:34:32 +00:00
/* 0x00 ~ 0x1F , Old Define ===== */
{ 0x02 , 0x11 } , /* 0x00, RT_CHANNEL_DOMAIN_FCC */
{ 0x02 , 0x0A } , /* 0x01, RT_CHANNEL_DOMAIN_IC */
{ 0x01 , 0x01 } , /* 0x02, RT_CHANNEL_DOMAIN_ETSI */
{ 0x01 , 0x00 } , /* 0x03, RT_CHANNEL_DOMAIN_SPAIN */
{ 0x01 , 0x00 } , /* 0x04, RT_CHANNEL_DOMAIN_FRANCE */
{ 0x03 , 0x00 } , /* 0x05, RT_CHANNEL_DOMAIN_MKK */
{ 0x03 , 0x00 } , /* 0x06, RT_CHANNEL_DOMAIN_MKK1 */
{ 0x01 , 0x09 } , /* 0x07, RT_CHANNEL_DOMAIN_ISRAEL */
{ 0x03 , 0x09 } , /* 0x08, RT_CHANNEL_DOMAIN_TELEC */
{ 0x03 , 0x00 } , /* 0x09, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN */
{ 0x00 , 0x00 } , /* 0x0A, RT_CHANNEL_DOMAIN_WORLD_WIDE_13 */
{ 0x02 , 0x0F } , /* 0x0B, RT_CHANNEL_DOMAIN_TAIWAN */
{ 0x01 , 0x08 } , /* 0x0C, RT_CHANNEL_DOMAIN_CHINA */
{ 0x02 , 0x06 } , /* 0x0D, RT_CHANNEL_DOMAIN_SINGAPORE_INDIA_MEXICO */
{ 0x02 , 0x0B } , /* 0x0E, RT_CHANNEL_DOMAIN_KOREA */
{ 0x02 , 0x09 } , /* 0x0F, RT_CHANNEL_DOMAIN_TURKEY */
{ 0x01 , 0x01 } , /* 0x10, RT_CHANNEL_DOMAIN_JAPAN */
{ 0x02 , 0x05 } , /* 0x11, RT_CHANNEL_DOMAIN_FCC_NO_DFS */
{ 0x01 , 0x12 } , /* 0x12, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */
{ 0x00 , 0x04 } , /* 0x13, RT_CHANNEL_DOMAIN_WORLD_WIDE_5G */
{ 0x02 , 0x10 } , /* 0x14, RT_CHANNEL_DOMAIN_TAIWAN_NO_DFS */
{ 0x00 , 0x12 } , /* 0x15, RT_CHANNEL_DOMAIN_ETSI_NO_DFS */
{ 0x00 , 0x13 } , /* 0x16, RT_CHANNEL_DOMAIN_KOREA_NO_DFS */
{ 0x03 , 0x12 } , /* 0x17, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */
{ 0x05 , 0x08 } , /* 0x18, RT_CHANNEL_DOMAIN_PAKISTAN_NO_DFS */
{ 0x02 , 0x08 } , /* 0x19, RT_CHANNEL_DOMAIN_TAIWAN2_NO_DFS */
{ 0x00 , 0x00 } , /* 0x1A, */
{ 0x00 , 0x00 } , /* 0x1B, */
{ 0x00 , 0x00 } , /* 0x1C, */
{ 0x00 , 0x00 } , /* 0x1D, */
{ 0x00 , 0x00 } , /* 0x1E, */
{ 0x05 , 0x04 } , /* 0x1F, RT_CHANNEL_DOMAIN_WORLD_WIDE_ONLY_5G */
/* 0x20 ~ 0x7F ,New Define ===== */
{ 0x00 , 0x00 } , /* 0x20, RT_CHANNEL_DOMAIN_WORLD_NULL */
{ 0x01 , 0x00 } , /* 0x21, RT_CHANNEL_DOMAIN_ETSI1_NULL */
{ 0x02 , 0x00 } , /* 0x22, RT_CHANNEL_DOMAIN_FCC1_NULL */
{ 0x03 , 0x00 } , /* 0x23, RT_CHANNEL_DOMAIN_MKK1_NULL */
{ 0x04 , 0x00 } , /* 0x24, RT_CHANNEL_DOMAIN_ETSI2_NULL */
{ 0x02 , 0x04 } , /* 0x25, RT_CHANNEL_DOMAIN_FCC1_FCC1 */
{ 0x00 , 0x01 } , /* 0x26, RT_CHANNEL_DOMAIN_WORLD_ETSI1 */
{ 0x03 , 0x0C } , /* 0x27, RT_CHANNEL_DOMAIN_MKK1_MKK1 */
{ 0x00 , 0x0B } , /* 0x28, RT_CHANNEL_DOMAIN_WORLD_KCC1 */
{ 0x00 , 0x05 } , /* 0x29, RT_CHANNEL_DOMAIN_WORLD_FCC2 */
{ 0x00 , 0x00 } , /* 0x2A, */
{ 0x00 , 0x00 } , /* 0x2B, */
{ 0x00 , 0x00 } , /* 0x2C, */
{ 0x00 , 0x00 } , /* 0x2D, */
{ 0x00 , 0x00 } , /* 0x2E, */
{ 0x00 , 0x00 } , /* 0x2F, */
{ 0x00 , 0x06 } , /* 0x30, RT_CHANNEL_DOMAIN_WORLD_FCC3 */
{ 0x00 , 0x07 } , /* 0x31, RT_CHANNEL_DOMAIN_WORLD_FCC4 */
{ 0x00 , 0x08 } , /* 0x32, RT_CHANNEL_DOMAIN_WORLD_FCC5 */
{ 0x00 , 0x09 } , /* 0x33, RT_CHANNEL_DOMAIN_WORLD_FCC6 */
{ 0x02 , 0x0A } , /* 0x34, RT_CHANNEL_DOMAIN_FCC1_FCC7 */
{ 0x00 , 0x02 } , /* 0x35, RT_CHANNEL_DOMAIN_WORLD_ETSI2 */
{ 0x00 , 0x03 } , /* 0x36, RT_CHANNEL_DOMAIN_WORLD_ETSI3 */
{ 0x03 , 0x0D } , /* 0x37, RT_CHANNEL_DOMAIN_MKK1_MKK2 */
{ 0x03 , 0x0E } , /* 0x38, RT_CHANNEL_DOMAIN_MKK1_MKK3 */
{ 0x02 , 0x0F } , /* 0x39, RT_CHANNEL_DOMAIN_FCC1_NCC1 */
{ 0x00 , 0x00 } , /* 0x3A, */
{ 0x00 , 0x00 } , /* 0x3B, */
{ 0x00 , 0x00 } , /* 0x3C, */
{ 0x00 , 0x00 } , /* 0x3D, */
{ 0x00 , 0x00 } , /* 0x3E, */
{ 0x00 , 0x00 } , /* 0x3F, */
{ 0x02 , 0x10 } , /* 0x40, RT_CHANNEL_DOMAIN_FCC1_NCC2 */
{ 0x03 , 0x00 } , /* 0x41, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G */
2013-05-08 21:45:39 +00:00
} ;
2015-02-19 21:34:32 +00:00
static RT_CHANNEL_PLAN_MAP RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE = { 0x03 , 0x02 } ; /* use the conbination for max channel numbers */
2013-05-08 21:45:39 +00:00
/*
* Search the @ param channel_num in given @ param channel_set
* @ ch_set : the given channel set
* @ ch : the given channel number
2014-12-19 06:59:46 +00:00
*
2013-05-08 21:45:39 +00:00
* return the index of channel_num in channel_set , - 1 if not found
*/
2014-12-11 21:15:04 +00:00
int rtw_ch_set_search_ch ( RT_CHANNEL_INFO * ch_set , const u32 ch )
2013-05-08 21:45:39 +00:00
{
int i ;
2014-12-11 21:15:04 +00:00
for ( i = 0 ; ch_set [ i ] . ChannelNum ! = 0 ; i + + ) {
if ( ch = = ch_set [ i ] . ChannelNum )
2013-05-08 21:45:39 +00:00
break ;
}
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
if ( i > = ch_set [ i ] . ChannelNum )
2013-05-08 21:45:39 +00:00
return - 1 ;
return i ;
}
/****************************************************************************
Following are the initialization functions for WiFi MLME
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2014-12-17 23:13:53 +00:00
int init_hw_mlme_ext ( struct adapter * padapter )
2013-05-08 21:45:39 +00:00
{
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
set_channel_bwmode ( padapter , pmlmeext - > cur_channel , pmlmeext - > cur_ch_offset , pmlmeext - > cur_bwmode ) ;
return _SUCCESS ;
}
2014-12-17 23:13:53 +00:00
static void init_mlme_ext_priv_value ( struct adapter * padapter )
2013-05-08 21:45:39 +00:00
{
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_TDLS
u8 i ;
# endif
2015-02-19 21:34:32 +00:00
/* unsigned char default_channel_set[MAX_CHANNEL_NUM] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0}; */
2014-12-11 21:15:04 +00:00
unsigned char mixed_datarate [ NumRates ] = { _1M_RATE_ , _2M_RATE_ , _5M_RATE_ , _11M_RATE_ , _6M_RATE_ , _9M_RATE_ , _12M_RATE_ , _18M_RATE_ , _24M_RATE_ , _36M_RATE_ , _48M_RATE_ , _54M_RATE_ , 0xff } ;
unsigned char mixed_basicrate [ NumRates ] = { _1M_RATE_ , _2M_RATE_ , _5M_RATE_ , _11M_RATE_ , _6M_RATE_ , _12M_RATE_ , _24M_RATE_ , 0xff , } ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
ATOMIC_SET ( & pmlmeext - > event_seq , 0 ) ;
2015-02-19 21:34:32 +00:00
pmlmeext - > mgnt_seq = 0 ; /* reset to zero when disconnect at client mode */
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_IEEE80211W
pmlmeext - > sa_query_seq = 0 ;
pmlmeext - > mgnt_80211w_IPN = 0 ;
pmlmeext - > mgnt_80211w_IPN_rx = 0 ;
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_IEEE80211W */
2013-05-08 21:45:39 +00:00
pmlmeext - > cur_channel = padapter - > registrypriv . channel ;
pmlmeext - > cur_bwmode = HT_CHANNEL_WIDTH_20 ;
pmlmeext - > cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
pmlmeext - > retry = 0 ;
pmlmeext - > cur_wireless_mode = padapter - > registrypriv . wireless_mode ;
2015-02-19 21:34:32 +00:00
/* memcpy(pmlmeext->channel_set, DefaultChannelPlan[padapter->mlmepriv.ChannelPlan].Channel, DefaultChannelPlan[padapter->mlmepriv.ChannelPlan].Len); */
/* memcpy(pmlmeext->channel_set, default_channel_set, MAX_CHANNEL_NUM); */
2015-02-19 20:50:04 +00:00
memcpy ( pmlmeext - > datarate , mixed_datarate , NumRates ) ;
memcpy ( pmlmeext - > basicrate , mixed_basicrate , NumRates ) ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
if ( pmlmeext - > cur_channel > 14 )
pmlmeext - > tx_rate = IEEE80211_OFDM_RATE_6MB ;
else
pmlmeext - > tx_rate = IEEE80211_CCK_RATE_1MB ;
2013-05-08 21:45:39 +00:00
pmlmeext - > sitesurvey_res . state = SCAN_DISABLE ;
pmlmeext - > sitesurvey_res . channel_idx = 0 ;
pmlmeext - > sitesurvey_res . bss_cnt = 0 ;
2014-12-29 02:13:24 +00:00
pmlmeext - > scan_abort = false ;
2013-05-08 21:45:39 +00:00
pmlmeinfo - > state = WIFI_FW_NULL_STATE ;
pmlmeinfo - > reauth_count = 0 ;
pmlmeinfo - > reassoc_count = 0 ;
pmlmeinfo - > link_count = 0 ;
pmlmeinfo - > auth_seq = 0 ;
pmlmeinfo - > auth_algo = dot11AuthAlgrthm_Open ;
pmlmeinfo - > key_index = 0 ;
pmlmeinfo - > iv = 0 ;
pmlmeinfo - > enc_algo = _NO_PRIVACY_ ;
pmlmeinfo - > authModeToggle = 0 ;
2015-02-19 20:58:09 +00:00
memset ( pmlmeinfo - > chg_txt , 0 , 128 ) ;
2013-05-08 21:45:39 +00:00
pmlmeinfo - > slotTime = SHORT_SLOT_TIME ;
pmlmeinfo - > preamble_mode = PREAMBLE_AUTO ;
pmlmeinfo - > dialogToken = 0 ;
pmlmeext - > action_public_rxseq = 0xffff ;
pmlmeext - > action_public_dialog_token = 0xff ;
}
2014-12-11 21:15:04 +00:00
static int has_channel ( RT_CHANNEL_INFO * channel_set ,
2013-05-08 21:45:39 +00:00
u8 chanset_size ,
u8 chan ) {
int i ;
for ( i = 0 ; i < chanset_size ; i + + ) {
2014-12-11 21:15:04 +00:00
if ( channel_set [ i ] . ChannelNum = = chan ) {
2013-05-08 21:45:39 +00:00
return 1 ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
return 0 ;
}
2014-12-17 23:13:53 +00:00
static void init_channel_list ( struct adapter * padapter , RT_CHANNEL_INFO * channel_set ,
2013-05-08 21:45:39 +00:00
u8 chanset_size ,
struct p2p_channels * channel_list ) {
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
struct p2p_oper_class_map op_class [ ] = {
{ IEEE80211G , 81 , 1 , 13 , 1 , BW20 } ,
{ IEEE80211G , 82 , 14 , 14 , 1 , BW20 } ,
2014-12-11 21:15:04 +00:00
{ IEEE80211A , 115 , 36 , 48 , 4 , BW20 } ,
{ IEEE80211A , 116 , 36 , 44 , 8 , BW40PLUS } ,
{ IEEE80211A , 117 , 40 , 48 , 8 , BW40MINUS } ,
{ IEEE80211A , 124 , 149 , 161 , 4 , BW20 } ,
{ IEEE80211A , 125 , 149 , 169 , 4 , BW20 } ,
{ IEEE80211A , 126 , 149 , 157 , 8 , BW40PLUS } ,
{ IEEE80211A , 127 , 153 , 161 , 8 , BW40MINUS } ,
2013-05-08 21:45:39 +00:00
{ - 1 , 0 , 0 , 0 , 0 , BW20 }
} ;
int cla , op ;
cla = 0 ;
for ( op = 0 ; op_class [ op ] . op_class ; op + + ) {
u8 ch ;
struct p2p_oper_class_map * o = & op_class [ op ] ;
struct p2p_reg_class * reg = NULL ;
for ( ch = o - > min_chan ; ch < = o - > max_chan ; ch + = o - > inc ) {
if ( ! has_channel ( channel_set , chanset_size , ch ) ) {
continue ;
}
if ( ( 0 = = padapter - > registrypriv . ht_enable ) & & ( 8 = = o - > inc ) )
continue ;
if ( ( 0 = = ( padapter - > registrypriv . cbw40_enable & BIT ( 1 ) ) ) & &
2014-12-11 21:15:04 +00:00
( ( BW40MINUS = = o - > bw ) | | ( BW40PLUS = = o - > bw ) ) )
2013-05-08 21:45:39 +00:00
continue ;
if ( reg = = NULL ) {
reg = & channel_list - > reg_class [ cla ] ;
cla + + ;
reg - > reg_class = o - > op_class ;
reg - > channels = 0 ;
}
reg - > channel [ reg - > channels ] = ch ;
reg - > channels + + ;
}
}
channel_list - > reg_classes = cla ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-17 23:13:53 +00:00
static u8 init_channel_set ( struct adapter * padapter , u8 ChannelPlan , RT_CHANNEL_INFO * channel_set )
2013-05-08 21:45:39 +00:00
{
2014-12-11 21:15:04 +00:00
u8 index , chanset_size = 0 ;
2014-12-29 02:13:24 +00:00
u8 b5GBand = false , b2_4GBand = false ;
2014-12-11 21:15:04 +00:00
u8 Index2G = 0 , Index5G = 0 ;
2013-05-08 21:45:39 +00:00
2015-02-19 20:58:09 +00:00
memset ( channel_set , 0 , sizeof ( RT_CHANNEL_INFO ) * MAX_CHANNEL_NUM ) ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
if ( ChannelPlan > = RT_CHANNEL_DOMAIN_MAX & & ChannelPlan ! = RT_CHANNEL_DOMAIN_REALTEK_DEFINE )
{
DBG_871X ( " ChannelPlan ID %x error !!!!! \n " , ChannelPlan ) ;
2013-05-08 21:45:39 +00:00
return chanset_size ;
}
2014-12-11 21:15:04 +00:00
if ( padapter - > registrypriv . wireless_mode & WIRELESS_11G )
{
2014-12-29 02:13:24 +00:00
b2_4GBand = true ;
2014-12-11 21:15:04 +00:00
if ( RT_CHANNEL_DOMAIN_REALTEK_DEFINE = = ChannelPlan )
2013-05-08 21:45:39 +00:00
Index2G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE . Index2G ;
else
Index2G = RTW_ChannelPlanMap [ ChannelPlan ] . Index2G ;
}
2014-12-11 21:15:04 +00:00
if ( padapter - > registrypriv . wireless_mode & WIRELESS_11A )
{
2014-12-29 02:13:24 +00:00
b5GBand = true ;
2014-12-11 21:15:04 +00:00
if ( RT_CHANNEL_DOMAIN_REALTEK_DEFINE = = ChannelPlan )
Index5G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE . Index5G ;
else
Index5G = RTW_ChannelPlanMap [ ChannelPlan ] . Index5G ;
}
if ( b2_4GBand )
{
for ( index = 0 ; index < RTW_ChannelPlan2G [ Index2G ] . Len ; index + + )
{
2013-05-08 21:45:39 +00:00
channel_set [ chanset_size ] . ChannelNum = RTW_ChannelPlan2G [ Index2G ] . Channel [ index ] ;
2015-02-19 21:34:32 +00:00
if ( ( RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN = = ChannelPlan ) | | /* Channel 1~11 is active, and 12~14 is passive */
2014-12-11 21:15:04 +00:00
( RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G = = ChannelPlan ) )
{
if ( channel_set [ chanset_size ] . ChannelNum > = 1 & & channel_set [ chanset_size ] . ChannelNum < = 11 )
2013-05-08 21:45:39 +00:00
channel_set [ chanset_size ] . ScanType = SCAN_ACTIVE ;
2014-12-11 21:15:04 +00:00
else if ( ( channel_set [ chanset_size ] . ChannelNum > = 12 & & channel_set [ chanset_size ] . ChannelNum < = 14 ) )
2014-12-19 06:59:46 +00:00
channel_set [ chanset_size ] . ScanType = SCAN_PASSIVE ;
2014-12-11 21:15:04 +00:00
}
else if ( RT_CHANNEL_DOMAIN_WORLD_WIDE_13 = = ChannelPlan | |
RT_CHANNEL_DOMAIN_WORLD_WIDE_5G = = ChannelPlan | |
2015-02-19 21:34:32 +00:00
RT_CHANNEL_DOMAIN_2G_WORLD = = Index2G ) /* channel 12~13, passive scan */
2014-12-11 21:15:04 +00:00
{
if ( channel_set [ chanset_size ] . ChannelNum < = 11 )
2013-05-08 21:45:39 +00:00
channel_set [ chanset_size ] . ScanType = SCAN_ACTIVE ;
else
channel_set [ chanset_size ] . ScanType = SCAN_PASSIVE ;
2014-12-11 21:15:04 +00:00
}
else
{
2013-05-08 21:45:39 +00:00
channel_set [ chanset_size ] . ScanType = SCAN_ACTIVE ;
}
chanset_size + + ;
}
}
2014-12-11 21:15:04 +00:00
if ( b5GBand )
{
for ( index = 0 ; index < RTW_ChannelPlan5G [ Index5G ] . Len ; index + + )
{
# ifdef CONFIG_DFS
channel_set [ chanset_size ] . ChannelNum = RTW_ChannelPlan5G [ Index5G ] . Channel [ index ] ;
2014-12-19 06:59:46 +00:00
if ( channel_set [ chanset_size ] . ChannelNum < = 48
2014-12-11 21:15:04 +00:00
| | channel_set [ chanset_size ] . ChannelNum > = 149 )
{
2015-02-19 21:34:32 +00:00
if ( RT_CHANNEL_DOMAIN_WORLD_WIDE_5G = = ChannelPlan ) /* passive scan for all 5G channels */
2014-12-11 21:15:04 +00:00
channel_set [ chanset_size ] . ScanType = SCAN_PASSIVE ;
else
channel_set [ chanset_size ] . ScanType = SCAN_ACTIVE ;
}
else
{
channel_set [ chanset_size ] . ScanType = SCAN_PASSIVE ;
}
chanset_size + + ;
# else /* CONFIG_DFS */
2014-12-19 06:59:46 +00:00
if ( RTW_ChannelPlan5G [ Index5G ] . Channel [ index ] < = 48
2014-12-11 21:15:04 +00:00
| | RTW_ChannelPlan5G [ Index5G ] . Channel [ index ] > = 149 ) {
channel_set [ chanset_size ] . ChannelNum = RTW_ChannelPlan5G [ Index5G ] . Channel [ index ] ;
2015-02-19 21:34:32 +00:00
if ( RT_CHANNEL_DOMAIN_WORLD_WIDE_5G = = ChannelPlan ) /* passive scan for all 5G channels */
2014-12-11 21:15:04 +00:00
channel_set [ chanset_size ] . ScanType = SCAN_PASSIVE ;
else
channel_set [ chanset_size ] . ScanType = SCAN_ACTIVE ;
DBG_871X ( " %s(): channel_set[%d].ChannelNum = %d \n " , __FUNCTION__ , chanset_size , channel_set [ chanset_size ] . ChannelNum ) ;
chanset_size + + ;
}
# endif /* CONFIG_DFS */
}
}
2013-05-08 21:45:39 +00:00
return chanset_size ;
}
2014-12-17 23:13:53 +00:00
int init_mlme_ext_priv ( struct adapter * padapter )
2013-05-08 21:45:39 +00:00
{
int res = _SUCCESS ;
2014-12-11 21:15:04 +00:00
struct registry_priv * pregistrypriv = & padapter - > registrypriv ;
2013-05-08 21:45:39 +00:00
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
struct mlme_priv * pmlmepriv = & ( padapter - > mlmepriv ) ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
2015-02-19 21:34:32 +00:00
/* We don't need to memset padapter->XXX to zero, because adapter is allocated by rtw_zvmalloc(). */
/* memset((u8 *)pmlmeext, 0, sizeof(struct mlme_ext_priv)); */
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
pmlmeext - > padapter = padapter ;
2015-02-19 21:34:32 +00:00
/* fill_fwpriv(padapter, &(pmlmeext->fwpriv)); */
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
init_mlme_ext_priv_value ( padapter ) ;
pmlmeinfo - > bAcceptAddbaReq = pregistrypriv - > bAcceptAddbaReq ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
init_mlme_ext_timer ( padapter ) ;
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_AP_MODE
2014-12-19 06:59:46 +00:00
init_mlme_ap_info ( padapter ) ;
2013-05-08 21:45:39 +00:00
# endif
2014-12-11 21:15:04 +00:00
pmlmeext - > max_chan_nums = init_channel_set ( padapter , pmlmepriv - > ChannelPlan , pmlmeext - > channel_set ) ;
2013-05-08 21:45:39 +00:00
init_channel_list ( padapter , pmlmeext - > channel_set , pmlmeext - > max_chan_nums , & pmlmeext - > channel_list ) ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
pmlmeext - > chan_scan_time = SURVEY_TO ;
2014-12-29 02:13:24 +00:00
pmlmeext - > mlmeext_init = true ;
2013-05-08 21:45:39 +00:00
2014-12-29 02:13:24 +00:00
pmlmeext - > active_keep_alive_check = true ;
2014-12-11 21:15:04 +00:00
2014-12-19 06:59:46 +00:00
# ifdef DBG_FIXED_CHAN
pmlmeext - > fixed_chan = 0xFF ;
2014-12-11 21:15:04 +00:00
# endif
2013-05-08 21:45:39 +00:00
return res ;
}
2014-12-11 21:15:04 +00:00
void free_mlme_ext_priv ( struct mlme_ext_priv * pmlmeext )
2013-05-08 21:45:39 +00:00
{
2014-12-17 23:13:53 +00:00
struct adapter * padapter = pmlmeext - > padapter ;
2013-05-08 21:45:39 +00:00
if ( ! padapter )
return ;
2014-12-29 02:13:24 +00:00
if ( padapter - > bDriverStopped = = true )
2014-12-11 21:15:04 +00:00
{
2013-05-08 21:45:39 +00:00
_cancel_timer_ex ( & pmlmeext - > survey_timer ) ;
_cancel_timer_ex ( & pmlmeext - > link_timer ) ;
2015-02-19 21:34:32 +00:00
/* _cancel_timer_ex(&pmlmeext->ADDBA_timer); */
2014-12-11 21:15:04 +00:00
}
}
2014-12-17 23:13:53 +00:00
static u8 cmp_pkt_chnl_diff ( struct adapter * padapter , u8 * pframe , uint packet_len )
2015-02-19 21:34:32 +00:00
{ /* if the channel is same, return 0. else return channel differential */
2014-12-11 21:15:04 +00:00
uint len ;
2014-12-19 06:59:46 +00:00
u8 channel ;
u8 * p ;
p = rtw_get_ie ( pframe + WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_ , _DSSET_IE_ , & len , packet_len - _BEACON_IE_OFFSET_ ) ;
if ( p )
{
channel = * ( p + 2 ) ;
if ( padapter - > mlmeextpriv . cur_channel > = channel )
{
return ( padapter - > mlmeextpriv . cur_channel - channel ) ;
}
else
{
return ( channel - padapter - > mlmeextpriv . cur_channel ) ;
}
}
2014-12-11 21:15:04 +00:00
else
2014-12-19 06:59:46 +00:00
{
return 0 ;
2013-05-08 21:45:39 +00:00
}
}
2014-12-17 23:13:53 +00:00
static void _mgt_dispatcher ( struct adapter * padapter , struct mlme_handler * ptable , union recv_frame * precv_frame )
2013-05-08 21:45:39 +00:00
{
2014-12-11 21:15:04 +00:00
u8 bc_addr [ ETH_ALEN ] = { 0xff , 0xff , 0xff , 0xff , 0xff , 0xff } ;
2014-12-19 06:59:46 +00:00
u8 * pframe = precv_frame - > u . hdr . rx_data ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
if ( ptable - > func )
{
2015-02-19 21:34:32 +00:00
/* receive the frames that ra(a1) is my address or ra(a1) is bc address. */
2013-05-08 21:45:39 +00:00
if ( ! _rtw_memcmp ( GetAddr1Ptr ( pframe ) , myid ( & padapter - > eeprompriv ) , ETH_ALEN ) & &
2014-12-19 06:59:46 +00:00
! _rtw_memcmp ( GetAddr1Ptr ( pframe ) , bc_addr , ETH_ALEN ) )
2014-12-11 21:15:04 +00:00
{
2013-05-08 21:45:39 +00:00
return ;
2014-12-11 21:15:04 +00:00
}
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
ptable - > func ( padapter , precv_frame ) ;
2014-12-11 21:15:04 +00:00
}
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-17 23:13:53 +00:00
void mgt_dispatcher ( struct adapter * padapter , union recv_frame * precv_frame )
2013-05-08 21:45:39 +00:00
{
int index ;
struct mlme_handler * ptable ;
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_AP_MODE
2013-05-08 21:45:39 +00:00
struct mlme_priv * pmlmepriv = & padapter - > mlmepriv ;
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_AP_MODE */
2014-12-11 21:15:04 +00:00
u8 bc_addr [ ETH_ALEN ] = { 0xff , 0xff , 0xff , 0xff , 0xff , 0xff } ;
2013-05-08 21:45:39 +00:00
u8 * pframe = precv_frame - > u . hdr . rx_data ;
struct sta_info * psta = rtw_get_stainfo ( & padapter - > stapriv , GetAddr2Ptr ( pframe ) ) ;
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_info_ ,
( " +mgt_dispatcher: type(0x%x) subtype(0x%x) \n " ,
GetFrameType ( pframe ) , GetFrameSubType ( pframe ) ) ) ;
2014-12-11 21:15:04 +00:00
if ( GetFrameType ( pframe ) ! = WIFI_MGT_TYPE )
{
2013-05-08 21:45:39 +00:00
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_err_ , ( " mgt_dispatcher: type(0x%x) error! \n " , GetFrameType ( pframe ) ) ) ;
return ;
}
2015-02-19 21:34:32 +00:00
/* receive the frames that ra(a1) is my address or ra(a1) is bc address. */
2013-05-08 21:45:39 +00:00
if ( ! _rtw_memcmp ( GetAddr1Ptr ( pframe ) , myid ( & padapter - > eeprompriv ) , ETH_ALEN ) & &
2014-12-11 21:15:04 +00:00
! _rtw_memcmp ( GetAddr1Ptr ( pframe ) , bc_addr , ETH_ALEN ) )
{
2013-05-08 21:45:39 +00:00
return ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
ptable = mlme_sta_tbl ;
index = GetFrameSubType ( pframe ) > > 4 ;
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_TDLS
if ( ( index < < 4 ) = = WIFI_ACTION ) {
2015-02-19 21:34:32 +00:00
/* category==public (4), action==TDLS_DISCOVERY_RESPONSE */
2014-12-11 21:15:04 +00:00
if ( * ( pframe + 24 ) = = 0x04 & & * ( pframe + 25 ) = = TDLS_DISCOVERY_RESPONSE ) {
DBG_871X ( " recv tdls discovery response frame \n " ) ;
On_TDLS_Dis_Rsp ( padapter , precv_frame ) ;
}
}
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_TDLS */
2014-12-11 21:15:04 +00:00
if ( index > 13 )
{
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_err_ , ( " Currently we do not support reserved sub-fr-type=%d \n " , index ) ) ;
2013-05-08 21:45:39 +00:00
return ;
}
ptable + = index ;
2014-12-11 21:15:04 +00:00
# if 1
if ( psta ! = NULL )
{
if ( GetRetry ( pframe ) )
{
if ( precv_frame - > u . hdr . attrib . seq_num = = psta - > RxMgmtFrameSeqNum )
{
2013-05-08 21:45:39 +00:00
/* drop the duplicate management frame */
2014-12-11 21:15:04 +00:00
DBG_871X ( " Drop duplicate management frame with seq_num = %d. \n " , precv_frame - > u . hdr . attrib . seq_num ) ;
2013-05-08 21:45:39 +00:00
return ;
}
}
psta - > RxMgmtFrameSeqNum = precv_frame - > u . hdr . attrib . seq_num ;
}
2014-12-11 21:15:04 +00:00
# else
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
if ( GetRetry ( pframe ) )
{
2015-02-19 21:34:32 +00:00
/* RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("drop due to decache!\n")); */
/* return; */
2014-12-11 21:15:04 +00:00
}
# endif
# ifdef CONFIG_AP_MODE
2014-12-19 06:59:46 +00:00
switch ( GetFrameSubType ( pframe ) )
2014-12-11 21:15:04 +00:00
{
case WIFI_AUTH :
2014-12-29 02:13:24 +00:00
if ( check_fwstate ( pmlmepriv , WIFI_AP_STATE ) = = true )
2014-12-11 21:15:04 +00:00
ptable - > func = & OnAuth ;
else
ptable - > func = & OnAuthClient ;
2015-02-19 21:34:32 +00:00
/* pass through */
2014-12-11 21:15:04 +00:00
case WIFI_ASSOCREQ :
case WIFI_REASSOCREQ :
2014-12-19 06:59:46 +00:00
_mgt_dispatcher ( padapter , ptable , precv_frame ) ;
# ifdef CONFIG_HOSTAPD_MLME
2014-12-29 02:13:24 +00:00
if ( check_fwstate ( pmlmepriv , WIFI_AP_STATE ) = = true )
2014-12-11 21:15:04 +00:00
rtw_hostapd_mlme_rx ( padapter , precv_frame ) ;
2014-12-19 06:59:46 +00:00
# endif
2014-12-11 21:15:04 +00:00
break ;
case WIFI_PROBEREQ :
2014-12-29 02:13:24 +00:00
if ( check_fwstate ( pmlmepriv , WIFI_AP_STATE ) = = true )
2014-12-11 21:15:04 +00:00
{
2014-12-19 06:59:46 +00:00
# ifdef CONFIG_HOSTAPD_MLME
rtw_hostapd_mlme_rx ( padapter , precv_frame ) ;
2014-12-11 21:15:04 +00:00
# else
_mgt_dispatcher ( padapter , ptable , precv_frame ) ;
# endif
}
else
_mgt_dispatcher ( padapter , ptable , precv_frame ) ;
break ;
2014-12-19 06:59:46 +00:00
case WIFI_BEACON :
2013-05-19 04:28:07 +00:00
_mgt_dispatcher ( padapter , ptable , precv_frame ) ;
2014-12-11 21:15:04 +00:00
break ;
case WIFI_ACTION :
2015-02-19 21:34:32 +00:00
/* if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) */
2014-12-19 06:59:46 +00:00
_mgt_dispatcher ( padapter , ptable , precv_frame ) ;
2014-12-11 21:15:04 +00:00
break ;
default :
2014-12-19 06:59:46 +00:00
_mgt_dispatcher ( padapter , ptable , precv_frame ) ;
2014-12-29 02:13:24 +00:00
if ( check_fwstate ( pmlmepriv , WIFI_AP_STATE ) = = true )
2014-12-19 06:59:46 +00:00
rtw_hostapd_mlme_rx ( padapter , precv_frame ) ;
2014-12-11 21:15:04 +00:00
break ;
2013-05-08 21:45:39 +00:00
}
# else
2014-12-11 21:15:04 +00:00
2013-05-19 04:28:07 +00:00
_mgt_dispatcher ( padapter , ptable , precv_frame ) ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
# endif
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_P2P
2014-12-19 04:28:04 +00:00
static u32 p2p_listen_state_process ( struct adapter * padapter , unsigned char * da )
2013-05-08 21:45:39 +00:00
{
2014-12-29 02:13:24 +00:00
bool response = true ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
if ( padapter - > wdinfo . driver_interface = = DRIVER_CFG80211 )
{
2014-12-29 02:13:24 +00:00
if ( padapter - > cfg80211_wdinfo . is_ro_ch = = false
2014-12-11 21:15:04 +00:00
| | rtw_get_oper_ch ( padapter ) ! = padapter - > wdinfo . listen_channel
2014-12-29 02:13:24 +00:00
| | wdev_to_priv ( padapter - > rtw_wdev ) - > p2p_enabled = = false
2014-12-11 21:15:04 +00:00
| | padapter - > mlmepriv . wps_probe_resp_ie = = NULL
| | padapter - > mlmepriv . p2p_probe_resp_ie = = NULL
)
{
# ifdef CONFIG_DEBUG_CFG80211
DBG_871X ( " DON'T issue_probersp_p2p: p2p_enabled:%d, wps_probe_resp_ie:%p, p2p_probe_resp_ie:%p, " ,
wdev_to_priv ( padapter - > rtw_wdev ) - > p2p_enabled ,
padapter - > mlmepriv . wps_probe_resp_ie ,
padapter - > mlmepriv . p2p_probe_resp_ie ) ;
2014-12-19 06:59:46 +00:00
DBG_871X ( " is_ro_ch:%d, op_ch:%d, p2p_listen_channel:%d \n " ,
2014-12-11 21:15:04 +00:00
padapter - > cfg80211_wdinfo . is_ro_ch ,
rtw_get_oper_ch ( padapter ) ,
padapter - > wdinfo . listen_channel ) ;
# endif
2014-12-29 02:13:24 +00:00
response = false ;
2014-12-11 21:15:04 +00:00
}
}
else
if ( padapter - > wdinfo . driver_interface = = DRIVER_WEXT )
{
2015-02-19 21:34:32 +00:00
/* do nothing if the device name is empty */
2014-12-11 21:15:04 +00:00
if ( ! padapter - > wdinfo . device_name_len )
{
2014-12-29 02:13:24 +00:00
response = false ;
2014-12-11 21:15:04 +00:00
}
}
2013-05-19 04:28:07 +00:00
2014-12-29 02:13:24 +00:00
if ( response = = true )
2014-12-11 21:15:04 +00:00
issue_probersp_p2p ( padapter , da ) ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
return _SUCCESS ;
}
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_P2P */
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
/****************************************************************************
Following are the callback functions for each subtype of the management frames
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2014-12-17 23:13:53 +00:00
unsigned int OnProbeReq ( struct adapter * padapter , union recv_frame * precv_frame )
2013-05-08 21:45:39 +00:00
{
unsigned int ielen ;
unsigned char * p ;
struct mlme_priv * pmlmepriv = & padapter - > mlmepriv ;
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
2014-12-19 06:59:46 +00:00
WLAN_BSSID_EX * cur = & ( pmlmeinfo - > network ) ;
2013-05-08 21:45:39 +00:00
u8 * pframe = precv_frame - > u . hdr . rx_data ;
uint len = precv_frame - > u . hdr . len ;
2014-12-29 02:13:24 +00:00
u8 is_valid_p2p_probereq = false ;
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_P2P
2013-05-08 21:45:39 +00:00
struct wifidirect_info * pwdinfo = & ( padapter - > wdinfo ) ;
2014-12-11 21:15:04 +00:00
struct rx_pkt_attrib * pattrib = & precv_frame - > u . hdr . attrib ;
2013-05-08 21:45:39 +00:00
u8 wifi_test_chk_rate = 1 ;
2014-12-19 06:59:46 +00:00
if ( ! rtw_p2p_chk_state ( pwdinfo , P2P_STATE_NONE ) & &
! rtw_p2p_chk_state ( pwdinfo , P2P_STATE_IDLE ) & &
2014-12-11 21:15:04 +00:00
! rtw_p2p_chk_role ( pwdinfo , P2P_ROLE_CLIENT ) & &
! rtw_p2p_chk_state ( pwdinfo , P2P_STATE_FIND_PHASE_SEARCH ) & &
! rtw_p2p_chk_state ( pwdinfo , P2P_STATE_SCAN )
)
{
2015-02-19 21:34:32 +00:00
/* Commented by Albert 2011/03/17 */
/* mcs_rate = 0 -> CCK 1M rate */
/* mcs_rate = 1 -> CCK 2M rate */
/* mcs_rate = 2 -> CCK 5.5M rate */
/* mcs_rate = 3 -> CCK 11M rate */
/* In the P2P mode, the driver should not support the CCK rate */
2014-12-11 21:15:04 +00:00
2015-02-19 21:34:32 +00:00
/* Commented by Kurt 2012/10/16 */
/* IOT issue: Google Nexus7 use 1M rate to send p2p_probe_req after GO nego completed and Nexus7 is client */
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_WIFI_TEST
if ( pattrib - > mcs_rate < = 3 )
{
wifi_test_chk_rate = 0 ;
}
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_WIFI_TEST */
2013-05-19 04:28:07 +00:00
2014-12-11 21:15:04 +00:00
if ( wifi_test_chk_rate = = 1 )
{
2014-12-29 02:13:24 +00:00
if ( ( is_valid_p2p_probereq = process_probe_req_p2p_ie ( pwdinfo , pframe , len ) ) = = true )
2014-12-11 21:15:04 +00:00
{
if ( rtw_p2p_chk_role ( pwdinfo , P2P_ROLE_DEVICE ) )
{
p2p_listen_state_process ( padapter , get_sa ( pframe ) ) ;
2013-05-08 21:45:39 +00:00
2014-12-19 06:59:46 +00:00
return _SUCCESS ;
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
if ( rtw_p2p_chk_role ( pwdinfo , P2P_ROLE_GO ) )
{
2013-05-08 21:45:39 +00:00
goto _continue ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
}
}
}
_continue :
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_P2P */
2014-12-11 21:15:04 +00:00
if ( check_fwstate ( pmlmepriv , WIFI_STATION_STATE ) )
{
return _SUCCESS ;
}
2013-05-08 21:45:39 +00:00
2014-12-29 02:13:24 +00:00
if ( check_fwstate ( pmlmepriv , _FW_LINKED ) = = false & &
check_fwstate ( pmlmepriv , WIFI_ADHOC_MASTER_STATE | WIFI_AP_STATE ) = = false )
2014-12-11 21:15:04 +00:00
{
2013-05-08 21:45:39 +00:00
return _SUCCESS ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
p = rtw_get_ie ( pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_ , _SSID_IE_ , ( int * ) & ielen ,
len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_ ) ;
2015-02-19 21:34:32 +00:00
/* check (wildcard) SSID */
2015-02-20 16:05:28 +00:00
if ( p ! = NULL ) {
2014-12-29 02:13:24 +00:00
if ( is_valid_p2p_probereq = = true )
2013-05-08 21:45:39 +00:00
goto _issue_probersp ;
2014-12-29 02:13:24 +00:00
if ( ( ielen ! = 0 & & false = = _rtw_memcmp ( ( void * ) ( p + 2 ) , ( void * ) cur - > Ssid . Ssid , cur - > Ssid . SsidLength ) )
2014-12-11 21:15:04 +00:00
| | ( ielen = = 0 & & pmlmeinfo - > hidden_ssid_mode )
)
2013-05-08 21:45:39 +00:00
return _SUCCESS ;
_issue_probersp :
2014-12-29 02:13:24 +00:00
if ( ( ( check_fwstate ( pmlmepriv , _FW_LINKED ) = = true & &
pmlmepriv - > cur_network . join_res = = true ) ) | | check_fwstate ( pmlmepriv , WIFI_ADHOC_MASTER_STATE ) )
2014-12-11 21:15:04 +00:00
{
2015-02-19 21:34:32 +00:00
/* DBG_871X("+issue_probersp during ap mode\n"); */
2014-12-19 06:59:46 +00:00
issue_probersp ( padapter , get_sa ( pframe ) , is_valid_p2p_probereq ) ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
return _SUCCESS ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-17 23:13:53 +00:00
unsigned int OnProbeRsp ( struct adapter * padapter , union recv_frame * precv_frame )
2013-05-08 21:45:39 +00:00
{
2014-12-11 21:15:04 +00:00
struct sta_info * psta ;
2013-05-08 21:45:39 +00:00
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
2014-12-11 21:15:04 +00:00
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
struct sta_priv * pstapriv = & padapter - > stapriv ;
u8 * pframe = precv_frame - > u . hdr . rx_data ;
# ifdef CONFIG_P2P
2013-05-08 21:45:39 +00:00
struct wifidirect_info * pwdinfo = & padapter - > wdinfo ;
# endif
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_P2P
if ( rtw_p2p_chk_state ( pwdinfo , P2P_STATE_TX_PROVISION_DIS_REQ ) )
{
2014-12-29 02:13:24 +00:00
if ( true = = pwdinfo - > tx_prov_disc_info . benable )
2014-12-11 21:15:04 +00:00
{
if ( _rtw_memcmp ( pwdinfo - > tx_prov_disc_info . peerIFAddr , GetAddr2Ptr ( pframe ) , ETH_ALEN ) )
{
if ( rtw_p2p_chk_role ( pwdinfo , P2P_ROLE_CLIENT ) )
{
2014-12-29 02:13:24 +00:00
pwdinfo - > tx_prov_disc_info . benable = false ;
2014-12-11 21:15:04 +00:00
issue_p2p_provision_request ( padapter ,
2014-12-19 06:59:46 +00:00
pwdinfo - > tx_prov_disc_info . ssid . Ssid ,
2014-12-11 21:15:04 +00:00
pwdinfo - > tx_prov_disc_info . ssid . SsidLength ,
pwdinfo - > tx_prov_disc_info . peerDevAddr ) ;
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
else if ( rtw_p2p_chk_role ( pwdinfo , P2P_ROLE_DEVICE ) | | rtw_p2p_chk_role ( pwdinfo , P2P_ROLE_GO ) )
{
2014-12-29 02:13:24 +00:00
pwdinfo - > tx_prov_disc_info . benable = false ;
2014-12-11 21:15:04 +00:00
issue_p2p_provision_request ( padapter ,
2014-12-19 06:59:46 +00:00
NULL ,
2014-12-11 21:15:04 +00:00
0 ,
pwdinfo - > tx_prov_disc_info . peerDevAddr ) ;
}
2014-12-19 06:59:46 +00:00
}
2013-05-08 21:45:39 +00:00
}
return _SUCCESS ;
2014-12-11 21:15:04 +00:00
}
else if ( rtw_p2p_chk_state ( pwdinfo , P2P_STATE_GONEGO_ING ) )
{
2014-12-29 02:13:24 +00:00
if ( true = = pwdinfo - > nego_req_info . benable )
2014-12-11 21:15:04 +00:00
{
DBG_871X ( " [%s] P2P State is GONEGO ING! \n " , __FUNCTION__ ) ;
if ( _rtw_memcmp ( pwdinfo - > nego_req_info . peerDevAddr , GetAddr2Ptr ( pframe ) , ETH_ALEN ) )
{
2014-12-29 02:13:24 +00:00
pwdinfo - > nego_req_info . benable = false ;
2014-12-11 21:15:04 +00:00
issue_p2p_GO_request ( padapter , pwdinfo - > nego_req_info . peerDevAddr ) ;
2013-05-08 21:45:39 +00:00
}
}
2014-12-11 21:15:04 +00:00
}
else if ( rtw_p2p_chk_state ( pwdinfo , P2P_STATE_TX_INVITE_REQ ) )
{
2014-12-29 02:13:24 +00:00
if ( true = = pwdinfo - > invitereq_info . benable )
2014-12-11 21:15:04 +00:00
{
DBG_871X ( " [%s] P2P_STATE_TX_INVITE_REQ! \n " , __FUNCTION__ ) ;
if ( _rtw_memcmp ( pwdinfo - > invitereq_info . peer_macaddr , GetAddr2Ptr ( pframe ) , ETH_ALEN ) )
{
2014-12-29 02:13:24 +00:00
pwdinfo - > invitereq_info . benable = false ;
2014-12-11 21:15:04 +00:00
issue_p2p_invitation_request ( padapter , pwdinfo - > invitereq_info . peer_macaddr ) ;
2013-05-08 21:45:39 +00:00
}
}
}
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_P2P */
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
if ( pmlmeext - > sitesurvey_res . state = = SCAN_PROCESS )
{
2014-12-19 06:59:46 +00:00
report_survey_event ( padapter , precv_frame ) ;
2013-05-08 21:45:39 +00:00
return _SUCCESS ;
}
return _SUCCESS ;
}
2014-12-17 23:13:53 +00:00
unsigned int OnBeacon ( struct adapter * padapter , union recv_frame * precv_frame )
2013-05-08 21:45:39 +00:00
{
int cam_idx ;
struct sta_info * psta ;
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
struct mlme_priv * pmlmepriv = & padapter - > mlmepriv ;
struct sta_priv * pstapriv = & padapter - > stapriv ;
u8 * pframe = precv_frame - > u . hdr . rx_data ;
uint len = precv_frame - > u . hdr . len ;
2014-12-11 21:15:04 +00:00
WLAN_BSSID_EX * pbss ;
2013-05-08 21:45:39 +00:00
int ret = _SUCCESS ;
2014-12-11 21:15:04 +00:00
u8 * p = NULL ;
u32 ielen = 0 ;
# ifdef CONFIG_ATTEMPT_TO_FIX_AP_BEACON_ERROR
p = rtw_get_ie ( pframe + sizeof ( struct rtw_ieee80211_hdr_3addr ) + _BEACON_IE_OFFSET_ , _EXT_SUPPORTEDRATES_IE_ , & ielen , precv_frame - > u . hdr . len - sizeof ( struct rtw_ieee80211_hdr_3addr ) - _BEACON_IE_OFFSET_ ) ;
if ( ( p ! = NULL ) & & ( ielen > 0 ) )
{
if ( ( * ( p + 1 + ielen ) = = 0x2D ) & & ( * ( p + 2 + ielen ) ! = 0x2D ) )
{
2014-12-19 06:59:46 +00:00
/* Invalid value 0x2D is detected in Extended Supported Rates (ESR) IE. Try to fix the IE length to avoid failed Beacon parsing. */
DBG_871X ( " [WIFIDBG] Error in ESR IE is detected in Beacon of BSSID: " MAC_FMT " . Fix the length of ESR IE to avoid failed Beacon parsing. \n " , MAC_ARG ( GetAddr3Ptr ( pframe ) ) ) ;
* ( p + 1 ) = ielen - 1 ;
2014-12-11 21:15:04 +00:00
}
}
# endif
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
if ( pmlmeext - > sitesurvey_res . state = = SCAN_PROCESS )
{
2013-05-08 21:45:39 +00:00
report_survey_event ( padapter , precv_frame ) ;
return _SUCCESS ;
}
2014-12-11 21:15:04 +00:00
if ( _rtw_memcmp ( GetAddr3Ptr ( pframe ) , get_my_bssid ( & pmlmeinfo - > network ) , ETH_ALEN ) )
{
if ( pmlmeinfo - > state & WIFI_FW_AUTH_NULL )
{
2015-02-19 21:34:32 +00:00
/* we should update current network before auth, or some IE is wrong */
2014-12-11 21:15:04 +00:00
pbss = ( WLAN_BSSID_EX * ) rtw_malloc ( sizeof ( WLAN_BSSID_EX ) ) ;
2013-05-08 21:45:39 +00:00
if ( pbss ) {
if ( collect_bss_info ( padapter , precv_frame , pbss ) = = _SUCCESS ) {
2014-12-29 02:13:24 +00:00
update_network ( & ( pmlmepriv - > cur_network . network ) , pbss , padapter , true ) ;
2013-05-08 21:45:39 +00:00
rtw_get_bcn_info ( & ( pmlmepriv - > cur_network ) ) ;
}
2014-12-11 21:15:04 +00:00
rtw_mfree ( ( u8 * ) pbss , sizeof ( WLAN_BSSID_EX ) ) ;
2013-05-08 21:45:39 +00:00
}
2015-02-19 21:34:32 +00:00
/* check the vendor of the assoc AP */
2014-12-19 06:59:46 +00:00
pmlmeinfo - > assoc_AP_vendor = check_assoc_AP ( pframe + sizeof ( struct rtw_ieee80211_hdr_3addr ) , len - sizeof ( struct rtw_ieee80211_hdr_3addr ) ) ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* update TSF Value */
2013-05-08 21:45:39 +00:00
update_TSF ( pmlmeext , pframe , len ) ;
2015-02-19 21:34:32 +00:00
/* start auth */
2013-05-08 21:45:39 +00:00
start_clnt_auth ( padapter ) ;
return _SUCCESS ;
}
2014-12-11 21:15:04 +00:00
if ( ( ( pmlmeinfo - > state & 0x03 ) = = WIFI_FW_STATION_STATE ) & & ( pmlmeinfo - > state & WIFI_FW_ASSOC_SUCCESS ) )
{
if ( ( psta = rtw_get_stainfo ( pstapriv , GetAddr2Ptr ( pframe ) ) ) ! = NULL )
{
2014-12-19 06:59:46 +00:00
# ifdef CONFIG_PATCH_JOIN_WRONG_CHANNEL
2015-02-19 21:34:32 +00:00
/* Merge from 8712 FW code */
2014-12-19 06:59:46 +00:00
if ( cmp_pkt_chnl_diff ( padapter , pframe , len ) ! = 0 )
2015-02-19 21:34:32 +00:00
{ /* join wrong channel, deauth and reconnect */
2014-12-11 21:15:04 +00:00
issue_deauth ( padapter , ( & ( pmlmeinfo - > network ) ) - > MacAddress , WLAN_REASON_DEAUTH_LEAVING ) ;
2014-12-19 06:59:46 +00:00
report_del_sta_event ( padapter , ( & ( pmlmeinfo - > network ) ) - > MacAddress , WLAN_REASON_JOIN_WRONG_CHANNEL ) ;
pmlmeinfo - > state & = ( ~ WIFI_FW_ASSOC_SUCCESS ) ;
2014-12-11 21:15:04 +00:00
return _SUCCESS ;
2014-12-19 06:59:46 +00:00
}
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_PATCH_JOIN_WRONG_CHANNEL */
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
ret = rtw_check_bcn_info ( padapter , pframe , len ) ;
if ( ! ret ) {
2014-12-11 21:15:04 +00:00
DBG_871X_LEVEL ( _drv_always_ , " ap has changed, disconnect now \n " ) ;
receive_disconnect ( padapter , pmlmeinfo - > network . MacAddress , 0 ) ;
2013-05-08 21:45:39 +00:00
return _SUCCESS ;
}
2015-02-19 21:34:32 +00:00
/* update WMM, ERP in the beacon */
/* todo: the timer is used instead of the number of the beacon received */
2013-05-08 21:45:39 +00:00
if ( ( sta_rx_pkts ( psta ) & 0xf ) = = 0 )
2014-12-11 21:15:04 +00:00
{
2015-02-19 21:34:32 +00:00
/* DBG_871X("update_bcn_info\n"); */
2013-05-08 21:45:39 +00:00
update_beacon_info ( padapter , pframe , len , psta ) ;
2014-12-11 21:15:04 +00:00
}
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_DFS
2015-02-19 21:34:32 +00:00
process_csa_ie ( padapter , pframe , len ) ; /* channel switch announcement */
# endif /* CONFIG_DFS */
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_P2P_PS
2013-05-08 21:45:39 +00:00
process_p2p_ps_ie ( padapter , ( pframe + WLAN_HDR_A3_LEN ) , ( len - WLAN_HDR_A3_LEN ) ) ;
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_P2P_PS */
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
}
else if ( ( pmlmeinfo - > state & 0x03 ) = = WIFI_FW_ADHOC_STATE )
{
if ( ( psta = rtw_get_stainfo ( pstapriv , GetAddr2Ptr ( pframe ) ) ) ! = NULL )
{
2015-02-19 21:34:32 +00:00
/* update WMM, ERP in the beacon */
/* todo: the timer is used instead of the number of the beacon received */
2013-05-08 21:45:39 +00:00
if ( ( sta_rx_pkts ( psta ) & 0xf ) = = 0 )
2014-12-11 21:15:04 +00:00
{
2015-02-19 21:34:32 +00:00
/* DBG_871X("update_bcn_info\n"); */
2013-05-08 21:45:39 +00:00
update_beacon_info ( padapter , pframe , len , psta ) ;
2014-12-11 21:15:04 +00:00
}
}
else
{
2015-02-19 21:34:32 +00:00
/* allocate a new CAM entry for IBSS station */
2014-12-11 21:15:04 +00:00
if ( ( cam_idx = allocate_fw_sta_entry ( padapter ) ) = = NUM_STA )
{
2013-05-08 21:45:39 +00:00
goto _END_ONBEACON_ ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* get supported rate */
2014-12-11 21:15:04 +00:00
if ( update_sta_support_rate ( padapter , ( pframe + WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_ ) , ( len - WLAN_HDR_A3_LEN - _BEACON_IE_OFFSET_ ) , cam_idx ) = = _FAIL )
{
2013-05-08 21:45:39 +00:00
pmlmeinfo - > FW_sta_info [ cam_idx ] . status = 0 ;
goto _END_ONBEACON_ ;
}
2015-02-19 21:34:32 +00:00
/* update TSF Value */
2014-12-19 06:59:46 +00:00
update_TSF ( pmlmeext , pframe , len ) ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* report sta add event */
2013-05-08 21:45:39 +00:00
report_add_sta_event ( padapter , GetAddr2Ptr ( pframe ) , cam_idx ) ;
}
}
}
_END_ONBEACON_ :
return _SUCCESS ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-17 23:13:53 +00:00
unsigned int OnAuth ( struct adapter * padapter , union recv_frame * precv_frame )
2013-05-08 21:45:39 +00:00
{
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_AP_MODE
_irqL irqL ;
2014-12-19 06:59:46 +00:00
unsigned int auth_mode , seq , ie_len ;
unsigned char * sa , * p ;
2014-12-11 21:15:04 +00:00
u16 algorithm ;
2013-05-08 21:45:39 +00:00
int status ;
2014-12-19 06:59:46 +00:00
static struct sta_info stat ;
struct sta_info * pstat = NULL ;
2013-05-08 21:45:39 +00:00
struct sta_priv * pstapriv = & padapter - > stapriv ;
struct security_priv * psecuritypriv = & padapter - > securitypriv ;
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
2014-12-19 06:59:46 +00:00
u8 * pframe = precv_frame - > u . hdr . rx_data ;
2013-05-08 21:45:39 +00:00
uint len = precv_frame - > u . hdr . len ;
2014-12-11 21:15:04 +00:00
if ( ( pmlmeinfo - > state & 0x03 ) ! = WIFI_FW_AP_STATE )
return _FAIL ;
2013-05-19 04:28:07 +00:00
2014-12-11 21:15:04 +00:00
DBG_871X ( " +OnAuth \n " ) ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
sa = GetAddr2Ptr ( pframe ) ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
auth_mode = psecuritypriv - > dot11AuthAlgrthm ;
2014-12-19 04:28:04 +00:00
seq = le16_to_cpu ( * ( __le16 * ) ( ( SIZE_PTR ) pframe + WLAN_HDR_A3_LEN + 2 ) ) ;
algorithm = le16_to_cpu ( * ( __le16 * ) ( ( SIZE_PTR ) pframe + WLAN_HDR_A3_LEN ) ) ;
2014-12-11 21:15:04 +00:00
DBG_871X ( " auth alg=%x, seq=%X \n " , algorithm , seq ) ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
if ( auth_mode = = 2 & &
psecuritypriv - > dot11PrivacyAlgrthm ! = _WEP40_ & &
psecuritypriv - > dot11PrivacyAlgrthm ! = _WEP104_ )
2013-05-08 21:45:39 +00:00
auth_mode = 0 ;
2015-02-19 21:34:32 +00:00
if ( ( algorithm > 0 & & auth_mode = = 0 ) | | /* rx a shared-key auth but shared not enabled */
( algorithm = = 0 & & auth_mode = = 1 ) ) /* rx a open-system auth but shared-key is enabled */
2014-12-19 06:59:46 +00:00
{
2014-12-11 21:15:04 +00:00
DBG_871X ( " auth rejected due to bad alg [alg=%d, auth_mib=%d] %02X%02X%02X%02X%02X%02X \n " ,
2013-05-08 21:45:39 +00:00
algorithm , auth_mode , sa [ 0 ] , sa [ 1 ] , sa [ 2 ] , sa [ 3 ] , sa [ 4 ] , sa [ 5 ] ) ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
status = _STATS_NO_SUPP_ALG_ ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
goto auth_fail ;
}
2014-12-19 06:59:46 +00:00
2014-12-29 02:13:24 +00:00
if ( rtw_access_ctrl ( padapter , sa ) = = false ) {
2013-05-08 21:45:39 +00:00
status = _STATS_UNABLE_HANDLE_STA_ ;
goto auth_fail ;
2014-12-19 06:59:46 +00:00
}
2013-05-08 21:45:39 +00:00
pstat = rtw_get_stainfo ( pstapriv , sa ) ;
2014-12-11 21:15:04 +00:00
if ( pstat = = NULL )
{
2015-02-19 21:34:32 +00:00
/* allocate a new one */
2014-12-11 21:15:04 +00:00
DBG_871X ( " going to alloc stainfo for sa= " MAC_FMT " \n " , MAC_ARG ( sa ) ) ;
2013-05-08 21:45:39 +00:00
pstat = rtw_alloc_stainfo ( pstapriv , sa ) ;
2014-12-11 21:15:04 +00:00
if ( pstat = = NULL )
{
DBG_871X ( " Exceed the upper limit of supported clients... \n " ) ;
2013-05-08 21:45:39 +00:00
status = _STATS_UNABLE_HANDLE_STA_ ;
goto auth_fail ;
}
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
pstat - > state = WIFI_FW_AUTH_NULL ;
pstat - > auth_seq = 0 ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* pstat->flags = 0; */
/* pstat->capability = 0; */
2014-12-11 21:15:04 +00:00
}
else
2014-12-19 06:59:46 +00:00
{
2014-12-11 21:15:04 +00:00
_enter_critical_bh ( & pstapriv - > asoc_list_lock , & irqL ) ;
2014-12-29 02:13:24 +00:00
if ( rtw_is_list_empty ( & pstat - > asoc_list ) = = false )
2014-12-19 06:59:46 +00:00
{
2013-05-08 21:45:39 +00:00
rtw_list_delete ( & pstat - > asoc_list ) ;
pstapriv - > asoc_list_cnt - - ;
2014-12-11 21:15:04 +00:00
if ( pstat - > expire_to > 0 )
{
2015-02-19 21:34:32 +00:00
/* TODO: STA re_auth within expire_to */
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
_exit_critical_bh ( & pstapriv - > asoc_list_lock , & irqL ) ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
if ( seq = = 1 ) {
2015-02-19 21:34:32 +00:00
/* TODO: STA re_auth and auth timeout */
2013-05-08 21:45:39 +00:00
}
}
2014-12-11 21:15:04 +00:00
_enter_critical_bh ( & pstapriv - > auth_list_lock , & irqL ) ;
if ( rtw_is_list_empty ( & pstat - > auth_list ) )
2014-12-19 06:59:46 +00:00
{
2013-05-08 21:45:39 +00:00
rtw_list_insert_tail ( & pstat - > auth_list , & pstapriv - > auth_list ) ;
pstapriv - > auth_list_cnt + + ;
2014-12-19 06:59:46 +00:00
}
2014-12-11 21:15:04 +00:00
_exit_critical_bh ( & pstapriv - > auth_list_lock , & irqL ) ;
2013-05-08 21:45:39 +00:00
if ( pstat - > auth_seq = = 0 )
pstat - > expire_to = pstapriv - > auth_to ;
2014-12-11 21:15:04 +00:00
if ( ( pstat - > auth_seq + 1 ) ! = seq )
{
DBG_871X ( " (1)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]! \n " ,
2013-05-08 21:45:39 +00:00
seq , pstat - > auth_seq + 1 ) ;
status = _STATS_OUT_OF_AUTH_SEQ_ ;
goto auth_fail ;
}
2014-12-11 21:15:04 +00:00
if ( algorithm = = 0 & & ( auth_mode = = 0 | | auth_mode = = 2 ) )
{
if ( seq = = 1 )
{
2013-05-08 21:45:39 +00:00
pstat - > state & = ~ WIFI_FW_AUTH_NULL ;
pstat - > state | = WIFI_FW_AUTH_SUCCESS ;
pstat - > expire_to = pstapriv - > assoc_to ;
2013-06-20 15:13:14 +00:00
pstat - > authalg = algorithm ;
2014-12-11 21:15:04 +00:00
}
else
{
DBG_871X ( " (2)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]! \n " ,
2013-05-08 21:45:39 +00:00
seq , pstat - > auth_seq + 1 ) ;
status = _STATS_OUT_OF_AUTH_SEQ_ ;
goto auth_fail ;
}
2014-12-11 21:15:04 +00:00
}
2015-02-19 21:34:32 +00:00
else /* shared system or auto authentication */
2014-12-11 21:15:04 +00:00
{
if ( seq = = 1 )
{
2015-02-19 21:34:32 +00:00
/* prepare for the challenging txt... */
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
pstat - > state & = ~ WIFI_FW_AUTH_NULL ;
pstat - > state | = WIFI_FW_AUTH_STATE ;
2013-06-20 15:13:14 +00:00
pstat - > authalg = algorithm ;
2013-05-08 21:45:39 +00:00
pstat - > auth_seq = 2 ;
2014-12-11 21:15:04 +00:00
}
else if ( seq = = 3 )
{
2015-02-19 21:34:32 +00:00
/* checking for challenging txt... */
2014-12-11 21:15:04 +00:00
DBG_871X ( " checking for challenging txt... \n " ) ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
p = rtw_get_ie ( pframe + WLAN_HDR_A3_LEN + 4 + _AUTH_IE_OFFSET_ , _CHLGETXT_IE_ , ( int * ) & ie_len ,
len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_ - 4 ) ;
2014-12-11 21:15:04 +00:00
if ( ( p = = NULL ) | | ( ie_len < = 0 ) )
{
DBG_871X ( " auth rejected because challenge failure!(1) \n " ) ;
2013-05-08 21:45:39 +00:00
status = _STATS_CHALLENGE_FAIL_ ;
goto auth_fail ;
}
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
if ( _rtw_memcmp ( ( void * ) ( p + 2 ) , pstat - > chg_txt , 128 ) )
{
2013-05-08 21:45:39 +00:00
pstat - > state & = ( ~ WIFI_FW_AUTH_STATE ) ;
pstat - > state | = WIFI_FW_AUTH_SUCCESS ;
2015-02-19 21:34:32 +00:00
/* challenging txt is correct... */
2013-05-08 21:45:39 +00:00
pstat - > expire_to = pstapriv - > assoc_to ;
2014-12-11 21:15:04 +00:00
}
else
{
DBG_871X ( " auth rejected because challenge failure! \n " ) ;
2013-05-08 21:45:39 +00:00
status = _STATS_CHALLENGE_FAIL_ ;
goto auth_fail ;
}
2014-12-11 21:15:04 +00:00
}
else
{
DBG_871X ( " (3)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]! \n " ,
2013-05-08 21:45:39 +00:00
seq , pstat - > auth_seq + 1 ) ;
status = _STATS_OUT_OF_AUTH_SEQ_ ;
goto auth_fail ;
}
}
2013-05-19 04:28:07 +00:00
2015-02-19 21:34:32 +00:00
/* Now, we are going to issue_auth... */
2014-12-19 06:59:46 +00:00
pstat - > auth_seq = seq + 1 ;
2013-05-08 21:45:39 +00:00
issue_auth ( padapter , pstat , ( unsigned short ) ( _STATS_SUCCESSFUL_ ) ) ;
if ( pstat - > state & WIFI_FW_AUTH_SUCCESS )
pstat - > auth_seq = 0 ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
return _SUCCESS ;
auth_fail :
2014-12-11 21:15:04 +00:00
if ( pstat )
2013-05-08 21:45:39 +00:00
rtw_free_stainfo ( padapter , pstat ) ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
pstat = & stat ;
2015-02-19 20:58:09 +00:00
memset ( ( char * ) pstat , ' \0 ' , sizeof ( stat ) ) ;
2013-05-08 21:45:39 +00:00
pstat - > auth_seq = 2 ;
2015-02-19 20:50:04 +00:00
memcpy ( pstat - > hwaddr , sa , 6 ) ;
2014-12-19 06:59:46 +00:00
issue_auth ( padapter , pstat , ( unsigned short ) status ) ;
2013-05-08 21:45:39 +00:00
# endif
return _FAIL ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-17 23:13:53 +00:00
unsigned int OnAuthClient ( struct adapter * padapter , union recv_frame * precv_frame )
2013-05-08 21:45:39 +00:00
{
2014-12-11 21:15:04 +00:00
unsigned int seq , len , status , algthm , offset ;
2013-05-08 21:45:39 +00:00
unsigned char * p ;
unsigned int go2asoc = 0 ;
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
u8 * pframe = precv_frame - > u . hdr . rx_data ;
uint pkt_len = precv_frame - > u . hdr . len ;
2014-12-11 21:15:04 +00:00
DBG_871X ( " %s \n " , __FUNCTION__ ) ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* check A1 matches or not */
2013-05-08 21:45:39 +00:00
if ( ! _rtw_memcmp ( myid ( & ( padapter - > eeprompriv ) ) , get_da ( pframe ) , ETH_ALEN ) )
return _SUCCESS ;
if ( ! ( pmlmeinfo - > state & WIFI_FW_AUTH_STATE ) )
return _SUCCESS ;
2014-12-11 21:15:04 +00:00
offset = ( GetPrivacy ( pframe ) ) ? 4 : 0 ;
2013-05-08 21:45:39 +00:00
2014-12-19 06:59:46 +00:00
algthm = le16_to_cpu ( * ( __le16 * ) ( ( SIZE_PTR ) pframe + WLAN_HDR_A3_LEN + offset ) ) ;
seq = le16_to_cpu ( * ( __le16 * ) ( ( SIZE_PTR ) pframe + WLAN_HDR_A3_LEN + offset + 2 ) ) ;
status = le16_to_cpu ( * ( __le16 * ) ( ( SIZE_PTR ) pframe + WLAN_HDR_A3_LEN + offset + 4 ) ) ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
if ( status ! = 0 )
{
DBG_871X ( " clnt auth fail, status: %d \n " , status ) ;
2015-02-19 21:34:32 +00:00
if ( status = = 13 ) /* pmlmeinfo->auth_algo == dot11AuthAlgrthm_Auto) */
2014-12-11 21:15:04 +00:00
{
if ( pmlmeinfo - > auth_algo = = dot11AuthAlgrthm_Shared )
2013-05-08 21:45:39 +00:00
pmlmeinfo - > auth_algo = dot11AuthAlgrthm_Open ;
else
pmlmeinfo - > auth_algo = dot11AuthAlgrthm_Shared ;
2015-02-19 21:34:32 +00:00
/* pmlmeinfo->reauth_count = 0; */
2013-05-08 21:45:39 +00:00
}
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
set_link_timer ( pmlmeext , 1 ) ;
goto authclnt_fail ;
}
2014-12-11 21:15:04 +00:00
if ( seq = = 2 )
{
if ( pmlmeinfo - > auth_algo = = dot11AuthAlgrthm_Shared )
{
2015-02-19 21:34:32 +00:00
/* legendary shared system */
2013-05-08 21:45:39 +00:00
p = rtw_get_ie ( pframe + WLAN_HDR_A3_LEN + _AUTH_IE_OFFSET_ , _CHLGETXT_IE_ , ( int * ) & len ,
pkt_len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_ ) ;
if ( p = = NULL )
2014-12-11 21:15:04 +00:00
{
2015-02-19 21:34:32 +00:00
/* DBG_871X("marc: no challenge text?\n"); */
2013-05-08 21:45:39 +00:00
goto authclnt_fail ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
2015-02-19 20:50:04 +00:00
memcpy ( ( void * ) ( pmlmeinfo - > chg_txt ) , ( void * ) ( p + 2 ) , len ) ;
2013-05-08 21:45:39 +00:00
pmlmeinfo - > auth_seq = 3 ;
issue_auth ( padapter , NULL , 0 ) ;
set_link_timer ( pmlmeext , REAUTH_TO ) ;
return _SUCCESS ;
2014-12-11 21:15:04 +00:00
}
else
{
2015-02-19 21:34:32 +00:00
/* open system */
2013-05-08 21:45:39 +00:00
go2asoc = 1 ;
}
2014-12-11 21:15:04 +00:00
}
else if ( seq = = 4 )
{
2013-05-08 21:45:39 +00:00
if ( pmlmeinfo - > auth_algo = = dot11AuthAlgrthm_Shared )
2014-12-11 21:15:04 +00:00
{
2013-05-08 21:45:39 +00:00
go2asoc = 1 ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
else
2014-12-11 21:15:04 +00:00
{
2013-05-08 21:45:39 +00:00
goto authclnt_fail ;
2014-12-11 21:15:04 +00:00
}
}
else
{
2015-02-19 21:34:32 +00:00
/* this is also illegal */
/* DBG_871X("marc: clnt auth failed due to illegal seq=%x\n", seq); */
2013-05-08 21:45:39 +00:00
goto authclnt_fail ;
}
2014-12-11 21:15:04 +00:00
if ( go2asoc )
{
DBG_871X_LEVEL ( _drv_always_ , " auth success, start assoc \n " ) ;
2013-05-08 21:45:39 +00:00
start_clnt_assoc ( padapter ) ;
return _SUCCESS ;
}
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
authclnt_fail :
2014-12-11 21:15:04 +00:00
2015-02-19 21:34:32 +00:00
/* pmlmeinfo->state &= ~(WIFI_FW_AUTH_STATE); */
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
return _FAIL ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-17 23:13:53 +00:00
unsigned int OnAssocReq ( struct adapter * padapter , union recv_frame * precv_frame )
2013-05-08 21:45:39 +00:00
{
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_AP_MODE
_irqL irqL ;
u16 capab_info , listen_interval ;
2014-12-19 06:59:46 +00:00
struct rtw_ieee802_11_elems elems ;
2013-05-08 21:45:39 +00:00
struct sta_info * pstat ;
unsigned char reassoc , * p , * pos , * wpa_ie ;
unsigned char WMM_IE [ ] = { 0x00 , 0x50 , 0xf2 , 0x02 , 0x00 , 0x01 } ;
int i , ie_len , wpa_ie_len , left ;
unsigned char supportRate [ 16 ] ;
int supportRateNum ;
unsigned short status = _STATS_SUCCESSFUL_ ;
2014-12-19 06:59:46 +00:00
unsigned short frame_type , ie_offset = 0 ;
2013-05-08 21:45:39 +00:00
struct mlme_priv * pmlmepriv = & padapter - > mlmepriv ;
struct security_priv * psecuritypriv = & padapter - > securitypriv ;
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
2014-12-19 06:59:46 +00:00
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
WLAN_BSSID_EX * cur = & ( pmlmeinfo - > network ) ;
2013-05-08 21:45:39 +00:00
struct sta_priv * pstapriv = & padapter - > stapriv ;
u8 * pframe = precv_frame - > u . hdr . rx_data ;
uint pkt_len = precv_frame - > u . hdr . len ;
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_P2P
2013-05-08 21:45:39 +00:00
struct wifidirect_info * pwdinfo = & ( padapter - > wdinfo ) ;
u8 p2p_status_code = P2P_STATUS_SUCCESS ;
u8 * p2pie ;
u32 p2pielen = 0 ;
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_WFD
u8 wfd_ie [ 128 ] = { 0x00 } ;
u32 wfd_ielen = 0 ;
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_WFD */
# endif /* CONFIG_P2P */
2014-12-11 21:15:04 +00:00
if ( ( pmlmeinfo - > state & 0x03 ) ! = WIFI_FW_AP_STATE )
2013-05-08 21:45:39 +00:00
return _FAIL ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
frame_type = GetFrameSubType ( pframe ) ;
2014-12-11 21:15:04 +00:00
if ( frame_type = = WIFI_ASSOCREQ )
{
2013-05-08 21:45:39 +00:00
reassoc = 0 ;
ie_offset = _ASOCREQ_IE_OFFSET_ ;
2014-12-19 06:59:46 +00:00
}
2015-02-19 21:34:32 +00:00
else /* WIFI_REASSOCREQ */
2014-12-11 21:15:04 +00:00
{
2013-05-08 21:45:39 +00:00
reassoc = 1 ;
ie_offset = _REASOCREQ_IE_OFFSET_ ;
}
2014-12-19 06:59:46 +00:00
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
if ( pkt_len < IEEE80211_3ADDR_LEN + ie_offset ) {
2014-12-11 21:15:04 +00:00
DBG_871X ( " handle_assoc(reassoc=%d) - too short payload (len=%lu) "
2013-05-08 21:45:39 +00:00
" \n " , reassoc , ( unsigned long ) pkt_len ) ;
return _FAIL ;
}
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
pstat = rtw_get_stainfo ( pstapriv , GetAddr2Ptr ( pframe ) ) ;
2014-12-11 21:15:04 +00:00
if ( pstat = = ( struct sta_info * ) NULL )
{
2013-05-08 21:45:39 +00:00
status = _RSON_CLS2_ ;
goto asoc_class2_error ;
}
capab_info = RTW_GET_LE16 ( pframe + WLAN_HDR_A3_LEN ) ;
2015-02-19 21:34:32 +00:00
/* capab_info = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN)); */
/* listen_interval = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN+2)); */
2014-12-11 21:15:04 +00:00
listen_interval = RTW_GET_LE16 ( pframe + WLAN_HDR_A3_LEN + 2 ) ;
2013-05-08 21:45:39 +00:00
left = pkt_len - ( IEEE80211_3ADDR_LEN + ie_offset ) ;
pos = pframe + ( IEEE80211_3ADDR_LEN + ie_offset ) ;
2014-12-19 06:59:46 +00:00
2013-05-19 04:28:07 +00:00
2014-12-11 21:15:04 +00:00
DBG_871X ( " %s \n " , __FUNCTION__ ) ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* check if this stat has been successfully authenticated/assocated */
2014-12-11 21:15:04 +00:00
if ( ! ( ( pstat - > state ) & WIFI_FW_AUTH_SUCCESS ) )
{
if ( ! ( ( pstat - > state ) & WIFI_FW_ASSOC_SUCCESS ) )
{
2013-05-08 21:45:39 +00:00
status = _RSON_CLS2_ ;
goto asoc_class2_error ;
2014-12-11 21:15:04 +00:00
}
else
{
2013-05-08 21:45:39 +00:00
pstat - > state & = ( ~ WIFI_FW_ASSOC_SUCCESS ) ;
2014-12-19 06:59:46 +00:00
pstat - > state | = WIFI_FW_ASSOC_STATE ;
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
}
else
{
2013-05-08 21:45:39 +00:00
pstat - > state & = ( ~ WIFI_FW_AUTH_SUCCESS ) ;
pstat - > state | = WIFI_FW_ASSOC_STATE ;
}
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
pstat - > capability = capab_info ;
2014-12-11 21:15:04 +00:00
2015-02-19 21:34:32 +00:00
/* now parse all ieee802_11 ie to point to elems */
2013-05-08 21:45:39 +00:00
if ( rtw_ieee802_11_parse_elems ( pos , left , & elems , 1 ) = = ParseFailed | |
! elems . ssid ) {
2014-12-11 21:15:04 +00:00
DBG_871X ( " STA " MAC_FMT " sent invalid association request \n " ,
MAC_ARG ( pstat - > hwaddr ) ) ;
2014-12-19 06:59:46 +00:00
status = _STATS_FAILURE_ ;
2013-05-08 21:45:39 +00:00
goto OnAssocReqFail ;
}
2015-02-19 21:34:32 +00:00
/* now we should check all the fields... */
/* checking SSID */
2013-05-08 21:45:39 +00:00
p = rtw_get_ie ( pframe + WLAN_HDR_A3_LEN + ie_offset , _SSID_IE_ , & ie_len ,
pkt_len - WLAN_HDR_A3_LEN - ie_offset ) ;
if ( p = = NULL )
2014-12-11 21:15:04 +00:00
{
2014-12-19 06:59:46 +00:00
status = _STATS_FAILURE_ ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
if ( ie_len = = 0 ) /* broadcast ssid, however it is not allowed in assocreq */
2013-05-08 21:45:39 +00:00
status = _STATS_FAILURE_ ;
2014-12-11 21:15:04 +00:00
else
{
2015-02-19 21:34:32 +00:00
/* check if ssid match */
2013-05-08 21:45:39 +00:00
if ( ! _rtw_memcmp ( ( void * ) ( p + 2 ) , cur - > Ssid . Ssid , cur - > Ssid . SsidLength ) )
status = _STATS_FAILURE_ ;
if ( ie_len ! = cur - > Ssid . SsidLength )
status = _STATS_FAILURE_ ;
}
2014-12-11 21:15:04 +00:00
if ( _STATS_SUCCESSFUL_ ! = status )
2013-05-08 21:45:39 +00:00
goto OnAssocReqFail ;
2015-02-19 21:34:32 +00:00
/* check if the supported rate is ok */
2013-05-08 21:45:39 +00:00
p = rtw_get_ie ( pframe + WLAN_HDR_A3_LEN + ie_offset , _SUPPORTEDRATES_IE_ , & ie_len , pkt_len - WLAN_HDR_A3_LEN - ie_offset ) ;
if ( p = = NULL ) {
2014-12-11 21:15:04 +00:00
DBG_871X ( " Rx a sta assoc-req which supported rate is empty! \n " ) ;
2015-02-19 21:34:32 +00:00
/* use our own rate set as statoin used */
/* memcpy(supportRate, AP_BSSRATE, AP_BSSRATE_LEN); */
/* supportRateNum = AP_BSSRATE_LEN; */
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
status = _STATS_FAILURE_ ;
goto OnAssocReqFail ;
2014-12-11 21:15:04 +00:00
}
else {
2015-02-19 20:50:04 +00:00
memcpy ( supportRate , p + 2 , ie_len ) ;
2013-05-08 21:45:39 +00:00
supportRateNum = ie_len ;
p = rtw_get_ie ( pframe + WLAN_HDR_A3_LEN + ie_offset , _EXT_SUPPORTEDRATES_IE_ , & ie_len ,
pkt_len - WLAN_HDR_A3_LEN - ie_offset ) ;
if ( p ! = NULL ) {
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
if ( supportRateNum < = sizeof ( supportRate ) )
{
2015-02-19 20:50:04 +00:00
memcpy ( supportRate + supportRateNum , p + 2 , ie_len ) ;
2013-05-08 21:45:39 +00:00
supportRateNum + = ie_len ;
2014-12-19 06:59:46 +00:00
}
2013-05-08 21:45:39 +00:00
}
}
2015-02-19 21:34:32 +00:00
/* todo: mask supportRate between AP & STA -> move to update raid */
/* get_matched_rate(pmlmeext, supportRate, &supportRateNum, 0); */
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* update station supportRate */
2013-05-08 21:45:39 +00:00
pstat - > bssratelen = supportRateNum ;
2015-02-19 20:50:04 +00:00
memcpy ( pstat - > bssrateset , supportRate , supportRateNum ) ;
2013-05-08 21:45:39 +00:00
UpdateBrateTblForSoftAP ( pstat - > bssrateset , pstat - > bssratelen ) ;
2015-02-19 21:34:32 +00:00
/* check RSN/WPA/WPS */
2013-05-08 21:45:39 +00:00
pstat - > dot8021xalg = 0 ;
2014-12-19 06:59:46 +00:00
pstat - > wpa_psk = 0 ;
2013-05-08 21:45:39 +00:00
pstat - > wpa_group_cipher = 0 ;
pstat - > wpa2_group_cipher = 0 ;
pstat - > wpa_pairwise_cipher = 0 ;
pstat - > wpa2_pairwise_cipher = 0 ;
2015-02-19 20:58:09 +00:00
memset ( pstat - > wpa_ie , 0 , sizeof ( pstat - > wpa_ie ) ) ;
2014-12-11 21:15:04 +00:00
if ( ( psecuritypriv - > wpa_psk & BIT ( 1 ) ) & & elems . rsn_ie ) {
2013-05-19 04:28:07 +00:00
2014-12-19 06:59:46 +00:00
int group_cipher = 0 , pairwise_cipher = 0 ;
2013-05-08 21:45:39 +00:00
wpa_ie = elems . rsn_ie ;
wpa_ie_len = elems . rsn_ie_len ;
2014-12-11 21:15:04 +00:00
if ( rtw_parse_wpa2_ie ( wpa_ie - 2 , wpa_ie_len + 2 , & group_cipher , & pairwise_cipher , NULL ) = = _SUCCESS )
{
2015-02-19 21:34:32 +00:00
pstat - > dot8021xalg = 1 ; /* psk, todo:802.1x */
2013-05-08 21:45:39 +00:00
pstat - > wpa_psk | = BIT ( 1 ) ;
2014-12-19 06:59:46 +00:00
pstat - > wpa2_group_cipher = group_cipher & psecuritypriv - > wpa2_group_cipher ;
2013-05-08 21:45:39 +00:00
pstat - > wpa2_pairwise_cipher = pairwise_cipher & psecuritypriv - > wpa2_pairwise_cipher ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
if ( ! pstat - > wpa2_group_cipher )
2013-05-08 21:45:39 +00:00
status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID ;
2014-12-11 21:15:04 +00:00
if ( ! pstat - > wpa2_pairwise_cipher )
2013-05-08 21:45:39 +00:00
status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID ;
2013-05-19 04:28:07 +00:00
}
2014-12-11 21:15:04 +00:00
else
{
status = WLAN_STATUS_INVALID_IE ;
2014-12-19 06:59:46 +00:00
}
2013-05-08 21:45:39 +00:00
} else if ( ( psecuritypriv - > wpa_psk & BIT ( 0 ) ) & & elems . wpa_ie ) {
2013-05-19 04:28:07 +00:00
2014-12-19 06:59:46 +00:00
int group_cipher = 0 , pairwise_cipher = 0 ;
2013-05-08 21:45:39 +00:00
wpa_ie = elems . wpa_ie ;
wpa_ie_len = elems . wpa_ie_len ;
2014-12-11 21:15:04 +00:00
if ( rtw_parse_wpa_ie ( wpa_ie - 2 , wpa_ie_len + 2 , & group_cipher , & pairwise_cipher , NULL ) = = _SUCCESS )
{
2015-02-19 21:34:32 +00:00
pstat - > dot8021xalg = 1 ; /* psk, todo:802.1x */
2013-05-08 21:45:39 +00:00
pstat - > wpa_psk | = BIT ( 0 ) ;
2014-12-19 06:59:46 +00:00
pstat - > wpa_group_cipher = group_cipher & psecuritypriv - > wpa_group_cipher ;
2013-05-08 21:45:39 +00:00
pstat - > wpa_pairwise_cipher = pairwise_cipher & psecuritypriv - > wpa_pairwise_cipher ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
if ( ! pstat - > wpa_group_cipher )
2013-05-08 21:45:39 +00:00
status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID ;
2014-12-11 21:15:04 +00:00
if ( ! pstat - > wpa_pairwise_cipher )
2013-05-08 21:45:39 +00:00
status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
}
else
{
2013-05-08 21:45:39 +00:00
status = WLAN_STATUS_INVALID_IE ;
}
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
} else {
wpa_ie = NULL ;
wpa_ie_len = 0 ;
}
2014-12-11 21:15:04 +00:00
if ( _STATS_SUCCESSFUL_ ! = status )
2013-05-08 21:45:39 +00:00
goto OnAssocReqFail ;
pstat - > flags & = ~ ( WLAN_STA_WPS | WLAN_STA_MAYBE_WPS ) ;
2014-12-11 21:15:04 +00:00
if ( wpa_ie = = NULL ) {
2013-05-08 21:45:39 +00:00
if ( elems . wps_ie ) {
2014-12-11 21:15:04 +00:00
DBG_871X ( " STA included WPS IE in "
2013-05-08 21:45:39 +00:00
" (Re)Association Request - assume WPS is "
" used \n " ) ;
pstat - > flags | = WLAN_STA_WPS ;
2015-02-19 21:34:32 +00:00
/* wpabuf_free(sta->wps_ie); */
/* sta->wps_ie = wpabuf_alloc_copy(elems.wps_ie + 4, */
/* elems.wps_ie_len - 4); */
2013-05-08 21:45:39 +00:00
} else {
2014-12-11 21:15:04 +00:00
DBG_871X ( " STA did not include WPA/RSN IE "
2013-05-08 21:45:39 +00:00
" in (Re)Association Request - possible WPS "
" use \n " ) ;
pstat - > flags | = WLAN_STA_MAYBE_WPS ;
}
2013-05-19 04:28:07 +00:00
2015-02-19 21:34:32 +00:00
/* AP support WPA/RSN, and sta is going to do WPS, but AP is not ready */
/* that the selected registrar of AP is _FLASE */
2014-12-19 06:59:46 +00:00
if ( ( psecuritypriv - > wpa_psk > 0 )
2014-12-11 21:15:04 +00:00
& & ( pstat - > flags & ( WLAN_STA_WPS | WLAN_STA_MAYBE_WPS ) ) )
{
if ( pmlmepriv - > wps_beacon_ie )
2014-12-19 06:59:46 +00:00
{
2014-12-11 21:15:04 +00:00
u8 selected_registrar = 0 ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
rtw_get_wps_attr_content ( pmlmepriv - > wps_beacon_ie , pmlmepriv - > wps_beacon_ie_len , WPS_ATTR_SELECTED_REGISTRAR , & selected_registrar , NULL ) ;
2014-12-11 21:15:04 +00:00
if ( ! selected_registrar )
2014-12-19 06:59:46 +00:00
{
2014-12-29 02:13:24 +00:00
DBG_871X ( " selected_registrar is false , or AP is not ready to do WPS \n " ) ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
status = _STATS_UNABLE_HANDLE_STA_ ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
goto OnAssocReqFail ;
2014-12-19 06:59:46 +00:00
}
}
2013-05-08 21:45:39 +00:00
}
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
}
else
{
2013-05-08 21:45:39 +00:00
int copy_len ;
2014-12-11 21:15:04 +00:00
if ( psecuritypriv - > wpa_psk = = 0 )
{
DBG_871X ( " STA " MAC_FMT " : WPA/RSN IE in association "
2014-12-19 06:59:46 +00:00
" request, but AP don't support WPA/RSN \n " , MAC_ARG ( pstat - > hwaddr ) ) ;
2013-05-08 21:45:39 +00:00
status = WLAN_STATUS_INVALID_IE ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
goto OnAssocReqFail ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
}
if ( elems . wps_ie ) {
2014-12-11 21:15:04 +00:00
DBG_871X ( " STA included WPS IE in "
2013-05-08 21:45:39 +00:00
" (Re)Association Request - WPS is "
" used \n " ) ;
pstat - > flags | = WLAN_STA_WPS ;
2014-12-11 21:15:04 +00:00
copy_len = 0 ;
}
else
{
copy_len = ( ( wpa_ie_len + 2 ) > sizeof ( pstat - > wpa_ie ) ) ? ( sizeof ( pstat - > wpa_ie ) ) : ( wpa_ie_len + 2 ) ;
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
if ( copy_len > 0 )
2015-02-19 20:50:04 +00:00
memcpy ( pstat - > wpa_ie , wpa_ie - 2 , copy_len ) ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
2015-02-19 21:34:32 +00:00
/* check if there is WMM IE & support WWM-PS */
2013-05-08 21:45:39 +00:00
pstat - > flags & = ~ WLAN_STA_WME ;
pstat - > qos_option = 0 ;
pstat - > qos_info = 0 ;
2014-12-29 02:13:24 +00:00
pstat - > has_legacy_ac = true ;
2013-05-08 21:45:39 +00:00
pstat - > uapsd_vo = 0 ;
pstat - > uapsd_vi = 0 ;
pstat - > uapsd_be = 0 ;
pstat - > uapsd_bk = 0 ;
2014-12-19 06:59:46 +00:00
if ( pmlmepriv - > qospriv . qos_option )
2014-12-11 21:15:04 +00:00
{
2013-05-08 21:45:39 +00:00
p = pframe + WLAN_HDR_A3_LEN + ie_offset ; ie_len = 0 ;
2014-12-19 06:59:46 +00:00
for ( ; ; )
2014-12-11 21:15:04 +00:00
{
2013-05-08 21:45:39 +00:00
p = rtw_get_ie ( p , _VENDOR_SPECIFIC_IE_ , & ie_len , pkt_len - WLAN_HDR_A3_LEN - ie_offset ) ;
if ( p ! = NULL ) {
if ( _rtw_memcmp ( p + 2 , WMM_IE , 6 ) ) {
2013-05-19 04:28:07 +00:00
2014-12-11 21:15:04 +00:00
pstat - > flags | = WLAN_STA_WME ;
2014-12-19 06:59:46 +00:00
pstat - > qos_option = 1 ;
2013-05-08 21:45:39 +00:00
pstat - > qos_info = * ( p + 8 ) ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
pstat - > max_sp_len = ( pstat - > qos_info > > 5 ) & 0x3 ;
2014-12-11 21:15:04 +00:00
if ( ( pstat - > qos_info & 0xf ) ! = 0xf )
2014-12-29 02:13:24 +00:00
pstat - > has_legacy_ac = true ;
2013-05-08 21:45:39 +00:00
else
2014-12-29 02:13:24 +00:00
pstat - > has_legacy_ac = false ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
if ( pstat - > qos_info & 0xf )
{
if ( pstat - > qos_info & BIT ( 0 ) )
2013-05-08 21:45:39 +00:00
pstat - > uapsd_vo = BIT ( 0 ) | BIT ( 1 ) ;
else
pstat - > uapsd_vo = 0 ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
if ( pstat - > qos_info & BIT ( 1 ) )
2013-05-08 21:45:39 +00:00
pstat - > uapsd_vi = BIT ( 0 ) | BIT ( 1 ) ;
else
pstat - > uapsd_vi = 0 ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
if ( pstat - > qos_info & BIT ( 2 ) )
2013-05-08 21:45:39 +00:00
pstat - > uapsd_bk = BIT ( 0 ) | BIT ( 1 ) ;
else
pstat - > uapsd_bk = 0 ;
2014-12-19 06:59:46 +00:00
if ( pstat - > qos_info & BIT ( 3 ) )
2013-05-08 21:45:39 +00:00
pstat - > uapsd_be = BIT ( 0 ) | BIT ( 1 ) ;
else
pstat - > uapsd_be = 0 ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
break ;
}
2014-12-11 21:15:04 +00:00
}
else {
2013-05-08 21:45:39 +00:00
break ;
}
p = p + ie_len + 2 ;
}
}
/* save HT capabilities in the sta object */
2015-02-19 20:58:09 +00:00
memset ( & pstat - > htpriv . ht_cap , 0 , sizeof ( struct rtw_ieee80211_ht_cap ) ) ;
2014-12-19 06:59:46 +00:00
if ( elems . ht_capabilities & & elems . ht_capabilities_len > = sizeof ( struct rtw_ieee80211_ht_cap ) )
2014-12-11 21:15:04 +00:00
{
2013-05-08 21:45:39 +00:00
pstat - > flags | = WLAN_STA_HT ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
pstat - > flags | = WLAN_STA_WME ;
2014-12-19 06:59:46 +00:00
2015-02-19 20:50:04 +00:00
memcpy ( & pstat - > htpriv . ht_cap , elems . ht_capabilities , sizeof ( struct rtw_ieee80211_ht_cap ) ) ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
} else
2013-05-08 21:45:39 +00:00
pstat - > flags & = ~ WLAN_STA_HT ;
2014-12-11 21:15:04 +00:00
2014-12-19 06:59:46 +00:00
2014-12-29 02:13:24 +00:00
if ( ( pmlmepriv - > htpriv . ht_option = = false ) & & ( pstat - > flags & WLAN_STA_HT ) )
2014-12-11 21:15:04 +00:00
{
2013-05-08 21:45:39 +00:00
status = _STATS_FAILURE_ ;
goto OnAssocReqFail ;
}
2014-12-19 06:59:46 +00:00
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
if ( ( pstat - > flags & WLAN_STA_HT ) & &
2014-12-11 21:15:04 +00:00
( ( pstat - > wpa2_pairwise_cipher & WPA_CIPHER_TKIP ) | |
( pstat - > wpa_pairwise_cipher & WPA_CIPHER_TKIP ) ) )
2014-12-19 06:59:46 +00:00
{
2014-12-11 21:15:04 +00:00
DBG_871X ( " HT: " MAC_FMT " tried to "
" use TKIP with HT association \n " , MAC_ARG ( pstat - > hwaddr ) ) ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* status = WLAN_STATUS_CIPHER_REJECTED_PER_POLICY; */
/* goto OnAssocReqFail; */
2014-12-11 21:15:04 +00:00
}
2015-02-19 21:34:32 +00:00
/* */
2014-12-19 06:59:46 +00:00
pstat - > flags | = WLAN_STA_NONERP ;
2013-05-08 21:45:39 +00:00
for ( i = 0 ; i < pstat - > bssratelen ; i + + ) {
if ( ( pstat - > bssrateset [ i ] & 0x7f ) > 22 ) {
pstat - > flags & = ~ WLAN_STA_NONERP ;
break ;
}
}
if ( pstat - > capability & WLAN_CAPABILITY_SHORT_PREAMBLE )
pstat - > flags | = WLAN_STA_SHORT_PREAMBLE ;
else
pstat - > flags & = ~ WLAN_STA_SHORT_PREAMBLE ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
if ( status ! = _STATS_SUCCESSFUL_ )
goto OnAssocReqFail ;
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_P2P
2014-12-29 02:13:24 +00:00
pstat - > is_p2p_device = false ;
2014-12-11 21:15:04 +00:00
if ( rtw_p2p_chk_role ( pwdinfo , P2P_ROLE_GO ) )
2014-12-19 06:59:46 +00:00
{
2014-12-11 21:15:04 +00:00
if ( ( p2pie = rtw_get_p2p_ie ( pframe + WLAN_HDR_A3_LEN + ie_offset , pkt_len - WLAN_HDR_A3_LEN - ie_offset , NULL , & p2pielen ) ) )
{
2014-12-29 02:13:24 +00:00
pstat - > is_p2p_device = true ;
2014-12-11 21:15:04 +00:00
if ( ( p2p_status_code = ( u8 ) process_assoc_req_p2p_ie ( pwdinfo , pframe , pkt_len , pstat ) ) > 0 )
{
2013-05-08 21:45:39 +00:00
pstat - > p2p_status_code = p2p_status_code ;
status = _STATS_CAP_FAIL_ ;
goto OnAssocReqFail ;
}
}
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_WFD
if ( rtw_get_wfd_ie ( pframe + WLAN_HDR_A3_LEN + ie_offset , pkt_len - WLAN_HDR_A3_LEN - ie_offset , wfd_ie , & wfd_ielen ) )
{
u8 attr_content [ 10 ] = { 0x00 } ;
u32 attr_contentlen = 0 ;
DBG_8192C ( " [%s] WFD IE Found!! \n " , __FUNCTION__ ) ;
rtw_get_wfd_attr_content ( wfd_ie , wfd_ielen , WFD_ATTR_DEVICE_INFO , attr_content , & attr_contentlen ) ;
if ( attr_contentlen )
{
pwdinfo - > wfd_info - > peer_rtsp_ctrlport = RTW_GET_BE16 ( attr_content + 2 ) ;
DBG_8192C ( " [%s] Peer PORT NUM = %d \n " , __FUNCTION__ , pwdinfo - > wfd_info - > peer_rtsp_ctrlport ) ;
}
}
# endif
2013-05-08 21:45:39 +00:00
}
pstat - > p2p_status_code = p2p_status_code ;
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_P2P */
2014-12-11 21:15:04 +00:00
2015-02-19 21:34:32 +00:00
/* TODO: identify_proprietary_vendor_ie(); */
/* Realtek proprietary IE */
/* identify if this is Broadcom sta */
/* identify if this is ralink sta */
/* Customer proprietary IE */
2013-05-08 21:45:39 +00:00
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
/* get a unique AID */
if ( pstat - > aid > 0 ) {
2014-12-11 21:15:04 +00:00
DBG_871X ( " old AID %d \n " , pstat - > aid ) ;
2013-05-08 21:45:39 +00:00
} else {
for ( pstat - > aid = 1 ; pstat - > aid < = NUM_STA ; pstat - > aid + + )
if ( pstapriv - > sta_aid [ pstat - > aid - 1 ] = = NULL )
break ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* if (pstat->aid > NUM_STA) { */
2013-05-08 21:45:39 +00:00
if ( pstat - > aid > pstapriv - > max_num_sta ) {
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
pstat - > aid = 0 ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
DBG_871X ( " no room for more AIDs \n " ) ;
2013-05-08 21:45:39 +00:00
status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
goto OnAssocReqFail ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
} else {
pstapriv - > sta_aid [ pstat - > aid - 1 ] = pstat ;
2014-12-11 21:15:04 +00:00
DBG_871X ( " allocate new AID = (%d) \n " , pstat - > aid ) ;
2014-12-19 06:59:46 +00:00
}
2013-05-08 21:45:39 +00:00
}
2013-05-19 04:28:07 +00:00
2014-12-19 06:59:46 +00:00
pstat - > state & = ( ~ WIFI_FW_ASSOC_STATE ) ;
2014-12-11 21:15:04 +00:00
pstat - > state | = WIFI_FW_ASSOC_SUCCESS ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
_enter_critical_bh ( & pstapriv - > auth_list_lock , & irqL ) ;
if ( ! rtw_is_list_empty ( & pstat - > auth_list ) )
{
2013-05-08 21:45:39 +00:00
rtw_list_delete ( & pstat - > auth_list ) ;
pstapriv - > auth_list_cnt - - ;
}
2014-12-11 21:15:04 +00:00
_exit_critical_bh ( & pstapriv - > auth_list_lock , & irqL ) ;
2013-05-08 21:45:39 +00:00
2014-12-19 06:59:46 +00:00
_enter_critical_bh ( & pstapriv - > asoc_list_lock , & irqL ) ;
2014-12-11 21:15:04 +00:00
if ( rtw_is_list_empty ( & pstat - > asoc_list ) )
{
2013-05-08 21:45:39 +00:00
pstat - > expire_to = pstapriv - > expire_to ;
rtw_list_insert_tail ( & pstat - > asoc_list , & pstapriv - > asoc_list ) ;
pstapriv - > asoc_list_cnt + + ;
}
2014-12-11 21:15:04 +00:00
_exit_critical_bh ( & pstapriv - > asoc_list_lock , & irqL ) ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* now the station is qualified to join our BSS... */
2014-12-11 21:15:04 +00:00
if ( pstat & & ( pstat - > state & WIFI_FW_ASSOC_SUCCESS ) & & ( _STATS_SUCCESSFUL_ = = status ) )
{
2015-02-19 21:34:32 +00:00
/* 1 bss_cap_update & sta_info_update */
2013-05-08 21:45:39 +00:00
bss_cap_update_on_sta_join ( padapter , pstat ) ;
sta_info_update ( padapter , pstat ) ;
2015-02-19 21:34:32 +00:00
/* 2 issue assoc rsp before notify station join event. */
2013-05-08 21:45:39 +00:00
if ( frame_type = = WIFI_ASSOCREQ )
issue_asocrsp ( padapter , status , pstat , WIFI_ASSOCRSP ) ;
else
issue_asocrsp ( padapter , status , pstat , WIFI_REASSOCRSP ) ;
2014-12-11 21:15:04 +00:00
_enter_critical_bh ( & pstat - > lock , & irqL ) ;
if ( pstat - > passoc_req )
{
rtw_mfree ( pstat - > passoc_req , pstat - > assoc_req_len ) ;
pstat - > passoc_req = NULL ;
pstat - > assoc_req_len = 0 ;
}
pstat - > passoc_req = rtw_zmalloc ( pkt_len ) ;
if ( pstat - > passoc_req )
{
2015-02-19 20:50:04 +00:00
memcpy ( pstat - > passoc_req , pframe , pkt_len ) ;
2014-12-11 21:15:04 +00:00
pstat - > assoc_req_len = pkt_len ;
}
2014-12-19 06:59:46 +00:00
_exit_critical_bh ( & pstat - > lock , & irqL ) ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* 3-(1) report sta add event */
2013-05-08 21:45:39 +00:00
report_add_sta_event ( padapter , pstat - > hwaddr , pstat - > aid ) ;
}
return _SUCCESS ;
asoc_class2_error :
issue_deauth ( padapter , ( void * ) GetAddr2Ptr ( pframe ) , status ) ;
2014-12-19 06:59:46 +00:00
return _FAIL ;
2013-05-08 21:45:39 +00:00
OnAssocReqFail :
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
pstat - > aid = 0 ;
if ( frame_type = = WIFI_ASSOCREQ )
issue_asocrsp ( padapter , status , pstat , WIFI_ASSOCRSP ) ;
else
issue_asocrsp ( padapter , status , pstat , WIFI_REASSOCRSP ) ;
2014-12-11 21:15:04 +00:00
# endif /* CONFIG_AP_MODE */
2014-12-19 06:59:46 +00:00
return _FAIL ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-17 23:13:53 +00:00
unsigned int OnAssocRsp ( struct adapter * padapter , union recv_frame * precv_frame )
2013-05-08 21:45:39 +00:00
{
uint i ;
int res ;
unsigned short status ;
2014-12-11 21:15:04 +00:00
PNDIS_802_11_VARIABLE_IEs pIE ;
2013-05-08 21:45:39 +00:00
struct mlme_priv * pmlmepriv = & padapter - > mlmepriv ;
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
2015-02-19 21:34:32 +00:00
/* WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); */
2013-05-08 21:45:39 +00:00
u8 * pframe = precv_frame - > u . hdr . rx_data ;
uint pkt_len = precv_frame - > u . hdr . len ;
2014-12-11 21:15:04 +00:00
PNDIS_802_11_VARIABLE_IEs pWapiIE = NULL ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
DBG_871X ( " %s \n " , __FUNCTION__ ) ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* check A1 matches or not */
2013-05-08 21:45:39 +00:00
if ( ! _rtw_memcmp ( myid ( & ( padapter - > eeprompriv ) ) , get_da ( pframe ) , ETH_ALEN ) )
return _SUCCESS ;
if ( ! ( pmlmeinfo - > state & ( WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE ) ) )
return _SUCCESS ;
if ( pmlmeinfo - > state & WIFI_FW_ASSOC_SUCCESS )
return _SUCCESS ;
_cancel_timer_ex ( & pmlmeext - > link_timer ) ;
2015-02-19 21:34:32 +00:00
/* status */
2014-12-19 04:28:04 +00:00
if ( ( status = le16_to_cpu ( * ( __le16 * ) ( pframe + WLAN_HDR_A3_LEN + 2 ) ) ) > 0 )
2014-12-11 21:15:04 +00:00
{
DBG_871X ( " assoc reject, status code: %d \n " , status ) ;
2013-05-08 21:45:39 +00:00
pmlmeinfo - > state = WIFI_FW_NULL_STATE ;
res = - 4 ;
goto report_assoc_result ;
}
2015-02-19 21:34:32 +00:00
/* get capabilities */
2014-12-19 04:28:04 +00:00
pmlmeinfo - > capability = le16_to_cpu ( * ( __le16 * ) ( pframe + WLAN_HDR_A3_LEN ) ) ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* set slot time */
2014-12-11 21:15:04 +00:00
pmlmeinfo - > slotTime = ( pmlmeinfo - > capability & BIT ( 10 ) ) ? 9 : 20 ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* AID */
2014-12-19 04:28:04 +00:00
res = pmlmeinfo - > aid = ( int ) ( le16_to_cpu ( * ( __le16 * ) ( pframe + WLAN_HDR_A3_LEN + 4 ) ) & 0x3fff ) ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* following are moved to join event callback function */
/* to handle HT, WMM, rate adaptive, update MAC reg */
/* for not to handle the synchronous IO in the tasklet */
2014-12-11 21:15:04 +00:00
for ( i = ( 6 + WLAN_HDR_A3_LEN ) ; i < pkt_len ; )
{
pIE = ( PNDIS_802_11_VARIABLE_IEs ) ( pframe + i ) ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
switch ( pIE - > ElementID )
{
case _VENDOR_SPECIFIC_IE_ :
2015-02-19 21:34:32 +00:00
if ( _rtw_memcmp ( pIE - > data , WMM_PARA_OUI , 6 ) ) /* WMM */
2014-12-11 21:15:04 +00:00
{
WMM_param_handler ( padapter , pIE ) ;
}
# if defined(CONFIG_P2P) && defined(CONFIG_WFD)
2015-02-19 21:34:32 +00:00
else if ( _rtw_memcmp ( pIE - > data , WFD_OUI , 4 ) ) /* WFD */
2014-12-11 21:15:04 +00:00
{
DBG_871X ( " [%s] Found WFD IE \n " , __FUNCTION__ ) ;
WFD_info_handler ( padapter , pIE ) ;
}
2014-12-19 06:59:46 +00:00
# endif
2014-12-11 21:15:04 +00:00
break ;
# ifdef CONFIG_WAPI_SUPPORT
case _WAPI_IE_ :
pWapiIE = pIE ;
break ;
# endif
2015-02-19 21:34:32 +00:00
case _HT_CAPABILITY_IE_ : /* HT caps */
2014-12-11 21:15:04 +00:00
HT_caps_handler ( padapter , pIE ) ;
break ;
2015-02-19 21:34:32 +00:00
case _HT_EXTRA_INFO_IE_ : /* HT info */
2014-12-11 21:15:04 +00:00
HT_info_handler ( padapter , pIE ) ;
break ;
case _ERPINFO_IE_ :
ERP_IE_handler ( padapter , pIE ) ;
default :
break ;
2013-05-08 21:45:39 +00:00
}
i + = ( pIE - > Length + 2 ) ;
}
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_WAPI_SUPPORT
rtw_wapi_on_assoc_ok ( padapter , pIE ) ;
# endif
2013-05-08 21:45:39 +00:00
pmlmeinfo - > state & = ( ~ WIFI_FW_ASSOC_STATE ) ;
pmlmeinfo - > state | = WIFI_FW_ASSOC_SUCCESS ;
2015-02-19 21:34:32 +00:00
/* Update Basic Rate Table for spec, 2010-12-28 , by thomas */
2013-05-08 21:45:39 +00:00
UpdateBrateTbl ( padapter , pmlmeinfo - > network . SupportedRates ) ;
report_assoc_result :
if ( res > 0 ) {
rtw_buf_update ( & pmlmepriv - > assoc_rsp , & pmlmepriv - > assoc_rsp_len , pframe , pkt_len ) ;
} else {
rtw_buf_free ( & pmlmepriv - > assoc_rsp , & pmlmepriv - > assoc_rsp_len ) ;
}
report_join_res ( padapter , res ) ;
return _SUCCESS ;
}
2014-12-17 23:13:53 +00:00
unsigned int OnDeAuth ( struct adapter * padapter , union recv_frame * precv_frame )
2013-05-08 21:45:39 +00:00
{
unsigned short reason ;
struct mlme_priv * pmlmepriv = & padapter - > mlmepriv ;
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
u8 * pframe = precv_frame - > u . hdr . rx_data ;
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_P2P
struct wifidirect_info * pwdinfo = & ( padapter - > wdinfo ) ;
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_P2P */
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* check A3 */
2013-05-08 21:45:39 +00:00
if ( ! ( _rtw_memcmp ( GetAddr3Ptr ( pframe ) , get_my_bssid ( & pmlmeinfo - > network ) , ETH_ALEN ) ) )
return _SUCCESS ;
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_P2P
if ( pwdinfo - > rx_invitereq_info . scan_op_ch_only )
{
_cancel_timer_ex ( & pwdinfo - > reset_ch_sitesurvey ) ;
_set_timer ( & pwdinfo - > reset_ch_sitesurvey , 10 ) ;
2013-05-08 21:45:39 +00:00
}
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_P2P */
2013-05-08 21:45:39 +00:00
2014-12-19 04:28:04 +00:00
reason = le16_to_cpu ( * ( __le16 * ) ( pframe + WLAN_HDR_A3_LEN ) ) ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
DBG_871X ( " %s Reason code(%d) \n " , __FUNCTION__ , reason ) ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_AP_MODE
2014-12-29 02:13:24 +00:00
if ( check_fwstate ( pmlmepriv , WIFI_AP_STATE ) = = true )
2014-12-19 06:59:46 +00:00
{
2014-12-11 21:15:04 +00:00
_irqL irqL ;
2013-05-08 21:45:39 +00:00
struct sta_info * psta ;
struct sta_priv * pstapriv = & padapter - > stapriv ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); */
/* rtw_free_stainfo(padapter, psta); */
/* _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); */
2013-05-19 04:28:07 +00:00
2014-12-11 21:15:04 +00:00
DBG_871X_LEVEL ( _drv_always_ , " ap recv deauth reason code(%d) sta:%pM \n " ,
2014-12-19 06:59:46 +00:00
reason , GetAddr2Ptr ( pframe ) ) ;
2013-05-08 21:45:39 +00:00
2014-12-19 06:59:46 +00:00
psta = rtw_get_stainfo ( pstapriv , GetAddr2Ptr ( pframe ) ) ;
2014-12-11 21:15:04 +00:00
if ( psta )
{
u8 updated ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
_enter_critical_bh ( & pstapriv - > asoc_list_lock , & irqL ) ;
2014-12-29 02:13:24 +00:00
if ( rtw_is_list_empty ( & psta - > asoc_list ) = = false )
2014-12-19 06:59:46 +00:00
{
2013-05-08 21:45:39 +00:00
rtw_list_delete ( & psta - > asoc_list ) ;
pstapriv - > asoc_list_cnt - - ;
2014-12-29 02:13:24 +00:00
updated = ap_free_sta ( padapter , psta , false , reason ) ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
_exit_critical_bh ( & pstapriv - > asoc_list_lock , & irqL ) ;
2013-05-08 21:45:39 +00:00
associated_clients_update ( padapter , updated ) ;
}
2014-12-19 06:59:46 +00:00
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
return _SUCCESS ;
2014-12-11 21:15:04 +00:00
}
else
2013-05-08 21:45:39 +00:00
# endif
{
2014-11-20 06:12:27 +00:00
int ignore_received_deauth = 0 ;
2015-02-19 21:34:32 +00:00
/* Commented by Albert 20130604 */
/* Before sending the auth frame to start the STA/GC mode connection with AP/GO, */
/* we will send the deauth first. */
/* However, the Win8.1 with BRCM Wi-Fi will send the deauth with reason code 6 to us after receieving our deauth. */
/* Added the following code to avoid this case. */
2014-12-11 21:15:04 +00:00
if ( ( pmlmeinfo - > state & WIFI_FW_AUTH_STATE ) | |
( pmlmeinfo - > state & WIFI_FW_ASSOC_STATE ) )
{
if ( reason = = WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA )
{
ignore_received_deauth = 1 ;
2014-11-20 06:12:27 +00:00
} else if ( WLAN_REASON_PREV_AUTH_NOT_VALID = = reason ) {
2015-02-19 21:34:32 +00:00
/* TODO: 802.11r */
2014-11-20 06:12:27 +00:00
ignore_received_deauth = 1 ;
}
}
2014-12-11 21:15:04 +00:00
DBG_871X_LEVEL ( _drv_always_ , " sta recv deauth reason code(%d) sta:%pM, ignore = %d \n " ,
2014-12-19 06:59:46 +00:00
reason , GetAddr3Ptr ( pframe ) , ignore_received_deauth ) ;
2014-12-11 21:15:04 +00:00
if ( 0 = = ignore_received_deauth )
{
receive_disconnect ( padapter , GetAddr3Ptr ( pframe ) , reason ) ;
}
2014-12-19 06:59:46 +00:00
}
2014-12-29 02:13:24 +00:00
pmlmepriv - > LinkDetectInfo . bBusyTraffic = false ;
2013-05-08 21:45:39 +00:00
return _SUCCESS ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-17 23:13:53 +00:00
unsigned int OnDisassoc ( struct adapter * padapter , union recv_frame * precv_frame )
2013-05-08 21:45:39 +00:00
{
2014-12-11 21:15:04 +00:00
unsigned short reason ;
2013-05-08 21:45:39 +00:00
struct mlme_priv * pmlmepriv = & padapter - > mlmepriv ;
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
u8 * pframe = precv_frame - > u . hdr . rx_data ;
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_P2P
struct wifidirect_info * pwdinfo = & ( padapter - > wdinfo ) ;
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_P2P */
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* check A3 */
2013-05-08 21:45:39 +00:00
if ( ! ( _rtw_memcmp ( GetAddr3Ptr ( pframe ) , get_my_bssid ( & pmlmeinfo - > network ) , ETH_ALEN ) ) )
return _SUCCESS ;
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_P2P
2014-12-19 04:28:04 +00:00
if ( pwdinfo - > rx_invitereq_info . scan_op_ch_only ) {
2014-12-11 21:15:04 +00:00
_cancel_timer_ex ( & pwdinfo - > reset_ch_sitesurvey ) ;
_set_timer ( & pwdinfo - > reset_ch_sitesurvey , 10 ) ;
2013-05-08 21:45:39 +00:00
}
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_P2P */
2013-05-08 21:45:39 +00:00
2014-12-19 04:28:04 +00:00
reason = le16_to_cpu ( * ( __le16 * ) ( pframe + WLAN_HDR_A3_LEN ) ) ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
DBG_871X ( " %s Reason code(%d) \n " , __FUNCTION__ , reason ) ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_AP_MODE
2014-12-29 02:13:24 +00:00
if ( check_fwstate ( pmlmepriv , WIFI_AP_STATE ) = = true ) {
2014-12-11 21:15:04 +00:00
_irqL irqL ;
2013-05-08 21:45:39 +00:00
struct sta_info * psta ;
struct sta_priv * pstapriv = & padapter - > stapriv ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); */
/* rtw_free_stainfo(padapter, psta); */
/* _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); */
2013-05-19 04:28:07 +00:00
2014-12-11 21:15:04 +00:00
DBG_871X_LEVEL ( _drv_always_ , " ap recv disassoc reason code(%d) sta:%pM \n " ,
reason , GetAddr2Ptr ( pframe ) ) ;
2013-05-08 21:45:39 +00:00
2014-12-19 06:59:46 +00:00
psta = rtw_get_stainfo ( pstapriv , GetAddr2Ptr ( pframe ) ) ;
2014-12-11 21:15:04 +00:00
if ( psta )
{
u8 updated ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
_enter_critical_bh ( & pstapriv - > asoc_list_lock , & irqL ) ;
2014-12-29 02:13:24 +00:00
if ( rtw_is_list_empty ( & psta - > asoc_list ) = = false )
2014-12-11 21:15:04 +00:00
{
2013-05-08 21:45:39 +00:00
rtw_list_delete ( & psta - > asoc_list ) ;
pstapriv - > asoc_list_cnt - - ;
2014-12-29 02:13:24 +00:00
updated = ap_free_sta ( padapter , psta , false , reason ) ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
_exit_critical_bh ( & pstapriv - > asoc_list_lock , & irqL ) ;
2013-05-08 21:45:39 +00:00
associated_clients_update ( padapter , updated ) ;
}
return _SUCCESS ;
2014-12-11 21:15:04 +00:00
}
else
2013-05-08 21:45:39 +00:00
# endif
{
2014-12-11 21:15:04 +00:00
DBG_871X_LEVEL ( _drv_always_ , " ap recv disassoc reason code(%d) sta:%pM \n " ,
reason , GetAddr3Ptr ( pframe ) ) ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
receive_disconnect ( padapter , GetAddr3Ptr ( pframe ) , reason ) ;
2014-12-19 06:59:46 +00:00
}
2014-12-29 02:13:24 +00:00
pmlmepriv - > LinkDetectInfo . bBusyTraffic = false ;
2013-05-08 21:45:39 +00:00
return _SUCCESS ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-17 23:13:53 +00:00
unsigned int OnAtim ( struct adapter * padapter , union recv_frame * precv_frame )
2013-05-08 21:45:39 +00:00
{
2014-12-11 21:15:04 +00:00
DBG_871X ( " %s \n " , __FUNCTION__ ) ;
2013-05-08 21:45:39 +00:00
return _SUCCESS ;
}
2014-12-19 04:28:04 +00:00
static unsigned int on_action_spct_ch_switch ( struct adapter * padapter , struct sta_info * psta , u8 * ies , uint ies_len )
2014-12-11 21:15:04 +00:00
{
unsigned int ret = _FAIL ;
struct mlme_ext_priv * mlmeext = & padapter - > mlmeextpriv ;
struct mlme_ext_info * pmlmeinfo = & ( mlmeext - > mlmext_info ) ;
if ( ! ( pmlmeinfo - > state & WIFI_FW_ASSOC_SUCCESS ) ) {
2014-12-19 06:59:46 +00:00
ret = _SUCCESS ;
2014-12-11 21:15:04 +00:00
goto exit ;
}
if ( ( pmlmeinfo - > state & 0x03 ) = = WIFI_FW_STATION_STATE ) {
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
int ch_switch_mode = - 1 , ch = - 1 , ch_switch_cnt = - 1 ;
int ch_offset = - 1 ;
u8 bwmode ;
struct ieee80211_info_element * ie ;
DBG_871X ( FUNC_NDEV_FMT " from " MAC_FMT " \n " ,
FUNC_NDEV_ARG ( padapter - > pnetdev ) , MAC_ARG ( psta - > hwaddr ) ) ;
for_each_ie ( ie , ies , ies_len ) {
if ( ie - > id = = WLAN_EID_CHANNEL_SWITCH ) {
ch_switch_mode = ie - > data [ 0 ] ;
ch = ie - > data [ 1 ] ;
ch_switch_cnt = ie - > data [ 2 ] ;
DBG_871X ( " ch_switch_mode:%d, ch:%d, ch_switch_cnt:%d \n " ,
ch_switch_mode , ch , ch_switch_cnt ) ;
}
else if ( ie - > id = = WLAN_EID_SECONDARY_CHANNEL_OFFSET ) {
ch_offset = secondary_ch_offset_to_hal_ch_offset ( ie - > data [ 0 ] ) ;
DBG_871X ( " ch_offset:%d \n " , ch_offset ) ;
}
}
if ( ch = = - 1 )
return _SUCCESS ;
if ( ch_offset = = - 1 )
bwmode = mlmeext - > cur_bwmode ;
else
bwmode = ( ch_offset = = HAL_PRIME_CHNL_OFFSET_DONT_CARE ) ?
HT_CHANNEL_WIDTH_20 : HT_CHANNEL_WIDTH_40 ;
ch_offset = ( ch_offset = = - 1 ) ? mlmeext - > cur_ch_offset : ch_offset ;
/* todo:
* 1. the decision of channel switching
* 2. things after channel switching
*/
2014-12-29 02:13:24 +00:00
ret = rtw_set_ch_cmd ( padapter , ch , bwmode , ch_offset , true ) ;
2014-12-11 21:15:04 +00:00
}
exit :
return ret ;
}
2014-12-17 23:13:53 +00:00
unsigned int on_action_spct ( struct adapter * padapter , union recv_frame * precv_frame )
2013-05-08 21:45:39 +00:00
{
unsigned int ret = _FAIL ;
struct sta_info * psta = NULL ;
struct sta_priv * pstapriv = & padapter - > stapriv ;
u8 * pframe = precv_frame - > u . hdr . rx_data ;
2014-12-11 21:15:04 +00:00
uint frame_len = precv_frame - > u . hdr . len ;
2013-05-08 21:45:39 +00:00
u8 * frame_body = ( u8 * ) ( pframe + sizeof ( struct rtw_ieee80211_hdr_3addr ) ) ;
u8 category ;
u8 action ;
2014-12-11 21:15:04 +00:00
DBG_871X ( FUNC_NDEV_FMT " \n " , FUNC_NDEV_ARG ( padapter - > pnetdev ) ) ;
2013-05-08 21:45:39 +00:00
psta = rtw_get_stainfo ( pstapriv , GetAddr2Ptr ( pframe ) ) ;
if ( ! psta )
goto exit ;
category = frame_body [ 0 ] ;
2014-12-11 21:15:04 +00:00
if ( category ! = RTW_WLAN_CATEGORY_SPECTRUM_MGMT )
2013-05-08 21:45:39 +00:00
goto exit ;
action = frame_body [ 1 ] ;
switch ( action ) {
case RTW_WLAN_ACTION_SPCT_MSR_REQ :
case RTW_WLAN_ACTION_SPCT_MSR_RPRT :
case RTW_WLAN_ACTION_SPCT_TPC_REQ :
case RTW_WLAN_ACTION_SPCT_TPC_RPRT :
break ;
case RTW_WLAN_ACTION_SPCT_CHL_SWITCH :
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_SPCT_CH_SWITCH
ret = on_action_spct_ch_switch ( padapter , psta , & frame_body [ 2 ] ,
frame_len - ( frame_body - pframe ) - 2 ) ;
# endif
2013-05-08 21:45:39 +00:00
break ;
default :
break ;
}
exit :
return ret ;
}
2014-12-17 23:13:53 +00:00
unsigned int OnAction_qos ( struct adapter * padapter , union recv_frame * precv_frame )
2013-05-08 21:45:39 +00:00
{
return _SUCCESS ;
}
2014-12-17 23:13:53 +00:00
unsigned int OnAction_dls ( struct adapter * padapter , union recv_frame * precv_frame )
2013-05-08 21:45:39 +00:00
{
return _SUCCESS ;
}
2014-12-17 23:13:53 +00:00
unsigned int OnAction_back ( struct adapter * padapter , union recv_frame * precv_frame )
2013-05-08 21:45:39 +00:00
{
u8 * addr ;
2014-12-11 21:15:04 +00:00
struct sta_info * psta = NULL ;
2013-05-08 21:45:39 +00:00
struct recv_reorder_ctrl * preorder_ctrl ;
unsigned char * frame_body ;
unsigned char category , action ;
unsigned short tid , status , reason_code = 0 ;
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
u8 * pframe = precv_frame - > u . hdr . rx_data ;
struct sta_priv * pstapriv = & padapter - > stapriv ;
2015-02-19 21:34:32 +00:00
/* check RA matches or not */
if ( ! _rtw_memcmp ( myid ( & ( padapter - > eeprompriv ) ) , GetAddr1Ptr ( pframe ) , ETH_ALEN ) ) /* for if1, sta/ap mode */
2013-05-08 21:45:39 +00:00
return _SUCCESS ;
2014-12-11 21:15:04 +00:00
DBG_871X ( " %s \n " , __FUNCTION__ ) ;
2013-05-08 21:45:39 +00:00
2014-12-19 06:59:46 +00:00
if ( ( pmlmeinfo - > state & 0x03 ) ! = WIFI_FW_AP_STATE )
2013-05-08 21:45:39 +00:00
if ( ! ( pmlmeinfo - > state & WIFI_FW_ASSOC_SUCCESS ) )
return _SUCCESS ;
addr = GetAddr2Ptr ( pframe ) ;
psta = rtw_get_stainfo ( pstapriv , addr ) ;
2014-12-11 21:15:04 +00:00
if ( psta = = NULL )
2013-05-08 21:45:39 +00:00
return _SUCCESS ;
frame_body = ( unsigned char * ) ( pframe + sizeof ( struct rtw_ieee80211_hdr_3addr ) ) ;
category = frame_body [ 0 ] ;
2015-02-19 21:34:32 +00:00
if ( category = = RTW_WLAN_CATEGORY_BACK ) /* representing Block Ack */
2014-12-11 21:15:04 +00:00
{
# ifdef CONFIG_TDLS
2014-12-19 06:59:46 +00:00
if ( ( psta - > tdls_sta_state & TDLS_LINKED_STATE ) & &
2014-12-29 02:13:24 +00:00
( psta - > htpriv . ht_option = = true ) & &
( psta - > htpriv . ampdu_enable = = true ) )
2014-12-11 21:15:04 +00:00
{
2015-02-19 21:34:32 +00:00
/* do nothing; just don't want to return _SUCCESS; */
2014-12-11 21:15:04 +00:00
}
else
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_TDLS */
2013-05-08 21:45:39 +00:00
if ( ! pmlmeinfo - > HT_enable )
2014-12-11 21:15:04 +00:00
{
2013-05-08 21:45:39 +00:00
return _SUCCESS ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
action = frame_body [ 1 ] ;
2014-12-11 21:15:04 +00:00
DBG_871X ( " %s, action=%d \n " , __FUNCTION__ , action ) ;
switch ( action )
{
2015-02-19 21:34:32 +00:00
case RTW_WLAN_ACTION_ADDBA_REQ : /* ADDBA request */
2014-12-11 21:15:04 +00:00
2015-02-19 20:50:04 +00:00
memcpy ( & ( pmlmeinfo - > ADDBA_req ) , & ( frame_body [ 2 ] ) , sizeof ( struct ADDBA_request ) ) ;
2015-02-19 21:34:32 +00:00
/* process_addba_req(padapter, (u8*)&(pmlmeinfo->ADDBA_req), GetAddr3Ptr(pframe)); */
2014-12-11 21:15:04 +00:00
process_addba_req ( padapter , ( u8 * ) & ( pmlmeinfo - > ADDBA_req ) , addr ) ;
2014-12-19 06:59:46 +00:00
2014-12-29 02:13:24 +00:00
if ( pmlmeinfo - > bAcceptAddbaReq = = true ) {
2014-12-11 21:15:04 +00:00
issue_action_BA ( padapter , addr , RTW_WLAN_ACTION_ADDBA_RESP , 0 ) ;
2014-12-19 04:28:04 +00:00
} else {
issue_action_BA ( padapter , addr ,
RTW_WLAN_ACTION_ADDBA_RESP ,
2015-02-19 21:34:32 +00:00
37 ) ; /* reject ADDBA Req */
2014-12-11 21:15:04 +00:00
}
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
break ;
2015-02-19 21:34:32 +00:00
case RTW_WLAN_ACTION_ADDBA_RESP : /* ADDBA response */
2014-12-11 21:15:04 +00:00
status = RTW_GET_LE16 ( & frame_body [ 3 ] ) ;
tid = ( ( frame_body [ 5 ] > > 2 ) & 0x7 ) ;
if ( status = = 0 )
2015-02-19 21:34:32 +00:00
{ /* successful */
2014-12-11 21:15:04 +00:00
DBG_871X ( " agg_enable for TID=%d \n " , tid ) ;
2014-12-19 06:59:46 +00:00
psta - > htpriv . agg_enable_bitmap | = 1 < < tid ;
psta - > htpriv . candidate_tid_bitmap & = ~ BIT ( tid ) ;
2014-12-11 21:15:04 +00:00
}
else
2014-12-19 06:59:46 +00:00
{
psta - > htpriv . agg_enable_bitmap & = ~ BIT ( tid ) ;
2014-12-11 21:15:04 +00:00
}
2015-02-19 21:34:32 +00:00
/* DBG_871X("marc: ADDBA RSP: %x\n", pmlmeinfo->agg_enable_bitmap); */
2014-12-11 21:15:04 +00:00
break ;
2015-02-19 21:34:32 +00:00
case RTW_WLAN_ACTION_DELBA : /* DELBA */
2014-12-11 21:15:04 +00:00
if ( ( frame_body [ 3 ] & BIT ( 3 ) ) = = 0 )
{
psta - > htpriv . agg_enable_bitmap & = ~ ( 1 < < ( ( frame_body [ 3 ] > > 4 ) & 0xf ) ) ;
psta - > htpriv . candidate_tid_bitmap & = ~ ( 1 < < ( ( frame_body [ 3 ] > > 4 ) & 0xf ) ) ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* reason_code = frame_body[4] | (frame_body[5] << 8); */
2014-12-11 21:15:04 +00:00
reason_code = RTW_GET_LE16 ( & frame_body [ 4 ] ) ;
}
else if ( ( frame_body [ 3 ] & BIT ( 3 ) ) = = BIT ( 3 ) )
2014-12-19 06:59:46 +00:00
{
2014-12-11 21:15:04 +00:00
tid = ( frame_body [ 3 ] > > 4 ) & 0x0F ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
preorder_ctrl = & psta - > recvreorder_ctrl [ tid ] ;
2014-12-29 02:13:24 +00:00
preorder_ctrl - > enable = false ;
2014-12-11 21:15:04 +00:00
preorder_ctrl - > indicate_seq = 0xffff ;
# ifdef DBG_RX_SEQ
DBG_871X ( " DBG_RX_SEQ %s:%d indicate_seq:%u \n " , __FUNCTION__ , __LINE__ ,
preorder_ctrl - > indicate_seq ) ;
# endif
}
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
DBG_871X ( " %s(): DELBA: %x(%x) \n " , __FUNCTION__ , pmlmeinfo - > agg_enable_bitmap , reason_code ) ;
2015-02-19 21:34:32 +00:00
/* todo: how to notify the host while receiving DELETE BA */
2014-12-11 21:15:04 +00:00
break ;
default :
break ;
2013-05-08 21:45:39 +00:00
}
}
return _SUCCESS ;
}
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_P2P
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
static int get_reg_classes_full_count ( struct p2p_channels channel_list ) {
2013-05-08 21:45:39 +00:00
int cnt = 0 ;
int i ;
2014-12-11 21:15:04 +00:00
for ( i = 0 ; i < channel_list . reg_classes ; i + + ) {
cnt + = channel_list . reg_class [ i ] . channels ;
2013-05-08 21:45:39 +00:00
}
return cnt ;
}
2014-12-11 21:15:04 +00:00
static void get_channel_cnt_24g_5gl_5gh ( struct mlme_ext_priv * pmlmeext , u8 * p24g_cnt , u8 * p5gl_cnt , u8 * p5gh_cnt )
{
int i = 0 ;
* p24g_cnt = 0 ;
* p5gl_cnt = 0 ;
2014-12-19 06:59:46 +00:00
* p5gh_cnt = 0 ;
2014-12-11 21:15:04 +00:00
for ( i = 0 ; i < pmlmeext - > max_chan_nums ; i + + )
{
if ( pmlmeext - > channel_set [ i ] . ChannelNum < = 14 )
{
( * p24g_cnt ) + + ;
}
else if ( ( pmlmeext - > channel_set [ i ] . ChannelNum > 14 ) & & ( pmlmeext - > channel_set [ i ] . ChannelNum < = 48 ) )
{
2015-02-19 21:34:32 +00:00
/* Just include the channel 36, 40, 44, 48 channels for 5G low */
2014-12-11 21:15:04 +00:00
( * p5gl_cnt ) + + ;
}
else if ( ( pmlmeext - > channel_set [ i ] . ChannelNum > = 149 ) & & ( pmlmeext - > channel_set [ i ] . ChannelNum < = 161 ) )
{
2015-02-19 21:34:32 +00:00
/* Just include the channel 149, 153, 157, 161 channels for 5G high */
2014-12-11 21:15:04 +00:00
( * p5gh_cnt ) + + ;
}
}
}
2014-12-17 23:13:53 +00:00
void issue_p2p_GO_request ( struct adapter * padapter , u8 * raddr )
2013-05-08 21:45:39 +00:00
{
unsigned char category = RTW_WLAN_CATEGORY_PUBLIC ;
2014-12-11 21:15:04 +00:00
u8 action = P2P_PUB_ACTION_ACTION ;
2014-12-19 04:28:04 +00:00
__be32 p2poui = cpu_to_be32 ( P2POUI ) ;
2014-12-11 21:15:04 +00:00
u8 oui_subtype = P2P_GO_NEGO_REQ ;
u8 wpsie [ 255 ] = { 0x00 } , p2pie [ 255 ] = { 0x00 } ;
u8 wpsielen = 0 , p2pielen = 0 , i ;
u8 channel_cnt_24g = 0 , channel_cnt_5gl = 0 , channel_cnt_5gh = 0 ;
u16 len_channellist_attr = 0 ;
# ifdef CONFIG_WFD
u32 wfdielen = 0 ;
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_WFD */
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
struct xmit_frame * pmgntframe ;
struct pkt_attrib * pattrib ;
unsigned char * pframe ;
2013-05-08 21:45:39 +00:00
struct rtw_ieee80211_hdr * pwlanhdr ;
2014-12-19 04:28:04 +00:00
__le16 * fctrl ;
2014-12-11 21:15:04 +00:00
struct xmit_priv * pxmitpriv = & ( padapter - > xmitpriv ) ;
2013-05-08 21:45:39 +00:00
struct mlme_ext_priv * pmlmeext = & ( padapter - > mlmeextpriv ) ;
2014-12-11 21:15:04 +00:00
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
struct wifidirect_info * pwdinfo = & ( padapter - > wdinfo ) ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
if ( ( pmgntframe = alloc_mgtxmitframe ( pxmitpriv ) ) = = NULL )
{
2013-05-08 21:45:39 +00:00
return ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
DBG_871X ( " [%s] In \n " , __FUNCTION__ ) ;
2015-02-19 21:34:32 +00:00
/* update attribute */
2013-05-08 21:45:39 +00:00
pattrib = & pmgntframe - > attrib ;
update_mgntframe_attrib ( padapter , pattrib ) ;
2015-02-19 20:58:09 +00:00
memset ( pmgntframe - > buf_addr , 0 , WLANHDR_OFFSET + TXDESC_OFFSET ) ;
2013-05-08 21:45:39 +00:00
pframe = ( u8 * ) ( pmgntframe - > buf_addr ) + TXDESC_OFFSET ;
pwlanhdr = ( struct rtw_ieee80211_hdr * ) pframe ;
fctrl = & ( pwlanhdr - > frame_ctl ) ;
* ( fctrl ) = 0 ;
2015-02-19 20:50:04 +00:00
memcpy ( pwlanhdr - > addr1 , raddr , ETH_ALEN ) ;
memcpy ( pwlanhdr - > addr2 , myid ( & ( padapter - > eeprompriv ) ) , ETH_ALEN ) ;
memcpy ( pwlanhdr - > addr3 , myid ( & ( padapter - > eeprompriv ) ) , ETH_ALEN ) ;
2013-05-08 21:45:39 +00:00
SetSeqNum ( pwlanhdr , pmlmeext - > mgnt_seq ) ;
pmlmeext - > mgnt_seq + + ;
SetFrameSubType ( pframe , WIFI_ACTION ) ;
pframe + = sizeof ( struct rtw_ieee80211_hdr_3addr ) ;
pattrib - > pktlen = sizeof ( struct rtw_ieee80211_hdr_3addr ) ;
pframe = rtw_set_fixed_ie ( pframe , 1 , & ( category ) , & ( pattrib - > pktlen ) ) ;
pframe = rtw_set_fixed_ie ( pframe , 1 , & ( action ) , & ( pattrib - > pktlen ) ) ;
2014-12-11 21:15:04 +00:00
pframe = rtw_set_fixed_ie ( pframe , 4 , ( unsigned char * ) & ( p2poui ) , & ( pattrib - > pktlen ) ) ;
2014-12-19 06:59:46 +00:00
pframe = rtw_set_fixed_ie ( pframe , 1 , & ( oui_subtype ) , & ( pattrib - > pktlen ) ) ;
2015-02-19 21:34:32 +00:00
pwdinfo - > negotiation_dialog_token = 1 ; /* Initialize the dialog value */
2013-05-08 21:45:39 +00:00
pframe = rtw_set_fixed_ie ( pframe , 1 , & pwdinfo - > negotiation_dialog_token , & ( pattrib - > pktlen ) ) ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
2015-02-19 21:34:32 +00:00
/* WPS Section */
2013-05-08 21:45:39 +00:00
wpsielen = 0 ;
2015-02-19 21:34:32 +00:00
/* WPS OUI */
2014-12-19 04:28:04 +00:00
* ( __be32 * ) ( wpsie ) = cpu_to_be32 ( WPSOUI ) ;
2013-05-08 21:45:39 +00:00
wpsielen + = 4 ;
2015-02-19 21:34:32 +00:00
/* WPS version */
/* Type: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( WPS_ATTR_VER1 ) ;
2013-05-08 21:45:39 +00:00
wpsielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( 0x0001 ) ;
2013-05-08 21:45:39 +00:00
wpsielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Value: */
wpsie [ wpsielen + + ] = WPS_VERSION_1 ; /* Version 1.0 */
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Device Password ID */
/* Type: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( WPS_ATTR_DEVICE_PWID ) ;
2013-05-08 21:45:39 +00:00
wpsielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( 0x0002 ) ;
2013-05-08 21:45:39 +00:00
wpsielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Value: */
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
if ( pwdinfo - > ui_got_wps_info = = P2P_GOT_WPSINFO_PEER_DISPLAY_PIN )
{
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( WPS_DPID_USER_SPEC ) ;
2014-12-11 21:15:04 +00:00
}
else if ( pwdinfo - > ui_got_wps_info = = P2P_GOT_WPSINFO_SELF_DISPLAY_PIN )
{
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( WPS_DPID_REGISTRAR_SPEC ) ;
2014-12-11 21:15:04 +00:00
}
else if ( pwdinfo - > ui_got_wps_info = = P2P_GOT_WPSINFO_PBC )
{
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( WPS_DPID_PBC ) ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
wpsielen + = 2 ;
2014-12-11 21:15:04 +00:00
pframe = rtw_set_ie ( pframe , _VENDOR_SPECIFIC_IE_ , wpsielen , ( unsigned char * ) wpsie , & pattrib - > pktlen ) ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* P2P IE Section. */
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* P2P OUI */
2013-05-08 21:45:39 +00:00
p2pielen = 0 ;
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = 0x50 ;
p2pie [ p2pielen + + ] = 0x6F ;
p2pie [ p2pielen + + ] = 0x9A ;
2015-02-19 21:34:32 +00:00
p2pie [ p2pielen + + ] = 0x09 ; /* WFA P2P v1.0 */
/* Commented by Albert 20110306 */
/* According to the P2P Specification, the group negoitation request frame should contain 9 P2P attributes */
/* 1. P2P Capability */
/* 2. Group Owner Intent */
/* 3. Configuration Timeout */
/* 4. Listen Channel */
/* 5. Extended Listen Timing */
/* 6. Intended P2P Interface Address */
/* 7. Channel List */
/* 8. P2P Device Info */
/* 9. Operating Channel */
/* P2P Capability */
/* Type: */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = P2P_ATTR_CAPABILITY ;
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( 0x0002 ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Value: */
/* Device Capability Bitmap, 1 byte */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = DMP_P2P_DEVCAP_SUPPORT ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Group Capability Bitmap, 1 byte */
2014-12-11 21:15:04 +00:00
if ( pwdinfo - > persistent_supported )
{
p2pie [ p2pielen + + ] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP ;
}
2013-05-08 21:45:39 +00:00
else
2014-12-11 21:15:04 +00:00
{
p2pie [ p2pielen + + ] = P2P_GRPCAP_CROSS_CONN ;
}
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Group Owner Intent */
/* Type: */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = P2P_ATTR_GO_INTENT ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( 0x0001 ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Value: */
/* Todo the tie breaker bit. */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = ( ( pwdinfo - > intent < < 1 ) | BIT ( 0 ) ) ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Configuration Timeout */
/* Type: */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = P2P_ATTR_CONF_TIMEOUT ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( 0x0002 ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Value: */
p2pie [ p2pielen + + ] = 200 ; /* 2 seconds needed to be the P2P GO */
p2pie [ p2pielen + + ] = 200 ; /* 2 seconds needed to be the P2P Client */
2013-05-08 21:45:39 +00:00
2013-05-19 04:28:07 +00:00
2015-02-19 21:34:32 +00:00
/* Listen Channel */
/* Type: */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = P2P_ATTR_LISTEN_CH ;
2013-05-19 04:28:07 +00:00
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( 0x0005 ) ;
2014-12-11 21:15:04 +00:00
p2pielen + = 2 ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Value: */
/* Country String */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = ' X ' ;
p2pie [ p2pielen + + ] = ' X ' ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* The third byte should be set to 0x04. */
/* Described in the "Operating Channel Attribute" section. */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = 0x04 ;
2015-02-19 21:34:32 +00:00
/* Operating Class */
p2pie [ p2pielen + + ] = 0x51 ; /* Copy from SD7 */
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* Channel Number */
p2pie [ p2pielen + + ] = pwdinfo - > listen_channel ; /* listening channel number */
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
2015-02-19 21:34:32 +00:00
/* Extended Listen Timing ATTR */
/* Type: */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = P2P_ATTR_EX_LISTEN_TIMING ;
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( 0x0004 ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Value: */
/* Availability Period */
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( 0xFFFF ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Availability Interval */
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( 0xFFFF ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Intended P2P Interface Address */
/* Type: */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = P2P_ATTR_INTENTED_IF_ADDR ;
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( ETH_ALEN ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Value: */
2015-02-19 20:50:04 +00:00
memcpy ( p2pie + p2pielen , myid ( & padapter - > eeprompriv ) , ETH_ALEN ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = ETH_ALEN ;
2015-02-19 21:34:32 +00:00
/* Channel List */
/* Type: */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = P2P_ATTR_CH_LIST ;
2015-02-19 21:34:32 +00:00
/* Length: */
/* Country String(3) */
/* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
/* + number of channels in all classes */
2013-05-08 21:45:39 +00:00
len_channellist_attr = 3
+ ( 1 + 1 ) * ( u16 ) ( pmlmeext - > channel_list . reg_classes )
2014-12-11 21:15:04 +00:00
+ get_reg_classes_full_count ( pmlmeext - > channel_list ) ;
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( len_channellist_attr ) ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Value: */
/* Country String */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = ' X ' ;
p2pie [ p2pielen + + ] = ' X ' ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* The third byte should be set to 0x04. */
/* Described in the "Operating Channel Attribute" section. */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = 0x04 ;
2013-05-19 04:28:07 +00:00
2015-02-19 21:34:32 +00:00
/* Channel Entry List */
2014-12-11 21:15:04 +00:00
{
int i , j ;
2013-05-08 21:45:39 +00:00
for ( j = 0 ; j < pmlmeext - > channel_list . reg_classes ; j + + ) {
2015-02-19 21:34:32 +00:00
/* Operating Class */
2013-05-08 21:45:39 +00:00
p2pie [ p2pielen + + ] = pmlmeext - > channel_list . reg_class [ j ] . reg_class ;
2015-02-19 21:34:32 +00:00
/* Number of Channels */
2013-05-08 21:45:39 +00:00
p2pie [ p2pielen + + ] = pmlmeext - > channel_list . reg_class [ j ] . channels ;
2015-02-19 21:34:32 +00:00
/* Channel List */
2013-05-08 21:45:39 +00:00
for ( i = 0 ; i < pmlmeext - > channel_list . reg_class [ j ] . channels ; i + + ) {
p2pie [ p2pielen + + ] = pmlmeext - > channel_list . reg_class [ j ] . channel [ i ] ;
}
}
}
2015-02-19 21:34:32 +00:00
/* Device Info */
/* Type: */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = P2P_ATTR_DEVICE_INFO ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Length: */
/* 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
/* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( 21 + pwdinfo - > device_name_len ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Value: */
/* P2P Device Address */
2015-02-19 20:50:04 +00:00
memcpy ( p2pie + p2pielen , myid ( & padapter - > eeprompriv ) , ETH_ALEN ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = ETH_ALEN ;
2015-02-19 21:34:32 +00:00
/* Config Method */
/* This field should be big endian. Noted by P2P specification. */
2013-05-08 21:45:39 +00:00
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( p2pie + p2pielen ) = cpu_to_be16 ( pwdinfo - > supported_wps_cm ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Primary Device Type */
/* Category ID */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( p2pie + p2pielen ) = cpu_to_be16 ( WPS_PDT_CID_MULIT_MEDIA ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* OUI */
2014-12-19 04:28:04 +00:00
* ( __be32 * ) ( p2pie + p2pielen ) = cpu_to_be32 ( WPSOUI ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 4 ;
2015-02-19 21:34:32 +00:00
/* Sub Category ID */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( p2pie + p2pielen ) = cpu_to_be16 ( WPS_PDT_SCID_MEDIA_SERVER ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Number of Secondary Device Types */
p2pie [ p2pielen + + ] = 0x00 ; /* No Secondary Device Type List */
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Device Name */
/* Type: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( p2pie + p2pielen ) = cpu_to_be16 ( WPS_ATTR_DEVICE_NAME ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( p2pie + p2pielen ) = cpu_to_be16 ( pwdinfo - > device_name_len ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Value: */
2015-02-19 20:50:04 +00:00
memcpy ( p2pie + p2pielen , pwdinfo - > device_name , pwdinfo - > device_name_len ) ;
2014-12-19 06:59:46 +00:00
p2pielen + = pwdinfo - > device_name_len ;
2013-05-19 04:28:07 +00:00
2015-02-19 21:34:32 +00:00
/* Operating Channel */
/* Type: */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = P2P_ATTR_OPERATING_CH ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( 0x0005 ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Value: */
/* Country String */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = ' X ' ;
p2pie [ p2pielen + + ] = ' X ' ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* The third byte should be set to 0x04. */
/* Described in the "Operating Channel Attribute" section. */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = 0x04 ;
2015-02-19 21:34:32 +00:00
/* Operating Class */
2014-12-11 21:15:04 +00:00
if ( pwdinfo - > operating_channel < = 14 )
{
2015-02-19 21:34:32 +00:00
/* Operating Class */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = 0x51 ;
}
else if ( ( pwdinfo - > operating_channel > = 36 ) & & ( pwdinfo - > operating_channel < = 48 ) )
{
2015-02-19 21:34:32 +00:00
/* Operating Class */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = 0x73 ;
}
else
{
2015-02-19 21:34:32 +00:00
/* Operating Class */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = 0x7c ;
}
2013-08-01 02:12:42 +00:00
2015-02-19 21:34:32 +00:00
/* Channel Number */
p2pie [ p2pielen + + ] = pwdinfo - > operating_channel ; /* operating channel number */
2013-05-08 21:45:39 +00:00
2014-12-19 06:59:46 +00:00
pframe = rtw_set_ie ( pframe , _VENDOR_SPECIFIC_IE_ , p2pielen , ( unsigned char * ) p2pie , & pattrib - > pktlen ) ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_WFD
wfdielen = build_nego_req_wfd_ie ( pwdinfo , pframe ) ;
pframe + = wfdielen ;
pattrib - > pktlen + = wfdielen ;
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_WFD */
2013-05-08 21:45:39 +00:00
pattrib - > last_txcmdsz = pattrib - > pktlen ;
dump_mgntframe ( padapter , pmgntframe ) ;
return ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
2014-12-19 04:28:04 +00:00
static void issue_p2p_GO_response ( struct adapter * padapter , u8 * raddr , u8 * frame_body , uint len , u8 result )
2013-05-08 21:45:39 +00:00
{
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
unsigned char category = RTW_WLAN_CATEGORY_PUBLIC ;
2014-12-11 21:15:04 +00:00
u8 action = P2P_PUB_ACTION_ACTION ;
2014-12-19 04:28:04 +00:00
__be32 p2poui = cpu_to_be32 ( P2POUI ) ;
2014-12-11 21:15:04 +00:00
u8 oui_subtype = P2P_GO_NEGO_RESP ;
u8 wpsie [ 255 ] = { 0x00 } , p2pie [ 255 ] = { 0x00 } ;
u8 p2pielen = 0 , i ;
2013-05-08 21:45:39 +00:00
uint wpsielen = 0 ;
2014-12-11 21:15:04 +00:00
u16 wps_devicepassword_id = 0x0000 ;
2013-05-08 21:45:39 +00:00
uint wps_devicepassword_id_len = 0 ;
2014-12-11 21:15:04 +00:00
u8 channel_cnt_24g = 0 , channel_cnt_5gl = 0 , channel_cnt_5gh ;
u16 len_channellist_attr = 0 ;
2014-12-19 06:59:46 +00:00
__be16 be_tmp ;
2013-05-08 21:45:39 +00:00
struct xmit_frame * pmgntframe ;
struct pkt_attrib * pattrib ;
unsigned char * pframe ;
struct rtw_ieee80211_hdr * pwlanhdr ;
2014-12-19 04:28:04 +00:00
__le16 * fctrl ;
2013-05-08 21:45:39 +00:00
struct xmit_priv * pxmitpriv = & ( padapter - > xmitpriv ) ;
struct mlme_ext_priv * pmlmeext = & ( padapter - > mlmeextpriv ) ;
2014-12-11 21:15:04 +00:00
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
struct wifidirect_info * pwdinfo = & ( padapter - > wdinfo ) ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_WFD
u32 wfdielen = 0 ;
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_WFD */
2014-12-11 21:15:04 +00:00
if ( ( pmgntframe = alloc_mgtxmitframe ( pxmitpriv ) ) = = NULL )
{
2013-05-08 21:45:39 +00:00
return ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
DBG_871X ( " [%s] In, result = %d \n " , __FUNCTION__ , result ) ;
2015-02-19 21:34:32 +00:00
/* update attribute */
2013-05-08 21:45:39 +00:00
pattrib = & pmgntframe - > attrib ;
update_mgntframe_attrib ( padapter , pattrib ) ;
2015-02-19 20:58:09 +00:00
memset ( pmgntframe - > buf_addr , 0 , WLANHDR_OFFSET + TXDESC_OFFSET ) ;
2013-05-08 21:45:39 +00:00
pframe = ( u8 * ) ( pmgntframe - > buf_addr ) + TXDESC_OFFSET ;
pwlanhdr = ( struct rtw_ieee80211_hdr * ) pframe ;
fctrl = & ( pwlanhdr - > frame_ctl ) ;
* ( fctrl ) = 0 ;
2015-02-19 20:50:04 +00:00
memcpy ( pwlanhdr - > addr1 , raddr , ETH_ALEN ) ;
memcpy ( pwlanhdr - > addr2 , myid ( & ( padapter - > eeprompriv ) ) , ETH_ALEN ) ;
memcpy ( pwlanhdr - > addr3 , myid ( & ( padapter - > eeprompriv ) ) , ETH_ALEN ) ;
2013-05-08 21:45:39 +00:00
SetSeqNum ( pwlanhdr , pmlmeext - > mgnt_seq ) ;
pmlmeext - > mgnt_seq + + ;
SetFrameSubType ( pframe , WIFI_ACTION ) ;
pframe + = sizeof ( struct rtw_ieee80211_hdr_3addr ) ;
pattrib - > pktlen = sizeof ( struct rtw_ieee80211_hdr_3addr ) ;
pframe = rtw_set_fixed_ie ( pframe , 1 , & ( category ) , & ( pattrib - > pktlen ) ) ;
pframe = rtw_set_fixed_ie ( pframe , 1 , & ( action ) , & ( pattrib - > pktlen ) ) ;
2014-12-11 21:15:04 +00:00
pframe = rtw_set_fixed_ie ( pframe , 4 , ( unsigned char * ) & ( p2poui ) , & ( pattrib - > pktlen ) ) ;
2014-12-19 06:59:46 +00:00
pframe = rtw_set_fixed_ie ( pframe , 1 , & ( oui_subtype ) , & ( pattrib - > pktlen ) ) ;
2015-02-19 21:34:32 +00:00
pwdinfo - > negotiation_dialog_token = frame_body [ 7 ] ; /* The Dialog Token of provisioning discovery request frame. */
2013-05-08 21:45:39 +00:00
pframe = rtw_set_fixed_ie ( pframe , 1 , & ( pwdinfo - > negotiation_dialog_token ) , & ( pattrib - > pktlen ) ) ;
2015-02-19 21:34:32 +00:00
/* Commented by Albert 20110328 */
/* Try to get the device password ID from the WPS IE of group negotiation request frame */
/* WiFi Direct test plan 5.1.15 */
2014-12-11 21:15:04 +00:00
rtw_get_wps_ie ( frame_body + _PUBLIC_ACTION_IE_OFFSET_ , len - _PUBLIC_ACTION_IE_OFFSET_ , wpsie , & wpsielen ) ;
2014-12-19 04:28:04 +00:00
rtw_get_wps_attr_content ( wpsie , wpsielen , WPS_ATTR_DEVICE_PWID , ( u8 * ) & be_tmp , & wps_devicepassword_id_len ) ;
wps_devicepassword_id = be16_to_cpu ( be_tmp ) ;
2013-05-08 21:45:39 +00:00
2015-02-19 20:58:09 +00:00
memset ( wpsie , 0x00 , 255 ) ;
2013-05-08 21:45:39 +00:00
wpsielen = 0 ;
2015-02-19 21:34:32 +00:00
/* WPS Section */
2013-05-08 21:45:39 +00:00
wpsielen = 0 ;
2015-02-19 21:34:32 +00:00
/* WPS OUI */
2014-12-19 04:28:04 +00:00
* ( __be32 * ) ( wpsie ) = cpu_to_be32 ( WPSOUI ) ;
2013-05-08 21:45:39 +00:00
wpsielen + = 4 ;
2015-02-19 21:34:32 +00:00
/* WPS version */
/* Type: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( WPS_ATTR_VER1 ) ;
2013-05-08 21:45:39 +00:00
wpsielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( 0x0001 ) ;
2013-05-08 21:45:39 +00:00
wpsielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Value: */
wpsie [ wpsielen + + ] = WPS_VERSION_1 ; /* Version 1.0 */
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Device Password ID */
/* Type: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( WPS_ATTR_DEVICE_PWID ) ;
2013-05-08 21:45:39 +00:00
wpsielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( 0x0002 ) ;
2013-05-08 21:45:39 +00:00
wpsielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Value: */
2014-12-11 21:15:04 +00:00
if ( wps_devicepassword_id = = WPS_DPID_USER_SPEC )
{
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( WPS_DPID_REGISTRAR_SPEC ) ;
2014-12-11 21:15:04 +00:00
}
else if ( wps_devicepassword_id = = WPS_DPID_REGISTRAR_SPEC )
{
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( WPS_DPID_USER_SPEC ) ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
else
2014-12-11 21:15:04 +00:00
{
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( WPS_DPID_PBC ) ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
wpsielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Commented by Kurt 20120113 */
/* If some device wants to do p2p handshake without sending prov_disc_req */
/* We have to get peer_req_cm from here. */
2014-12-11 21:15:04 +00:00
if ( _rtw_memcmp ( pwdinfo - > rx_prov_disc_info . strconfig_method_desc_of_prov_disc_req , " 000 " , 3 ) )
{
if ( wps_devicepassword_id = = WPS_DPID_USER_SPEC )
{
2015-02-19 20:50:04 +00:00
memcpy ( pwdinfo - > rx_prov_disc_info . strconfig_method_desc_of_prov_disc_req , " dis " , 3 ) ;
2014-12-11 21:15:04 +00:00
}
else if ( wps_devicepassword_id = = WPS_DPID_REGISTRAR_SPEC )
{
2015-02-19 20:50:04 +00:00
memcpy ( pwdinfo - > rx_prov_disc_info . strconfig_method_desc_of_prov_disc_req , " pad " , 3 ) ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
else
2014-12-11 21:15:04 +00:00
{
2015-02-19 20:50:04 +00:00
memcpy ( pwdinfo - > rx_prov_disc_info . strconfig_method_desc_of_prov_disc_req , " pbc " , 3 ) ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
pframe = rtw_set_ie ( pframe , _VENDOR_SPECIFIC_IE_ , wpsielen , ( unsigned char * ) wpsie , & pattrib - > pktlen ) ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* P2P IE Section. */
2014-12-11 21:15:04 +00:00
2015-02-19 21:34:32 +00:00
/* P2P OUI */
2013-05-08 21:45:39 +00:00
p2pielen = 0 ;
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = 0x50 ;
p2pie [ p2pielen + + ] = 0x6F ;
p2pie [ p2pielen + + ] = 0x9A ;
2015-02-19 21:34:32 +00:00
p2pie [ p2pielen + + ] = 0x09 ; /* WFA P2P v1.0 */
2014-12-11 21:15:04 +00:00
2015-02-19 21:34:32 +00:00
/* Commented by Albert 20100908 */
/* According to the P2P Specification, the group negoitation response frame should contain 9 P2P attributes */
/* 1. Status */
/* 2. P2P Capability */
/* 3. Group Owner Intent */
/* 4. Configuration Timeout */
/* 5. Operating Channel */
/* 6. Intended P2P Interface Address */
/* 7. Channel List */
/* 8. Device Info */
/* 9. Group ID ( Only GO ) */
2014-12-11 21:15:04 +00:00
2015-02-19 21:34:32 +00:00
/* ToDo: */
2014-12-11 21:15:04 +00:00
2015-02-19 21:34:32 +00:00
/* P2P Status */
/* Type: */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = P2P_ATTR_STATUS ;
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( 0x0001 ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Value: */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = result ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* P2P Capability */
/* Type: */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = P2P_ATTR_CAPABILITY ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( 0x0002 ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Value: */
/* Device Capability Bitmap, 1 byte */
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
if ( rtw_p2p_chk_role ( pwdinfo , P2P_ROLE_CLIENT ) )
{
2015-02-19 21:34:32 +00:00
/* Commented by Albert 2011/03/08 */
/* According to the P2P specification */
/* if the sending device will be client, the P2P Capability should be reserved of group negotation response frame */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = 0 ;
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
else
{
2015-02-19 21:34:32 +00:00
/* Be group owner or meet the error case */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = DMP_P2P_DEVCAP_SUPPORT ;
}
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* Group Capability Bitmap, 1 byte */
2014-12-11 21:15:04 +00:00
if ( pwdinfo - > persistent_supported )
{
p2pie [ p2pielen + + ] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP ;
}
else
{
p2pie [ p2pielen + + ] = P2P_GRPCAP_CROSS_CONN ;
2013-05-08 21:45:39 +00:00
}
2015-02-19 21:34:32 +00:00
/* Group Owner Intent */
/* Type: */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = P2P_ATTR_GO_INTENT ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( 0x0001 ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Value: */
2014-12-11 21:15:04 +00:00
if ( pwdinfo - > peer_intent & 0x01 )
{
2015-02-19 21:34:32 +00:00
/* Peer's tie breaker bit is 1, our tie breaker bit should be 0 */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = ( pwdinfo - > intent < < 1 ) ;
}
else
{
2015-02-19 21:34:32 +00:00
/* Peer's tie breaker bit is 0, our tie breaker bit should be 1 */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = ( ( pwdinfo - > intent < < 1 ) | BIT ( 0 ) ) ;
2013-05-08 21:45:39 +00:00
}
2015-02-19 21:34:32 +00:00
/* Configuration Timeout */
/* Type: */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = P2P_ATTR_CONF_TIMEOUT ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( 0x0002 ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Value: */
p2pie [ p2pielen + + ] = 200 ; /* 2 seconds needed to be the P2P GO */
p2pie [ p2pielen + + ] = 200 ; /* 2 seconds needed to be the P2P Client */
2013-08-01 02:12:42 +00:00
2015-02-19 21:34:32 +00:00
/* Operating Channel */
/* Type: */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = P2P_ATTR_OPERATING_CH ;
2013-08-01 02:12:42 +00:00
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( 0x0005 ) ;
2014-12-11 21:15:04 +00:00
p2pielen + = 2 ;
2013-05-19 04:28:07 +00:00
2015-02-19 21:34:32 +00:00
/* Value: */
/* Country String */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = ' X ' ;
p2pie [ p2pielen + + ] = ' X ' ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* The third byte should be set to 0x04. */
/* Described in the "Operating Channel Attribute" section. */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = 0x04 ;
2015-02-19 21:34:32 +00:00
/* Operating Class */
2014-12-11 21:15:04 +00:00
if ( pwdinfo - > operating_channel < = 14 )
{
2015-02-19 21:34:32 +00:00
/* Operating Class */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = 0x51 ;
}
else if ( ( pwdinfo - > operating_channel > = 36 ) & & ( pwdinfo - > operating_channel < = 48 ) )
{
2015-02-19 21:34:32 +00:00
/* Operating Class */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = 0x73 ;
}
else
{
2015-02-19 21:34:32 +00:00
/* Operating Class */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = 0x7c ;
}
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* Channel Number */
p2pie [ p2pielen + + ] = pwdinfo - > operating_channel ; /* operating channel number */
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Intended P2P Interface Address */
/* Type: */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = P2P_ATTR_INTENTED_IF_ADDR ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( ETH_ALEN ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Value: */
2015-02-19 20:50:04 +00:00
memcpy ( p2pie + p2pielen , myid ( & padapter - > eeprompriv ) , ETH_ALEN ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = ETH_ALEN ;
2015-02-19 21:34:32 +00:00
/* Channel List */
/* Type: */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = P2P_ATTR_CH_LIST ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Country String(3) */
/* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
/* + number of channels in all classes */
2013-05-08 21:45:39 +00:00
len_channellist_attr = 3
+ ( 1 + 1 ) * ( u16 ) pmlmeext - > channel_list . reg_classes
2014-12-11 21:15:04 +00:00
+ get_reg_classes_full_count ( pmlmeext - > channel_list ) ;
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( len_channellist_attr ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Value: */
/* Country String */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = ' X ' ;
p2pie [ p2pielen + + ] = ' X ' ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* The third byte should be set to 0x04. */
/* Described in the "Operating Channel Attribute" section. */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = 0x04 ;
2015-02-19 21:34:32 +00:00
/* Channel Entry List */
2014-12-11 21:15:04 +00:00
{
int i , j ;
for ( j = 0 ; j < pmlmeext - > channel_list . reg_classes ; j + + ) {
2015-02-19 21:34:32 +00:00
/* Operating Class */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = pmlmeext - > channel_list . reg_class [ j ] . reg_class ;
2013-05-19 04:28:07 +00:00
2015-02-19 21:34:32 +00:00
/* Number of Channels */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = pmlmeext - > channel_list . reg_class [ j ] . channels ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Channel List */
2014-12-11 21:15:04 +00:00
for ( i = 0 ; i < pmlmeext - > channel_list . reg_class [ j ] . channels ; i + + ) {
p2pie [ p2pielen + + ] = pmlmeext - > channel_list . reg_class [ j ] . channel [ i ] ;
}
}
}
2015-02-19 21:34:32 +00:00
/* Device Info */
/* Type: */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = P2P_ATTR_DEVICE_INFO ;
2015-02-19 21:34:32 +00:00
/* Length: */
/* 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
/* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( 21 + pwdinfo - > device_name_len ) ;
2014-12-11 21:15:04 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Value: */
/* P2P Device Address */
2015-02-19 20:50:04 +00:00
memcpy ( p2pie + p2pielen , myid ( & padapter - > eeprompriv ) , ETH_ALEN ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = ETH_ALEN ;
2015-02-19 21:34:32 +00:00
/* Config Method */
/* This field should be big endian. Noted by P2P specification. */
2013-05-08 21:45:39 +00:00
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( p2pie + p2pielen ) = cpu_to_be16 ( pwdinfo - > supported_wps_cm ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Primary Device Type */
/* Category ID */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( p2pie + p2pielen ) = cpu_to_be16 ( WPS_PDT_CID_MULIT_MEDIA ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* OUI */
2014-12-19 04:28:04 +00:00
* ( __be32 * ) ( p2pie + p2pielen ) = cpu_to_be32 ( WPSOUI ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 4 ;
2015-02-19 21:34:32 +00:00
/* Sub Category ID */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( p2pie + p2pielen ) = cpu_to_be16 ( WPS_PDT_SCID_MEDIA_SERVER ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Number of Secondary Device Types */
p2pie [ p2pielen + + ] = 0x00 ; /* No Secondary Device Type List */
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Device Name */
/* Type: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( p2pie + p2pielen ) = cpu_to_be16 ( WPS_ATTR_DEVICE_NAME ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( p2pie + p2pielen ) = cpu_to_be16 ( pwdinfo - > device_name_len ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Value: */
2015-02-19 20:50:04 +00:00
memcpy ( p2pie + p2pielen , pwdinfo - > device_name , pwdinfo - > device_name_len ) ;
2014-12-19 06:59:46 +00:00
p2pielen + = pwdinfo - > device_name_len ;
2014-12-11 21:15:04 +00:00
if ( rtw_p2p_chk_role ( pwdinfo , P2P_ROLE_GO ) )
{
2015-02-19 21:34:32 +00:00
/* Group ID Attribute */
/* Type: */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = P2P_ATTR_GROUP_ID ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( ETH_ALEN + pwdinfo - > nego_ssidlen ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Value: */
/* p2P Device Address */
2015-02-19 20:50:04 +00:00
memcpy ( p2pie + p2pielen , pwdinfo - > device_addr , ETH_ALEN ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = ETH_ALEN ;
2015-02-19 21:34:32 +00:00
/* SSID */
2015-02-19 20:50:04 +00:00
memcpy ( p2pie + p2pielen , pwdinfo - > nego_ssid , pwdinfo - > nego_ssidlen ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = pwdinfo - > nego_ssidlen ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-19 06:59:46 +00:00
pframe = rtw_set_ie ( pframe , _VENDOR_SPECIFIC_IE_ , p2pielen , ( unsigned char * ) p2pie , & pattrib - > pktlen ) ;
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_WFD
wfdielen = build_nego_resp_wfd_ie ( pwdinfo , pframe ) ;
pframe + = wfdielen ;
pattrib - > pktlen + = wfdielen ;
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_WFD */
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
pattrib - > last_txcmdsz = pattrib - > pktlen ;
dump_mgntframe ( padapter , pmgntframe ) ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
return ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-19 04:28:04 +00:00
static void issue_p2p_GO_confirm ( struct adapter * padapter , u8 * raddr , u8 result )
2013-05-08 21:45:39 +00:00
{
2013-05-19 04:28:07 +00:00
2014-12-11 21:15:04 +00:00
unsigned char category = RTW_WLAN_CATEGORY_PUBLIC ;
u8 action = P2P_PUB_ACTION_ACTION ;
2014-12-19 04:28:04 +00:00
__be32 p2poui = cpu_to_be32 ( P2POUI ) ;
2014-12-11 21:15:04 +00:00
u8 oui_subtype = P2P_GO_NEGO_CONF ;
u8 wpsie [ 255 ] = { 0x00 } , p2pie [ 255 ] = { 0x00 } ;
u8 wpsielen = 0 , p2pielen = 0 ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
struct xmit_frame * pmgntframe ;
struct pkt_attrib * pattrib ;
unsigned char * pframe ;
struct rtw_ieee80211_hdr * pwlanhdr ;
2014-12-19 04:28:04 +00:00
__le16 * fctrl ;
2013-05-08 21:45:39 +00:00
struct xmit_priv * pxmitpriv = & ( padapter - > xmitpriv ) ;
struct mlme_ext_priv * pmlmeext = & ( padapter - > mlmeextpriv ) ;
2014-12-11 21:15:04 +00:00
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
struct wifidirect_info * pwdinfo = & ( padapter - > wdinfo ) ;
# ifdef CONFIG_WFD
u32 wfdielen = 0 ;
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_WFD */
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
if ( ( pmgntframe = alloc_mgtxmitframe ( pxmitpriv ) ) = = NULL )
{
2013-05-08 21:45:39 +00:00
return ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
DBG_871X ( " [%s] In \n " , __FUNCTION__ ) ;
2015-02-19 21:34:32 +00:00
/* update attribute */
2013-05-08 21:45:39 +00:00
pattrib = & pmgntframe - > attrib ;
update_mgntframe_attrib ( padapter , pattrib ) ;
2015-02-19 20:58:09 +00:00
memset ( pmgntframe - > buf_addr , 0 , WLANHDR_OFFSET + TXDESC_OFFSET ) ;
2013-05-08 21:45:39 +00:00
pframe = ( u8 * ) ( pmgntframe - > buf_addr ) + TXDESC_OFFSET ;
pwlanhdr = ( struct rtw_ieee80211_hdr * ) pframe ;
fctrl = & ( pwlanhdr - > frame_ctl ) ;
* ( fctrl ) = 0 ;
2015-02-19 20:50:04 +00:00
memcpy ( pwlanhdr - > addr1 , raddr , ETH_ALEN ) ;
memcpy ( pwlanhdr - > addr2 , myid ( & ( padapter - > eeprompriv ) ) , ETH_ALEN ) ;
memcpy ( pwlanhdr - > addr3 , myid ( & ( padapter - > eeprompriv ) ) , ETH_ALEN ) ;
2013-05-08 21:45:39 +00:00
SetSeqNum ( pwlanhdr , pmlmeext - > mgnt_seq ) ;
pmlmeext - > mgnt_seq + + ;
SetFrameSubType ( pframe , WIFI_ACTION ) ;
pframe + = sizeof ( struct rtw_ieee80211_hdr_3addr ) ;
pattrib - > pktlen = sizeof ( struct rtw_ieee80211_hdr_3addr ) ;
pframe = rtw_set_fixed_ie ( pframe , 1 , & ( category ) , & ( pattrib - > pktlen ) ) ;
pframe = rtw_set_fixed_ie ( pframe , 1 , & ( action ) , & ( pattrib - > pktlen ) ) ;
2014-12-11 21:15:04 +00:00
pframe = rtw_set_fixed_ie ( pframe , 4 , ( unsigned char * ) & ( p2poui ) , & ( pattrib - > pktlen ) ) ;
2014-12-19 06:59:46 +00:00
pframe = rtw_set_fixed_ie ( pframe , 1 , & ( oui_subtype ) , & ( pattrib - > pktlen ) ) ;
2013-05-08 21:45:39 +00:00
pframe = rtw_set_fixed_ie ( pframe , 1 , & ( pwdinfo - > negotiation_dialog_token ) , & ( pattrib - > pktlen ) ) ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
2015-02-19 21:34:32 +00:00
/* P2P IE Section. */
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* P2P OUI */
2013-05-08 21:45:39 +00:00
p2pielen = 0 ;
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = 0x50 ;
p2pie [ p2pielen + + ] = 0x6F ;
p2pie [ p2pielen + + ] = 0x9A ;
2015-02-19 21:34:32 +00:00
p2pie [ p2pielen + + ] = 0x09 ; /* WFA P2P v1.0 */
/* Commented by Albert 20110306 */
/* According to the P2P Specification, the group negoitation request frame should contain 5 P2P attributes */
/* 1. Status */
/* 2. P2P Capability */
/* 3. Operating Channel */
/* 4. Channel List */
/* 5. Group ID ( if this WiFi is GO ) */
/* P2P Status */
/* Type: */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = P2P_ATTR_STATUS ;
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( 0x0001 ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Value: */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = result ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* P2P Capability */
/* Type: */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = P2P_ATTR_CAPABILITY ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( 0x0002 ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Value: */
/* Device Capability Bitmap, 1 byte */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = DMP_P2P_DEVCAP_SUPPORT ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* Group Capability Bitmap, 1 byte */
2014-12-11 21:15:04 +00:00
if ( pwdinfo - > persistent_supported )
{
p2pie [ p2pielen + + ] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP ;
}
2013-05-08 21:45:39 +00:00
else
2014-12-11 21:15:04 +00:00
{
p2pie [ p2pielen + + ] = P2P_GRPCAP_CROSS_CONN ;
}
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Operating Channel */
/* Type: */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = P2P_ATTR_OPERATING_CH ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( 0x0005 ) ;
2014-12-11 21:15:04 +00:00
p2pielen + = 2 ;
2013-05-19 04:28:07 +00:00
2015-02-19 21:34:32 +00:00
/* Value: */
/* Country String */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = ' X ' ;
p2pie [ p2pielen + + ] = ' X ' ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* The third byte should be set to 0x04. */
/* Described in the "Operating Channel Attribute" section. */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = 0x04 ;
2013-05-08 21:45:39 +00:00
2013-05-19 04:28:07 +00:00
2014-12-11 21:15:04 +00:00
if ( rtw_p2p_chk_role ( pwdinfo , P2P_ROLE_CLIENT ) )
{
if ( pwdinfo - > peer_operating_ch < = 14 )
{
2015-02-19 21:34:32 +00:00
/* Operating Class */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = 0x51 ;
}
else if ( ( pwdinfo - > peer_operating_ch > = 36 ) & & ( pwdinfo - > peer_operating_ch < = 48 ) )
{
2015-02-19 21:34:32 +00:00
/* Operating Class */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = 0x73 ;
}
else
{
2015-02-19 21:34:32 +00:00
/* Operating Class */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = 0x7c ;
}
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = pwdinfo - > peer_operating_ch ;
}
else
{
if ( pwdinfo - > operating_channel < = 14 )
{
2015-02-19 21:34:32 +00:00
/* Operating Class */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = 0x51 ;
}
else if ( ( pwdinfo - > operating_channel > = 36 ) & & ( pwdinfo - > operating_channel < = 48 ) )
{
2015-02-19 21:34:32 +00:00
/* Operating Class */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = 0x73 ;
}
else
{
2015-02-19 21:34:32 +00:00
/* Operating Class */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = 0x7c ;
}
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* Channel Number */
p2pie [ p2pielen + + ] = pwdinfo - > operating_channel ; /* Use the listen channel as the operating channel */
2013-05-08 21:45:39 +00:00
}
2015-02-19 21:34:32 +00:00
/* Channel List */
/* Type: */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = P2P_ATTR_CH_LIST ;
2015-02-09 23:28:30 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( 6 ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Country String */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = ' X ' ;
p2pie [ p2pielen + + ] = ' X ' ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* The third byte should be set to 0x04. */
/* Described in the "Operating Channel Attribute" section. */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = 0x04 ;
2015-02-19 21:34:32 +00:00
/* Value: */
2014-12-11 21:15:04 +00:00
if ( rtw_p2p_chk_role ( pwdinfo , P2P_ROLE_CLIENT ) )
{
if ( pwdinfo - > peer_operating_ch < = 14 )
{
2015-02-19 21:34:32 +00:00
/* Operating Class */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = 0x51 ;
}
else if ( ( pwdinfo - > peer_operating_ch > = 36 ) & & ( pwdinfo - > peer_operating_ch < = 48 ) )
{
2015-02-19 21:34:32 +00:00
/* Operating Class */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = 0x73 ;
}
else
{
2015-02-19 21:34:32 +00:00
/* Operating Class */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = 0x7c ;
}
p2pie [ p2pielen + + ] = 1 ;
p2pie [ p2pielen + + ] = pwdinfo - > peer_operating_ch ;
}
else
{
if ( pwdinfo - > operating_channel < = 14 )
{
2015-02-19 21:34:32 +00:00
/* Operating Class */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = 0x51 ;
}
else if ( ( pwdinfo - > operating_channel > = 36 ) & & ( pwdinfo - > operating_channel < = 48 ) )
{
2015-02-19 21:34:32 +00:00
/* Operating Class */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = 0x73 ;
}
else
{
2015-02-19 21:34:32 +00:00
/* Operating Class */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = 0x7c ;
}
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* Channel Number */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = 1 ;
2015-02-19 21:34:32 +00:00
p2pie [ p2pielen + + ] = pwdinfo - > operating_channel ; /* Use the listen channel as the operating channel */
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
if ( rtw_p2p_chk_role ( pwdinfo , P2P_ROLE_GO ) )
{
2015-02-19 21:34:32 +00:00
/* Group ID Attribute */
/* Type: */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = P2P_ATTR_GROUP_ID ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( ETH_ALEN + pwdinfo - > nego_ssidlen ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Value: */
/* p2P Device Address */
2015-02-19 20:50:04 +00:00
memcpy ( p2pie + p2pielen , pwdinfo - > device_addr , ETH_ALEN ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = ETH_ALEN ;
2015-02-19 21:34:32 +00:00
/* SSID */
2015-02-19 20:50:04 +00:00
memcpy ( p2pie + p2pielen , pwdinfo - > nego_ssid , pwdinfo - > nego_ssidlen ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = pwdinfo - > nego_ssidlen ;
}
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
pframe = rtw_set_ie ( pframe , _VENDOR_SPECIFIC_IE_ , p2pielen , ( unsigned char * ) p2pie , & pattrib - > pktlen ) ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_WFD
wfdielen = build_nego_confirm_wfd_ie ( pwdinfo , pframe ) ;
pframe + = wfdielen ;
pattrib - > pktlen + = wfdielen ;
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_WFD */
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
pattrib - > last_txcmdsz = pattrib - > pktlen ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
dump_mgntframe ( padapter , pmgntframe ) ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
return ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-17 23:13:53 +00:00
void issue_p2p_invitation_request ( struct adapter * padapter , u8 * raddr )
2013-05-08 21:45:39 +00:00
{
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
unsigned char category = RTW_WLAN_CATEGORY_PUBLIC ;
2014-12-15 05:08:37 +00:00
u8 action = P2P_PUB_ACTION_ACTION ;
2014-12-19 04:28:04 +00:00
__be32 p2poui = cpu_to_be32 ( P2POUI ) ;
2014-12-15 05:08:37 +00:00
u8 oui_subtype = P2P_INVIT_REQ ;
u8 p2pie [ 255 ] = { 0x00 } ;
u8 p2pielen = 0 , i ;
u8 dialogToken = 3 ;
u8 channel_cnt_24g = 0 , channel_cnt_5gl = 0 , channel_cnt_5gh = 0 ;
2014-12-19 06:59:46 +00:00
u16 len_channellist_attr = 0 ;
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_WFD
2014-12-15 05:08:37 +00:00
u32 wfdielen = 0 ;
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_WFD */
2014-12-15 05:08:37 +00:00
struct xmit_frame * pmgntframe ;
struct pkt_attrib * pattrib ;
unsigned char * pframe ;
2013-05-08 21:45:39 +00:00
struct rtw_ieee80211_hdr * pwlanhdr ;
2014-12-19 04:28:04 +00:00
__le16 * fctrl ;
2014-12-15 05:08:37 +00:00
struct xmit_priv * pxmitpriv = & ( padapter - > xmitpriv ) ;
2013-05-08 21:45:39 +00:00
struct mlme_ext_priv * pmlmeext = & ( padapter - > mlmeextpriv ) ;
2014-12-11 21:15:04 +00:00
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
struct wifidirect_info * pwdinfo = & ( padapter - > wdinfo ) ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
if ( ( pmgntframe = alloc_mgtxmitframe ( pxmitpriv ) ) = = NULL )
2013-05-08 21:45:39 +00:00
return ;
2015-02-19 21:34:32 +00:00
/* update attribute */
2013-05-08 21:45:39 +00:00
pattrib = & pmgntframe - > attrib ;
update_mgntframe_attrib ( padapter , pattrib ) ;
2015-02-19 20:58:09 +00:00
memset ( pmgntframe - > buf_addr , 0 , WLANHDR_OFFSET + TXDESC_OFFSET ) ;
2013-05-08 21:45:39 +00:00
pframe = ( u8 * ) ( pmgntframe - > buf_addr ) + TXDESC_OFFSET ;
pwlanhdr = ( struct rtw_ieee80211_hdr * ) pframe ;
fctrl = & ( pwlanhdr - > frame_ctl ) ;
* ( fctrl ) = 0 ;
2015-02-19 20:50:04 +00:00
memcpy ( pwlanhdr - > addr1 , raddr , ETH_ALEN ) ;
memcpy ( pwlanhdr - > addr2 , myid ( & ( padapter - > eeprompriv ) ) , ETH_ALEN ) ;
memcpy ( pwlanhdr - > addr3 , raddr , ETH_ALEN ) ;
2013-05-08 21:45:39 +00:00
SetSeqNum ( pwlanhdr , pmlmeext - > mgnt_seq ) ;
pmlmeext - > mgnt_seq + + ;
SetFrameSubType ( pframe , WIFI_ACTION ) ;
pframe + = sizeof ( struct rtw_ieee80211_hdr_3addr ) ;
pattrib - > pktlen = sizeof ( struct rtw_ieee80211_hdr_3addr ) ;
pframe = rtw_set_fixed_ie ( pframe , 1 , & ( category ) , & ( pattrib - > pktlen ) ) ;
pframe = rtw_set_fixed_ie ( pframe , 1 , & ( action ) , & ( pattrib - > pktlen ) ) ;
2014-12-11 21:15:04 +00:00
pframe = rtw_set_fixed_ie ( pframe , 4 , ( unsigned char * ) & ( p2poui ) , & ( pattrib - > pktlen ) ) ;
2014-12-19 06:59:46 +00:00
pframe = rtw_set_fixed_ie ( pframe , 1 , & ( oui_subtype ) , & ( pattrib - > pktlen ) ) ;
2013-05-08 21:45:39 +00:00
pframe = rtw_set_fixed_ie ( pframe , 1 , & ( dialogToken ) , & ( pattrib - > pktlen ) ) ;
2015-02-19 21:34:32 +00:00
/* P2P IE Section. */
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* P2P OUI */
2013-05-08 21:45:39 +00:00
p2pielen = 0 ;
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = 0x50 ;
p2pie [ p2pielen + + ] = 0x6F ;
p2pie [ p2pielen + + ] = 0x9A ;
2015-02-19 21:34:32 +00:00
p2pie [ p2pielen + + ] = 0x09 ; /* WFA P2P v1.0 */
/* Commented by Albert 20101011 */
/* According to the P2P Specification, the P2P Invitation request frame should contain 7 P2P attributes */
/* 1. Configuration Timeout */
/* 2. Invitation Flags */
/* 3. Operating Channel ( Only GO ) */
/* 4. P2P Group BSSID ( Should be included if I am the GO ) */
/* 5. Channel List */
/* 6. P2P Group ID */
/* 7. P2P Device Info */
/* Configuration Timeout */
/* Type: */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = P2P_ATTR_CONF_TIMEOUT ;
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( 0x0002 ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Value: */
p2pie [ p2pielen + + ] = 200 ; /* 2 seconds needed to be the P2P GO */
p2pie [ p2pielen + + ] = 200 ; /* 2 seconds needed to be the P2P Client */
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Invitation Flags */
/* Type: */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = P2P_ATTR_INVITATION_FLAGS ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( 0x0001 ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Value: */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = P2P_INVITATION_FLAGS_PERSISTENT ;
2013-05-08 21:45:39 +00:00
2013-05-19 04:28:07 +00:00
2015-02-19 21:34:32 +00:00
/* Operating Channel */
/* Type: */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = P2P_ATTR_OPERATING_CH ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( 0x0005 ) ;
2014-12-11 21:15:04 +00:00
p2pielen + = 2 ;
2013-05-19 04:28:07 +00:00
2015-02-19 21:34:32 +00:00
/* Value: */
/* Country String */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = ' X ' ;
p2pie [ p2pielen + + ] = ' X ' ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* The third byte should be set to 0x04. */
/* Described in the "Operating Channel Attribute" section. */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = 0x04 ;
2015-02-19 21:34:32 +00:00
/* Operating Class */
2014-12-11 21:15:04 +00:00
if ( pwdinfo - > invitereq_info . operating_ch < = 14 )
p2pie [ p2pielen + + ] = 0x51 ;
else if ( ( pwdinfo - > invitereq_info . operating_ch > = 36 ) & & ( pwdinfo - > invitereq_info . operating_ch < = 48 ) )
p2pie [ p2pielen + + ] = 0x73 ;
else
p2pie [ p2pielen + + ] = 0x7c ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* Channel Number */
p2pie [ p2pielen + + ] = pwdinfo - > invitereq_info . operating_ch ; /* operating channel number */
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
if ( _rtw_memcmp ( myid ( & padapter - > eeprompriv ) , pwdinfo - > invitereq_info . go_bssid , ETH_ALEN ) )
{
2015-02-19 21:34:32 +00:00
/* P2P Group BSSID */
/* Type: */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = P2P_ATTR_GROUP_BSSID ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( ETH_ALEN ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Value: */
/* P2P Device Address for GO */
2015-02-19 20:50:04 +00:00
memcpy ( p2pie + p2pielen , pwdinfo - > invitereq_info . go_bssid , ETH_ALEN ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = ETH_ALEN ;
}
2015-02-19 21:34:32 +00:00
/* Channel List */
/* Type: */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = P2P_ATTR_CH_LIST ;
2013-05-08 21:45:39 +00:00
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* Length: */
/* Country String(3) */
/* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
/* + number of channels in all classes */
2013-05-08 21:45:39 +00:00
len_channellist_attr = 3
+ ( 1 + 1 ) * ( u16 ) pmlmeext - > channel_list . reg_classes
2014-12-11 21:15:04 +00:00
+ get_reg_classes_full_count ( pmlmeext - > channel_list ) ;
2013-05-08 21:45:39 +00:00
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( len_channellist_attr ) ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Value: */
/* Country String */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = ' X ' ;
p2pie [ p2pielen + + ] = ' X ' ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* The third byte should be set to 0x04. */
/* Described in the "Operating Channel Attribute" section. */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = 0x04 ;
2015-02-19 21:34:32 +00:00
/* Channel Entry List */
2014-12-11 21:15:04 +00:00
{
int i , j ;
for ( j = 0 ; j < pmlmeext - > channel_list . reg_classes ; j + + ) {
2015-02-19 21:34:32 +00:00
/* Operating Class */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = pmlmeext - > channel_list . reg_class [ j ] . reg_class ;
2013-05-19 04:28:07 +00:00
2015-02-19 21:34:32 +00:00
/* Number of Channels */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = pmlmeext - > channel_list . reg_class [ j ] . channels ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Channel List */
2014-12-11 21:15:04 +00:00
for ( i = 0 ; i < pmlmeext - > channel_list . reg_class [ j ] . channels ; i + + ) {
p2pie [ p2pielen + + ] = pmlmeext - > channel_list . reg_class [ j ] . channel [ i ] ;
}
}
}
2015-02-19 21:34:32 +00:00
/* P2P Group ID */
/* Type: */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = P2P_ATTR_GROUP_ID ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( 6 + pwdinfo - > invitereq_info . ssidlen ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Value: */
/* P2P Device Address for GO */
2015-02-19 20:50:04 +00:00
memcpy ( p2pie + p2pielen , pwdinfo - > invitereq_info . go_bssid , ETH_ALEN ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = ETH_ALEN ;
2015-02-19 21:34:32 +00:00
/* SSID */
2015-02-19 20:50:04 +00:00
memcpy ( p2pie + p2pielen , pwdinfo - > invitereq_info . go_ssid , pwdinfo - > invitereq_info . ssidlen ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = pwdinfo - > invitereq_info . ssidlen ;
2014-12-19 06:59:46 +00:00
2013-05-19 04:28:07 +00:00
2015-02-19 21:34:32 +00:00
/* Device Info */
/* Type: */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = P2P_ATTR_DEVICE_INFO ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Length: */
/* 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
/* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( 21 + pwdinfo - > device_name_len ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* Value: */
/* P2P Device Address */
2015-02-19 20:50:04 +00:00
memcpy ( p2pie + p2pielen , myid ( & padapter - > eeprompriv ) , ETH_ALEN ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = ETH_ALEN ;
2015-02-19 21:34:32 +00:00
/* Config Method */
/* This field should be big endian. Noted by P2P specification. */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( p2pie + p2pielen ) = cpu_to_be16 ( WPS_CONFIG_METHOD_DISPLAY ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Primary Device Type */
/* Category ID */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( p2pie + p2pielen ) = cpu_to_be16 ( WPS_PDT_CID_MULIT_MEDIA ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* OUI */
2014-12-19 04:28:04 +00:00
* ( __be32 * ) ( p2pie + p2pielen ) = cpu_to_be32 ( WPSOUI ) ;
2014-12-11 21:15:04 +00:00
p2pielen + = 4 ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Sub Category ID */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( p2pie + p2pielen ) = cpu_to_be16 ( WPS_PDT_SCID_MEDIA_SERVER ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Number of Secondary Device Types */
p2pie [ p2pielen + + ] = 0x00 ; /* No Secondary Device Type List */
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Device Name */
/* Type: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( p2pie + p2pielen ) = cpu_to_be16 ( WPS_ATTR_DEVICE_NAME ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( p2pie + p2pielen ) = cpu_to_be16 ( pwdinfo - > device_name_len ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Value: */
2015-02-19 20:50:04 +00:00
memcpy ( p2pie + p2pielen , pwdinfo - > device_name , pwdinfo - > device_name_len ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = pwdinfo - > device_name_len ;
2014-12-19 06:59:46 +00:00
pframe = rtw_set_ie ( pframe , _VENDOR_SPECIFIC_IE_ , p2pielen , ( unsigned char * ) p2pie , & pattrib - > pktlen ) ;
2013-05-19 04:28:07 +00:00
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_WFD
wfdielen = build_invitation_req_wfd_ie ( pwdinfo , pframe ) ;
pframe + = wfdielen ;
pattrib - > pktlen + = wfdielen ;
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_WFD */
2013-05-08 21:45:39 +00:00
pattrib - > last_txcmdsz = pattrib - > pktlen ;
dump_mgntframe ( padapter , pmgntframe ) ;
return ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-17 23:13:53 +00:00
void issue_p2p_invitation_response ( struct adapter * padapter , u8 * raddr , u8 dialogToken , u8 status_code )
2013-05-08 21:45:39 +00:00
{
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
unsigned char category = RTW_WLAN_CATEGORY_PUBLIC ;
2014-12-11 21:15:04 +00:00
u8 action = P2P_PUB_ACTION_ACTION ;
2014-12-19 04:28:04 +00:00
__be32 p2poui = cpu_to_be32 ( P2POUI ) ;
2014-12-11 21:15:04 +00:00
u8 oui_subtype = P2P_INVIT_RESP ;
u8 p2pie [ 255 ] = { 0x00 } ;
u8 p2pielen = 0 , i ;
u8 channel_cnt_24g = 0 , channel_cnt_5gl = 0 , channel_cnt_5gh = 0 ;
u16 len_channellist_attr = 0 ;
# ifdef CONFIG_WFD
u32 wfdielen = 0 ;
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_WFD */
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
struct xmit_frame * pmgntframe ;
struct pkt_attrib * pattrib ;
unsigned char * pframe ;
struct rtw_ieee80211_hdr * pwlanhdr ;
2014-12-19 04:28:04 +00:00
__le16 * fctrl ;
2013-05-08 21:45:39 +00:00
struct xmit_priv * pxmitpriv = & ( padapter - > xmitpriv ) ;
struct mlme_ext_priv * pmlmeext = & ( padapter - > mlmeextpriv ) ;
2014-12-11 21:15:04 +00:00
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
struct wifidirect_info * pwdinfo = & ( padapter - > wdinfo ) ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
if ( ( pmgntframe = alloc_mgtxmitframe ( pxmitpriv ) ) = = NULL )
{
2013-05-08 21:45:39 +00:00
return ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* update attribute */
2013-05-08 21:45:39 +00:00
pattrib = & pmgntframe - > attrib ;
update_mgntframe_attrib ( padapter , pattrib ) ;
2015-02-19 20:58:09 +00:00
memset ( pmgntframe - > buf_addr , 0 , WLANHDR_OFFSET + TXDESC_OFFSET ) ;
2013-05-08 21:45:39 +00:00
pframe = ( u8 * ) ( pmgntframe - > buf_addr ) + TXDESC_OFFSET ;
pwlanhdr = ( struct rtw_ieee80211_hdr * ) pframe ;
fctrl = & ( pwlanhdr - > frame_ctl ) ;
* ( fctrl ) = 0 ;
2015-02-19 20:50:04 +00:00
memcpy ( pwlanhdr - > addr1 , raddr , ETH_ALEN ) ;
memcpy ( pwlanhdr - > addr2 , myid ( & ( padapter - > eeprompriv ) ) , ETH_ALEN ) ;
memcpy ( pwlanhdr - > addr3 , raddr , ETH_ALEN ) ;
2013-05-08 21:45:39 +00:00
SetSeqNum ( pwlanhdr , pmlmeext - > mgnt_seq ) ;
pmlmeext - > mgnt_seq + + ;
SetFrameSubType ( pframe , WIFI_ACTION ) ;
pframe + = sizeof ( struct rtw_ieee80211_hdr_3addr ) ;
pattrib - > pktlen = sizeof ( struct rtw_ieee80211_hdr_3addr ) ;
pframe = rtw_set_fixed_ie ( pframe , 1 , & ( category ) , & ( pattrib - > pktlen ) ) ;
pframe = rtw_set_fixed_ie ( pframe , 1 , & ( action ) , & ( pattrib - > pktlen ) ) ;
2014-12-11 21:15:04 +00:00
pframe = rtw_set_fixed_ie ( pframe , 4 , ( unsigned char * ) & ( p2poui ) , & ( pattrib - > pktlen ) ) ;
2014-12-19 06:59:46 +00:00
pframe = rtw_set_fixed_ie ( pframe , 1 , & ( oui_subtype ) , & ( pattrib - > pktlen ) ) ;
2013-05-08 21:45:39 +00:00
pframe = rtw_set_fixed_ie ( pframe , 1 , & ( dialogToken ) , & ( pattrib - > pktlen ) ) ;
2015-02-19 21:34:32 +00:00
/* P2P IE Section. */
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* P2P OUI */
2013-05-08 21:45:39 +00:00
p2pielen = 0 ;
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = 0x50 ;
p2pie [ p2pielen + + ] = 0x6F ;
p2pie [ p2pielen + + ] = 0x9A ;
2015-02-19 21:34:32 +00:00
p2pie [ p2pielen + + ] = 0x09 ; /* WFA P2P v1.0 */
/* Commented by Albert 20101005 */
/* According to the P2P Specification, the P2P Invitation response frame should contain 5 P2P attributes */
/* 1. Status */
/* 2. Configuration Timeout */
/* 3. Operating Channel ( Only GO ) */
/* 4. P2P Group BSSID ( Only GO ) */
/* 5. Channel List */
/* P2P Status */
/* Type: */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = P2P_ATTR_STATUS ;
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( 0x0001 ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Value: */
/* When status code is P2P_STATUS_FAIL_INFO_UNAVAILABLE. */
/* Sent the event receiving the P2P Invitation Req frame to DMP UI. */
/* DMP had to compare the MAC address to find out the profile. */
/* So, the WiFi driver will send the P2P_STATUS_FAIL_INFO_UNAVAILABLE to NB. */
/* If the UI found the corresponding profile, the WiFi driver sends the P2P Invitation Req */
/* to NB to rebuild the persistent group. */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = status_code ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* Configuration Timeout */
/* Type: */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = P2P_ATTR_CONF_TIMEOUT ;
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( 0x0002 ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Value: */
p2pie [ p2pielen + + ] = 200 ; /* 2 seconds needed to be the P2P GO */
p2pie [ p2pielen + + ] = 200 ; /* 2 seconds needed to be the P2P Client */
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
if ( status_code = = P2P_STATUS_SUCCESS )
{
if ( rtw_p2p_chk_role ( pwdinfo , P2P_ROLE_GO ) )
{
2015-02-19 21:34:32 +00:00
/* The P2P Invitation request frame asks this Wi-Fi device to be the P2P GO */
/* In this case, the P2P Invitation response frame should carry the two more P2P attributes. */
/* First one is operating channel attribute. */
/* Second one is P2P Group BSSID attribute. */
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Operating Channel */
/* Type: */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = P2P_ATTR_OPERATING_CH ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( 0x0005 ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Value: */
/* Country String */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = ' X ' ;
p2pie [ p2pielen + + ] = ' X ' ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* The third byte should be set to 0x04. */
/* Described in the "Operating Channel Attribute" section. */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = 0x04 ;
2015-02-19 21:34:32 +00:00
/* Operating Class */
p2pie [ p2pielen + + ] = 0x51 ; /* Copy from SD7 */
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* Channel Number */
p2pie [ p2pielen + + ] = pwdinfo - > operating_channel ; /* operating channel number */
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
2015-02-19 21:34:32 +00:00
/* P2P Group BSSID */
/* Type: */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = P2P_ATTR_GROUP_BSSID ;
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( ETH_ALEN ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Value: */
/* P2P Device Address for GO */
2015-02-19 20:50:04 +00:00
memcpy ( p2pie + p2pielen , myid ( & padapter - > eeprompriv ) , ETH_ALEN ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = ETH_ALEN ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
}
2015-02-19 21:34:32 +00:00
/* Channel List */
/* Type: */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = P2P_ATTR_CH_LIST ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Length: */
/* Country String(3) */
/* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
/* + number of channels in all classes */
2013-05-08 21:45:39 +00:00
len_channellist_attr = 3
+ ( 1 + 1 ) * ( u16 ) pmlmeext - > channel_list . reg_classes
2014-12-11 21:15:04 +00:00
+ get_reg_classes_full_count ( pmlmeext - > channel_list ) ;
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( len_channellist_attr ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Value: */
/* Country String */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = ' X ' ;
p2pie [ p2pielen + + ] = ' X ' ;
2015-02-19 21:34:32 +00:00
/* The third byte should be set to 0x04. */
/* Described in the "Operating Channel Attribute" section. */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = 0x04 ;
2015-02-19 21:34:32 +00:00
/* Channel Entry List */
2013-05-08 21:45:39 +00:00
{
int i , j ;
for ( j = 0 ; j < pmlmeext - > channel_list . reg_classes ; j + + ) {
2015-02-19 21:34:32 +00:00
/* Operating Class */
2013-05-08 21:45:39 +00:00
p2pie [ p2pielen + + ] = pmlmeext - > channel_list . reg_class [ j ] . reg_class ;
2015-02-19 21:34:32 +00:00
/* Number of Channels */
2013-05-08 21:45:39 +00:00
p2pie [ p2pielen + + ] = pmlmeext - > channel_list . reg_class [ j ] . channels ;
2015-02-19 21:34:32 +00:00
/* Channel List */
2013-05-08 21:45:39 +00:00
for ( i = 0 ; i < pmlmeext - > channel_list . reg_class [ j ] . channels ; i + + ) {
p2pie [ p2pielen + + ] = pmlmeext - > channel_list . reg_class [ j ] . channel [ i ] ;
}
}
}
}
2014-12-19 06:59:46 +00:00
pframe = rtw_set_ie ( pframe , _VENDOR_SPECIFIC_IE_ , p2pielen , ( unsigned char * ) p2pie , & pattrib - > pktlen ) ;
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_WFD
wfdielen = build_invitation_resp_wfd_ie ( pwdinfo , pframe ) ;
pframe + = wfdielen ;
pattrib - > pktlen + = wfdielen ;
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_WFD */
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
pattrib - > last_txcmdsz = pattrib - > pktlen ;
dump_mgntframe ( padapter , pmgntframe ) ;
return ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-17 23:13:53 +00:00
void issue_p2p_provision_request ( struct adapter * padapter , u8 * pssid , u8 ussidlen , u8 * pdev_raddr )
2013-05-08 21:45:39 +00:00
{
unsigned char category = RTW_WLAN_CATEGORY_PUBLIC ;
2014-12-11 21:15:04 +00:00
u8 action = P2P_PUB_ACTION_ACTION ;
u8 dialogToken = 1 ;
2014-12-19 04:28:04 +00:00
__be32 p2poui = cpu_to_be32 ( P2POUI ) ;
2014-12-11 21:15:04 +00:00
u8 oui_subtype = P2P_PROVISION_DISC_REQ ;
u8 wpsie [ 100 ] = { 0x00 } ;
u8 wpsielen = 0 ;
2013-05-08 21:45:39 +00:00
u32 p2pielen = 0 ;
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_WFD
u32 wfdielen = 0 ;
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_WFD */
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
struct xmit_frame * pmgntframe ;
struct pkt_attrib * pattrib ;
unsigned char * pframe ;
struct rtw_ieee80211_hdr * pwlanhdr ;
2014-12-19 04:28:04 +00:00
__le16 * fctrl ;
2013-05-08 21:45:39 +00:00
struct xmit_priv * pxmitpriv = & ( padapter - > xmitpriv ) ;
struct mlme_ext_priv * pmlmeext = & ( padapter - > mlmeextpriv ) ;
2014-12-11 21:15:04 +00:00
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
2013-05-08 21:45:39 +00:00
struct wifidirect_info * pwdinfo = & ( padapter - > wdinfo ) ;
2014-12-11 21:15:04 +00:00
if ( ( pmgntframe = alloc_mgtxmitframe ( pxmitpriv ) ) = = NULL )
{
2013-05-08 21:45:39 +00:00
return ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
DBG_871X ( " [%s] In \n " , __FUNCTION__ ) ;
2015-02-19 21:34:32 +00:00
/* update attribute */
2013-05-08 21:45:39 +00:00
pattrib = & pmgntframe - > attrib ;
update_mgntframe_attrib ( padapter , pattrib ) ;
2015-02-19 20:58:09 +00:00
memset ( pmgntframe - > buf_addr , 0 , WLANHDR_OFFSET + TXDESC_OFFSET ) ;
2013-05-08 21:45:39 +00:00
pframe = ( u8 * ) ( pmgntframe - > buf_addr ) + TXDESC_OFFSET ;
pwlanhdr = ( struct rtw_ieee80211_hdr * ) pframe ;
fctrl = & ( pwlanhdr - > frame_ctl ) ;
* ( fctrl ) = 0 ;
2015-02-19 20:50:04 +00:00
memcpy ( pwlanhdr - > addr1 , pdev_raddr , ETH_ALEN ) ;
memcpy ( pwlanhdr - > addr2 , myid ( & ( padapter - > eeprompriv ) ) , ETH_ALEN ) ;
memcpy ( pwlanhdr - > addr3 , pdev_raddr , ETH_ALEN ) ;
2013-05-08 21:45:39 +00:00
SetSeqNum ( pwlanhdr , pmlmeext - > mgnt_seq ) ;
pmlmeext - > mgnt_seq + + ;
SetFrameSubType ( pframe , WIFI_ACTION ) ;
pframe + = sizeof ( struct rtw_ieee80211_hdr_3addr ) ;
pattrib - > pktlen = sizeof ( struct rtw_ieee80211_hdr_3addr ) ;
pframe = rtw_set_fixed_ie ( pframe , 1 , & ( category ) , & ( pattrib - > pktlen ) ) ;
pframe = rtw_set_fixed_ie ( pframe , 1 , & ( action ) , & ( pattrib - > pktlen ) ) ;
2014-12-11 21:15:04 +00:00
pframe = rtw_set_fixed_ie ( pframe , 4 , ( unsigned char * ) & ( p2poui ) , & ( pattrib - > pktlen ) ) ;
2014-12-19 06:59:46 +00:00
pframe = rtw_set_fixed_ie ( pframe , 1 , & ( oui_subtype ) , & ( pattrib - > pktlen ) ) ;
pframe = rtw_set_fixed_ie ( pframe , 1 , & ( dialogToken ) , & ( pattrib - > pktlen ) ) ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
p2pielen = build_prov_disc_request_p2p_ie ( pwdinfo , pframe , pssid , ussidlen , pdev_raddr ) ;
2013-05-08 21:45:39 +00:00
pframe + = p2pielen ;
pattrib - > pktlen + = p2pielen ;
wpsielen = 0 ;
2015-02-19 21:34:32 +00:00
/* WPS OUI */
2014-12-19 04:28:04 +00:00
* ( __be32 * ) ( wpsie ) = cpu_to_be32 ( WPSOUI ) ;
2013-05-08 21:45:39 +00:00
wpsielen + = 4 ;
2015-02-19 21:34:32 +00:00
/* WPS version */
/* Type: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( WPS_ATTR_VER1 ) ;
2013-05-08 21:45:39 +00:00
wpsielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( 0x0001 ) ;
2013-05-08 21:45:39 +00:00
wpsielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Value: */
wpsie [ wpsielen + + ] = WPS_VERSION_1 ; /* Version 1.0 */
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Config Method */
/* Type: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( WPS_ATTR_CONF_METHOD ) ;
2013-05-08 21:45:39 +00:00
wpsielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( 0x0002 ) ;
2013-05-08 21:45:39 +00:00
wpsielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Value: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( pwdinfo - > tx_prov_disc_info . wps_config_method_request ) ;
2013-05-08 21:45:39 +00:00
wpsielen + = 2 ;
2014-12-11 21:15:04 +00:00
pframe = rtw_set_ie ( pframe , _VENDOR_SPECIFIC_IE_ , wpsielen , ( unsigned char * ) wpsie , & pattrib - > pktlen ) ;
# ifdef CONFIG_WFD
wfdielen = build_provdisc_req_wfd_ie ( pwdinfo , pframe ) ;
pframe + = wfdielen ;
pattrib - > pktlen + = wfdielen ;
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_WFD */
2013-05-08 21:45:39 +00:00
pattrib - > last_txcmdsz = pattrib - > pktlen ;
dump_mgntframe ( padapter , pmgntframe ) ;
return ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
2014-12-19 04:28:04 +00:00
static u8 is_matched_in_profilelist ( u8 * peermacaddr , struct profile_info * profileinfo )
2013-05-08 21:45:39 +00:00
{
u8 i , match_result = 0 ;
2014-12-11 21:15:04 +00:00
DBG_871X ( " [%s] peermac = %.2X %.2X %.2X %.2X %.2X %.2X \n " , __FUNCTION__ ,
2014-12-19 06:59:46 +00:00
peermacaddr [ 0 ] , peermacaddr [ 1 ] , peermacaddr [ 2 ] , peermacaddr [ 3 ] , peermacaddr [ 4 ] , peermacaddr [ 5 ] ) ;
2014-12-11 21:15:04 +00:00
for ( i = 0 ; i < P2P_MAX_PERSISTENT_GROUP_NUM ; i + + , profileinfo + + )
{
DBG_871X ( " [%s] profileinfo_mac = %.2X %.2X %.2X %.2X %.2X %.2X \n " , __FUNCTION__ ,
2014-12-19 06:59:46 +00:00
profileinfo - > peermac [ 0 ] , profileinfo - > peermac [ 1 ] , profileinfo - > peermac [ 2 ] , profileinfo - > peermac [ 3 ] , profileinfo - > peermac [ 4 ] , profileinfo - > peermac [ 5 ] ) ;
2014-12-11 21:15:04 +00:00
if ( _rtw_memcmp ( peermacaddr , profileinfo - > peermac , ETH_ALEN ) )
{
2013-05-08 21:45:39 +00:00
match_result = 1 ;
2014-12-11 21:15:04 +00:00
DBG_871X ( " [%s] Match! \n " , __FUNCTION__ ) ;
2013-05-08 21:45:39 +00:00
break ;
}
}
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
return ( match_result ) ;
2013-05-08 21:45:39 +00:00
}
2014-12-17 23:13:53 +00:00
void issue_probersp_p2p ( struct adapter * padapter , unsigned char * da )
2013-05-08 21:45:39 +00:00
{
struct xmit_frame * pmgntframe ;
struct pkt_attrib * pattrib ;
unsigned char * pframe ;
struct rtw_ieee80211_hdr * pwlanhdr ;
2014-12-19 06:59:46 +00:00
__le16 * fctrl ;
2013-05-08 21:45:39 +00:00
unsigned char * mac ;
2013-10-19 17:45:47 +00:00
struct xmit_priv * pxmitpriv = & ( padapter - > xmitpriv ) ;
2013-05-08 21:45:39 +00:00
struct mlme_ext_priv * pmlmeext = & ( padapter - > mlmeextpriv ) ;
2014-12-11 21:15:04 +00:00
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
struct mlme_priv * pmlmepriv = & ( padapter - > mlmepriv ) ;
2015-02-19 21:34:32 +00:00
/* WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); */
2014-12-11 21:15:04 +00:00
u16 beacon_interval = 100 ;
u16 capInfo = 0 ;
2013-05-08 21:45:39 +00:00
struct wifidirect_info * pwdinfo = & ( padapter - > wdinfo ) ;
2014-12-11 21:15:04 +00:00
u8 wpsie [ 255 ] = { 0x00 } ;
2013-05-08 21:45:39 +00:00
u32 wpsielen = 0 , p2pielen = 0 ;
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_WFD
u32 wfdielen = 0 ;
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_WFD */
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_INTEL_WIDI
u8 zero_array_check [ L2SDTA_SERVICE_VE_LEN ] = { 0x00 } ;
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_INTEL_WIDI */
2014-12-11 21:15:04 +00:00
2015-02-19 21:34:32 +00:00
/* DBG_871X("%s\n", __FUNCTION__); */
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
if ( ( pmgntframe = alloc_mgtxmitframe ( pxmitpriv ) ) = = NULL )
{
2013-05-08 21:45:39 +00:00
return ;
2014-12-11 21:15:04 +00:00
}
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* update attribute */
2013-05-08 21:45:39 +00:00
pattrib = & pmgntframe - > attrib ;
2014-12-19 06:59:46 +00:00
update_mgntframe_attrib ( padapter , pattrib ) ;
2015-02-19 20:58:09 +00:00
memset ( pmgntframe - > buf_addr , 0 , WLANHDR_OFFSET + TXDESC_OFFSET ) ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
pframe = ( u8 * ) ( pmgntframe - > buf_addr ) + TXDESC_OFFSET ;
2014-12-19 06:59:46 +00:00
pwlanhdr = ( struct rtw_ieee80211_hdr * ) pframe ;
2013-05-08 21:45:39 +00:00
mac = myid ( & ( padapter - > eeprompriv ) ) ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
fctrl = & ( pwlanhdr - > frame_ctl ) ;
* ( fctrl ) = 0 ;
2015-02-19 20:50:04 +00:00
memcpy ( pwlanhdr - > addr1 , da , ETH_ALEN ) ;
memcpy ( pwlanhdr - > addr2 , mac , ETH_ALEN ) ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* Use the device address for BSSID field. */
2015-02-19 20:50:04 +00:00
memcpy ( pwlanhdr - > addr3 , mac , ETH_ALEN ) ;
2013-05-08 21:45:39 +00:00
SetSeqNum ( pwlanhdr , pmlmeext - > mgnt_seq ) ;
pmlmeext - > mgnt_seq + + ;
SetFrameSubType ( fctrl , WIFI_PROBERSP ) ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
pattrib - > hdrlen = sizeof ( struct rtw_ieee80211_hdr_3addr ) ;
pattrib - > pktlen = pattrib - > hdrlen ;
pframe + = pattrib - > hdrlen ;
2015-02-19 21:34:32 +00:00
/* timestamp will be inserted by hardware */
2013-05-08 21:45:39 +00:00
pframe + = 8 ;
pattrib - > pktlen + = 8 ;
2015-02-19 21:34:32 +00:00
/* beacon interval: 2 bytes */
2015-02-19 20:50:04 +00:00
memcpy ( pframe , ( unsigned char * ) & beacon_interval , 2 ) ;
2013-05-08 21:45:39 +00:00
pframe + = 2 ;
pattrib - > pktlen + = 2 ;
2015-02-19 21:34:32 +00:00
/* capability info: 2 bytes */
/* ESS and IBSS bits must be 0 (defined in the 3.1.2.1.1 of WiFi Direct Spec) */
2013-05-08 21:45:39 +00:00
capInfo | = cap_ShortPremble ;
capInfo | = cap_ShortSlot ;
2014-12-19 06:59:46 +00:00
2015-02-19 20:50:04 +00:00
memcpy ( pframe , ( unsigned char * ) & capInfo , 2 ) ;
2013-05-08 21:45:39 +00:00
pframe + = 2 ;
pattrib - > pktlen + = 2 ;
2014-12-11 21:15:04 +00:00
2015-02-19 21:34:32 +00:00
/* SSID */
2013-05-08 21:45:39 +00:00
pframe = rtw_set_ie ( pframe , _SSID_IE_ , 7 , pwdinfo - > p2p_wildcard_ssid , & pattrib - > pktlen ) ;
2015-02-19 21:34:32 +00:00
/* supported rates... */
/* Use the OFDM rate in the P2P probe response frame. ( 6(B), 9(B), 12, 18, 24, 36, 48, 54 ) */
2013-05-08 21:45:39 +00:00
pframe = rtw_set_ie ( pframe , _SUPPORTEDRATES_IE_ , 8 , pwdinfo - > support_rate , & pattrib - > pktlen ) ;
2015-02-19 21:34:32 +00:00
/* DS parameter set */
2013-08-01 02:12:42 +00:00
pframe = rtw_set_ie ( pframe , _DSSET_IE_ , 1 , ( unsigned char * ) & pwdinfo - > listen_channel , & pattrib - > pktlen ) ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
if ( wdev_to_priv ( padapter - > rtw_wdev ) - > p2p_enabled & & pwdinfo - > driver_interface = = DRIVER_CFG80211 )
{
if ( pmlmepriv - > wps_probe_resp_ie ! = NULL & & pmlmepriv - > p2p_probe_resp_ie ! = NULL )
{
2015-02-19 21:34:32 +00:00
/* WPS IE */
2015-02-19 20:50:04 +00:00
memcpy ( pframe , pmlmepriv - > wps_probe_resp_ie , pmlmepriv - > wps_probe_resp_ie_len ) ;
2014-12-11 21:15:04 +00:00
pattrib - > pktlen + = pmlmepriv - > wps_probe_resp_ie_len ;
pframe + = pmlmepriv - > wps_probe_resp_ie_len ;
2015-02-19 21:34:32 +00:00
/* P2P IE */
2015-02-19 20:50:04 +00:00
memcpy ( pframe , pmlmepriv - > p2p_probe_resp_ie , pmlmepriv - > p2p_probe_resp_ie_len ) ;
2014-12-11 21:15:04 +00:00
pattrib - > pktlen + = pmlmepriv - > p2p_probe_resp_ie_len ;
pframe + = pmlmepriv - > p2p_probe_resp_ie_len ;
}
2015-02-20 04:52:01 +00:00
} else {
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Todo: WPS IE */
/* Noted by Albert 20100907 */
/* According to the WPS specification, all the WPS attribute is presented by Big Endian. */
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
wpsielen = 0 ;
2015-02-19 21:34:32 +00:00
/* WPS OUI */
2014-12-19 04:28:04 +00:00
* ( __be32 * ) ( wpsie ) = cpu_to_be32 ( WPSOUI ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 4 ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* WPS version */
/* Type: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( WPS_ATTR_VER1 ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 2 ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( 0x0001 ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 2 ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Value: */
wpsie [ wpsielen + + ] = WPS_VERSION_1 ; /* Version 1.0 */
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_INTEL_WIDI
2015-02-19 21:34:32 +00:00
/* Commented by Kurt */
/* Appended WiDi info. only if we did issued_probereq_widi(), and then we saved ven. ext. in pmlmepriv->sa_ext. */
2014-12-29 02:13:24 +00:00
if ( _rtw_memcmp ( pmlmepriv - > sa_ext , zero_array_check , L2SDTA_SERVICE_VE_LEN ) = = false
2014-12-11 21:15:04 +00:00
| | pmlmepriv - > num_p2p_sdt ! = 0 )
{
2015-02-19 21:34:32 +00:00
/* Sec dev type */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( WPS_ATTR_SEC_DEV_TYPE_LIST ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 2 ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( 0x0008 ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 2 ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Value: */
/* Category ID */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( WPS_PDT_CID_DISPLAYS ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 2 ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* OUI */
2014-12-19 04:28:04 +00:00
* ( __be32 * ) ( wpsie + wpsielen ) = cpu_to_be32 ( INTEL_DEV_TYPE_OUI ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 4 ;
2013-05-08 21:45:39 +00:00
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( WPS_PDT_SCID_WIDI_CONSUMER_SINK ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 2 ;
2013-05-08 21:45:39 +00:00
2014-12-29 02:13:24 +00:00
if ( _rtw_memcmp ( pmlmepriv - > sa_ext , zero_array_check , L2SDTA_SERVICE_VE_LEN ) = = false )
2014-12-11 21:15:04 +00:00
{
2015-02-19 21:34:32 +00:00
/* Vendor Extension */
2015-02-19 20:50:04 +00:00
memcpy ( wpsie + wpsielen , pmlmepriv - > sa_ext , L2SDTA_SERVICE_VE_LEN ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = L2SDTA_SERVICE_VE_LEN ;
}
}
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_INTEL_WIDI */
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* WiFi Simple Config State */
/* Type: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( WPS_ATTR_SIMPLE_CONF_STATE ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 2 ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( 0x0001 ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 2 ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Value: */
wpsie [ wpsielen + + ] = WPS_WSC_STATE_NOT_CONFIG ; /* Not Configured. */
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Response Type */
/* Type: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( WPS_ATTR_RESP_TYPE ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 2 ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( 0x0001 ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 2 ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Value: */
2014-12-11 21:15:04 +00:00
wpsie [ wpsielen + + ] = WPS_RESPONSE_TYPE_8021X ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* UUID-E */
/* Type: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( WPS_ATTR_UUID_E ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 2 ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( 0x0010 ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 2 ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Value: */
2014-12-11 21:15:04 +00:00
if ( pwdinfo - > external_uuid = = 0 ) {
2015-02-19 20:58:09 +00:00
memset ( wpsie + wpsielen , 0x0 , 16 ) ;
2015-02-19 20:50:04 +00:00
memcpy ( wpsie + wpsielen , myid ( & padapter - > eeprompriv ) , ETH_ALEN ) ;
2014-12-11 21:15:04 +00:00
} else {
2015-02-19 20:50:04 +00:00
memcpy ( wpsie + wpsielen , pwdinfo - > uuid , 0x10 ) ;
2014-12-11 21:15:04 +00:00
}
wpsielen + = 0x10 ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Manufacturer */
/* Type: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( WPS_ATTR_MANUFACTURER ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 2 ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( 0x0007 ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 2 ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Value: */
2015-02-19 20:50:04 +00:00
memcpy ( wpsie + wpsielen , " Realtek " , 7 ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 7 ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Model Name */
/* Type: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( WPS_ATTR_MODEL_NAME ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 2 ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( 0x0006 ) ;
2014-12-19 06:59:46 +00:00
wpsielen + = 2 ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Value: */
2015-02-19 20:50:04 +00:00
memcpy ( wpsie + wpsielen , " 8192CU " , 6 ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 6 ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Model Number */
/* Type: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( WPS_ATTR_MODEL_NUMBER ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 2 ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( 0x0001 ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 2 ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Value: */
wpsie [ wpsielen + + ] = 0x31 ; /* character 1 */
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Serial Number */
/* Type: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( WPS_ATTR_SERIAL_NUMBER ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 2 ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( ETH_ALEN ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 2 ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Value: */
2015-02-19 20:50:04 +00:00
memcpy ( wpsie + wpsielen , " 123456 " , ETH_ALEN ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = ETH_ALEN ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Primary Device Type */
/* Type: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( WPS_ATTR_PRIMARY_DEV_TYPE ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 2 ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( 0x0008 ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 2 ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Value: */
/* Category ID */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( WPS_PDT_CID_MULIT_MEDIA ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 2 ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* OUI */
2014-12-19 04:28:04 +00:00
* ( __be32 * ) ( wpsie + wpsielen ) = cpu_to_be32 ( WPSOUI ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 4 ;
2013-05-19 04:28:07 +00:00
2015-02-19 21:34:32 +00:00
/* Sub Category ID */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( WPS_PDT_SCID_MEDIA_SERVER ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 2 ;
2013-05-19 04:28:07 +00:00
2015-02-19 21:34:32 +00:00
/* Device Name */
/* Type: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( WPS_ATTR_DEVICE_NAME ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( pwdinfo - > device_name_len ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Value: */
2014-12-11 21:15:04 +00:00
if ( pwdinfo - > device_name_len )
{
2015-02-19 20:50:04 +00:00
memcpy ( wpsie + wpsielen , pwdinfo - > device_name , pwdinfo - > device_name_len ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = pwdinfo - > device_name_len ;
}
2015-02-19 21:34:32 +00:00
/* Config Method */
/* Type: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( WPS_ATTR_CONF_METHOD ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( 0x0002 ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Value: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( pwdinfo - > supported_wps_cm ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 2 ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
pframe = rtw_set_ie ( pframe , _VENDOR_SPECIFIC_IE_ , wpsielen , ( unsigned char * ) wpsie , & pattrib - > pktlen ) ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
p2pielen = build_probe_resp_p2p_ie ( pwdinfo , pframe ) ;
pframe + = p2pielen ;
pattrib - > pktlen + = p2pielen ;
}
# ifdef CONFIG_WFD
2015-02-20 04:52:01 +00:00
if ( true = = pwdinfo - > wfd_info - > wfd_enable ) {
2014-12-11 21:15:04 +00:00
wfdielen = build_probe_resp_wfd_ie ( pwdinfo , pframe , 0 ) ;
pframe + = wfdielen ;
pattrib - > pktlen + = wfdielen ;
}
else if ( pmlmepriv - > wfd_probe_resp_ie ! = NULL & & pmlmepriv - > wfd_probe_resp_ie_len > 0 )
{
2015-02-19 21:34:32 +00:00
/* WFD IE */
2015-02-19 20:50:04 +00:00
memcpy ( pframe , pmlmepriv - > wfd_probe_resp_ie , pmlmepriv - > wfd_probe_resp_ie_len ) ;
2014-12-11 21:15:04 +00:00
pattrib - > pktlen + = pmlmepriv - > wfd_probe_resp_ie_len ;
2014-12-19 06:59:46 +00:00
pframe + = pmlmepriv - > wfd_probe_resp_ie_len ;
2014-12-11 21:15:04 +00:00
}
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_WFD */
2013-05-08 21:45:39 +00:00
pattrib - > last_txcmdsz = pattrib - > pktlen ;
2014-12-19 06:59:46 +00:00
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
dump_mgntframe ( padapter , pmgntframe ) ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
return ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-19 04:28:04 +00:00
static int _issue_probereq_p2p ( struct adapter * padapter , u8 * da , int wait_ack )
2013-05-08 21:45:39 +00:00
{
int ret = _FAIL ;
struct xmit_frame * pmgntframe ;
struct pkt_attrib * pattrib ;
unsigned char * pframe ;
struct rtw_ieee80211_hdr * pwlanhdr ;
2014-12-19 04:28:04 +00:00
__le16 * fctrl ;
2013-05-08 21:45:39 +00:00
unsigned char * mac ;
2014-12-11 21:15:04 +00:00
unsigned char bssrate [ NumRates ] ;
2013-05-08 21:45:39 +00:00
struct xmit_priv * pxmitpriv = & ( padapter - > xmitpriv ) ;
struct mlme_ext_priv * pmlmeext = & ( padapter - > mlmeextpriv ) ;
2014-12-11 21:15:04 +00:00
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
int bssrate_len = 0 ;
u8 bc_addr [ ] = { 0xff , 0xff , 0xff , 0xff , 0xff , 0xff } ;
2014-12-19 06:59:46 +00:00
struct wifidirect_info * pwdinfo = & ( padapter - > wdinfo ) ;
2014-12-11 21:15:04 +00:00
u8 wpsie [ 255 ] = { 0x00 } , p2pie [ 255 ] = { 0x00 } ;
u16 wpsielen = 0 , p2pielen = 0 ;
# ifdef CONFIG_WFD
u32 wfdielen = 0 ;
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_WFD */
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
struct mlme_priv * pmlmepriv = & ( padapter - > mlmepriv ) ;
2014-12-19 06:59:46 +00:00
2013-05-19 04:28:07 +00:00
2014-12-11 21:15:04 +00:00
if ( ( pmgntframe = alloc_mgtxmitframe ( pxmitpriv ) ) = = NULL )
{
2013-05-08 21:45:39 +00:00
goto exit ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* update attribute */
2013-05-08 21:45:39 +00:00
pattrib = & pmgntframe - > attrib ;
update_mgntframe_attrib ( padapter , pattrib ) ;
2014-12-11 21:15:04 +00:00
2015-02-19 20:58:09 +00:00
memset ( pmgntframe - > buf_addr , 0 , WLANHDR_OFFSET + TXDESC_OFFSET ) ;
2013-05-08 21:45:39 +00:00
pframe = ( u8 * ) ( pmgntframe - > buf_addr ) + TXDESC_OFFSET ;
pwlanhdr = ( struct rtw_ieee80211_hdr * ) pframe ;
mac = myid ( & ( padapter - > eeprompriv ) ) ;
fctrl = & ( pwlanhdr - > frame_ctl ) ;
* ( fctrl ) = 0 ;
if ( da ) {
2015-02-19 20:50:04 +00:00
memcpy ( pwlanhdr - > addr1 , da , ETH_ALEN ) ;
memcpy ( pwlanhdr - > addr3 , da , ETH_ALEN ) ;
2013-05-08 21:45:39 +00:00
} else {
2014-12-11 21:15:04 +00:00
if ( ( pwdinfo - > p2p_info . scan_op_ch_only ) | | ( pwdinfo - > rx_invitereq_info . scan_op_ch_only ) )
{
2015-02-19 21:34:32 +00:00
/* This two flags will be set when this is only the P2P client mode. */
2015-02-19 20:50:04 +00:00
memcpy ( pwlanhdr - > addr1 , pwdinfo - > p2p_peer_interface_addr , ETH_ALEN ) ;
memcpy ( pwlanhdr - > addr3 , pwdinfo - > p2p_peer_interface_addr , ETH_ALEN ) ;
2014-12-11 21:15:04 +00:00
}
else
{
2015-02-19 21:34:32 +00:00
/* broadcast probe request frame */
2015-02-19 20:50:04 +00:00
memcpy ( pwlanhdr - > addr1 , bc_addr , ETH_ALEN ) ;
memcpy ( pwlanhdr - > addr3 , bc_addr , ETH_ALEN ) ;
2013-05-08 21:45:39 +00:00
}
}
2015-02-19 20:50:04 +00:00
memcpy ( pwlanhdr - > addr2 , mac , ETH_ALEN ) ;
2013-05-08 21:45:39 +00:00
SetSeqNum ( pwlanhdr , pmlmeext - > mgnt_seq ) ;
pmlmeext - > mgnt_seq + + ;
SetFrameSubType ( pframe , WIFI_PROBEREQ ) ;
pframe + = sizeof ( struct rtw_ieee80211_hdr_3addr ) ;
pattrib - > pktlen = sizeof ( struct rtw_ieee80211_hdr_3addr ) ;
2014-12-11 21:15:04 +00:00
if ( rtw_p2p_chk_state ( pwdinfo , P2P_STATE_TX_PROVISION_DIS_REQ ) )
{
2013-05-08 21:45:39 +00:00
pframe = rtw_set_ie ( pframe , _SSID_IE_ , pwdinfo - > tx_prov_disc_info . ssid . SsidLength , pwdinfo - > tx_prov_disc_info . ssid . Ssid , & ( pattrib - > pktlen ) ) ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
else
2014-12-11 21:15:04 +00:00
{
2013-05-08 21:45:39 +00:00
pframe = rtw_set_ie ( pframe , _SSID_IE_ , P2P_WILDCARD_SSID_LEN , pwdinfo - > p2p_wildcard_ssid , & ( pattrib - > pktlen ) ) ;
2014-12-11 21:15:04 +00:00
}
2015-02-19 21:34:32 +00:00
/* Use the OFDM rate in the P2P probe request frame. ( 6(B), 9(B), 12(B), 24(B), 36, 48, 54 ) */
2013-05-08 21:45:39 +00:00
pframe = rtw_set_ie ( pframe , _SUPPORTEDRATES_IE_ , 8 , pwdinfo - > support_rate , & pattrib - > pktlen ) ;
2014-12-11 21:15:04 +00:00
if ( wdev_to_priv ( padapter - > rtw_wdev ) - > p2p_enabled & & pwdinfo - > driver_interface = = DRIVER_CFG80211 )
{
if ( pmlmepriv - > wps_probe_req_ie ! = NULL & & pmlmepriv - > p2p_probe_req_ie ! = NULL )
{
2015-02-19 21:34:32 +00:00
/* WPS IE */
2015-02-19 20:50:04 +00:00
memcpy ( pframe , pmlmepriv - > wps_probe_req_ie , pmlmepriv - > wps_probe_req_ie_len ) ;
2014-12-11 21:15:04 +00:00
pattrib - > pktlen + = pmlmepriv - > wps_probe_req_ie_len ;
pframe + = pmlmepriv - > wps_probe_req_ie_len ;
2015-02-19 21:34:32 +00:00
/* P2P IE */
2015-02-19 20:50:04 +00:00
memcpy ( pframe , pmlmepriv - > p2p_probe_req_ie , pmlmepriv - > p2p_probe_req_ie_len ) ;
2014-12-11 21:15:04 +00:00
pattrib - > pktlen + = pmlmepriv - > p2p_probe_req_ie_len ;
pframe + = pmlmepriv - > p2p_probe_req_ie_len ;
}
2015-02-20 04:52:01 +00:00
} else {
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* WPS IE */
/* Noted by Albert 20110221 */
/* According to the WPS specification, all the WPS attribute is presented by Big Endian. */
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
wpsielen = 0 ;
2015-02-19 21:34:32 +00:00
/* WPS OUI */
2014-12-19 04:28:04 +00:00
* ( __be32 * ) ( wpsie ) = cpu_to_be32 ( WPSOUI ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 4 ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* WPS version */
/* Type: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( WPS_ATTR_VER1 ) ;
2013-05-08 21:45:39 +00:00
wpsielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( 0x0001 ) ;
2013-05-08 21:45:39 +00:00
wpsielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Value: */
wpsie [ wpsielen + + ] = WPS_VERSION_1 ; /* Version 1.0 */
2013-07-09 22:38:46 +00:00
2014-12-11 21:15:04 +00:00
if ( pmlmepriv - > wps_probe_req_ie = = NULL )
{
2015-02-19 21:34:32 +00:00
/* UUID-E */
/* Type: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( WPS_ATTR_UUID_E ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( 0x0010 ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Value: */
2014-12-11 21:15:04 +00:00
if ( pwdinfo - > external_uuid = = 0 ) {
2015-02-19 20:58:09 +00:00
memset ( wpsie + wpsielen , 0x0 , 16 ) ;
2015-02-19 20:50:04 +00:00
memcpy ( wpsie + wpsielen , myid ( & padapter - > eeprompriv ) , ETH_ALEN ) ;
2014-12-11 21:15:04 +00:00
} else {
2015-02-19 20:50:04 +00:00
memcpy ( wpsie + wpsielen , pwdinfo - > uuid , 0x10 ) ;
2014-12-11 21:15:04 +00:00
}
wpsielen + = 0x10 ;
2013-07-09 22:38:46 +00:00
2015-02-19 21:34:32 +00:00
/* Config Method */
/* Type: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( WPS_ATTR_CONF_METHOD ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 2 ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( 0x0002 ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 2 ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Value: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( pwdinfo - > supported_wps_cm ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 2 ;
}
2013-05-19 04:28:07 +00:00
2015-02-19 21:34:32 +00:00
/* Device Name */
/* Type: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( WPS_ATTR_DEVICE_NAME ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 2 ;
2013-07-20 18:18:13 +00:00
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( pwdinfo - > device_name_len ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 2 ;
2013-07-20 18:18:13 +00:00
2015-02-19 21:34:32 +00:00
/* Value: */
2015-02-19 20:50:04 +00:00
memcpy ( wpsie + wpsielen , pwdinfo - > device_name , pwdinfo - > device_name_len ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = pwdinfo - > device_name_len ;
2013-07-20 18:18:13 +00:00
2015-02-19 21:34:32 +00:00
/* Primary Device Type */
/* Type: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( WPS_ATTR_PRIMARY_DEV_TYPE ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 2 ;
2013-07-20 18:18:13 +00:00
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( 0x0008 ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 2 ;
2013-07-20 18:18:13 +00:00
2015-02-19 21:34:32 +00:00
/* Value: */
/* Category ID */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( WPS_PDT_CID_RTK_WIDI ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 2 ;
2013-07-20 18:18:13 +00:00
2015-02-19 21:34:32 +00:00
/* OUI */
2014-12-19 04:28:04 +00:00
* ( __be32 * ) ( wpsie + wpsielen ) = cpu_to_be32 ( WPSOUI ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 4 ;
2013-07-20 18:18:13 +00:00
2015-02-19 21:34:32 +00:00
/* Sub Category ID */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( WPS_PDT_SCID_RTK_DMP ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 2 ;
2013-07-20 18:18:13 +00:00
2015-02-19 21:34:32 +00:00
/* Device Password ID */
/* Type: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( WPS_ATTR_DEVICE_PWID ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 2 ;
2013-07-20 18:18:13 +00:00
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( 0x0002 ) ;
2014-12-11 21:15:04 +00:00
wpsielen + = 2 ;
2013-07-20 18:18:13 +00:00
2015-02-19 21:34:32 +00:00
/* Value: */
* ( __be16 * ) ( wpsie + wpsielen ) = cpu_to_be16 ( WPS_DPID_REGISTRAR_SPEC ) ; /* Registrar-specified */
2014-12-19 06:59:46 +00:00
wpsielen + = 2 ;
2013-07-20 18:18:13 +00:00
2014-12-11 21:15:04 +00:00
pframe = rtw_set_ie ( pframe , _VENDOR_SPECIFIC_IE_ , wpsielen , ( unsigned char * ) wpsie , & pattrib - > pktlen ) ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* P2P OUI */
2014-12-11 21:15:04 +00:00
p2pielen = 0 ;
p2pie [ p2pielen + + ] = 0x50 ;
p2pie [ p2pielen + + ] = 0x6F ;
p2pie [ p2pielen + + ] = 0x9A ;
2015-02-19 21:34:32 +00:00
p2pie [ p2pielen + + ] = 0x09 ; /* WFA P2P v1.0 */
/* Commented by Albert 20110221 */
/* According to the P2P Specification, the probe request frame should contain 5 P2P attributes */
/* 1. P2P Capability */
/* 2. P2P Device ID if this probe request wants to find the specific P2P device */
/* 3. Listen Channel */
/* 4. Extended Listen Timing */
/* 5. Operating Channel if this WiFi is working as the group owner now */
/* P2P Capability */
/* Type: */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = P2P_ATTR_CAPABILITY ;
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( 0x0002 ) ;
2014-12-11 21:15:04 +00:00
p2pielen + = 2 ;
2013-07-20 18:18:13 +00:00
2015-02-19 21:34:32 +00:00
/* Value: */
/* Device Capability Bitmap, 1 byte */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = DMP_P2P_DEVCAP_SUPPORT ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* Group Capability Bitmap, 1 byte */
2014-12-11 21:15:04 +00:00
if ( pwdinfo - > persistent_supported )
p2pie [ p2pielen + + ] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT ;
else
p2pie [ p2pielen + + ] = DMP_P2P_GRPCAP_SUPPORT ;
2013-07-20 18:18:13 +00:00
2015-02-19 21:34:32 +00:00
/* Listen Channel */
/* Type: */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = P2P_ATTR_LISTEN_CH ;
2013-07-20 18:18:13 +00:00
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( 0x0005 ) ;
2014-12-11 21:15:04 +00:00
p2pielen + = 2 ;
2013-07-20 18:18:13 +00:00
2015-02-19 21:34:32 +00:00
/* Value: */
/* Country String */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = ' X ' ;
p2pie [ p2pielen + + ] = ' X ' ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* The third byte should be set to 0x04. */
/* Described in the "Operating Channel Attribute" section. */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = 0x04 ;
2015-02-19 21:34:32 +00:00
/* Operating Class */
p2pie [ p2pielen + + ] = 0x51 ; /* Copy from SD7 */
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* Channel Number */
p2pie [ p2pielen + + ] = pwdinfo - > listen_channel ; /* listen channel */
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
2015-02-19 21:34:32 +00:00
/* Extended Listen Timing */
/* Type: */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = P2P_ATTR_EX_LISTEN_TIMING ;
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( 0x0004 ) ;
2014-12-11 21:15:04 +00:00
p2pielen + = 2 ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Value: */
/* Availability Period */
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( 0xFFFF ) ;
2013-05-08 21:45:39 +00:00
p2pielen + = 2 ;
2015-02-19 21:34:32 +00:00
/* Availability Interval */
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( 0xFFFF ) ;
2014-12-11 21:15:04 +00:00
p2pielen + = 2 ;
2013-05-19 04:28:07 +00:00
2014-12-11 21:15:04 +00:00
if ( rtw_p2p_chk_role ( pwdinfo , P2P_ROLE_GO ) )
{
2015-02-19 21:34:32 +00:00
/* Operating Channel (if this WiFi is working as the group owner now) */
/* Type: */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = P2P_ATTR_OPERATING_CH ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( 0x0005 ) ;
2014-12-11 21:15:04 +00:00
p2pielen + = 2 ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Value: */
/* Country String */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = ' X ' ;
p2pie [ p2pielen + + ] = ' X ' ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* The third byte should be set to 0x04. */
/* Described in the "Operating Channel Attribute" section. */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = 0x04 ;
2015-02-19 21:34:32 +00:00
/* Operating Class */
p2pie [ p2pielen + + ] = 0x51 ; /* Copy from SD7 */
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* Channel Number */
p2pie [ p2pielen + + ] = pwdinfo - > operating_channel ; /* operating channel number */
2014-12-11 21:15:04 +00:00
2014-12-19 06:59:46 +00:00
}
pframe = rtw_set_ie ( pframe , _VENDOR_SPECIFIC_IE_ , p2pielen , ( unsigned char * ) p2pie , & pattrib - > pktlen ) ;
2014-12-11 21:15:04 +00:00
if ( pmlmepriv - > wps_probe_req_ie ! = NULL )
{
2015-02-19 21:34:32 +00:00
/* WPS IE */
2015-02-19 20:50:04 +00:00
memcpy ( pframe , pmlmepriv - > wps_probe_req_ie , pmlmepriv - > wps_probe_req_ie_len ) ;
2014-12-11 21:15:04 +00:00
pattrib - > pktlen + = pmlmepriv - > wps_probe_req_ie_len ;
pframe + = pmlmepriv - > wps_probe_req_ie_len ;
}
2013-07-20 18:18:13 +00:00
}
2013-05-19 04:28:07 +00:00
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_WFD
2014-12-29 02:13:24 +00:00
if ( true = = pwdinfo - > wfd_info - > wfd_enable )
2014-12-11 21:15:04 +00:00
{
wfdielen = build_probe_req_wfd_ie ( pwdinfo , pframe ) ;
pframe + = wfdielen ;
pattrib - > pktlen + = wfdielen ;
}
2014-12-19 06:59:46 +00:00
else if ( pmlmepriv - > wfd_probe_req_ie ! = NULL & & pmlmepriv - > wfd_probe_req_ie_len > 0 )
2014-12-11 21:15:04 +00:00
{
2015-02-19 21:34:32 +00:00
/* WFD IE */
2015-02-19 20:50:04 +00:00
memcpy ( pframe , pmlmepriv - > wfd_probe_req_ie , pmlmepriv - > wfd_probe_req_ie_len ) ;
2014-12-11 21:15:04 +00:00
pattrib - > pktlen + = pmlmepriv - > wfd_probe_req_ie_len ;
2014-12-19 06:59:46 +00:00
pframe + = pmlmepriv - > wfd_probe_req_ie_len ;
2013-05-08 21:45:39 +00:00
}
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_WFD */
2013-05-08 21:45:39 +00:00
pattrib - > last_txcmdsz = pattrib - > pktlen ;
2014-12-11 21:15:04 +00:00
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_info_ , ( " issuing probe_req, tx_len=%d \n " , pattrib - > last_txcmdsz ) ) ;
2013-05-08 21:45:39 +00:00
if ( wait_ack ) {
ret = dump_mgntframe_and_wait_ack ( padapter , pmgntframe ) ;
} else {
dump_mgntframe ( padapter , pmgntframe ) ;
ret = _SUCCESS ;
}
exit :
return ret ;
}
2014-12-17 23:13:53 +00:00
inline void issue_probereq_p2p ( struct adapter * adapter , u8 * da )
2013-05-08 21:45:39 +00:00
{
2014-12-29 02:13:24 +00:00
_issue_probereq_p2p ( adapter , da , false ) ;
2013-05-08 21:45:39 +00:00
}
2014-12-17 23:13:53 +00:00
int issue_probereq_p2p_ex ( struct adapter * adapter , u8 * da , int try_cnt , int wait_ms )
2013-05-08 21:45:39 +00:00
{
int ret ;
int i = 0 ;
u32 start = rtw_get_current_time ( ) ;
2014-12-11 21:15:04 +00:00
do
{
2014-12-29 02:13:24 +00:00
ret = _issue_probereq_p2p ( adapter , da , wait_ms > 0 ? true : false ) ;
2013-05-08 21:45:39 +00:00
i + + ;
if ( adapter - > bDriverStopped | | adapter - > bSurpriseRemoved )
break ;
2014-12-11 21:15:04 +00:00
if ( i < try_cnt & & wait_ms > 0 & & ret = = _FAIL )
2013-05-08 21:45:39 +00:00
rtw_msleep_os ( wait_ms ) ;
2014-12-11 21:15:04 +00:00
} while ( ( i < try_cnt ) & & ( ( ret = = _FAIL ) | | ( wait_ms = = 0 ) ) ) ;
2013-05-08 21:45:39 +00:00
if ( ret ! = _FAIL ) {
ret = _SUCCESS ;
2014-12-11 21:15:04 +00:00
# ifndef DBG_XMIT_ACK
2013-05-08 21:45:39 +00:00
goto exit ;
2014-12-11 21:15:04 +00:00
# endif
2013-05-08 21:45:39 +00:00
}
if ( try_cnt & & wait_ms ) {
if ( da )
2014-12-11 21:15:04 +00:00
DBG_871X ( FUNC_ADPT_FMT " to " MAC_FMT " , ch:%u%s, %d/%d in %u ms \n " ,
FUNC_ADPT_ARG ( adapter ) , MAC_ARG ( da ) , rtw_get_oper_ch ( adapter ) ,
ret = = _SUCCESS ? " , acked " : " " , i , try_cnt , rtw_get_passing_time_ms ( start ) ) ;
2013-05-08 21:45:39 +00:00
else
2014-12-11 21:15:04 +00:00
DBG_871X ( FUNC_ADPT_FMT " , ch:%u%s, %d/%d in %u ms \n " ,
2013-05-08 21:45:39 +00:00
FUNC_ADPT_ARG ( adapter ) , rtw_get_oper_ch ( adapter ) ,
2014-12-11 21:15:04 +00:00
ret = = _SUCCESS ? " , acked " : " " , i , try_cnt , rtw_get_passing_time_ms ( start ) ) ;
2013-05-08 21:45:39 +00:00
}
exit :
return ret ;
}
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_P2P */
2013-05-08 21:45:39 +00:00
2014-12-19 04:28:04 +00:00
static s32 rtw_action_public_decache ( union recv_frame * recv_frame , s32 token )
2013-05-08 21:45:39 +00:00
{
2014-12-17 23:13:53 +00:00
struct adapter * adapter = recv_frame - > u . hdr . adapter ;
2013-05-08 21:45:39 +00:00
struct mlme_ext_priv * mlmeext = & ( adapter - > mlmeextpriv ) ;
u8 * frame = recv_frame - > u . hdr . rx_data ;
2014-12-11 21:15:04 +00:00
u16 seq_ctrl = ( ( recv_frame - > u . hdr . attrib . seq_num & 0xffff ) < < 4 ) |
2013-05-08 21:45:39 +00:00
( recv_frame - > u . hdr . attrib . frag_num & 0xf ) ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
if ( GetRetry ( frame ) ) {
if ( token > = 0 ) {
2014-12-11 21:15:04 +00:00
if ( ( seq_ctrl = = mlmeext - > action_public_rxseq )
& & ( token = = mlmeext - > action_public_dialog_token ) )
{
DBG_871X ( FUNC_ADPT_FMT " seq_ctrl=0x%x, rxseq=0x%x, token:%d \n " ,
2013-05-08 21:45:39 +00:00
FUNC_ADPT_ARG ( adapter ) , seq_ctrl , mlmeext - > action_public_rxseq , token ) ;
return _FAIL ;
}
} else {
if ( seq_ctrl = = mlmeext - > action_public_rxseq ) {
2014-12-11 21:15:04 +00:00
DBG_871X ( FUNC_ADPT_FMT " seq_ctrl=0x%x, rxseq=0x%x \n " ,
2013-05-08 21:45:39 +00:00
FUNC_ADPT_ARG ( adapter ) , seq_ctrl , mlmeext - > action_public_rxseq ) ;
return _FAIL ;
}
}
}
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
mlmeext - > action_public_rxseq = seq_ctrl ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
if ( token > = 0 )
mlmeext - > action_public_dialog_token = token ;
return _SUCCESS ;
}
2014-12-19 04:28:04 +00:00
static unsigned int on_action_public_p2p ( union recv_frame * precv_frame )
2013-05-08 21:45:39 +00:00
{
2014-12-17 23:13:53 +00:00
struct adapter * padapter = precv_frame - > u . hdr . adapter ;
2013-05-08 21:45:39 +00:00
u8 * pframe = precv_frame - > u . hdr . rx_data ;
2013-10-19 17:45:47 +00:00
uint len = precv_frame - > u . hdr . len ;
2014-12-11 21:15:04 +00:00
u8 * frame_body ;
u8 dialogToken = 0 ;
# ifdef CONFIG_P2P
2013-05-08 21:45:39 +00:00
u8 * p2p_ie ;
2014-12-11 21:15:04 +00:00
u32 p2p_ielen , wps_ielen ;
struct wifidirect_info * pwdinfo = & ( padapter - > wdinfo ) ;
2013-05-08 21:45:39 +00:00
u8 result = P2P_STATUS_SUCCESS ;
u8 empty_addr [ ETH_ALEN ] = { 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 } ;
2014-12-11 21:15:04 +00:00
u8 * merged_p2pie = NULL ;
u32 merged_p2p_ielen = 0 ;
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_P2P */
2013-05-08 21:45:39 +00:00
frame_body = ( unsigned char * ) ( pframe + sizeof ( struct rtw_ieee80211_hdr_3addr ) ) ;
dialogToken = frame_body [ 7 ] ;
if ( rtw_action_public_decache ( precv_frame , dialogToken ) = = _FAIL )
return _FAIL ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_P2P
_cancel_timer_ex ( & pwdinfo - > reset_ch_sitesurvey ) ;
if ( wdev_to_priv ( padapter - > rtw_wdev ) - > p2p_enabled & & pwdinfo - > driver_interface = = DRIVER_CFG80211 )
{
rtw_cfg80211_rx_p2p_action_public ( padapter , pframe , len ) ;
2015-02-20 04:52:01 +00:00
} else {
2015-02-19 21:34:32 +00:00
/* Do nothing if the driver doesn't enable the P2P function. */
2014-12-11 21:15:04 +00:00
if ( rtw_p2p_chk_state ( pwdinfo , P2P_STATE_NONE ) | | rtw_p2p_chk_state ( pwdinfo , P2P_STATE_IDLE ) )
return _SUCCESS ;
2013-05-19 04:28:07 +00:00
2014-12-11 21:15:04 +00:00
len - = sizeof ( struct rtw_ieee80211_hdr_3addr ) ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
switch ( frame_body [ 6 ] ) /* OUI Subtype */
2014-12-11 21:15:04 +00:00
{
case P2P_GO_NEGO_REQ :
{
DBG_871X ( " [%s] Got GO Nego Req Frame \n " , __FUNCTION__ ) ;
2015-02-19 20:58:09 +00:00
memset ( & pwdinfo - > groupid_info , 0x00 , sizeof ( struct group_id_info ) ) ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
if ( rtw_p2p_chk_state ( pwdinfo , P2P_STATE_RX_PROVISION_DIS_REQ ) )
{
rtw_p2p_set_state ( pwdinfo , rtw_p2p_pre_state ( pwdinfo ) ) ;
}
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
if ( rtw_p2p_chk_state ( pwdinfo , P2P_STATE_GONEGO_FAIL ) )
{
2015-02-19 21:34:32 +00:00
/* Commented by Albert 20110526 */
/* In this case, this means the previous nego fail doesn't be reset yet. */
2014-12-11 21:15:04 +00:00
_cancel_timer_ex ( & pwdinfo - > restore_p2p_state_timer ) ;
2015-02-19 21:34:32 +00:00
/* Restore the previous p2p state */
2014-12-11 21:15:04 +00:00
rtw_p2p_set_state ( pwdinfo , rtw_p2p_pre_state ( pwdinfo ) ) ;
2014-12-19 06:59:46 +00:00
DBG_871X ( " [%s] Restore the previous p2p state to %d \n " , __FUNCTION__ , rtw_p2p_state ( pwdinfo ) ) ;
}
2015-02-19 21:34:32 +00:00
/* Commented by Kurt 20110902 */
/* Add if statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered. */
2014-12-11 21:15:04 +00:00
if ( ! rtw_p2p_chk_state ( pwdinfo , P2P_STATE_GONEGO_ING ) )
rtw_p2p_set_pre_state ( pwdinfo , rtw_p2p_state ( pwdinfo ) ) ;
2015-02-19 21:34:32 +00:00
/* Commented by Kurt 20120113 */
/* Get peer_dev_addr here if peer doesn't issue prov_disc frame. */
2014-12-11 21:15:04 +00:00
if ( _rtw_memcmp ( pwdinfo - > rx_prov_disc_info . peerDevAddr , empty_addr , ETH_ALEN ) ) ;
2015-02-19 20:50:04 +00:00
memcpy ( pwdinfo - > rx_prov_disc_info . peerDevAddr , GetAddr2Ptr ( pframe ) , ETH_ALEN ) ;
2014-12-11 21:15:04 +00:00
result = process_p2p_group_negotation_req ( pwdinfo , frame_body , len ) ;
issue_p2p_GO_response ( padapter , GetAddr2Ptr ( pframe ) , frame_body , len , result ) ;
# ifdef CONFIG_INTEL_WIDI
if ( ( padapter - > mlmepriv . widi_state = = INTEL_WIDI_STATE_LISTEN ) & & ( padapter - > mlmepriv . widi_state ! = INTEL_WIDI_STATE_WFD_CONNECTION ) )
{
padapter - > mlmepriv . widi_state = INTEL_WIDI_STATE_WFD_CONNECTION ;
_cancel_timer_ex ( & ( padapter - > mlmepriv . listen_timer ) ) ;
intel_widi_wk_cmd ( padapter , INTEL_WIDI_LISTEN_STOP_WK , NULL ) ;
}
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_INTEL_WIDI */
2014-12-11 21:15:04 +00:00
2015-02-19 21:34:32 +00:00
/* Commented by Albert 20110718 */
/* No matter negotiating or negotiation failure, the driver should set up the restore P2P state timer. */
2014-12-11 21:15:04 +00:00
_set_timer ( & pwdinfo - > restore_p2p_state_timer , 5000 ) ;
2014-12-19 06:59:46 +00:00
break ;
2014-12-11 21:15:04 +00:00
}
case P2P_GO_NEGO_RESP :
{
DBG_871X ( " [%s] Got GO Nego Resp Frame \n " , __FUNCTION__ ) ;
if ( rtw_p2p_chk_state ( pwdinfo , P2P_STATE_GONEGO_ING ) )
{
2015-02-19 21:34:32 +00:00
/* Commented by Albert 20110425 */
/* The restore timer is enabled when issuing the nego request frame of rtw_p2p_connect function. */
2014-12-11 21:15:04 +00:00
_cancel_timer_ex ( & pwdinfo - > restore_p2p_state_timer ) ;
2014-12-29 02:13:24 +00:00
pwdinfo - > nego_req_info . benable = false ;
2014-12-11 21:15:04 +00:00
result = process_p2p_group_negotation_resp ( pwdinfo , frame_body , len ) ;
issue_p2p_GO_confirm ( pwdinfo - > padapter , GetAddr2Ptr ( pframe ) , result ) ;
if ( P2P_STATUS_SUCCESS = = result )
{
if ( rtw_p2p_role ( pwdinfo ) = = P2P_ROLE_CLIENT )
{
pwdinfo - > p2p_info . operation_ch [ 0 ] = pwdinfo - > peer_operating_ch ;
# ifdef P2P_OP_CHECK_SOCIAL_CH
2015-02-19 21:34:32 +00:00
pwdinfo - > p2p_info . operation_ch [ 1 ] = 1 ; /* Check whether GO is operating in channel 1; */
pwdinfo - > p2p_info . operation_ch [ 2 ] = 6 ; /* Check whether GO is operating in channel 6; */
pwdinfo - > p2p_info . operation_ch [ 3 ] = 11 ; /* Check whether GO is operating in channel 11; */
# endif /* P2P_OP_CHECK_SOCIAL_CH */
2014-12-11 21:15:04 +00:00
pwdinfo - > p2p_info . scan_op_ch_only = 1 ;
_set_timer ( & pwdinfo - > reset_ch_sitesurvey2 , P2P_RESET_SCAN_CH ) ;
}
}
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Reset the dialog token for group negotiation frames. */
2014-12-11 21:15:04 +00:00
pwdinfo - > negotiation_dialog_token = 1 ;
2013-07-20 18:18:13 +00:00
2014-12-11 21:15:04 +00:00
if ( rtw_p2p_chk_state ( pwdinfo , P2P_STATE_GONEGO_FAIL ) )
{
_set_timer ( & pwdinfo - > restore_p2p_state_timer , 5000 ) ;
}
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
else
{
DBG_871X ( " [%s] Skipped GO Nego Resp Frame (p2p_state != P2P_STATE_GONEGO_ING) \n " , __FUNCTION__ ) ;
}
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
break ;
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
case P2P_GO_NEGO_CONF :
{
DBG_871X ( " [%s] Got GO Nego Confirm Frame \n " , __FUNCTION__ ) ;
result = process_p2p_group_negotation_confirm ( pwdinfo , frame_body , len ) ;
if ( P2P_STATUS_SUCCESS = = result )
{
if ( rtw_p2p_role ( pwdinfo ) = = P2P_ROLE_CLIENT )
{
pwdinfo - > p2p_info . operation_ch [ 0 ] = pwdinfo - > peer_operating_ch ;
# ifdef P2P_OP_CHECK_SOCIAL_CH
2015-02-19 21:34:32 +00:00
pwdinfo - > p2p_info . operation_ch [ 1 ] = 1 ; /* Check whether GO is operating in channel 1; */
pwdinfo - > p2p_info . operation_ch [ 2 ] = 6 ; /* Check whether GO is operating in channel 6; */
pwdinfo - > p2p_info . operation_ch [ 3 ] = 11 ; /* Check whether GO is operating in channel 11; */
# endif /* P2P_OP_CHECK_SOCIAL_CH */
2014-12-11 21:15:04 +00:00
pwdinfo - > p2p_info . scan_op_ch_only = 1 ;
_set_timer ( & pwdinfo - > reset_ch_sitesurvey2 , P2P_RESET_SCAN_CH ) ;
}
2013-08-01 02:12:42 +00:00
}
2014-12-11 21:15:04 +00:00
break ;
}
case P2P_INVIT_REQ :
{
2015-02-19 21:34:32 +00:00
/* Added by Albert 2010/10/05 */
/* Received the P2P Invite Request frame. */
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
DBG_871X ( " [%s] Got invite request frame! \n " , __FUNCTION__ ) ;
if ( ( p2p_ie = rtw_get_p2p_ie ( frame_body + _PUBLIC_ACTION_IE_OFFSET_ , len - _PUBLIC_ACTION_IE_OFFSET_ , NULL , & p2p_ielen ) ) )
{
2015-02-19 21:34:32 +00:00
/* Parse the necessary information from the P2P Invitation Request frame. */
/* For example: The MAC address of sending this P2P Invitation Request frame. */
2014-12-11 21:15:04 +00:00
u32 attr_contentlen = 0 ;
u8 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE ;
struct group_id_info group_id ;
u8 invitation_flag = 0 ;
merged_p2p_ielen = rtw_get_p2p_merged_ies_len ( frame_body + _PUBLIC_ACTION_IE_OFFSET_ , len - _PUBLIC_ACTION_IE_OFFSET_ ) ;
2015-02-19 21:34:32 +00:00
merged_p2pie = rtw_zmalloc ( merged_p2p_ielen + 2 ) ; /* 2 is for EID and Length */
2014-12-11 21:15:04 +00:00
if ( merged_p2pie = = NULL )
{
DBG_871X ( " [%s] Malloc p2p ie fail \n " , __FUNCTION__ ) ;
goto exit ;
}
2015-02-19 20:58:09 +00:00
memset ( merged_p2pie , 0x00 , merged_p2p_ielen ) ;
2014-12-11 21:15:04 +00:00
merged_p2p_ielen = rtw_p2p_merge_ies ( frame_body + _PUBLIC_ACTION_IE_OFFSET_ , len - _PUBLIC_ACTION_IE_OFFSET_ , merged_p2pie ) ;
rtw_get_p2p_attr_content ( merged_p2pie , merged_p2p_ielen , P2P_ATTR_INVITATION_FLAGS , & invitation_flag , & attr_contentlen ) ;
if ( attr_contentlen )
{
rtw_get_p2p_attr_content ( merged_p2pie , merged_p2p_ielen , P2P_ATTR_GROUP_BSSID , pwdinfo - > p2p_peer_interface_addr , & attr_contentlen ) ;
2015-02-19 21:34:32 +00:00
/* Commented by Albert 20120510 */
/* Copy to the pwdinfo->p2p_peer_interface_addr. */
/* So that the WFD UI ( or Sigma ) can get the peer interface address by using the following command. */
/* #> iwpriv wlan0 p2p_get peer_ifa */
/* After having the peer interface address, the sigma can find the correct conf file for wpa_supplicant. */
2014-12-11 21:15:04 +00:00
if ( attr_contentlen )
{
DBG_871X ( " [%s] GO's BSSID = %.2X %.2X %.2X %.2X %.2X %.2X \n " , __FUNCTION__ ,
pwdinfo - > p2p_peer_interface_addr [ 0 ] , pwdinfo - > p2p_peer_interface_addr [ 1 ] ,
pwdinfo - > p2p_peer_interface_addr [ 2 ] , pwdinfo - > p2p_peer_interface_addr [ 3 ] ,
pwdinfo - > p2p_peer_interface_addr [ 4 ] , pwdinfo - > p2p_peer_interface_addr [ 5 ] ) ;
2014-12-19 06:59:46 +00:00
}
2014-12-11 21:15:04 +00:00
if ( invitation_flag & P2P_INVITATION_FLAGS_PERSISTENT )
{
2015-02-19 21:34:32 +00:00
/* Re-invoke the persistent group. */
2014-12-19 06:59:46 +00:00
2015-02-19 20:58:09 +00:00
memset ( & group_id , 0x00 , sizeof ( struct group_id_info ) ) ;
2014-12-11 21:15:04 +00:00
rtw_get_p2p_attr_content ( merged_p2pie , merged_p2p_ielen , P2P_ATTR_GROUP_ID , ( u8 * ) & group_id , & attr_contentlen ) ;
if ( attr_contentlen )
{
if ( _rtw_memcmp ( group_id . go_device_addr , myid ( & padapter - > eeprompriv ) , ETH_ALEN ) )
{
2015-02-19 21:34:32 +00:00
/* The p2p device sending this p2p invitation request wants this Wi-Fi device to be the persistent GO. */
2014-12-11 21:15:04 +00:00
rtw_p2p_set_state ( pwdinfo , P2P_STATE_RECV_INVITE_REQ_GO ) ;
rtw_p2p_set_role ( pwdinfo , P2P_ROLE_GO ) ;
status_code = P2P_STATUS_SUCCESS ;
}
else
{
2015-02-19 21:34:32 +00:00
/* The p2p device sending this p2p invitation request wants to be the persistent GO. */
2014-12-11 21:15:04 +00:00
if ( is_matched_in_profilelist ( pwdinfo - > p2p_peer_interface_addr , & pwdinfo - > profileinfo [ 0 ] ) )
{
u8 operatingch_info [ 5 ] = { 0x00 } ;
if ( rtw_get_p2p_attr_content ( merged_p2pie , merged_p2p_ielen , P2P_ATTR_OPERATING_CH , operatingch_info , & attr_contentlen ) )
{
if ( rtw_ch_set_search_ch ( padapter - > mlmeextpriv . channel_set , ( u32 ) operatingch_info [ 4 ] ) )
{
2015-02-19 21:34:32 +00:00
/* The operating channel is acceptable for this device. */
2014-12-11 21:15:04 +00:00
pwdinfo - > rx_invitereq_info . operation_ch [ 0 ] = operatingch_info [ 4 ] ;
# ifdef P2P_OP_CHECK_SOCIAL_CH
2015-02-19 21:34:32 +00:00
pwdinfo - > rx_invitereq_info . operation_ch [ 1 ] = 1 ; /* Check whether GO is operating in channel 1; */
pwdinfo - > rx_invitereq_info . operation_ch [ 2 ] = 6 ; /* Check whether GO is operating in channel 6; */
pwdinfo - > rx_invitereq_info . operation_ch [ 3 ] = 11 ; /* Check whether GO is operating in channel 11; */
# endif /* P2P_OP_CHECK_SOCIAL_CH */
2014-12-11 21:15:04 +00:00
pwdinfo - > rx_invitereq_info . scan_op_ch_only = 1 ;
_set_timer ( & pwdinfo - > reset_ch_sitesurvey , P2P_RESET_SCAN_CH ) ;
rtw_p2p_set_state ( pwdinfo , P2P_STATE_RECV_INVITE_REQ_MATCH ) ;
rtw_p2p_set_role ( pwdinfo , P2P_ROLE_CLIENT ) ;
status_code = P2P_STATUS_SUCCESS ;
}
else
{
2015-02-19 21:34:32 +00:00
/* The operating channel isn't supported by this device. */
2014-12-11 21:15:04 +00:00
rtw_p2p_set_state ( pwdinfo , P2P_STATE_RECV_INVITE_REQ_DISMATCH ) ;
rtw_p2p_set_role ( pwdinfo , P2P_ROLE_DEVICE ) ;
status_code = P2P_STATUS_FAIL_NO_COMMON_CH ;
_set_timer ( & pwdinfo - > restore_p2p_state_timer , 3000 ) ;
}
}
else
{
2015-02-19 21:34:32 +00:00
/* Commented by Albert 20121130 */
/* Intel will use the different P2P IE to store the operating channel information */
/* Workaround for Intel WiDi 3.5 */
2014-12-11 21:15:04 +00:00
rtw_p2p_set_state ( pwdinfo , P2P_STATE_RECV_INVITE_REQ_MATCH ) ;
rtw_p2p_set_role ( pwdinfo , P2P_ROLE_CLIENT ) ;
status_code = P2P_STATUS_SUCCESS ;
2014-12-19 06:59:46 +00:00
}
2014-12-11 21:15:04 +00:00
}
else
{
rtw_p2p_set_state ( pwdinfo , P2P_STATE_RECV_INVITE_REQ_DISMATCH ) ;
# ifdef CONFIG_INTEL_WIDI
2015-02-19 20:50:04 +00:00
memcpy ( pwdinfo - > p2p_peer_device_addr , group_id . go_device_addr , ETH_ALEN ) ;
2014-12-11 21:15:04 +00:00
rtw_p2p_set_role ( pwdinfo , P2P_ROLE_CLIENT ) ;
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_INTEL_WIDI */
2014-12-11 21:15:04 +00:00
status_code = P2P_STATUS_FAIL_UNKNOWN_P2PGROUP ;
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
}
}
else
{
DBG_871X ( " [%s] P2P Group ID Attribute NOT FOUND! \n " , __FUNCTION__ ) ;
status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE ;
2014-12-19 06:59:46 +00:00
}
2014-12-11 21:15:04 +00:00
}
else
{
2015-02-19 21:34:32 +00:00
/* Received the invitation to join a P2P group. */
2014-12-11 21:15:04 +00:00
2015-02-19 20:58:09 +00:00
memset ( & group_id , 0x00 , sizeof ( struct group_id_info ) ) ;
2014-12-11 21:15:04 +00:00
rtw_get_p2p_attr_content ( merged_p2pie , merged_p2p_ielen , P2P_ATTR_GROUP_ID , ( u8 * ) & group_id , & attr_contentlen ) ;
if ( attr_contentlen )
{
if ( _rtw_memcmp ( group_id . go_device_addr , myid ( & padapter - > eeprompriv ) , ETH_ALEN ) )
{
2015-02-19 21:34:32 +00:00
/* In this case, the GO can't be myself. */
2014-12-11 21:15:04 +00:00
rtw_p2p_set_state ( pwdinfo , P2P_STATE_RECV_INVITE_REQ_DISMATCH ) ;
status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE ;
}
else
{
2015-02-19 21:34:32 +00:00
/* The p2p device sending this p2p invitation request wants to join an existing P2P group */
/* Commented by Albert 2012/06/28 */
/* In this case, this Wi-Fi device should use the iwpriv command to get the peer device address. */
/* The peer device address should be the destination address for the provisioning discovery request. */
/* Then, this Wi-Fi device should use the iwpriv command to get the peer interface address. */
/* The peer interface address should be the address for WPS mac address */
2015-02-19 20:50:04 +00:00
memcpy ( pwdinfo - > p2p_peer_device_addr , group_id . go_device_addr , ETH_ALEN ) ;
2014-12-11 21:15:04 +00:00
rtw_p2p_set_role ( pwdinfo , P2P_ROLE_CLIENT ) ;
rtw_p2p_set_state ( pwdinfo , P2P_STATE_RECV_INVITE_REQ_JOIN ) ;
2013-08-01 02:12:42 +00:00
status_code = P2P_STATUS_SUCCESS ;
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
}
else
{
DBG_871X ( " [%s] P2P Group ID Attribute NOT FOUND! \n " , __FUNCTION__ ) ;
status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE ;
2013-05-19 04:28:07 +00:00
}
2013-05-08 21:45:39 +00:00
}
}
2014-12-11 21:15:04 +00:00
else
{
DBG_871X ( " [%s] P2P Invitation Flags Attribute NOT FOUND! \n " , __FUNCTION__ ) ;
2013-08-01 02:12:42 +00:00
status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE ;
2014-12-19 06:59:46 +00:00
}
2013-08-01 02:12:42 +00:00
2014-12-11 21:15:04 +00:00
DBG_871X ( " [%s] status_code = %d \n " , __FUNCTION__ , status_code ) ;
2013-08-01 02:12:42 +00:00
2014-12-11 21:15:04 +00:00
pwdinfo - > inviteresp_info . token = frame_body [ 7 ] ;
issue_p2p_invitation_response ( padapter , GetAddr2Ptr ( pframe ) , pwdinfo - > inviteresp_info . token , status_code ) ;
_set_timer ( & pwdinfo - > restore_p2p_state_timer , 3000 ) ;
}
# ifdef CONFIG_INTEL_WIDI
if ( ( padapter - > mlmepriv . widi_state = = INTEL_WIDI_STATE_LISTEN ) & & ( padapter - > mlmepriv . widi_state ! = INTEL_WIDI_STATE_WFD_CONNECTION ) )
{
padapter - > mlmepriv . widi_state = INTEL_WIDI_STATE_WFD_CONNECTION ;
_cancel_timer_ex ( & ( padapter - > mlmepriv . listen_timer ) ) ;
intel_widi_wk_cmd ( padapter , INTEL_WIDI_LISTEN_STOP_WK , NULL ) ;
}
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_INTEL_WIDI */
2014-12-11 21:15:04 +00:00
break ;
}
case P2P_INVIT_RESP :
{
u8 attr_content = 0x00 ;
u32 attr_contentlen = 0 ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
DBG_871X ( " [%s] Got invite response frame! \n " , __FUNCTION__ ) ;
_cancel_timer_ex ( & pwdinfo - > restore_p2p_state_timer ) ;
if ( ( p2p_ie = rtw_get_p2p_ie ( frame_body + _PUBLIC_ACTION_IE_OFFSET_ , len - _PUBLIC_ACTION_IE_OFFSET_ , NULL , & p2p_ielen ) ) )
{
rtw_get_p2p_attr_content ( p2p_ie , p2p_ielen , P2P_ATTR_STATUS , & attr_content , & attr_contentlen ) ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
if ( attr_contentlen = = 1 )
{
DBG_871X ( " [%s] Status = %d \n " , __FUNCTION__ , attr_content ) ;
2014-12-29 02:13:24 +00:00
pwdinfo - > invitereq_info . benable = false ;
2014-12-11 21:15:04 +00:00
if ( attr_content = = P2P_STATUS_SUCCESS )
{
if ( _rtw_memcmp ( pwdinfo - > invitereq_info . go_bssid , myid ( & padapter - > eeprompriv ) , ETH_ALEN ) )
{
rtw_p2p_set_role ( pwdinfo , P2P_ROLE_GO ) ;
}
else
{
rtw_p2p_set_role ( pwdinfo , P2P_ROLE_CLIENT ) ;
}
rtw_p2p_set_state ( pwdinfo , P2P_STATE_RX_INVITE_RESP_OK ) ;
}
else
{
rtw_p2p_set_role ( pwdinfo , P2P_ROLE_DEVICE ) ;
rtw_p2p_set_state ( pwdinfo , P2P_STATE_RX_INVITE_RESP_FAIL ) ;
}
}
else
{
rtw_p2p_set_role ( pwdinfo , P2P_ROLE_DEVICE ) ;
rtw_p2p_set_state ( pwdinfo , P2P_STATE_RX_INVITE_RESP_FAIL ) ;
2013-08-01 02:12:42 +00:00
}
2014-12-11 21:15:04 +00:00
}
else
{
2013-05-08 21:45:39 +00:00
rtw_p2p_set_role ( pwdinfo , P2P_ROLE_DEVICE ) ;
2014-12-11 21:15:04 +00:00
rtw_p2p_set_state ( pwdinfo , P2P_STATE_RX_INVITE_RESP_FAIL ) ;
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
if ( rtw_p2p_chk_state ( pwdinfo , P2P_STATE_RX_INVITE_RESP_FAIL ) )
{
_set_timer ( & pwdinfo - > restore_p2p_state_timer , 5000 ) ;
}
break ;
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
case P2P_DEVDISC_REQ :
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
process_p2p_devdisc_req ( pwdinfo , pframe , len ) ;
break ;
case P2P_DEVDISC_RESP :
process_p2p_devdisc_resp ( pwdinfo , pframe , len ) ;
break ;
case P2P_PROVISION_DISC_REQ :
DBG_871X ( " [%s] Got Provisioning Discovery Request Frame \n " , __FUNCTION__ ) ;
process_p2p_provdisc_req ( pwdinfo , pframe , len ) ;
2015-02-19 20:50:04 +00:00
memcpy ( pwdinfo - > rx_prov_disc_info . peerDevAddr , GetAddr2Ptr ( pframe ) , ETH_ALEN ) ;
2014-12-11 21:15:04 +00:00
2015-02-19 21:34:32 +00:00
/* 20110902 Kurt */
/* Add the following statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered. */
2014-12-11 21:15:04 +00:00
if ( ! rtw_p2p_chk_state ( pwdinfo , P2P_STATE_RX_PROVISION_DIS_REQ ) )
rtw_p2p_set_pre_state ( pwdinfo , rtw_p2p_state ( pwdinfo ) ) ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
rtw_p2p_set_state ( pwdinfo , P2P_STATE_RX_PROVISION_DIS_REQ ) ;
_set_timer ( & pwdinfo - > restore_p2p_state_timer , P2P_PROVISION_TIMEOUT ) ;
# ifdef CONFIG_INTEL_WIDI
if ( ( padapter - > mlmepriv . widi_state = = INTEL_WIDI_STATE_LISTEN ) & & ( padapter - > mlmepriv . widi_state ! = INTEL_WIDI_STATE_WFD_CONNECTION ) )
{
padapter - > mlmepriv . widi_state = INTEL_WIDI_STATE_WFD_CONNECTION ;
_cancel_timer_ex ( & ( padapter - > mlmepriv . listen_timer ) ) ;
intel_widi_wk_cmd ( padapter , INTEL_WIDI_LISTEN_STOP_WK , NULL ) ;
}
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_INTEL_WIDI */
2014-12-11 21:15:04 +00:00
break ;
case P2P_PROVISION_DISC_RESP :
2015-02-19 21:34:32 +00:00
/* Commented by Albert 20110707 */
/* Should we check the pwdinfo->tx_prov_disc_info.bsent flag here?? */
2014-12-11 21:15:04 +00:00
DBG_871X ( " [%s] Got Provisioning Discovery Response Frame \n " , __FUNCTION__ ) ;
2015-02-19 21:34:32 +00:00
/* Commented by Albert 20110426 */
/* The restore timer is enabled when issuing the provisioing request frame in rtw_p2p_prov_disc function. */
2014-12-11 21:15:04 +00:00
_cancel_timer_ex ( & pwdinfo - > restore_p2p_state_timer ) ;
rtw_p2p_set_state ( pwdinfo , P2P_STATE_RX_PROVISION_DIS_RSP ) ;
process_p2p_provdisc_resp ( pwdinfo , pframe ) ;
_set_timer ( & pwdinfo - > restore_p2p_state_timer , P2P_PROVISION_TIMEOUT ) ;
break ;
}
2013-08-01 02:12:42 +00:00
}
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_P2P */
2014-12-11 21:15:04 +00:00
exit :
if ( merged_p2pie )
{
rtw_mfree ( merged_p2pie , merged_p2p_ielen + 2 ) ;
2013-05-08 21:45:39 +00:00
}
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
return _SUCCESS ;
}
2014-12-19 04:28:04 +00:00
static unsigned int on_action_public_vendor ( union recv_frame * precv_frame )
2013-05-08 21:45:39 +00:00
{
unsigned int ret = _FAIL ;
u8 * pframe = precv_frame - > u . hdr . rx_data ;
2014-12-11 21:15:04 +00:00
uint frame_len = precv_frame - > u . hdr . len ;
2013-05-08 21:45:39 +00:00
u8 * frame_body = pframe + sizeof ( struct rtw_ieee80211_hdr_3addr ) ;
2014-12-29 02:13:24 +00:00
if ( _rtw_memcmp ( frame_body + 2 , P2P_OUI , 4 ) = = true ) {
2013-05-08 21:45:39 +00:00
ret = on_action_public_p2p ( precv_frame ) ;
}
return ret ;
}
2014-12-19 04:28:04 +00:00
static unsigned int on_action_public_default ( union recv_frame * precv_frame , u8 action )
2013-05-08 21:45:39 +00:00
{
unsigned int ret = _FAIL ;
u8 * pframe = precv_frame - > u . hdr . rx_data ;
2014-12-11 21:15:04 +00:00
uint frame_len = precv_frame - > u . hdr . len ;
2013-05-08 21:45:39 +00:00
u8 * frame_body = pframe + sizeof ( struct rtw_ieee80211_hdr_3addr ) ;
u8 token ;
2014-12-17 23:13:53 +00:00
struct adapter * adapter = precv_frame - > u . hdr . adapter ;
2014-12-11 21:15:04 +00:00
int cnt = 0 ;
char msg [ 64 ] ;
2013-05-08 21:45:39 +00:00
token = frame_body [ 2 ] ;
if ( rtw_action_public_decache ( precv_frame , token ) = = _FAIL )
goto exit ;
2014-12-11 21:15:04 +00:00
cnt + = sprintf ( ( msg + cnt ) , " %s(token:%u) " , action_public_str ( action ) , token ) ;
rtw_cfg80211_rx_action ( adapter , pframe , frame_len , msg ) ;
2013-05-19 04:28:07 +00:00
2014-12-11 21:15:04 +00:00
ret = _SUCCESS ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
exit :
return ret ;
}
2014-12-17 23:13:53 +00:00
unsigned int on_action_public ( struct adapter * padapter , union recv_frame * precv_frame )
2013-05-08 21:45:39 +00:00
{
unsigned int ret = _FAIL ;
u8 * pframe = precv_frame - > u . hdr . rx_data ;
2014-12-11 21:15:04 +00:00
uint frame_len = precv_frame - > u . hdr . len ;
2013-05-08 21:45:39 +00:00
u8 * frame_body = pframe + sizeof ( struct rtw_ieee80211_hdr_3addr ) ;
u8 category , action ;
/* check RA matches or not */
if ( ! _rtw_memcmp ( myid ( & ( padapter - > eeprompriv ) ) , GetAddr1Ptr ( pframe ) , ETH_ALEN ) )
goto exit ;
category = frame_body [ 0 ] ;
2014-12-11 21:15:04 +00:00
if ( category ! = RTW_WLAN_CATEGORY_PUBLIC )
2013-05-08 21:45:39 +00:00
goto exit ;
action = frame_body [ 1 ] ;
switch ( action ) {
case ACT_PUBLIC_VENDOR :
ret = on_action_public_vendor ( precv_frame ) ;
break ;
default :
ret = on_action_public_default ( precv_frame , action ) ;
break ;
}
exit :
return ret ;
}
2014-12-17 23:13:53 +00:00
unsigned int OnAction_ht ( struct adapter * padapter , union recv_frame * precv_frame )
2014-12-11 21:15:04 +00:00
{
return _SUCCESS ;
}
# ifdef CONFIG_IEEE80211W
2014-12-17 23:13:53 +00:00
unsigned int OnAction_sa_query ( struct adapter * padapter , union recv_frame * precv_frame )
2013-05-08 21:45:39 +00:00
{
2014-12-11 21:15:04 +00:00
u8 * pframe = precv_frame - > u . hdr . rx_data ;
struct rx_pkt_attrib * pattrib = & precv_frame - > u . hdr . attrib ;
struct mlme_ext_priv * pmlmeext = & ( padapter - > mlmeextpriv ) ;
unsigned short tid ;
2015-02-19 21:34:32 +00:00
/* Baron */
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
DBG_871X ( " OnAction_sa_query \n " ) ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
switch ( pframe [ WLAN_HDR_A3_LEN + 1 ] )
{
2015-02-19 21:34:32 +00:00
case 0 : /* SA Query req */
2015-02-19 20:50:04 +00:00
memcpy ( & tid , & pframe [ WLAN_HDR_A3_LEN + 2 ] , sizeof ( unsigned short ) ) ;
2014-12-11 21:15:04 +00:00
DBG_871X ( " OnAction_sa_query request,action=%d, tid=%04x \n " , pframe [ WLAN_HDR_A3_LEN + 1 ] , tid ) ;
issue_action_SA_Query ( padapter , GetAddr2Ptr ( pframe ) , 1 , tid ) ;
break ;
2015-02-19 21:34:32 +00:00
case 1 : /* SA Query rsp */
2014-12-11 21:15:04 +00:00
_cancel_timer_ex ( & pmlmeext - > sa_query_timer ) ;
DBG_871X ( " OnAction_sa_query response,action=%d, tid=%04x, cahcel timer \n " , pframe [ WLAN_HDR_A3_LEN + 1 ] , pframe [ WLAN_HDR_A3_LEN + 2 ] ) ;
break ;
default :
break ;
}
if ( 0 )
{
int pp ;
printk ( " pattrib->pktlen = %d => " , pattrib - > pkt_len ) ;
for ( pp = 0 ; pp < pattrib - > pkt_len ; pp + + )
printk ( " %02x " , pframe [ pp ] ) ;
printk ( " \n " ) ;
2014-12-19 06:59:46 +00:00
}
2013-05-08 21:45:39 +00:00
return _SUCCESS ;
}
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_IEEE80211W */
2013-05-08 21:45:39 +00:00
2014-12-17 23:13:53 +00:00
unsigned int OnAction_wmm ( struct adapter * padapter , union recv_frame * precv_frame )
2013-05-08 21:45:39 +00:00
{
return _SUCCESS ;
}
2014-12-17 23:13:53 +00:00
unsigned int OnAction_p2p ( struct adapter * padapter , union recv_frame * precv_frame )
2013-05-08 21:45:39 +00:00
{
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_P2P
2013-05-08 21:45:39 +00:00
u8 * frame_body ;
2014-12-11 21:15:04 +00:00
u8 category , OUI_Subtype , dialogToken = 0 ;
2013-05-08 21:45:39 +00:00
u8 * pframe = precv_frame - > u . hdr . rx_data ;
uint len = precv_frame - > u . hdr . len ;
2014-12-11 21:15:04 +00:00
struct wifidirect_info * pwdinfo = & ( padapter - > wdinfo ) ;
2014-12-19 06:59:46 +00:00
2013-05-19 04:28:07 +00:00
2014-12-11 21:15:04 +00:00
DBG_871X ( " %s \n " , __FUNCTION__ ) ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* check RA matches or not */
if ( ! _rtw_memcmp ( myid ( & ( padapter - > eeprompriv ) ) , GetAddr1Ptr ( pframe ) , ETH_ALEN ) ) /* for if1, sta/ap mode */
2013-05-08 21:45:39 +00:00
return _SUCCESS ;
frame_body = ( unsigned char * ) ( pframe + sizeof ( struct rtw_ieee80211_hdr_3addr ) ) ;
category = frame_body [ 0 ] ;
2014-12-11 21:15:04 +00:00
if ( category ! = RTW_WLAN_CATEGORY_P2P )
2013-05-08 21:45:39 +00:00
return _SUCCESS ;
2014-12-19 04:28:04 +00:00
if ( be32_to_cpu ( * ( ( __be32 * ) ( frame_body + 1 ) ) ) ! = P2POUI )
2013-05-08 21:45:39 +00:00
return _SUCCESS ;
2014-12-11 21:15:04 +00:00
if ( wdev_to_priv ( padapter - > rtw_wdev ) - > p2p_enabled & & pwdinfo - > driver_interface = = DRIVER_CFG80211 )
{
rtw_cfg80211_rx_action_p2p ( padapter , pframe , len ) ;
return _SUCCESS ;
2015-02-20 04:52:01 +00:00
} else {
2014-12-11 21:15:04 +00:00
len - = sizeof ( struct rtw_ieee80211_hdr_3addr ) ;
OUI_Subtype = frame_body [ 5 ] ;
dialogToken = frame_body [ 6 ] ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
switch ( OUI_Subtype )
{
case P2P_NOTICE_OF_ABSENCE :
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
break ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
case P2P_PRESENCE_REQUEST :
2014-12-19 06:59:46 +00:00
process_p2p_presence_req ( pwdinfo , pframe , len ) ;
2014-12-11 21:15:04 +00:00
break ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
case P2P_PRESENCE_RESPONSE :
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
break ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
case P2P_GO_DISC_REQUEST :
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
break ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
default :
break ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
}
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_P2P */
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
return _SUCCESS ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-17 23:13:53 +00:00
unsigned int OnAction ( struct adapter * padapter , union recv_frame * precv_frame )
2013-05-08 21:45:39 +00:00
{
int i ;
unsigned char category ;
struct action_handler * ptable ;
unsigned char * frame_body ;
2014-12-19 06:59:46 +00:00
u8 * pframe = precv_frame - > u . hdr . rx_data ;
2013-05-08 21:45:39 +00:00
frame_body = ( unsigned char * ) ( pframe + sizeof ( struct rtw_ieee80211_hdr_3addr ) ) ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
category = frame_body [ 0 ] ;
2014-12-19 06:59:46 +00:00
for ( i = 0 ; i < sizeof ( OnAction_tbl ) / sizeof ( struct action_handler ) ; i + + )
2014-12-11 21:15:04 +00:00
{
2013-05-08 21:45:39 +00:00
ptable = & OnAction_tbl [ i ] ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
if ( category = = ptable - > num )
2013-05-08 21:45:39 +00:00
ptable - > func ( padapter , precv_frame ) ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
return _SUCCESS ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-17 23:13:53 +00:00
unsigned int DoReserved ( struct adapter * padapter , union recv_frame * precv_frame )
2013-05-08 21:45:39 +00:00
{
2014-12-11 21:15:04 +00:00
2015-02-19 21:34:32 +00:00
/* DBG_871X("rcvd mgt frame(%x, %x)\n", (GetFrameSubType(pframe) >> 4), *(unsigned int *)GetAddr1Ptr(pframe)); */
2013-05-08 21:45:39 +00:00
return _SUCCESS ;
}
2014-12-19 04:28:04 +00:00
static struct xmit_frame * _alloc_mgtxmitframe ( struct xmit_priv * pxmitpriv , bool once )
2013-05-08 21:45:39 +00:00
{
2014-12-11 21:15:04 +00:00
struct xmit_frame * pmgntframe ;
struct xmit_buf * pxmitbuf ;
if ( once )
pmgntframe = rtw_alloc_xmitframe_once ( pxmitpriv ) ;
else
pmgntframe = rtw_alloc_xmitframe_ext ( pxmitpriv ) ;
2013-05-08 21:45:39 +00:00
2013-08-01 02:12:42 +00:00
if ( pmgntframe = = NULL ) {
2014-12-11 21:15:04 +00:00
DBG_871X ( FUNC_ADPT_FMT " alloc xmitframe fail, once:%d \n " , FUNC_ADPT_ARG ( pxmitpriv - > adapter ) , once ) ;
goto exit ;
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
if ( ( pxmitbuf = rtw_alloc_xmitbuf_ext ( pxmitpriv ) ) = = NULL ) {
DBG_871X ( FUNC_ADPT_FMT " alloc xmitbuf fail \n " , FUNC_ADPT_ARG ( pxmitpriv - > adapter ) ) ;
2013-05-08 21:45:39 +00:00
rtw_free_xmitframe ( pxmitpriv , pmgntframe ) ;
2014-12-11 21:15:04 +00:00
pmgntframe = NULL ;
goto exit ;
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
pmgntframe - > frame_tag = MGNT_FRAMETAG ;
pmgntframe - > pxmitbuf = pxmitbuf ;
pmgntframe - > buf_addr = pxmitbuf - > pbuf ;
pxmitbuf - > priv_data = pmgntframe ;
2014-12-11 21:15:04 +00:00
exit :
2013-05-08 21:45:39 +00:00
return pmgntframe ;
2014-12-11 21:15:04 +00:00
}
inline struct xmit_frame * alloc_mgtxmitframe ( struct xmit_priv * pxmitpriv )
{
2014-12-29 02:13:24 +00:00
return _alloc_mgtxmitframe ( pxmitpriv , false ) ;
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
inline struct xmit_frame * alloc_mgtxmitframe_once ( struct xmit_priv * pxmitpriv )
{
2014-12-29 02:13:24 +00:00
return _alloc_mgtxmitframe ( pxmitpriv , true ) ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
/****************************************************************************
Following are some TX fuctions for WiFi MLME
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2014-12-17 23:13:53 +00:00
void update_mgnt_tx_rate ( struct adapter * padapter , u8 rate )
2013-05-08 21:45:39 +00:00
{
struct mlme_ext_priv * pmlmeext = & ( padapter - > mlmeextpriv ) ;
pmlmeext - > tx_rate = rate ;
2014-12-11 21:15:04 +00:00
DBG_871X ( " %s(): rate = %x \n " , __FUNCTION__ , rate ) ;
2013-05-08 21:45:39 +00:00
}
2014-12-17 23:13:53 +00:00
void update_mgntframe_attrib ( struct adapter * padapter , struct pkt_attrib * pattrib )
2013-05-08 21:45:39 +00:00
{
struct mlme_ext_priv * pmlmeext = & ( padapter - > mlmeextpriv ) ;
2015-02-19 20:58:09 +00:00
memset ( ( u8 * ) ( pattrib ) , 0 , sizeof ( struct pkt_attrib ) ) ;
2013-05-08 21:45:39 +00:00
pattrib - > hdrlen = 24 ;
pattrib - > nr_frags = 1 ;
pattrib - > priority = 7 ;
pattrib - > mac_id = 0 ;
pattrib - > qsel = 0x12 ;
pattrib - > pktlen = 0 ;
2014-12-11 21:15:04 +00:00
if ( pmlmeext - > cur_wireless_mode & WIRELESS_11B )
2015-02-19 21:34:32 +00:00
pattrib - > raid = 6 ; /* b mode */
2013-05-08 21:45:39 +00:00
else
2015-02-19 21:34:32 +00:00
pattrib - > raid = 5 ; /* a/g mode */
2013-05-08 21:45:39 +00:00
pattrib - > encrypt = _NO_PRIVACY_ ;
2014-12-29 02:13:24 +00:00
pattrib - > bswenc = false ;
2013-05-08 21:45:39 +00:00
2014-12-29 02:13:24 +00:00
pattrib - > qos_en = false ;
pattrib - > ht_en = false ;
2013-05-08 21:45:39 +00:00
pattrib - > bwmode = HT_CHANNEL_WIDTH_20 ;
pattrib - > ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE ;
2014-12-29 02:13:24 +00:00
pattrib - > sgi = false ;
2013-05-08 21:45:39 +00:00
pattrib - > seqnum = pmlmeext - > mgnt_seq ;
2014-12-29 02:13:24 +00:00
pattrib - > retry_ctrl = true ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-17 23:13:53 +00:00
void dump_mgntframe ( struct adapter * padapter , struct xmit_frame * pmgntframe )
2013-05-08 21:45:39 +00:00
{
2014-12-29 02:13:24 +00:00
if ( padapter - > bSurpriseRemoved = = true | |
padapter - > bDriverStopped = = true )
2014-12-11 21:15:04 +00:00
{
rtw_free_xmitbuf ( & padapter - > xmitpriv , pmgntframe - > pxmitbuf ) ;
rtw_free_xmitframe ( & padapter - > xmitpriv , pmgntframe ) ;
2013-05-08 21:45:39 +00:00
return ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
rtw_hal_mgnt_xmit ( padapter , pmgntframe ) ;
}
2014-12-17 23:13:53 +00:00
s32 dump_mgntframe_and_wait ( struct adapter * padapter , struct xmit_frame * pmgntframe , int timeout_ms )
2013-05-08 21:45:39 +00:00
{
s32 ret = _FAIL ;
2014-12-11 21:15:04 +00:00
_irqL irqL ;
2014-12-19 06:59:46 +00:00
struct xmit_priv * pxmitpriv = & padapter - > xmitpriv ;
2013-05-08 21:45:39 +00:00
struct xmit_buf * pxmitbuf = pmgntframe - > pxmitbuf ;
struct submit_ctx sctx ;
2014-12-29 02:13:24 +00:00
if ( padapter - > bSurpriseRemoved = = true | |
padapter - > bDriverStopped = = true )
2014-12-11 21:15:04 +00:00
{
rtw_free_xmitbuf ( & padapter - > xmitpriv , pmgntframe - > pxmitbuf ) ;
rtw_free_xmitframe ( & padapter - > xmitpriv , pmgntframe ) ;
2013-05-08 21:45:39 +00:00
return ret ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
rtw_sctx_init ( & sctx , timeout_ms ) ;
pxmitbuf - > sctx = & sctx ;
ret = rtw_hal_mgnt_xmit ( padapter , pmgntframe ) ;
if ( ret = = _SUCCESS )
ret = rtw_sctx_wait ( & sctx ) ;
2014-12-11 21:15:04 +00:00
_enter_critical ( & pxmitpriv - > lock_sctx , & irqL ) ;
pxmitbuf - > sctx = NULL ;
_exit_critical ( & pxmitpriv - > lock_sctx , & irqL ) ;
2013-05-08 21:45:39 +00:00
return ret ;
}
2014-12-17 23:13:53 +00:00
s32 dump_mgntframe_and_wait_ack ( struct adapter * padapter , struct xmit_frame * pmgntframe )
2013-05-08 21:45:39 +00:00
{
s32 ret = _FAIL ;
2015-02-19 21:34:32 +00:00
u32 timeout_ms = 500 ; /* 500ms */
2013-05-08 21:45:39 +00:00
struct xmit_priv * pxmitpriv = & padapter - > xmitpriv ;
2014-12-19 06:59:46 +00:00
2014-12-29 02:13:24 +00:00
if ( padapter - > bSurpriseRemoved = = true | |
padapter - > bDriverStopped = = true )
2014-12-11 21:15:04 +00:00
{
rtw_free_xmitbuf ( & padapter - > xmitpriv , pmgntframe - > pxmitbuf ) ;
rtw_free_xmitframe ( & padapter - > xmitpriv , pmgntframe ) ;
2013-05-08 21:45:39 +00:00
return - 1 ;
2014-12-19 06:59:46 +00:00
}
2013-05-08 21:45:39 +00:00
_enter_critical_mutex ( & pxmitpriv - > ack_tx_mutex , NULL ) ;
2014-12-29 02:13:24 +00:00
pxmitpriv - > ack_tx = true ;
2013-05-08 21:45:39 +00:00
pmgntframe - > ack_report = 1 ;
if ( rtw_hal_mgnt_xmit ( padapter , pmgntframe ) = = _SUCCESS ) {
ret = rtw_ack_tx_wait ( pxmitpriv , timeout_ms ) ;
}
2014-12-29 02:13:24 +00:00
pxmitpriv - > ack_tx = false ;
2013-05-08 21:45:39 +00:00
_exit_critical_mutex ( & pxmitpriv - > ack_tx_mutex , NULL ) ;
return ret ;
}
2014-12-19 04:28:04 +00:00
static int update_hidden_ssid ( u8 * ies , u32 ies_len , u8 hidden_ssid_mode )
2013-05-08 21:45:39 +00:00
{
u8 * ssid_ie ;
2014-12-11 21:15:04 +00:00
sint ssid_len_ori ;
2013-05-08 21:45:39 +00:00
int len_diff = 0 ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
ssid_ie = rtw_get_ie ( ies , WLAN_EID_SSID , & ssid_len_ori , ies_len ) ;
2014-12-11 21:15:04 +00:00
if ( ssid_ie & & ssid_len_ori > 0 )
{
switch ( hidden_ssid_mode )
{
case 1 :
{
u8 * next_ie = ssid_ie + 2 + ssid_len_ori ;
u32 remain_len = 0 ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
remain_len = ies_len - ( next_ie - ies ) ;
2014-12-19 06:59:46 +00:00
ssid_ie [ 1 ] = 0 ;
2015-02-19 20:50:04 +00:00
memcpy ( ssid_ie + 2 , next_ie , remain_len ) ;
2014-12-11 21:15:04 +00:00
len_diff - = ssid_len_ori ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
break ;
2014-12-19 06:59:46 +00:00
}
2014-12-11 21:15:04 +00:00
case 2 :
2015-02-19 20:58:09 +00:00
memset ( & ssid_ie [ 2 ] , 0 , ssid_len_ori ) ;
2014-12-11 21:15:04 +00:00
break ;
default :
break ;
2013-05-08 21:45:39 +00:00
}
}
return len_diff ;
}
2014-12-17 23:13:53 +00:00
void issue_beacon ( struct adapter * padapter , int timeout_ms )
2013-05-08 21:45:39 +00:00
{
struct xmit_frame * pmgntframe ;
struct pkt_attrib * pattrib ;
unsigned char * pframe ;
struct rtw_ieee80211_hdr * pwlanhdr ;
2014-12-19 04:28:04 +00:00
__le16 * fctrl ;
2013-05-08 21:45:39 +00:00
unsigned int rate_len ;
struct xmit_priv * pxmitpriv = & ( padapter - > xmitpriv ) ;
2015-02-20 15:52:14 +00:00
# if defined (CONFIG_AP_MODE)
2014-12-11 21:15:04 +00:00
_irqL irqL ;
2013-05-08 21:45:39 +00:00
struct mlme_priv * pmlmepriv = & ( padapter - > mlmepriv ) ;
2015-02-20 15:52:14 +00:00
# endif /* if defined (CONFIG_AP_MODE) */
2013-05-08 21:45:39 +00:00
struct mlme_ext_priv * pmlmeext = & ( padapter - > mlmeextpriv ) ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
2014-12-19 06:59:46 +00:00
WLAN_BSSID_EX * cur_network = & ( pmlmeinfo - > network ) ;
2013-05-08 21:45:39 +00:00
u8 bc_addr [ ] = { 0xff , 0xff , 0xff , 0xff , 0xff , 0xff } ;
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_P2P
2013-05-08 21:45:39 +00:00
struct wifidirect_info * pwdinfo = & ( padapter - > wdinfo ) ;
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_P2P */
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
2015-02-19 21:34:32 +00:00
/* DBG_871X("%s\n", __FUNCTION__); */
2014-12-11 21:15:04 +00:00
if ( ( pmgntframe = alloc_mgtxmitframe ( pxmitpriv ) ) = = NULL )
{
DBG_871X ( " %s, alloc mgnt frame fail \n " , __FUNCTION__ ) ;
2013-05-08 21:45:39 +00:00
return ;
}
2015-02-20 15:52:14 +00:00
# if defined (CONFIG_AP_MODE)
2014-12-11 21:15:04 +00:00
_enter_critical_bh ( & pmlmepriv - > bcn_update_lock , & irqL ) ;
2015-02-20 15:52:14 +00:00
# endif /* if defined (CONFIG_AP_MODE) */
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* update attribute */
2013-05-08 21:45:39 +00:00
pattrib = & pmgntframe - > attrib ;
update_mgntframe_attrib ( padapter , pattrib ) ;
pattrib - > qsel = 0x10 ;
2014-12-19 06:59:46 +00:00
2015-02-19 20:58:09 +00:00
memset ( pmgntframe - > buf_addr , 0 , WLANHDR_OFFSET + TXDESC_OFFSET ) ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
pframe = ( u8 * ) ( pmgntframe - > buf_addr ) + TXDESC_OFFSET ;
2014-12-19 06:59:46 +00:00
pwlanhdr = ( struct rtw_ieee80211_hdr * ) pframe ;
2013-05-08 21:45:39 +00:00
fctrl = & ( pwlanhdr - > frame_ctl ) ;
* ( fctrl ) = 0 ;
2014-12-19 06:59:46 +00:00
2015-02-19 20:50:04 +00:00
memcpy ( pwlanhdr - > addr1 , bc_addr , ETH_ALEN ) ;
memcpy ( pwlanhdr - > addr2 , myid ( & ( padapter - > eeprompriv ) ) , ETH_ALEN ) ;
memcpy ( pwlanhdr - > addr3 , get_my_bssid ( cur_network ) , ETH_ALEN ) ;
2013-05-08 21:45:39 +00:00
SetSeqNum ( pwlanhdr , 0 /*pmlmeext->mgnt_seq*/ ) ;
2015-02-19 21:34:32 +00:00
/* pmlmeext->mgnt_seq++; */
2013-05-08 21:45:39 +00:00
SetFrameSubType ( pframe , WIFI_BEACON ) ;
2014-12-19 06:59:46 +00:00
pframe + = sizeof ( struct rtw_ieee80211_hdr_3addr ) ;
2013-05-08 21:45:39 +00:00
pattrib - > pktlen = sizeof ( struct rtw_ieee80211_hdr_3addr ) ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
if ( ( pmlmeinfo - > state & 0x03 ) = = WIFI_FW_AP_STATE )
{
2015-02-19 21:34:32 +00:00
/* DBG_871X("ie len=%d\n", cur_network->IELength); */
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_P2P
2015-02-19 21:34:32 +00:00
/* for P2P : Primary Device Type & Device Name */
2014-12-11 21:15:04 +00:00
u32 wpsielen = 0 , insert_len = 0 ;
2014-12-19 06:59:46 +00:00
u8 * wpsie = NULL ;
2013-05-08 21:45:39 +00:00
wpsie = rtw_get_wps_ie ( cur_network - > IEs + _FIXED_IE_LENGTH_ , cur_network - > IELength - _FIXED_IE_LENGTH_ , NULL , & wpsielen ) ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
if ( rtw_p2p_chk_role ( pwdinfo , P2P_ROLE_GO ) & & wpsie & & wpsielen > 0 )
{
2013-05-08 21:45:39 +00:00
uint wps_offset , remainder_ielen ;
u8 * premainder_ie , * pframe_wscie ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
wps_offset = ( uint ) ( wpsie - cur_network - > IEs ) ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
premainder_ie = wpsie + wpsielen ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
remainder_ielen = cur_network - > IELength - wps_offset - wpsielen ;
2014-12-11 21:15:04 +00:00
if ( wdev_to_priv ( padapter - > rtw_wdev ) - > p2p_enabled & & pwdinfo - > driver_interface = = DRIVER_CFG80211 )
{
if ( pmlmepriv - > wps_beacon_ie & & pmlmepriv - > wps_beacon_ie_len > 0 )
{
2015-02-19 20:50:04 +00:00
memcpy ( pframe , cur_network - > IEs , wps_offset ) ;
2014-12-11 21:15:04 +00:00
pframe + = wps_offset ;
pattrib - > pktlen + = wps_offset ;
2015-02-19 20:50:04 +00:00
memcpy ( pframe , pmlmepriv - > wps_beacon_ie , pmlmepriv - > wps_beacon_ie_len ) ;
2014-12-11 21:15:04 +00:00
pframe + = pmlmepriv - > wps_beacon_ie_len ;
pattrib - > pktlen + = pmlmepriv - > wps_beacon_ie_len ;
2015-02-19 21:34:32 +00:00
/* copy remainder_ie to pframe */
2015-02-19 20:50:04 +00:00
memcpy ( pframe , premainder_ie , remainder_ielen ) ;
2014-12-19 06:59:46 +00:00
pframe + = remainder_ielen ;
2014-12-11 21:15:04 +00:00
pattrib - > pktlen + = remainder_ielen ;
}
else
{
2015-02-19 20:50:04 +00:00
memcpy ( pframe , cur_network - > IEs , cur_network - > IELength ) ;
2014-12-11 21:15:04 +00:00
pframe + = cur_network - > IELength ;
pattrib - > pktlen + = cur_network - > IELength ;
}
2015-02-20 04:52:01 +00:00
} else {
2014-12-11 21:15:04 +00:00
pframe_wscie = pframe + wps_offset ;
2015-02-19 20:50:04 +00:00
memcpy ( pframe , cur_network - > IEs , wps_offset + wpsielen ) ;
2014-12-19 06:59:46 +00:00
pframe + = ( wps_offset + wpsielen ) ;
2014-12-11 21:15:04 +00:00
pattrib - > pktlen + = ( wps_offset + wpsielen ) ;
2015-02-19 21:34:32 +00:00
/* now pframe is end of wsc ie, insert Primary Device Type & Device Name */
/* Primary Device Type */
/* Type: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( pframe + insert_len ) = cpu_to_be16 ( WPS_ATTR_PRIMARY_DEV_TYPE ) ;
2014-12-11 21:15:04 +00:00
insert_len + = 2 ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( pframe + insert_len ) = cpu_to_be16 ( 0x0008 ) ;
2014-12-11 21:15:04 +00:00
insert_len + = 2 ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* Value: */
/* Category ID */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( pframe + insert_len ) = cpu_to_be16 ( WPS_PDT_CID_MULIT_MEDIA ) ;
2014-12-11 21:15:04 +00:00
insert_len + = 2 ;
2015-02-19 21:34:32 +00:00
/* OUI */
2014-12-19 04:28:04 +00:00
* ( __be32 * ) ( pframe + insert_len ) = cpu_to_be32 ( WPSOUI ) ;
2014-12-11 21:15:04 +00:00
insert_len + = 4 ;
2015-02-19 21:34:32 +00:00
/* Sub Category ID */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( pframe + insert_len ) = cpu_to_be16 ( WPS_PDT_SCID_MEDIA_SERVER ) ;
2014-12-11 21:15:04 +00:00
insert_len + = 2 ;
2015-02-19 21:34:32 +00:00
/* Device Name */
/* Type: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( pframe + insert_len ) = cpu_to_be16 ( WPS_ATTR_DEVICE_NAME ) ;
2014-12-11 21:15:04 +00:00
insert_len + = 2 ;
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( pframe + insert_len ) = cpu_to_be16 ( pwdinfo - > device_name_len ) ;
2014-12-11 21:15:04 +00:00
insert_len + = 2 ;
2015-02-19 21:34:32 +00:00
/* Value: */
2015-02-19 20:50:04 +00:00
memcpy ( pframe + insert_len , pwdinfo - > device_name , pwdinfo - > device_name_len ) ;
2014-12-11 21:15:04 +00:00
insert_len + = pwdinfo - > device_name_len ;
2015-02-19 21:34:32 +00:00
/* update wsc ie length */
2014-12-11 21:15:04 +00:00
* ( pframe_wscie + 1 ) = ( wpsielen - 2 ) + insert_len ;
2015-02-19 21:34:32 +00:00
/* pframe move to end */
2014-12-11 21:15:04 +00:00
pframe + = insert_len ;
pattrib - > pktlen + = insert_len ;
2015-02-19 21:34:32 +00:00
/* copy remainder_ie to pframe */
2015-02-19 20:50:04 +00:00
memcpy ( pframe , premainder_ie , remainder_ielen ) ;
2014-12-19 06:59:46 +00:00
pframe + = remainder_ielen ;
2014-12-11 21:15:04 +00:00
pattrib - > pktlen + = remainder_ielen ;
}
}
else
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_P2P */
2013-05-08 21:45:39 +00:00
{
int len_diff ;
2015-02-19 20:50:04 +00:00
memcpy ( pframe , cur_network - > IEs , cur_network - > IELength ) ;
2013-05-08 21:45:39 +00:00
len_diff = update_hidden_ssid (
pframe + _BEACON_IE_OFFSET_
, cur_network - > IELength - _BEACON_IE_OFFSET_
, pmlmeinfo - > hidden_ssid_mode
) ;
pframe + = ( cur_network - > IELength + len_diff ) ;
pattrib - > pktlen + = ( cur_network - > IELength + len_diff ) ;
}
{
u8 * wps_ie ;
uint wps_ielen ;
u8 sr = 0 ;
wps_ie = rtw_get_wps_ie ( pmgntframe - > buf_addr + TXDESC_OFFSET + sizeof ( struct rtw_ieee80211_hdr_3addr ) + _BEACON_IE_OFFSET_ ,
pattrib - > pktlen - sizeof ( struct rtw_ieee80211_hdr_3addr ) - _BEACON_IE_OFFSET_ , NULL , & wps_ielen ) ;
2014-12-11 21:15:04 +00:00
if ( wps_ie & & wps_ielen > 0 ) {
rtw_get_wps_attr_content ( wps_ie , wps_ielen , WPS_ATTR_SELECTED_REGISTRAR , ( u8 * ) ( & sr ) , NULL ) ;
}
2013-05-08 21:45:39 +00:00
if ( sr ! = 0 )
set_fwstate ( pmlmepriv , WIFI_UNDER_WPS ) ;
else
_clr_fwstate_ ( pmlmepriv , WIFI_UNDER_WPS ) ;
}
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_P2P
if ( rtw_p2p_chk_role ( pwdinfo , P2P_ROLE_GO ) )
{
2013-05-08 21:45:39 +00:00
u32 len ;
2014-12-11 21:15:04 +00:00
if ( wdev_to_priv ( padapter - > rtw_wdev ) - > p2p_enabled & & pwdinfo - > driver_interface = = DRIVER_CFG80211 )
{
len = pmlmepriv - > p2p_beacon_ie_len ;
2014-12-19 06:59:46 +00:00
if ( pmlmepriv - > p2p_beacon_ie & & len > 0 )
2015-02-19 20:50:04 +00:00
memcpy ( pframe , pmlmepriv - > p2p_beacon_ie , len ) ;
2015-02-20 04:52:01 +00:00
} else {
2014-12-11 21:15:04 +00:00
len = build_beacon_p2p_ie ( pwdinfo , pframe ) ;
}
2013-05-08 21:45:39 +00:00
pframe + = len ;
pattrib - > pktlen + = len ;
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_WFD
2015-02-20 04:52:01 +00:00
if ( pwdinfo - > wfd_info - > wfd_enable ) {
2014-12-11 21:15:04 +00:00
len = build_beacon_wfd_ie ( pwdinfo , pframe ) ;
2015-02-20 04:52:01 +00:00
} else {
2014-12-11 21:15:04 +00:00
len = 0 ;
if ( pmlmepriv - > wfd_beacon_ie & & pmlmepriv - > wfd_beacon_ie_len > 0 )
{
len = pmlmepriv - > wfd_beacon_ie_len ;
2015-02-19 20:50:04 +00:00
memcpy ( pframe , pmlmepriv - > wfd_beacon_ie , len ) ;
2014-12-11 21:15:04 +00:00
}
2014-12-19 06:59:46 +00:00
}
2014-12-11 21:15:04 +00:00
pframe + = len ;
pattrib - > pktlen + = len ;
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_WFD */
2013-05-08 21:45:39 +00:00
}
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_P2P */
2013-05-08 21:45:39 +00:00
goto _issue_bcn ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
}
2015-02-19 21:34:32 +00:00
/* below for ad-hoc mode */
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* timestamp will be inserted by hardware */
2013-05-08 21:45:39 +00:00
pframe + = 8 ;
pattrib - > pktlen + = 8 ;
2015-02-19 21:34:32 +00:00
/* beacon interval: 2 bytes */
2013-05-08 21:45:39 +00:00
2015-02-19 20:50:04 +00:00
memcpy ( pframe , ( unsigned char * ) ( rtw_get_beacon_interval_from_ie ( cur_network - > IEs ) ) , 2 ) ;
2013-05-08 21:45:39 +00:00
pframe + = 2 ;
pattrib - > pktlen + = 2 ;
2015-02-19 21:34:32 +00:00
/* capability info: 2 bytes */
2013-05-08 21:45:39 +00:00
2015-02-19 20:50:04 +00:00
memcpy ( pframe , ( unsigned char * ) ( rtw_get_capability_from_ie ( cur_network - > IEs ) ) , 2 ) ;
2013-05-08 21:45:39 +00:00
pframe + = 2 ;
pattrib - > pktlen + = 2 ;
2015-02-19 21:34:32 +00:00
/* SSID */
2013-05-08 21:45:39 +00:00
pframe = rtw_set_ie ( pframe , _SSID_IE_ , cur_network - > Ssid . SsidLength , cur_network - > Ssid . Ssid , & pattrib - > pktlen ) ;
2015-02-19 21:34:32 +00:00
/* supported rates... */
2013-05-08 21:45:39 +00:00
rate_len = rtw_get_rateset_len ( cur_network - > SupportedRates ) ;
2014-12-11 21:15:04 +00:00
pframe = rtw_set_ie ( pframe , _SUPPORTEDRATES_IE_ , ( ( rate_len > 8 ) ? 8 : rate_len ) , cur_network - > SupportedRates , & pattrib - > pktlen ) ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* DS parameter set */
2013-05-08 21:45:39 +00:00
pframe = rtw_set_ie ( pframe , _DSSET_IE_ , 1 , ( unsigned char * ) & ( cur_network - > Configuration . DSConfig ) , & pattrib - > pktlen ) ;
2015-02-19 21:34:32 +00:00
/* if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) */
2013-05-08 21:45:39 +00:00
{
2014-12-11 21:15:04 +00:00
u8 erpinfo = 0 ;
2013-05-08 21:45:39 +00:00
u32 ATIMWindow ;
2015-02-19 21:34:32 +00:00
/* IBSS Parameter Set... */
/* ATIMWindow = cur->Configuration.ATIMWindow; */
2013-05-08 21:45:39 +00:00
ATIMWindow = 0 ;
pframe = rtw_set_ie ( pframe , _IBSS_PARA_IE_ , 2 , ( unsigned char * ) ( & ATIMWindow ) , & pattrib - > pktlen ) ;
2015-02-19 21:34:32 +00:00
/* ERP IE */
2013-05-08 21:45:39 +00:00
pframe = rtw_set_ie ( pframe , _ERPINFO_IE_ , 1 , & erpinfo , & pattrib - > pktlen ) ;
2014-12-19 06:59:46 +00:00
}
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* EXTERNDED SUPPORTED RATE */
2013-05-08 21:45:39 +00:00
if ( rate_len > 8 )
2014-12-11 21:15:04 +00:00
{
2013-05-08 21:45:39 +00:00
pframe = rtw_set_ie ( pframe , _EXT_SUPPORTEDRATES_IE_ , ( rate_len - 8 ) , ( cur_network - > SupportedRates + 8 ) , & pattrib - > pktlen ) ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* todo:HT for adhoc */
2013-05-19 04:28:07 +00:00
2014-12-11 21:15:04 +00:00
_issue_bcn :
2015-02-20 15:52:14 +00:00
# if defined (CONFIG_AP_MODE)
2014-12-29 02:13:24 +00:00
pmlmepriv - > update_bcn = false ;
2014-12-19 06:59:46 +00:00
_exit_critical_bh ( & pmlmepriv - > bcn_update_lock , & irqL ) ;
2015-02-20 15:52:14 +00:00
# endif /* if defined (CONFIG_AP_MODE) */
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
if ( ( pattrib - > pktlen + TXDESC_SIZE ) > 512 )
{
DBG_871X ( " beacon frame too large \n " ) ;
2013-05-08 21:45:39 +00:00
return ;
}
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
pattrib - > last_txcmdsz = pattrib - > pktlen ;
2015-02-19 21:34:32 +00:00
/* DBG_871X("issue bcn_sz=%d\n", pattrib->last_txcmdsz); */
2014-12-11 21:15:04 +00:00
if ( timeout_ms > 0 )
2013-05-08 21:45:39 +00:00
dump_mgntframe_and_wait ( padapter , pmgntframe , timeout_ms ) ;
else
dump_mgntframe ( padapter , pmgntframe ) ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-17 23:13:53 +00:00
void issue_probersp ( struct adapter * padapter , unsigned char * da , u8 is_valid_p2p_probereq )
2013-05-08 21:45:39 +00:00
{
struct xmit_frame * pmgntframe ;
struct pkt_attrib * pattrib ;
unsigned char * pframe ;
struct rtw_ieee80211_hdr * pwlanhdr ;
2014-12-19 06:59:46 +00:00
__le16 * fctrl ;
2013-05-08 21:45:39 +00:00
unsigned char * mac , * bssid ;
struct xmit_priv * pxmitpriv = & ( padapter - > xmitpriv ) ;
2015-02-20 15:52:14 +00:00
# if defined (CONFIG_AP_MODE)
2013-05-08 21:45:39 +00:00
u8 * pwps_ie ;
uint wps_ielen ;
struct mlme_priv * pmlmepriv = & padapter - > mlmepriv ;
2015-02-20 15:52:14 +00:00
# endif /* if defined (CONFIG_AP_MODE) */
2013-05-08 21:45:39 +00:00
struct mlme_ext_priv * pmlmeext = & ( padapter - > mlmeextpriv ) ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
2014-12-19 06:59:46 +00:00
WLAN_BSSID_EX * cur_network = & ( pmlmeinfo - > network ) ;
2013-05-08 21:45:39 +00:00
unsigned int rate_len ;
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_P2P
2013-05-08 21:45:39 +00:00
struct wifidirect_info * pwdinfo = & ( padapter - > wdinfo ) ;
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_WFD
u32 wfdielen = 0 ;
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_WFD */
# endif /* CONFIG_P2P */
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* DBG_871X("%s\n", __FUNCTION__); */
2014-12-11 21:15:04 +00:00
if ( ( pmgntframe = alloc_mgtxmitframe ( pxmitpriv ) ) = = NULL )
{
DBG_871X ( " %s, alloc mgnt frame fail \n " , __FUNCTION__ ) ;
2013-05-08 21:45:39 +00:00
return ;
}
2013-05-19 04:28:07 +00:00
2015-02-19 21:34:32 +00:00
/* update attribute */
2014-12-11 21:15:04 +00:00
pattrib = & pmgntframe - > attrib ;
2014-12-19 06:59:46 +00:00
update_mgntframe_attrib ( padapter , pattrib ) ;
2015-02-19 20:58:09 +00:00
memset ( pmgntframe - > buf_addr , 0 , WLANHDR_OFFSET + TXDESC_OFFSET ) ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
pframe = ( u8 * ) ( pmgntframe - > buf_addr ) + TXDESC_OFFSET ;
2014-12-19 06:59:46 +00:00
pwlanhdr = ( struct rtw_ieee80211_hdr * ) pframe ;
2013-05-08 21:45:39 +00:00
mac = myid ( & ( padapter - > eeprompriv ) ) ;
bssid = cur_network - > MacAddress ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
fctrl = & ( pwlanhdr - > frame_ctl ) ;
* ( fctrl ) = 0 ;
2015-02-19 20:50:04 +00:00
memcpy ( pwlanhdr - > addr1 , da , ETH_ALEN ) ;
memcpy ( pwlanhdr - > addr2 , mac , ETH_ALEN ) ;
memcpy ( pwlanhdr - > addr3 , bssid , ETH_ALEN ) ;
2013-05-08 21:45:39 +00:00
SetSeqNum ( pwlanhdr , pmlmeext - > mgnt_seq ) ;
pmlmeext - > mgnt_seq + + ;
SetFrameSubType ( fctrl , WIFI_PROBERSP ) ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
pattrib - > hdrlen = sizeof ( struct rtw_ieee80211_hdr_3addr ) ;
pattrib - > pktlen = pattrib - > hdrlen ;
pframe + = pattrib - > hdrlen ;
2013-05-19 04:28:07 +00:00
2014-12-11 21:15:04 +00:00
if ( cur_network - > IELength > MAX_IE_SZ )
return ;
2014-12-19 06:59:46 +00:00
2015-02-20 15:52:14 +00:00
# if defined (CONFIG_AP_MODE)
2014-12-11 21:15:04 +00:00
if ( ( pmlmeinfo - > state & 0x03 ) = = WIFI_FW_AP_STATE )
{
2013-05-08 21:45:39 +00:00
pwps_ie = rtw_get_wps_ie ( cur_network - > IEs + _FIXED_IE_LENGTH_ , cur_network - > IELength - _FIXED_IE_LENGTH_ , NULL , & wps_ielen ) ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* inerset & update wps_probe_resp_ie */
2014-12-11 21:15:04 +00:00
if ( ( pmlmepriv - > wps_probe_resp_ie ! = NULL ) & & pwps_ie & & ( wps_ielen > 0 ) )
{
2013-05-08 21:45:39 +00:00
uint wps_offset , remainder_ielen ;
2014-12-19 06:59:46 +00:00
u8 * premainder_ie ;
2013-05-08 21:45:39 +00:00
wps_offset = ( uint ) ( pwps_ie - cur_network - > IEs ) ;
premainder_ie = pwps_ie + wps_ielen ;
remainder_ielen = cur_network - > IELength - wps_offset - wps_ielen ;
2015-02-19 20:50:04 +00:00
memcpy ( pframe , cur_network - > IEs , wps_offset ) ;
2014-12-19 06:59:46 +00:00
pframe + = wps_offset ;
pattrib - > pktlen + = wps_offset ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
wps_ielen = ( uint ) pmlmepriv - > wps_probe_resp_ie [ 1 ] ; /* to get ie data len */
2014-12-11 21:15:04 +00:00
if ( ( wps_offset + wps_ielen + 2 ) < = MAX_IE_SZ )
{
2015-02-19 20:50:04 +00:00
memcpy ( pframe , pmlmepriv - > wps_probe_resp_ie , wps_ielen + 2 ) ;
2014-12-19 06:59:46 +00:00
pframe + = wps_ielen + 2 ;
pattrib - > pktlen + = wps_ielen + 2 ;
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
if ( ( wps_offset + wps_ielen + 2 + remainder_ielen ) < = MAX_IE_SZ )
{
2015-02-19 20:50:04 +00:00
memcpy ( pframe , premainder_ie , remainder_ielen ) ;
2014-12-19 06:59:46 +00:00
pframe + = remainder_ielen ;
pattrib - > pktlen + = remainder_ielen ;
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
}
else
{
2015-02-19 20:50:04 +00:00
memcpy ( pframe , cur_network - > IEs , cur_network - > IELength ) ;
2013-05-08 21:45:39 +00:00
pframe + = cur_network - > IELength ;
pattrib - > pktlen + = cur_network - > IELength ;
}
2014-12-11 21:15:04 +00:00
/* retrieve SSID IE from cur_network->Ssid */
{
u8 * ssid_ie ;
sint ssid_ielen ;
sint ssid_ielen_diff ;
u8 buf [ MAX_IE_SZ ] ;
u8 * ies = pmgntframe - > buf_addr + TXDESC_OFFSET + sizeof ( struct rtw_ieee80211_hdr_3addr ) ;
ssid_ie = rtw_get_ie ( ies + _FIXED_IE_LENGTH_ , _SSID_IE_ , & ssid_ielen ,
( pframe - ies ) - _FIXED_IE_LENGTH_ ) ;
ssid_ielen_diff = cur_network - > Ssid . SsidLength - ssid_ielen ;
if ( ssid_ie & & cur_network - > Ssid . SsidLength ) {
uint remainder_ielen ;
u8 * remainder_ie ;
remainder_ie = ssid_ie + 2 ;
remainder_ielen = ( pframe - remainder_ie ) ;
DBG_871X_LEVEL ( _drv_warning_ , FUNC_ADPT_FMT " remainder_ielen > MAX_IE_SZ \n " , FUNC_ADPT_ARG ( padapter ) ) ;
if ( remainder_ielen > MAX_IE_SZ ) {
remainder_ielen = MAX_IE_SZ ;
}
2015-02-19 20:50:04 +00:00
memcpy ( buf , remainder_ie , remainder_ielen ) ;
memcpy ( remainder_ie + ssid_ielen_diff , buf , remainder_ielen ) ;
2014-12-11 21:15:04 +00:00
* ( ssid_ie + 1 ) = cur_network - > Ssid . SsidLength ;
2015-02-19 20:50:04 +00:00
memcpy ( ssid_ie + 2 , cur_network - > Ssid . Ssid , cur_network - > Ssid . SsidLength ) ;
2014-12-11 21:15:04 +00:00
pframe + = ssid_ielen_diff ;
pattrib - > pktlen + = ssid_ielen_diff ;
}
}
2014-12-19 06:59:46 +00:00
}
else
# endif
2013-05-08 21:45:39 +00:00
{
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* timestamp will be inserted by hardware */
2013-05-08 21:45:39 +00:00
pframe + = 8 ;
pattrib - > pktlen + = 8 ;
2015-02-19 21:34:32 +00:00
/* beacon interval: 2 bytes */
2013-05-08 21:45:39 +00:00
2015-02-19 20:50:04 +00:00
memcpy ( pframe , ( unsigned char * ) ( rtw_get_beacon_interval_from_ie ( cur_network - > IEs ) ) , 2 ) ;
2013-05-08 21:45:39 +00:00
pframe + = 2 ;
pattrib - > pktlen + = 2 ;
2015-02-19 21:34:32 +00:00
/* capability info: 2 bytes */
2013-05-08 21:45:39 +00:00
2015-02-19 20:50:04 +00:00
memcpy ( pframe , ( unsigned char * ) ( rtw_get_capability_from_ie ( cur_network - > IEs ) ) , 2 ) ;
2013-05-08 21:45:39 +00:00
pframe + = 2 ;
pattrib - > pktlen + = 2 ;
2015-02-19 21:34:32 +00:00
/* below for ad-hoc mode */
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* SSID */
2013-05-08 21:45:39 +00:00
pframe = rtw_set_ie ( pframe , _SSID_IE_ , cur_network - > Ssid . SsidLength , cur_network - > Ssid . Ssid , & pattrib - > pktlen ) ;
2015-02-19 21:34:32 +00:00
/* supported rates... */
2013-05-08 21:45:39 +00:00
rate_len = rtw_get_rateset_len ( cur_network - > SupportedRates ) ;
2014-12-11 21:15:04 +00:00
pframe = rtw_set_ie ( pframe , _SUPPORTEDRATES_IE_ , ( ( rate_len > 8 ) ? 8 : rate_len ) , cur_network - > SupportedRates , & pattrib - > pktlen ) ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* DS parameter set */
2014-12-11 21:15:04 +00:00
pframe = rtw_set_ie ( pframe , _DSSET_IE_ , 1 , ( unsigned char * ) & ( cur_network - > Configuration . DSConfig ) , & pattrib - > pktlen ) ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
if ( ( pmlmeinfo - > state & 0x03 ) = = WIFI_FW_ADHOC_STATE )
{
u8 erpinfo = 0 ;
2013-05-08 21:45:39 +00:00
u32 ATIMWindow ;
2015-02-19 21:34:32 +00:00
/* IBSS Parameter Set... */
/* ATIMWindow = cur->Configuration.ATIMWindow; */
2013-05-08 21:45:39 +00:00
ATIMWindow = 0 ;
pframe = rtw_set_ie ( pframe , _IBSS_PARA_IE_ , 2 , ( unsigned char * ) ( & ATIMWindow ) , & pattrib - > pktlen ) ;
2015-02-19 21:34:32 +00:00
/* ERP IE */
2013-05-08 21:45:39 +00:00
pframe = rtw_set_ie ( pframe , _ERPINFO_IE_ , 1 , & erpinfo , & pattrib - > pktlen ) ;
}
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* EXTERNDED SUPPORTED RATE */
2013-05-08 21:45:39 +00:00
if ( rate_len > 8 )
2014-12-11 21:15:04 +00:00
{
2013-05-08 21:45:39 +00:00
pframe = rtw_set_ie ( pframe , _EXT_SUPPORTEDRATES_IE_ , ( rate_len - 8 ) , ( cur_network - > SupportedRates + 8 ) , & pattrib - > pktlen ) ;
2014-12-11 21:15:04 +00:00
}
2015-02-19 21:34:32 +00:00
/* todo:HT for adhoc */
2013-05-08 21:45:39 +00:00
2014-12-19 06:59:46 +00:00
}
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_P2P
if ( rtw_p2p_chk_role ( pwdinfo , P2P_ROLE_GO ) /*&& is_valid_p2p_probereq*/ )
{
2013-05-08 21:45:39 +00:00
u32 len ;
2014-12-11 21:15:04 +00:00
if ( wdev_to_priv ( padapter - > rtw_wdev ) - > p2p_enabled & & pwdinfo - > driver_interface = = DRIVER_CFG80211 )
{
2015-02-19 21:34:32 +00:00
/* if pwdinfo->role == P2P_ROLE_DEVICE will call issue_probersp_p2p() */
2014-12-11 21:15:04 +00:00
len = pmlmepriv - > p2p_go_probe_resp_ie_len ;
if ( pmlmepriv - > p2p_go_probe_resp_ie & & len > 0 )
2015-02-19 20:50:04 +00:00
memcpy ( pframe , pmlmepriv - > p2p_go_probe_resp_ie , len ) ;
2015-02-20 04:52:01 +00:00
} else {
2014-12-11 21:15:04 +00:00
len = build_probe_resp_p2p_ie ( pwdinfo , pframe ) ;
}
2013-05-08 21:45:39 +00:00
pframe + = len ;
pattrib - > pktlen + = len ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_WFD
2014-12-29 02:13:24 +00:00
if ( true = = pwdinfo - > wfd_info - > wfd_enable )
2014-12-11 21:15:04 +00:00
{
len = build_probe_resp_wfd_ie ( pwdinfo , pframe , 0 ) ;
}
else
2014-12-19 06:59:46 +00:00
{
2014-12-11 21:15:04 +00:00
len = 0 ;
if ( pmlmepriv - > wfd_probe_resp_ie & & pmlmepriv - > wfd_probe_resp_ie_len > 0 )
{
len = pmlmepriv - > wfd_probe_resp_ie_len ;
2015-02-19 20:50:04 +00:00
memcpy ( pframe , pmlmepriv - > wfd_probe_resp_ie , len ) ;
2014-12-19 06:59:46 +00:00
}
2014-12-11 21:15:04 +00:00
}
pframe + = len ;
pattrib - > pktlen + = len ;
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_WFD */
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
}
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_P2P */
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
pattrib - > last_txcmdsz = pattrib - > pktlen ;
2014-12-19 06:59:46 +00:00
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
dump_mgntframe ( padapter , pmgntframe ) ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
return ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-19 04:28:04 +00:00
static int _issue_probereq ( struct adapter * padapter , NDIS_802_11_SSID * pssid , u8 * da , int wait_ack )
2013-05-08 21:45:39 +00:00
{
int ret = _FAIL ;
struct xmit_frame * pmgntframe ;
struct pkt_attrib * pattrib ;
unsigned char * pframe ;
struct rtw_ieee80211_hdr * pwlanhdr ;
2014-12-19 04:28:04 +00:00
__le16 * fctrl ;
2013-05-08 21:45:39 +00:00
unsigned char * mac ;
unsigned char bssrate [ NumRates ] ;
struct xmit_priv * pxmitpriv = & ( padapter - > xmitpriv ) ;
struct mlme_priv * pmlmepriv = & ( padapter - > mlmepriv ) ;
struct mlme_ext_priv * pmlmeext = & ( padapter - > mlmeextpriv ) ;
2014-12-11 21:15:04 +00:00
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
2013-05-08 21:45:39 +00:00
int bssrate_len = 0 ;
u8 bc_addr [ ] = { 0xff , 0xff , 0xff , 0xff , 0xff , 0xff } ;
2014-12-11 21:15:04 +00:00
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_notice_ , ( " +issue_probereq \n " ) ) ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
if ( ( pmgntframe = alloc_mgtxmitframe ( pxmitpriv ) ) = = NULL )
{
2013-05-08 21:45:39 +00:00
goto exit ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* update attribute */
2013-05-08 21:45:39 +00:00
pattrib = & pmgntframe - > attrib ;
update_mgntframe_attrib ( padapter , pattrib ) ;
2014-12-11 21:15:04 +00:00
2015-02-19 20:58:09 +00:00
memset ( pmgntframe - > buf_addr , 0 , WLANHDR_OFFSET + TXDESC_OFFSET ) ;
2013-05-08 21:45:39 +00:00
pframe = ( u8 * ) ( pmgntframe - > buf_addr ) + TXDESC_OFFSET ;
pwlanhdr = ( struct rtw_ieee80211_hdr * ) pframe ;
mac = myid ( & ( padapter - > eeprompriv ) ) ;
fctrl = & ( pwlanhdr - > frame_ctl ) ;
* ( fctrl ) = 0 ;
2014-12-11 21:15:04 +00:00
if ( da )
{
2015-02-19 21:34:32 +00:00
/* unicast probe request frame */
2015-02-19 20:50:04 +00:00
memcpy ( pwlanhdr - > addr1 , da , ETH_ALEN ) ;
memcpy ( pwlanhdr - > addr3 , da , ETH_ALEN ) ;
2014-12-11 21:15:04 +00:00
}
else
{
2015-02-19 21:34:32 +00:00
/* broadcast probe request frame */
2015-02-19 20:50:04 +00:00
memcpy ( pwlanhdr - > addr1 , bc_addr , ETH_ALEN ) ;
memcpy ( pwlanhdr - > addr3 , bc_addr , ETH_ALEN ) ;
2013-05-08 21:45:39 +00:00
}
2015-02-19 20:50:04 +00:00
memcpy ( pwlanhdr - > addr2 , mac , ETH_ALEN ) ;
2013-05-08 21:45:39 +00:00
SetSeqNum ( pwlanhdr , pmlmeext - > mgnt_seq ) ;
pmlmeext - > mgnt_seq + + ;
SetFrameSubType ( pframe , WIFI_PROBEREQ ) ;
pframe + = sizeof ( struct rtw_ieee80211_hdr_3addr ) ;
pattrib - > pktlen = sizeof ( struct rtw_ieee80211_hdr_3addr ) ;
2014-12-11 21:15:04 +00:00
if ( pssid )
2013-05-08 21:45:39 +00:00
pframe = rtw_set_ie ( pframe , _SSID_IE_ , pssid - > SsidLength , pssid - > Ssid , & ( pattrib - > pktlen ) ) ;
else
pframe = rtw_set_ie ( pframe , _SSID_IE_ , 0 , NULL , & ( pattrib - > pktlen ) ) ;
get_rate_set ( padapter , bssrate , & bssrate_len ) ;
2014-12-11 21:15:04 +00:00
if ( bssrate_len > 8 )
{
2013-05-08 21:45:39 +00:00
pframe = rtw_set_ie ( pframe , _SUPPORTEDRATES_IE_ , 8 , bssrate , & ( pattrib - > pktlen ) ) ;
pframe = rtw_set_ie ( pframe , _EXT_SUPPORTEDRATES_IE_ , ( bssrate_len - 8 ) , ( bssrate + 8 ) , & ( pattrib - > pktlen ) ) ;
2014-12-11 21:15:04 +00:00
}
else
{
2013-05-08 21:45:39 +00:00
pframe = rtw_set_ie ( pframe , _SUPPORTEDRATES_IE_ , bssrate_len , bssrate , & ( pattrib - > pktlen ) ) ;
}
2015-02-19 21:34:32 +00:00
/* add wps_ie for wps2.0 */
2014-12-11 21:15:04 +00:00
if ( pmlmepriv - > wps_probe_req_ie_len > 0 & & pmlmepriv - > wps_probe_req_ie )
{
2015-02-19 20:50:04 +00:00
memcpy ( pframe , pmlmepriv - > wps_probe_req_ie , pmlmepriv - > wps_probe_req_ie_len ) ;
2013-05-08 21:45:39 +00:00
pframe + = pmlmepriv - > wps_probe_req_ie_len ;
pattrib - > pktlen + = pmlmepriv - > wps_probe_req_ie_len ;
2014-12-19 06:59:46 +00:00
}
2013-05-08 21:45:39 +00:00
pattrib - > last_txcmdsz = pattrib - > pktlen ;
2014-12-11 21:15:04 +00:00
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_notice_ , ( " issuing probe_req, tx_len=%d \n " , pattrib - > last_txcmdsz ) ) ;
2013-05-08 21:45:39 +00:00
if ( wait_ack ) {
ret = dump_mgntframe_and_wait_ack ( padapter , pmgntframe ) ;
} else {
dump_mgntframe ( padapter , pmgntframe ) ;
ret = _SUCCESS ;
}
exit :
return ret ;
}
2014-12-17 23:13:53 +00:00
inline void issue_probereq ( struct adapter * padapter , NDIS_802_11_SSID * pssid , u8 * da )
2013-05-08 21:45:39 +00:00
{
2014-12-29 02:13:24 +00:00
_issue_probereq ( padapter , pssid , da , false ) ;
2013-05-08 21:45:39 +00:00
}
2014-12-17 23:13:53 +00:00
int issue_probereq_ex ( struct adapter * padapter , NDIS_802_11_SSID * pssid , u8 * da ,
2013-05-08 21:45:39 +00:00
int try_cnt , int wait_ms )
{
int ret ;
int i = 0 ;
u32 start = rtw_get_current_time ( ) ;
2014-12-11 21:15:04 +00:00
do
{
2014-12-29 02:13:24 +00:00
ret = _issue_probereq ( padapter , pssid , da , wait_ms > 0 ? true : false ) ;
2013-05-08 21:45:39 +00:00
i + + ;
if ( padapter - > bDriverStopped | | padapter - > bSurpriseRemoved )
break ;
2014-12-11 21:15:04 +00:00
if ( i < try_cnt & & wait_ms > 0 & & ret = = _FAIL )
2013-05-08 21:45:39 +00:00
rtw_msleep_os ( wait_ms ) ;
2014-12-11 21:15:04 +00:00
} while ( ( i < try_cnt ) & & ( ( ret = = _FAIL ) | | ( wait_ms = = 0 ) ) ) ;
2013-05-08 21:45:39 +00:00
if ( ret ! = _FAIL ) {
ret = _SUCCESS ;
2014-12-11 21:15:04 +00:00
# ifndef DBG_XMIT_ACK
2013-05-08 21:45:39 +00:00
goto exit ;
2014-12-11 21:15:04 +00:00
# endif
2013-05-08 21:45:39 +00:00
}
if ( try_cnt & & wait_ms ) {
if ( da )
2014-12-11 21:15:04 +00:00
DBG_871X ( FUNC_ADPT_FMT " to " MAC_FMT " , ch:%u%s, %d/%d in %u ms \n " ,
FUNC_ADPT_ARG ( padapter ) , MAC_ARG ( da ) , rtw_get_oper_ch ( padapter ) ,
ret = = _SUCCESS ? " , acked " : " " , i , try_cnt , rtw_get_passing_time_ms ( start ) ) ;
2013-05-08 21:45:39 +00:00
else
2014-12-11 21:15:04 +00:00
DBG_871X ( FUNC_ADPT_FMT " , ch:%u%s, %d/%d in %u ms \n " ,
2013-05-08 21:45:39 +00:00
FUNC_ADPT_ARG ( padapter ) , rtw_get_oper_ch ( padapter ) ,
2014-12-11 21:15:04 +00:00
ret = = _SUCCESS ? " , acked " : " " , i , try_cnt , rtw_get_passing_time_ms ( start ) ) ;
2013-05-08 21:45:39 +00:00
}
exit :
return ret ;
}
2015-02-19 21:34:32 +00:00
/* if psta == NULL, indiate we are station(client) now... */
2014-12-17 23:13:53 +00:00
void issue_auth ( struct adapter * padapter , struct sta_info * psta , unsigned short status )
2013-05-08 21:45:39 +00:00
{
2014-12-19 04:28:04 +00:00
struct xmit_frame * pmgntframe ;
struct pkt_attrib * pattrib ;
unsigned char * pframe ;
2014-12-11 21:15:04 +00:00
struct rtw_ieee80211_hdr * pwlanhdr ;
2014-12-19 04:28:04 +00:00
__le16 * fctrl ;
2015-02-16 19:00:49 +00:00
unsigned int val32 ;
u16 val16 ;
__le16 le_val16 ;
2013-05-08 21:45:39 +00:00
int use_shared_key = 0 ;
2014-12-11 21:15:04 +00:00
struct xmit_priv * pxmitpriv = & ( padapter - > xmitpriv ) ;
2013-05-08 21:45:39 +00:00
struct mlme_ext_priv * pmlmeext = & ( padapter - > mlmeextpriv ) ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
2015-02-16 19:00:49 +00:00
pmgntframe = alloc_mgtxmitframe ( pxmitpriv ) ;
if ( pmgntframe = = NULL )
2013-05-08 21:45:39 +00:00
return ;
2015-02-19 21:34:32 +00:00
/* update attribute */
2013-05-08 21:45:39 +00:00
pattrib = & pmgntframe - > attrib ;
update_mgntframe_attrib ( padapter , pattrib ) ;
2015-02-19 20:58:09 +00:00
memset ( pmgntframe - > buf_addr , 0 , WLANHDR_OFFSET + TXDESC_OFFSET ) ;
2013-05-08 21:45:39 +00:00
pframe = ( u8 * ) ( pmgntframe - > buf_addr ) + TXDESC_OFFSET ;
pwlanhdr = ( struct rtw_ieee80211_hdr * ) pframe ;
fctrl = & ( pwlanhdr - > frame_ctl ) ;
* ( fctrl ) = 0 ;
SetSeqNum ( pwlanhdr , pmlmeext - > mgnt_seq ) ;
pmlmeext - > mgnt_seq + + ;
SetFrameSubType ( pframe , WIFI_AUTH ) ;
pframe + = sizeof ( struct rtw_ieee80211_hdr_3addr ) ;
pattrib - > pktlen = sizeof ( struct rtw_ieee80211_hdr_3addr ) ;
2015-02-19 21:34:32 +00:00
if ( psta ) { /* for AP mode */
2015-02-16 19:00:49 +00:00
memcpy ( pwlanhdr - > addr1 , psta - > hwaddr , ETH_ALEN ) ;
memcpy ( pwlanhdr - > addr2 , myid ( & ( padapter - > eeprompriv ) ) , ETH_ALEN ) ;
memcpy ( pwlanhdr - > addr3 , myid ( & ( padapter - > eeprompriv ) ) , ETH_ALEN ) ;
2013-05-08 21:45:39 +00:00
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* setting auth algo number */
2015-02-16 19:00:49 +00:00
val16 = ( u16 ) psta - > authalg ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
if ( status ! = _STATS_SUCCESSFUL_ )
2013-05-08 21:45:39 +00:00
val16 = 0 ;
2015-02-16 19:00:49 +00:00
if ( val16 ) {
le_val16 = cpu_to_le16 ( val16 ) ;
2013-05-08 21:45:39 +00:00
use_shared_key = 1 ;
2015-02-16 19:00:49 +00:00
} else {
le_val16 = 0 ;
}
pframe = rtw_set_fixed_ie ( pframe , _AUTH_ALGM_NUM_ , ( unsigned char * ) & le_val16 , & ( pattrib - > pktlen ) ) ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* setting auth seq number */
2015-02-16 19:00:49 +00:00
val16 = ( u16 ) psta - > auth_seq ;
le_val16 = cpu_to_le16 ( val16 ) ;
pframe = rtw_set_fixed_ie ( pframe , _AUTH_SEQ_NUM_ , ( unsigned char * ) & le_val16 , & ( pattrib - > pktlen ) ) ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* setting status code... */
2015-02-16 19:00:49 +00:00
val16 = status ;
le_val16 = cpu_to_le16 ( val16 ) ;
pframe = rtw_set_fixed_ie ( pframe , _STATUS_CODE_ , ( unsigned char * ) & le_val16 , & ( pattrib - > pktlen ) ) ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* added challenging text... */
2014-12-11 21:15:04 +00:00
if ( ( psta - > auth_seq = = 2 ) & & ( psta - > state & WIFI_FW_AUTH_STATE ) & & ( use_shared_key = = 1 ) )
2014-12-19 06:59:46 +00:00
pframe = rtw_set_ie ( pframe , _CHLGETXT_IE_ , 128 , psta - > chg_txt , & ( pattrib - > pktlen ) ) ;
} else {
2015-02-16 19:00:49 +00:00
__le32 le_tmp32 ;
__le16 le_tmp16 ;
memcpy ( pwlanhdr - > addr1 , get_my_bssid ( & pmlmeinfo - > network ) , ETH_ALEN ) ;
memcpy ( pwlanhdr - > addr2 , myid ( & padapter - > eeprompriv ) , ETH_ALEN ) ;
memcpy ( pwlanhdr - > addr3 , get_my_bssid ( & pmlmeinfo - > network ) , ETH_ALEN ) ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* setting auth algo number */
2015-02-16 19:00:49 +00:00
val16 = ( pmlmeinfo - > auth_algo = = dot11AuthAlgrthm_Shared ) ? 1 : 0 ; /* 0:OPEN System, 1:Shared key */
2014-12-19 04:28:04 +00:00
if ( val16 )
2013-05-08 21:45:39 +00:00
use_shared_key = 1 ;
2015-02-16 19:00:49 +00:00
/* setting IV for auth seq #3 */
if ( ( pmlmeinfo - > auth_seq = = 3 ) & & ( pmlmeinfo - > state & WIFI_FW_AUTH_STATE ) & & ( use_shared_key = = 1 ) ) {
val32 = ( ( pmlmeinfo - > iv + + ) | ( pmlmeinfo - > key_index < < 30 ) ) ;
le_tmp32 = cpu_to_le32 ( val32 ) ;
pframe = rtw_set_fixed_ie ( pframe , 4 , ( unsigned char * ) & le_tmp32 , & ( pattrib - > pktlen ) ) ;
2013-05-08 21:45:39 +00:00
pattrib - > iv_len = 4 ;
}
2015-02-16 19:00:49 +00:00
le_tmp16 = cpu_to_le16 ( val16 ) ;
pframe = rtw_set_fixed_ie ( pframe , _AUTH_ALGM_NUM_ , ( unsigned char * ) & le_tmp16 , & ( pattrib - > pktlen ) ) ;
2014-12-19 06:59:46 +00:00
2015-02-16 19:00:49 +00:00
/* setting auth seq number */
val16 = pmlmeinfo - > auth_seq ;
le_tmp16 = cpu_to_le16 ( val16 ) ;
pframe = rtw_set_fixed_ie ( pframe , _AUTH_SEQ_NUM_ , ( unsigned char * ) & le_tmp16 , & ( pattrib - > pktlen ) ) ;
2013-05-08 21:45:39 +00:00
2015-02-16 19:00:49 +00:00
/* setting status code... */
le_tmp16 = cpu_to_le16 ( status ) ;
pframe = rtw_set_fixed_ie ( pframe , _STATUS_CODE_ , ( unsigned char * ) & le_tmp16 , & ( pattrib - > pktlen ) ) ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* then checking to see if sending challenging text... */
2014-12-19 04:28:04 +00:00
if ( ( pmlmeinfo - > auth_seq = = 3 ) & & ( pmlmeinfo - > state & WIFI_FW_AUTH_STATE ) & & ( use_shared_key = = 1 ) ) {
2013-05-08 21:45:39 +00:00
pframe = rtw_set_ie ( pframe , _CHLGETXT_IE_ , 128 , pmlmeinfo - > chg_txt , & ( pattrib - > pktlen ) ) ;
SetPrivacy ( fctrl ) ;
2014-12-19 06:59:46 +00:00
pattrib - > hdrlen = sizeof ( struct rtw_ieee80211_hdr_3addr ) ;
2013-05-08 21:45:39 +00:00
pattrib - > encrypt = _WEP40_ ;
pattrib - > icv_len = 4 ;
2014-12-19 06:59:46 +00:00
pattrib - > pktlen + = pattrib - > icv_len ;
2013-05-08 21:45:39 +00:00
}
}
pattrib - > last_txcmdsz = pattrib - > pktlen ;
rtw_wep_encrypt ( padapter , ( u8 * ) pmgntframe ) ;
2014-12-11 21:15:04 +00:00
DBG_871X ( " %s \n " , __FUNCTION__ ) ;
2013-05-08 21:45:39 +00:00
dump_mgntframe ( padapter , pmgntframe ) ;
return ;
}
2014-12-11 21:15:04 +00:00
2014-12-17 23:13:53 +00:00
void issue_asocrsp ( struct adapter * padapter , unsigned short status , struct sta_info * pstat , int pkt_type )
2013-05-08 21:45:39 +00:00
{
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_AP_MODE
2013-05-08 21:45:39 +00:00
struct xmit_frame * pmgntframe ;
struct rtw_ieee80211_hdr * pwlanhdr ;
struct pkt_attrib * pattrib ;
unsigned char * pbuf , * pframe ;
2015-02-16 19:00:49 +00:00
u16 val ;
2014-12-19 04:28:04 +00:00
__le16 * fctrl ;
2013-05-08 21:45:39 +00:00
struct xmit_priv * pxmitpriv = & ( padapter - > xmitpriv ) ;
struct mlme_priv * pmlmepriv = & ( padapter - > mlmepriv ) ;
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
2014-12-19 06:59:46 +00:00
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
2014-12-11 21:15:04 +00:00
WLAN_BSSID_EX * pnetwork = & ( pmlmeinfo - > network ) ;
2014-12-19 06:59:46 +00:00
u8 * ie = pnetwork - > IEs ;
2015-02-16 19:00:49 +00:00
__le16 lestatus , leval ;
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_P2P
2013-05-08 21:45:39 +00:00
struct wifidirect_info * pwdinfo = & ( padapter - > wdinfo ) ;
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_WFD
u32 wfdielen = 0 ;
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_WFD */
2014-12-11 21:15:04 +00:00
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_P2P */
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
DBG_871X ( " %s \n " , __FUNCTION__ ) ;
2013-05-08 21:45:39 +00:00
2015-02-16 19:00:49 +00:00
pmgntframe = alloc_mgtxmitframe ( pxmitpriv ) ;
if ( pmgntframe = = NULL )
2013-05-08 21:45:39 +00:00
return ;
2015-02-16 19:00:49 +00:00
/* update attribute */
2013-05-08 21:45:39 +00:00
pattrib = & pmgntframe - > attrib ;
update_mgntframe_attrib ( padapter , pattrib ) ;
2014-12-11 21:15:04 +00:00
2015-02-16 19:00:49 +00:00
memset ( pmgntframe - > buf_addr , 0 , WLANHDR_OFFSET + TXDESC_OFFSET ) ;
2013-05-08 21:45:39 +00:00
pframe = ( u8 * ) ( pmgntframe - > buf_addr ) + TXDESC_OFFSET ;
pwlanhdr = ( struct rtw_ieee80211_hdr * ) pframe ;
fctrl = & ( pwlanhdr - > frame_ctl ) ;
* ( fctrl ) = 0 ;
2015-02-16 19:00:49 +00:00
memcpy ( ( void * ) GetAddr1Ptr ( pwlanhdr ) , pstat - > hwaddr , ETH_ALEN ) ;
memcpy ( ( void * ) GetAddr2Ptr ( pwlanhdr ) , myid ( & ( padapter - > eeprompriv ) ) , ETH_ALEN ) ;
memcpy ( ( void * ) GetAddr3Ptr ( pwlanhdr ) , get_my_bssid ( & ( pmlmeinfo - > network ) ) , ETH_ALEN ) ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
SetSeqNum ( pwlanhdr , pmlmeext - > mgnt_seq ) ;
pmlmeext - > mgnt_seq + + ;
if ( ( pkt_type = = WIFI_ASSOCRSP ) | | ( pkt_type = = WIFI_REASSOCRSP ) )
2014-12-19 06:59:46 +00:00
SetFrameSubType ( pwlanhdr , pkt_type ) ;
2013-05-08 21:45:39 +00:00
else
return ;
pattrib - > hdrlen = sizeof ( struct rtw_ieee80211_hdr_3addr ) ;
pattrib - > pktlen + = pattrib - > hdrlen ;
pframe + = pattrib - > hdrlen ;
2015-02-16 19:00:49 +00:00
/* capability */
val = * ( unsigned short * ) rtw_get_capability_from_ie ( ie ) ;
2013-05-08 21:45:39 +00:00
pframe = rtw_set_fixed_ie ( pframe , _CAPABILITY_ , ( unsigned char * ) & val , & ( pattrib - > pktlen ) ) ;
2015-02-16 19:00:49 +00:00
lestatus = cpu_to_le16 ( status ) ;
pframe = rtw_set_fixed_ie ( pframe , _STATUS_CODE_ , ( unsigned char * ) & lestatus , & ( pattrib - > pktlen ) ) ;
2014-12-19 06:59:46 +00:00
2015-02-16 19:00:49 +00:00
leval = cpu_to_le16 ( pstat - > aid | BIT ( 14 ) | BIT ( 15 ) ) ;
pframe = rtw_set_fixed_ie ( pframe , _ASOC_ID_ , ( unsigned char * ) & leval , & ( pattrib - > pktlen ) ) ;
2013-05-19 04:28:07 +00:00
2014-12-19 04:28:04 +00:00
if ( pstat - > bssratelen < = 8 ) {
2013-05-08 21:45:39 +00:00
pframe = rtw_set_ie ( pframe , _SUPPORTEDRATES_IE_ , pstat - > bssratelen , pstat - > bssrateset , & ( pattrib - > pktlen ) ) ;
2014-12-19 04:28:04 +00:00
} else {
2013-05-08 21:45:39 +00:00
pframe = rtw_set_ie ( pframe , _SUPPORTEDRATES_IE_ , 8 , pstat - > bssrateset , & ( pattrib - > pktlen ) ) ;
pframe = rtw_set_ie ( pframe , _EXT_SUPPORTEDRATES_IE_ , ( pstat - > bssratelen - 8 ) , pstat - > bssrateset + 8 , & ( pattrib - > pktlen ) ) ;
}
2014-12-19 04:28:04 +00:00
if ( ( pstat - > flags & WLAN_STA_HT ) & & ( pmlmepriv - > htpriv . ht_option ) ) {
2014-12-11 21:15:04 +00:00
uint ie_len = 0 ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* FILL HT CAP INFO IE */
/* p = hostapd_eid_ht_capabilities_info(hapd, p); */
2013-05-08 21:45:39 +00:00
pbuf = rtw_get_ie ( ie + _BEACON_IE_OFFSET_ , _HT_CAPABILITY_IE_ , & ie_len , ( pnetwork - > IELength - _BEACON_IE_OFFSET_ ) ) ;
2014-12-19 04:28:04 +00:00
if ( pbuf & & ie_len > 0 ) {
2015-02-19 20:50:04 +00:00
memcpy ( pframe , pbuf , ie_len + 2 ) ;
2013-05-08 21:45:39 +00:00
pframe + = ( ie_len + 2 ) ;
2014-12-11 21:15:04 +00:00
pattrib - > pktlen + = ( ie_len + 2 ) ;
2013-05-08 21:45:39 +00:00
}
2015-02-19 21:34:32 +00:00
/* FILL HT ADD INFO IE */
/* p = hostapd_eid_ht_operation(hapd, p); */
2013-05-08 21:45:39 +00:00
pbuf = rtw_get_ie ( ie + _BEACON_IE_OFFSET_ , _HT_ADD_INFO_IE_ , & ie_len , ( pnetwork - > IELength - _BEACON_IE_OFFSET_ ) ) ;
2014-12-19 04:28:04 +00:00
if ( pbuf & & ie_len > 0 ) {
2015-02-19 20:50:04 +00:00
memcpy ( pframe , pbuf , ie_len + 2 ) ;
2013-05-08 21:45:39 +00:00
pframe + = ( ie_len + 2 ) ;
2014-12-11 21:15:04 +00:00
pattrib - > pktlen + = ( ie_len + 2 ) ;
2013-05-08 21:45:39 +00:00
}
2014-12-19 06:59:46 +00:00
}
2013-05-19 04:28:07 +00:00
2015-02-19 21:34:32 +00:00
/* FILL WMM IE */
2014-12-19 04:28:04 +00:00
if ( ( pstat - > flags & WLAN_STA_WME ) & & ( pmlmepriv - > qospriv . qos_option ) ) {
2014-12-11 21:15:04 +00:00
uint ie_len = 0 ;
2014-12-19 06:59:46 +00:00
unsigned char WMM_PARA_IE [ ] = { 0x00 , 0x50 , 0xf2 , 0x02 , 0x01 , 0x01 } ;
for ( pbuf = ie + _BEACON_IE_OFFSET_ ; ; pbuf + = ( ie_len + 2 ) ) {
pbuf = rtw_get_ie ( pbuf , _VENDOR_SPECIFIC_IE_ , & ie_len , ( pnetwork - > IELength - _BEACON_IE_OFFSET_ - ( ie_len + 2 ) ) ) ;
if ( pbuf & & _rtw_memcmp ( pbuf + 2 , WMM_PARA_IE , 6 ) ) {
2015-02-19 20:50:04 +00:00
memcpy ( pframe , pbuf , ie_len + 2 ) ;
2013-05-08 21:45:39 +00:00
pframe + = ( ie_len + 2 ) ;
2014-12-11 21:15:04 +00:00
pattrib - > pktlen + = ( ie_len + 2 ) ;
2014-12-19 06:59:46 +00:00
break ;
2013-05-08 21:45:39 +00:00
}
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
if ( ( pbuf = = NULL ) | | ( ie_len = = 0 ) )
break ;
}
}
if ( pmlmeinfo - > assoc_AP_vendor = = HT_IOT_PEER_REALTEK )
pframe = rtw_set_ie ( pframe , _VENDOR_SPECIFIC_IE_ , 6 , REALTEK_96B_IE , & ( pattrib - > pktlen ) ) ;
2015-02-19 21:34:32 +00:00
/* add WPS IE ie for wps 2.0 */
2014-12-19 04:28:04 +00:00
if ( pmlmepriv - > wps_assoc_resp_ie & & pmlmepriv - > wps_assoc_resp_ie_len > 0 ) {
2015-02-19 20:50:04 +00:00
memcpy ( pframe , pmlmepriv - > wps_assoc_resp_ie , pmlmepriv - > wps_assoc_resp_ie_len ) ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
pframe + = pmlmepriv - > wps_assoc_resp_ie_len ;
pattrib - > pktlen + = pmlmepriv - > wps_assoc_resp_ie_len ;
}
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_P2P
2014-12-19 04:28:04 +00:00
if ( padapter - > wdinfo . driver_interface = = DRIVER_WEXT ) {
2014-12-29 02:13:24 +00:00
if ( rtw_p2p_chk_role ( pwdinfo , P2P_ROLE_GO ) & & ( pstat - > is_p2p_device = = true ) ) {
2014-12-11 21:15:04 +00:00
u32 len ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
len = build_assoc_resp_p2p_ie ( pwdinfo , pframe , pstat - > p2p_status_code ) ;
pframe + = len ;
pattrib - > pktlen + = len ;
}
}
# ifdef CONFIG_WFD
if ( rtw_p2p_chk_role ( pwdinfo , P2P_ROLE_GO )
2014-12-29 02:13:24 +00:00
& & ( true = = pwdinfo - > wfd_info - > wfd_enable )
2014-12-11 21:15:04 +00:00
)
{
wfdielen = build_assoc_resp_wfd_ie ( pwdinfo , pframe ) ;
pframe + = wfdielen ;
pattrib - > pktlen + = wfdielen ;
2013-05-08 21:45:39 +00:00
}
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_WFD */
# endif /* CONFIG_P2P */
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
pattrib - > last_txcmdsz = pattrib - > pktlen ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
dump_mgntframe ( padapter , pmgntframe ) ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
# endif
}
2014-12-17 23:13:53 +00:00
void issue_assocreq ( struct adapter * padapter )
2013-05-08 21:45:39 +00:00
{
int ret = _FAIL ;
2014-12-19 04:28:04 +00:00
struct xmit_frame * pmgntframe ;
struct pkt_attrib * pattrib ;
unsigned char * pframe , * p ;
struct rtw_ieee80211_hdr * pwlanhdr ;
__le16 * fctrl ;
__le16 val16 ;
unsigned int i , j , ie_len , index = 0 ;
unsigned char rf_type , bssrate [ NumRates ] , sta_bssrate [ NumRates ] ;
2014-12-11 21:15:04 +00:00
PNDIS_802_11_VARIABLE_IEs pIE ;
2013-05-08 21:45:39 +00:00
struct registry_priv * pregpriv = & padapter - > registrypriv ;
struct xmit_priv * pxmitpriv = & ( padapter - > xmitpriv ) ;
struct mlme_priv * pmlmepriv = & ( padapter - > mlmepriv ) ;
struct mlme_ext_priv * pmlmeext = & ( padapter - > mlmeextpriv ) ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
int bssrate_len = 0 , sta_bssrate_len = 0 ;
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_P2P
2013-05-08 21:45:39 +00:00
struct wifidirect_info * pwdinfo = & ( padapter - > wdinfo ) ;
2014-12-11 21:15:04 +00:00
u8 p2pie [ 255 ] = { 0x00 } ;
2014-12-19 06:59:46 +00:00
u16 p2pielen = 0 ;
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_WFD
u32 wfdielen = 0 ;
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_WFD */
# endif /* CONFIG_P2P */
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_DFS
u16 cap ;
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_DFS */
2014-12-11 21:15:04 +00:00
if ( ( pmgntframe = alloc_mgtxmitframe ( pxmitpriv ) ) = = NULL )
2013-05-08 21:45:39 +00:00
goto exit ;
2015-02-19 21:34:32 +00:00
/* update attribute */
2013-05-08 21:45:39 +00:00
pattrib = & pmgntframe - > attrib ;
update_mgntframe_attrib ( padapter , pattrib ) ;
2014-12-11 21:15:04 +00:00
2015-02-19 20:58:09 +00:00
memset ( pmgntframe - > buf_addr , 0 , WLANHDR_OFFSET + TXDESC_OFFSET ) ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
pframe = ( u8 * ) ( pmgntframe - > buf_addr ) + TXDESC_OFFSET ;
pwlanhdr = ( struct rtw_ieee80211_hdr * ) pframe ;
fctrl = & ( pwlanhdr - > frame_ctl ) ;
* ( fctrl ) = 0 ;
2015-02-19 20:50:04 +00:00
memcpy ( pwlanhdr - > addr1 , get_my_bssid ( & ( pmlmeinfo - > network ) ) , ETH_ALEN ) ;
memcpy ( pwlanhdr - > addr2 , myid ( & ( padapter - > eeprompriv ) ) , ETH_ALEN ) ;
memcpy ( pwlanhdr - > addr3 , get_my_bssid ( & ( pmlmeinfo - > network ) ) , ETH_ALEN ) ;
2013-05-08 21:45:39 +00:00
SetSeqNum ( pwlanhdr , pmlmeext - > mgnt_seq ) ;
pmlmeext - > mgnt_seq + + ;
SetFrameSubType ( pframe , WIFI_ASSOCREQ ) ;
pframe + = sizeof ( struct rtw_ieee80211_hdr_3addr ) ;
pattrib - > pktlen = sizeof ( struct rtw_ieee80211_hdr_3addr ) ;
2015-02-19 21:34:32 +00:00
/* caps */
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_DFS
2015-02-19 20:50:04 +00:00
memcpy ( & cap , rtw_get_capability_from_ie ( pmlmeinfo - > network . IEs ) , 2 ) ;
2014-12-11 21:15:04 +00:00
cap | = BIT ( 8 ) ;
2015-02-19 20:50:04 +00:00
memcpy ( pframe , & cap , 2 ) ;
2014-12-11 21:15:04 +00:00
# else
2015-02-19 20:50:04 +00:00
memcpy ( pframe , rtw_get_capability_from_ie ( pmlmeinfo - > network . IEs ) , 2 ) ;
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_DFS */
2013-05-08 21:45:39 +00:00
pframe + = 2 ;
pattrib - > pktlen + = 2 ;
2015-02-19 21:34:32 +00:00
/* listen interval */
/* todo: listen interval for power saving */
2014-12-11 21:15:04 +00:00
val16 = cpu_to_le16 ( 3 ) ;
2015-02-19 20:50:04 +00:00
memcpy ( pframe , ( unsigned char * ) & val16 , 2 ) ;
2013-05-08 21:45:39 +00:00
pframe + = 2 ;
pattrib - > pktlen + = 2 ;
2015-02-19 21:34:32 +00:00
/* SSID */
2013-05-08 21:45:39 +00:00
pframe = rtw_set_ie ( pframe , _SSID_IE_ , pmlmeinfo - > network . Ssid . SsidLength , pmlmeinfo - > network . Ssid . Ssid , & ( pattrib - > pktlen ) ) ;
2015-02-19 21:34:32 +00:00
/* supported rate & extended supported rate */
2013-05-08 21:45:39 +00:00
get_rate_set ( padapter , sta_bssrate , & sta_bssrate_len ) ;
2015-02-19 21:34:32 +00:00
/* DBG_871X("sta_bssrate_len=%d\n", sta_bssrate_len); */
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
if ( pmlmeext - > cur_channel = = 14 ) /* for JAPAN, channel 14 can only uses B Mode(CCK) */
2014-12-11 21:15:04 +00:00
{
2013-05-08 21:45:39 +00:00
sta_bssrate_len = 4 ;
2014-12-11 21:15:04 +00:00
}
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* for (i = 0; i < sta_bssrate_len; i++) { */
/* DBG_871X("sta_bssrate[%d]=%02X\n", i, sta_bssrate[i]); */
/* */
2013-05-08 21:45:39 +00:00
for ( i = 0 ; i < NDIS_802_11_LENGTH_RATES_EX ; i + + ) {
2014-12-11 21:15:04 +00:00
if ( pmlmeinfo - > network . SupportedRates [ i ] = = 0 ) break ;
DBG_871X ( " network.SupportedRates[%d]=%02X \n " , i , pmlmeinfo - > network . SupportedRates [ i ] ) ;
2013-05-08 21:45:39 +00:00
}
2014-12-19 06:59:46 +00:00
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
for ( i = 0 ; i < NDIS_802_11_LENGTH_RATES_EX ; i + + ) {
2014-12-11 21:15:04 +00:00
if ( pmlmeinfo - > network . SupportedRates [ i ] = = 0 ) break ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* Check if the AP's supported rates are also supported by STA. */
2014-12-11 21:15:04 +00:00
for ( j = 0 ; j < sta_bssrate_len ; j + + ) {
2015-02-19 21:34:32 +00:00
/* Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP */
2014-12-19 06:59:46 +00:00
if ( ( pmlmeinfo - > network . SupportedRates [ i ] | IEEE80211_BASIC_RATE_MASK )
2014-12-11 21:15:04 +00:00
= = ( sta_bssrate [ j ] | IEEE80211_BASIC_RATE_MASK ) ) {
2015-02-19 21:34:32 +00:00
/* DBG_871X("match i = %d, j=%d\n", i, j); */
2013-05-08 21:45:39 +00:00
break ;
2014-12-11 21:15:04 +00:00
} else {
2015-02-19 21:34:32 +00:00
/* DBG_871X("not match: %02X != %02X\n", (pmlmeinfo->network.SupportedRates[i]|IEEE80211_BASIC_RATE_MASK), (sta_bssrate[j]|IEEE80211_BASIC_RATE_MASK)); */
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
}
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
if ( j = = sta_bssrate_len ) {
2015-02-19 21:34:32 +00:00
/* the rate is not supported by STA */
2014-12-11 21:15:04 +00:00
DBG_871X ( " %s(): the rate[%d]=%02X is not supported by STA! \n " , __FUNCTION__ , i , pmlmeinfo - > network . SupportedRates [ i ] ) ;
2013-05-08 21:45:39 +00:00
} else {
2015-02-19 21:34:32 +00:00
/* the rate is supported by STA */
2013-05-08 21:45:39 +00:00
bssrate [ index + + ] = pmlmeinfo - > network . SupportedRates [ i ] ;
}
}
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
bssrate_len = index ;
2014-12-11 21:15:04 +00:00
DBG_871X ( " bssrate_len = %d \n " , bssrate_len ) ;
2013-05-08 21:45:39 +00:00
if ( bssrate_len = = 0 ) {
rtw_free_xmitbuf ( pxmitpriv , pmgntframe - > pxmitbuf ) ;
rtw_free_xmitframe ( pxmitpriv , pmgntframe ) ;
2015-02-19 21:34:32 +00:00
goto exit ; /* don't connect to AP if no joint supported rate */
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
2014-12-19 04:28:04 +00:00
if ( bssrate_len > 8 ) {
2013-05-08 21:45:39 +00:00
pframe = rtw_set_ie ( pframe , _SUPPORTEDRATES_IE_ , 8 , bssrate , & ( pattrib - > pktlen ) ) ;
pframe = rtw_set_ie ( pframe , _EXT_SUPPORTEDRATES_IE_ , ( bssrate_len - 8 ) , ( bssrate + 8 ) , & ( pattrib - > pktlen ) ) ;
2014-12-19 04:28:04 +00:00
} else {
2013-05-08 21:45:39 +00:00
pframe = rtw_set_ie ( pframe , _SUPPORTEDRATES_IE_ , bssrate_len , bssrate , & ( pattrib - > pktlen ) ) ;
}
2015-02-19 21:34:32 +00:00
/* RSN */
2014-12-11 21:15:04 +00:00
p = rtw_get_ie ( ( pmlmeinfo - > network . IEs + sizeof ( NDIS_802_11_FIXED_IEs ) ) , _RSN_IE_2_ , & ie_len , ( pmlmeinfo - > network . IELength - sizeof ( NDIS_802_11_FIXED_IEs ) ) ) ;
2013-05-08 21:45:39 +00:00
if ( p ! = NULL )
pframe = rtw_set_ie ( pframe , _RSN_IE_2_ , ie_len , ( p + 2 ) , & ( pattrib - > pktlen ) ) ;
2015-02-19 21:34:32 +00:00
/* HT caps */
2014-12-29 02:13:24 +00:00
if ( padapter - > mlmepriv . htpriv . ht_option = = true ) {
2014-12-11 21:15:04 +00:00
p = rtw_get_ie ( ( pmlmeinfo - > network . IEs + sizeof ( NDIS_802_11_FIXED_IEs ) ) , _HT_CAPABILITY_IE_ , & ie_len , ( pmlmeinfo - > network . IELength - sizeof ( NDIS_802_11_FIXED_IEs ) ) ) ;
2014-12-19 04:28:04 +00:00
if ( p & & ( ! is_ap_in_tkip ( padapter ) ) ) {
2015-02-19 20:50:04 +00:00
memcpy ( & ( pmlmeinfo - > HT_caps ) , ( p + 2 ) , sizeof ( struct HT_caps_element ) ) ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* to disable 40M Hz support while gd_bw_40MHz_en = 0 */
2013-05-08 21:45:39 +00:00
if ( pregpriv - > cbw40_enable = = 0 )
2014-12-19 04:28:04 +00:00
pmlmeinfo - > HT_caps . u . HT_cap_element . HT_caps_info & = cpu_to_le16 ( ~ ( BIT ( 6 ) | BIT ( 1 ) ) ) ;
2013-05-08 21:45:39 +00:00
else
2014-12-19 04:28:04 +00:00
pmlmeinfo - > HT_caps . u . HT_cap_element . HT_caps_info | = cpu_to_le16 ( BIT ( 1 ) ) ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* todo: disable SM power save mode */
2014-12-19 04:28:04 +00:00
pmlmeinfo - > HT_caps . u . HT_cap_element . HT_caps_info | = cpu_to_le16 ( 0x000c ) ;
2013-05-08 21:45:39 +00:00
rtw_hal_get_hwreg ( padapter , HW_VAR_RF_TYPE , ( u8 * ) ( & rf_type ) ) ;
2015-02-19 21:34:32 +00:00
/* switch (pregpriv->rf_config) */
2014-12-19 04:28:04 +00:00
switch ( rf_type ) {
case RF_1T1R :
if ( pregpriv - > rx_stbc )
2015-02-19 21:34:32 +00:00
pmlmeinfo - > HT_caps . u . HT_cap_element . HT_caps_info | = cpu_to_le16 ( 0x0100 ) ; /* RX STBC One spatial stream */
2014-12-19 06:59:46 +00:00
2015-02-19 20:50:04 +00:00
memcpy ( pmlmeinfo - > HT_caps . u . HT_cap_element . MCS_rate , MCS_rate_1R , 16 ) ;
2014-12-19 04:28:04 +00:00
break ;
case RF_2T2R :
case RF_1T2R :
default :
2015-02-19 21:34:32 +00:00
if ( ( pregpriv - > rx_stbc = = 0x3 ) | | /* enable for 2.4/5 GHz */
( ( pmlmeext - > cur_wireless_mode & WIRELESS_11_24N ) & & ( pregpriv - > rx_stbc = = 0x1 ) ) | | /* enable for 2.4GHz */
( ( pmlmeext - > cur_wireless_mode & WIRELESS_11_5N ) & & ( pregpriv - > rx_stbc = = 0x2 ) ) | | /* enable for 5GHz */
2014-12-19 04:28:04 +00:00
( pregpriv - > wifi_spec = = 1 ) ) {
DBG_871X ( " declare supporting RX STBC \n " ) ;
2015-02-19 21:34:32 +00:00
pmlmeinfo - > HT_caps . u . HT_cap_element . HT_caps_info | = cpu_to_le16 ( 0x0200 ) ; /* RX STBC two spatial stream */
2014-12-19 04:28:04 +00:00
}
# ifdef CONFIG_DISABLE_MCS13TO15
if ( pmlmeext - > cur_bwmode = = HT_CHANNEL_WIDTH_40 & & ( pregpriv - > wifi_spec ! = 1 ) )
2015-02-19 20:50:04 +00:00
memcpy ( pmlmeinfo - > HT_caps . u . HT_cap_element . MCS_rate , MCS_rate_2R_MCS13TO15_OFF , 16 ) ;
2014-12-19 04:28:04 +00:00
else
2015-02-19 20:50:04 +00:00
memcpy ( pmlmeinfo - > HT_caps . u . HT_cap_element . MCS_rate , MCS_rate_2R , 16 ) ;
2015-02-19 21:34:32 +00:00
# else /* CONFIG_DISABLE_MCS13TO15 */
2015-02-19 20:50:04 +00:00
memcpy ( pmlmeinfo - > HT_caps . u . HT_cap_element . MCS_rate , MCS_rate_2R , 16 ) ;
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_DISABLE_MCS13TO15 */
2014-12-19 04:28:04 +00:00
break ;
2014-12-11 21:15:04 +00:00
}
# ifdef RTL8192C_RECONFIG_TO_1T1R
{
if ( pregpriv - > rx_stbc )
2015-02-19 21:34:32 +00:00
pmlmeinfo - > HT_caps . u . HT_cap_element . HT_caps_info | = cpu_to_le16 ( 0x0100 ) ; /* RX STBC One spatial stream */
2014-12-19 06:59:46 +00:00
2015-02-19 20:50:04 +00:00
memcpy ( pmlmeinfo - > HT_caps . u . HT_cap_element . MCS_rate , MCS_rate_1R , 16 ) ;
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
# endif
# ifdef CONFIG_BT_COEXIST
2014-12-29 02:13:24 +00:00
if ( BT_1Ant ( padapter ) = = true )
2014-12-11 21:15:04 +00:00
{
2015-02-19 21:34:32 +00:00
/* set to 8K */
2014-12-11 21:15:04 +00:00
pmlmeinfo - > HT_caps . u . HT_cap_element . AMPDU_para & = ( u8 ) ~ IEEE80211_HT_CAP_AMPDU_FACTOR ;
}
# endif
2013-05-08 21:45:39 +00:00
pframe = rtw_set_ie ( pframe , _HT_CAPABILITY_IE_ , ie_len , ( u8 * ) ( & ( pmlmeinfo - > HT_caps ) ) , & ( pattrib - > pktlen ) ) ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
}
}
2015-02-19 21:34:32 +00:00
/* vendor specific IE, such as WPA, WMM, WPS */
2014-12-11 21:15:04 +00:00
for ( i = sizeof ( NDIS_802_11_FIXED_IEs ) ; i < pmlmeinfo - > network . IELength ; )
{
pIE = ( PNDIS_802_11_VARIABLE_IEs ) ( pmlmeinfo - > network . IEs + i ) ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
switch ( pIE - > ElementID )
{
case _VENDOR_SPECIFIC_IE_ :
if ( ( _rtw_memcmp ( pIE - > data , RTW_WPA_OUI , 4 ) ) | |
( _rtw_memcmp ( pIE - > data , WMM_OUI , 4 ) ) | |
( _rtw_memcmp ( pIE - > data , WPS_OUI , 4 ) ) )
{
if ( ! padapter - > registrypriv . wifi_spec )
{
2015-02-19 21:34:32 +00:00
/* Commented by Kurt 20110629 */
/* In some older APs, WPS handshake */
/* would be fail if we append vender extensions informations to AP */
2014-12-11 21:15:04 +00:00
if ( _rtw_memcmp ( pIE - > data , WPS_OUI , 4 ) ) {
pIE - > Length = 14 ;
}
}
pframe = rtw_set_ie ( pframe , _VENDOR_SPECIFIC_IE_ , pIE - > Length , pIE - > data , & ( pattrib - > pktlen ) ) ;
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
break ;
default :
break ;
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
i + = ( pIE - > Length + 2 ) ;
}
if ( pmlmeinfo - > assoc_AP_vendor = = HT_IOT_PEER_REALTEK )
2014-12-11 21:15:04 +00:00
{
2013-05-08 21:45:39 +00:00
pframe = rtw_set_ie ( pframe , _VENDOR_SPECIFIC_IE_ , 6 , REALTEK_96B_IE , & ( pattrib - > pktlen ) ) ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_WAPI_SUPPORT
rtw_build_assoc_req_wapi_ie ( padapter , pframe , pattrib ) ;
# endif
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_P2P
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
if ( wdev_to_priv ( padapter - > rtw_wdev ) - > p2p_enabled & & pwdinfo - > driver_interface = = DRIVER_CFG80211 )
{
if ( pmlmepriv - > p2p_assoc_req_ie & & pmlmepriv - > p2p_assoc_req_ie_len > 0 )
{
2015-02-19 20:50:04 +00:00
memcpy ( pframe , pmlmepriv - > p2p_assoc_req_ie , pmlmepriv - > p2p_assoc_req_ie_len ) ;
2014-12-11 21:15:04 +00:00
pframe + = pmlmepriv - > p2p_assoc_req_ie_len ;
pattrib - > pktlen + = pmlmepriv - > p2p_assoc_req_ie_len ;
}
2015-02-20 04:52:01 +00:00
} else {
2014-12-11 21:15:04 +00:00
if ( ! rtw_p2p_chk_state ( pwdinfo , P2P_STATE_NONE ) & & ! rtw_p2p_chk_state ( pwdinfo , P2P_STATE_IDLE ) )
{
2015-02-19 21:34:32 +00:00
/* Should add the P2P IE in the association request frame. */
/* P2P OUI */
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
p2pielen = 0 ;
p2pie [ p2pielen + + ] = 0x50 ;
p2pie [ p2pielen + + ] = 0x6F ;
p2pie [ p2pielen + + ] = 0x9A ;
2015-02-19 21:34:32 +00:00
p2pie [ p2pielen + + ] = 0x09 ; /* WFA P2P v1.0 */
/* Commented by Albert 20101109 */
/* According to the P2P Specification, the association request frame should contain 3 P2P attributes */
/* 1. P2P Capability */
/* 2. Extended Listen Timing */
/* 3. Device Info */
/* Commented by Albert 20110516 */
/* 4. P2P Interface */
/* P2P Capability */
/* Type: */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = P2P_ATTR_CAPABILITY ;
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( 0x0002 ) ;
2014-12-11 21:15:04 +00:00
p2pielen + = 2 ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Value: */
/* Device Capability Bitmap, 1 byte */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = DMP_P2P_DEVCAP_SUPPORT ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Group Capability Bitmap, 1 byte */
2014-12-11 21:15:04 +00:00
if ( pwdinfo - > persistent_supported )
p2pie [ p2pielen + + ] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT ;
else
p2pie [ p2pielen + + ] = DMP_P2P_GRPCAP_SUPPORT ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Extended Listen Timing */
/* Type: */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = P2P_ATTR_EX_LISTEN_TIMING ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( 0x0004 ) ;
2014-12-11 21:15:04 +00:00
p2pielen + = 2 ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Value: */
/* Availability Period */
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( 0xFFFF ) ;
2014-12-11 21:15:04 +00:00
p2pielen + = 2 ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Availability Interval */
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( 0xFFFF ) ;
2014-12-11 21:15:04 +00:00
p2pielen + = 2 ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Device Info */
/* Type: */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = P2P_ATTR_DEVICE_INFO ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Length: */
/* 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
/* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( 21 + pwdinfo - > device_name_len ) ;
2014-12-11 21:15:04 +00:00
p2pielen + = 2 ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Value: */
/* P2P Device Address */
2015-02-19 20:50:04 +00:00
memcpy ( p2pie + p2pielen , myid ( & padapter - > eeprompriv ) , ETH_ALEN ) ;
2014-12-11 21:15:04 +00:00
p2pielen + = ETH_ALEN ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Config Method */
/* This field should be big endian. Noted by P2P specification. */
2014-12-11 21:15:04 +00:00
if ( ( pwdinfo - > ui_got_wps_info = = P2P_GOT_WPSINFO_PEER_DISPLAY_PIN ) | |
( pwdinfo - > ui_got_wps_info = = P2P_GOT_WPSINFO_SELF_DISPLAY_PIN ) )
{
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( p2pie + p2pielen ) = cpu_to_be16 ( WPS_CONFIG_METHOD_DISPLAY ) ;
2014-12-11 21:15:04 +00:00
}
else
{
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( p2pie + p2pielen ) = cpu_to_be16 ( WPS_CONFIG_METHOD_PBC ) ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
p2pielen + = 2 ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Primary Device Type */
/* Category ID */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( p2pie + p2pielen ) = cpu_to_be16 ( WPS_PDT_CID_MULIT_MEDIA ) ;
2014-12-11 21:15:04 +00:00
p2pielen + = 2 ;
2013-05-19 04:28:07 +00:00
2015-02-19 21:34:32 +00:00
/* OUI */
2014-12-19 04:28:04 +00:00
* ( __be32 * ) ( p2pie + p2pielen ) = cpu_to_be32 ( WPSOUI ) ;
2014-12-11 21:15:04 +00:00
p2pielen + = 4 ;
2013-05-19 04:28:07 +00:00
2015-02-19 21:34:32 +00:00
/* Sub Category ID */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( p2pie + p2pielen ) = cpu_to_be16 ( WPS_PDT_SCID_MEDIA_SERVER ) ;
2014-12-11 21:15:04 +00:00
p2pielen + = 2 ;
2013-05-19 04:28:07 +00:00
2015-02-19 21:34:32 +00:00
/* Number of Secondary Device Types */
p2pie [ p2pielen + + ] = 0x00 ; /* No Secondary Device Type List */
2013-07-20 18:18:13 +00:00
2015-02-19 21:34:32 +00:00
/* Device Name */
/* Type: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( p2pie + p2pielen ) = cpu_to_be16 ( WPS_ATTR_DEVICE_NAME ) ;
2014-12-11 21:15:04 +00:00
p2pielen + = 2 ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __be16 * ) ( p2pie + p2pielen ) = cpu_to_be16 ( pwdinfo - > device_name_len ) ;
2014-12-11 21:15:04 +00:00
p2pielen + = 2 ;
2013-05-19 04:28:07 +00:00
2015-02-19 21:34:32 +00:00
/* Value: */
2015-02-19 20:50:04 +00:00
memcpy ( p2pie + p2pielen , pwdinfo - > device_name , pwdinfo - > device_name_len ) ;
2014-12-11 21:15:04 +00:00
p2pielen + = pwdinfo - > device_name_len ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* P2P Interface */
/* Type: */
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = P2P_ATTR_INTERFACE ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* Length: */
2014-12-19 04:28:04 +00:00
* ( __le16 * ) ( p2pie + p2pielen ) = cpu_to_le16 ( 0x000D ) ;
2014-12-11 21:15:04 +00:00
p2pielen + = 2 ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* Value: */
memcpy ( p2pie + p2pielen , pwdinfo - > device_addr , ETH_ALEN ) ; /* P2P Device Address */
2014-12-11 21:15:04 +00:00
p2pielen + = ETH_ALEN ;
2013-05-19 04:28:07 +00:00
2015-02-19 21:34:32 +00:00
p2pie [ p2pielen + + ] = 1 ; /* P2P Interface Address Count */
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
memcpy ( p2pie + p2pielen , pwdinfo - > device_addr , ETH_ALEN ) ; /* P2P Interface Address List */
2014-12-11 21:15:04 +00:00
p2pielen + = ETH_ALEN ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
pframe = rtw_set_ie ( pframe , _VENDOR_SPECIFIC_IE_ , p2pielen , ( unsigned char * ) p2pie , & pattrib - > pktlen ) ;
# ifdef CONFIG_WFD
2015-02-19 21:34:32 +00:00
/* wfdielen = build_assoc_req_wfd_ie(pwdinfo, pframe); */
/* pframe += wfdielen; */
/* pattrib->pktlen += wfdielen; */
# endif /* CONFIG_WFD */
2014-12-11 21:15:04 +00:00
}
}
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_P2P */
2013-07-20 18:18:13 +00:00
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_WFD
2014-12-29 02:13:24 +00:00
if ( true = = pwdinfo - > wfd_info - > wfd_enable )
2014-12-11 21:15:04 +00:00
{
wfdielen = build_assoc_req_wfd_ie ( pwdinfo , pframe ) ;
pframe + = wfdielen ;
pattrib - > pktlen + = wfdielen ;
2013-05-08 21:45:39 +00:00
}
2014-12-19 06:59:46 +00:00
else if ( pmlmepriv - > wfd_assoc_req_ie ! = NULL & & pmlmepriv - > wfd_assoc_req_ie_len > 0 )
2014-12-11 21:15:04 +00:00
{
2015-02-19 21:34:32 +00:00
/* WFD IE */
2015-02-19 20:50:04 +00:00
memcpy ( pframe , pmlmepriv - > wfd_assoc_req_ie , pmlmepriv - > wfd_assoc_req_ie_len ) ;
2014-12-11 21:15:04 +00:00
pattrib - > pktlen + = pmlmepriv - > wfd_assoc_req_ie_len ;
2014-12-19 06:59:46 +00:00
pframe + = pmlmepriv - > wfd_assoc_req_ie_len ;
2014-12-11 21:15:04 +00:00
}
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_WFD */
2013-05-08 21:45:39 +00:00
pattrib - > last_txcmdsz = pattrib - > pktlen ;
dump_mgntframe ( padapter , pmgntframe ) ;
ret = _SUCCESS ;
exit :
if ( ret = = _SUCCESS )
rtw_buf_update ( & pmlmepriv - > assoc_req , & pmlmepriv - > assoc_req_len , ( u8 * ) pwlanhdr , pattrib - > pktlen ) ;
else
rtw_buf_free ( & pmlmepriv - > assoc_req , & pmlmepriv - > assoc_req_len ) ;
return ;
}
2015-02-19 21:34:32 +00:00
/* when wait_ack is ture, this function shoule be called at process context */
2014-12-17 23:13:53 +00:00
static int _issue_nulldata ( struct adapter * padapter , unsigned char * da , unsigned int power_mode , int wait_ack )
2013-05-08 21:45:39 +00:00
{
int ret = _FAIL ;
struct xmit_frame * pmgntframe ;
struct pkt_attrib * pattrib ;
unsigned char * pframe ;
struct rtw_ieee80211_hdr * pwlanhdr ;
2014-12-19 04:28:04 +00:00
__le16 * fctrl ;
2013-05-08 21:45:39 +00:00
struct xmit_priv * pxmitpriv ;
struct mlme_ext_priv * pmlmeext ;
struct mlme_ext_info * pmlmeinfo ;
2015-02-19 21:34:32 +00:00
/* DBG_871X("%s:%d\n", __FUNCTION__, power_mode); */
2014-12-11 21:15:04 +00:00
if ( ! padapter )
2013-05-08 21:45:39 +00:00
goto exit ;
pxmitpriv = & ( padapter - > xmitpriv ) ;
pmlmeext = & ( padapter - > mlmeextpriv ) ;
pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
2014-12-11 21:15:04 +00:00
if ( ( pmgntframe = alloc_mgtxmitframe ( pxmitpriv ) ) = = NULL )
{
2013-05-08 21:45:39 +00:00
goto exit ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* update attribute */
2013-05-08 21:45:39 +00:00
pattrib = & pmgntframe - > attrib ;
update_mgntframe_attrib ( padapter , pattrib ) ;
2014-12-29 02:13:24 +00:00
pattrib - > retry_ctrl = false ;
2013-05-08 21:45:39 +00:00
2015-02-19 20:58:09 +00:00
memset ( pmgntframe - > buf_addr , 0 , WLANHDR_OFFSET + TXDESC_OFFSET ) ;
2013-05-08 21:45:39 +00:00
pframe = ( u8 * ) ( pmgntframe - > buf_addr ) + TXDESC_OFFSET ;
pwlanhdr = ( struct rtw_ieee80211_hdr * ) pframe ;
fctrl = & ( pwlanhdr - > frame_ctl ) ;
* ( fctrl ) = 0 ;
2014-12-11 21:15:04 +00:00
if ( ( pmlmeinfo - > state & 0x03 ) = = WIFI_FW_AP_STATE )
{
2013-05-08 21:45:39 +00:00
SetFrDs ( fctrl ) ;
2014-12-11 21:15:04 +00:00
}
else if ( ( pmlmeinfo - > state & 0x03 ) = = WIFI_FW_STATION_STATE )
{
2013-05-08 21:45:39 +00:00
SetToDs ( fctrl ) ;
2014-12-11 21:15:04 +00:00
}
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
if ( power_mode )
2014-12-11 21:15:04 +00:00
{
2013-05-08 21:45:39 +00:00
SetPwrMgt ( fctrl ) ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
2015-02-19 20:50:04 +00:00
memcpy ( pwlanhdr - > addr1 , da , ETH_ALEN ) ;
memcpy ( pwlanhdr - > addr2 , myid ( & ( padapter - > eeprompriv ) ) , ETH_ALEN ) ;
memcpy ( pwlanhdr - > addr3 , get_my_bssid ( & ( pmlmeinfo - > network ) ) , ETH_ALEN ) ;
2013-05-08 21:45:39 +00:00
SetSeqNum ( pwlanhdr , pmlmeext - > mgnt_seq ) ;
pmlmeext - > mgnt_seq + + ;
SetFrameSubType ( pframe , WIFI_DATA_NULL ) ;
pframe + = sizeof ( struct rtw_ieee80211_hdr_3addr ) ;
pattrib - > pktlen = sizeof ( struct rtw_ieee80211_hdr_3addr ) ;
pattrib - > last_txcmdsz = pattrib - > pktlen ;
2014-12-11 21:15:04 +00:00
if ( wait_ack )
{
2013-05-08 21:45:39 +00:00
ret = dump_mgntframe_and_wait_ack ( padapter , pmgntframe ) ;
2014-12-11 21:15:04 +00:00
}
else
{
2013-05-08 21:45:39 +00:00
dump_mgntframe ( padapter , pmgntframe ) ;
ret = _SUCCESS ;
}
exit :
return ret ;
}
2014-12-11 21:15:04 +00:00
2015-02-19 21:34:32 +00:00
/* when wait_ms >0 , this function shoule be called at process context */
/* da == NULL for station mode */
2014-12-17 23:13:53 +00:00
int issue_nulldata ( struct adapter * padapter , unsigned char * da , unsigned int power_mode , int try_cnt , int wait_ms )
2013-05-08 21:45:39 +00:00
{
int ret ;
int i = 0 ;
u32 start = rtw_get_current_time ( ) ;
struct mlme_ext_priv * pmlmeext = & ( padapter - > mlmeextpriv ) ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
/* da == NULL, assum it's null data for sta to ap*/
if ( da = = NULL )
da = get_my_bssid ( & ( pmlmeinfo - > network ) ) ;
2014-12-11 21:15:04 +00:00
do
{
2014-12-29 02:13:24 +00:00
ret = _issue_nulldata ( padapter , da , power_mode , wait_ms > 0 ? true : false ) ;
2013-05-08 21:45:39 +00:00
i + + ;
if ( padapter - > bDriverStopped | | padapter - > bSurpriseRemoved )
break ;
2014-12-11 21:15:04 +00:00
if ( i < try_cnt & & wait_ms > 0 & & ret = = _FAIL )
2013-05-08 21:45:39 +00:00
rtw_msleep_os ( wait_ms ) ;
2014-12-11 21:15:04 +00:00
} while ( ( i < try_cnt ) & & ( ( ret = = _FAIL ) | | ( wait_ms = = 0 ) ) ) ;
2013-05-08 21:45:39 +00:00
if ( ret ! = _FAIL ) {
ret = _SUCCESS ;
2014-12-11 21:15:04 +00:00
# ifndef DBG_XMIT_ACK
2013-05-08 21:45:39 +00:00
goto exit ;
2014-12-11 21:15:04 +00:00
# endif
2013-05-08 21:45:39 +00:00
}
if ( try_cnt & & wait_ms ) {
if ( da )
2014-12-11 21:15:04 +00:00
DBG_871X ( FUNC_ADPT_FMT " to " MAC_FMT " , ch:%u%s, %d/%d in %u ms \n " ,
FUNC_ADPT_ARG ( padapter ) , MAC_ARG ( da ) , rtw_get_oper_ch ( padapter ) ,
ret = = _SUCCESS ? " , acked " : " " , i , try_cnt , rtw_get_passing_time_ms ( start ) ) ;
2013-05-08 21:45:39 +00:00
else
2014-12-11 21:15:04 +00:00
DBG_871X ( FUNC_ADPT_FMT " , ch:%u%s, %d/%d in %u ms \n " ,
2013-05-08 21:45:39 +00:00
FUNC_ADPT_ARG ( padapter ) , rtw_get_oper_ch ( padapter ) ,
2014-12-11 21:15:04 +00:00
ret = = _SUCCESS ? " , acked " : " " , i , try_cnt , rtw_get_passing_time_ms ( start ) ) ;
2013-05-08 21:45:39 +00:00
}
exit :
return ret ;
}
2015-02-19 21:34:32 +00:00
/* when wait_ack is ture, this function shoule be called at process context */
2014-12-17 23:13:53 +00:00
static int _issue_qos_nulldata ( struct adapter * padapter , unsigned char * da , u16 tid , int wait_ack )
2013-05-08 21:45:39 +00:00
{
int ret = _FAIL ;
struct xmit_frame * pmgntframe ;
struct pkt_attrib * pattrib ;
unsigned char * pframe ;
struct rtw_ieee80211_hdr * pwlanhdr ;
2014-12-19 06:59:46 +00:00
__le16 * fctrl ;
2014-12-19 04:28:04 +00:00
unsigned short * qc ;
2013-05-08 21:45:39 +00:00
struct xmit_priv * pxmitpriv = & ( padapter - > xmitpriv ) ;
struct mlme_ext_priv * pmlmeext = & ( padapter - > mlmeextpriv ) ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
2014-12-11 21:15:04 +00:00
DBG_871X ( " %s \n " , __FUNCTION__ ) ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
if ( ( pmgntframe = alloc_mgtxmitframe ( pxmitpriv ) ) = = NULL )
{
2013-05-08 21:45:39 +00:00
goto exit ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* update attribute */
2013-05-08 21:45:39 +00:00
pattrib = & pmgntframe - > attrib ;
update_mgntframe_attrib ( padapter , pattrib ) ;
2014-12-11 21:15:04 +00:00
pattrib - > hdrlen + = 2 ;
2014-12-29 02:13:24 +00:00
pattrib - > qos_en = true ;
2013-05-08 21:45:39 +00:00
pattrib - > eosp = 1 ;
pattrib - > ack_policy = 0 ;
pattrib - > mdata = 0 ;
2015-02-19 20:58:09 +00:00
memset ( pmgntframe - > buf_addr , 0 , WLANHDR_OFFSET + TXDESC_OFFSET ) ;
2013-05-08 21:45:39 +00:00
pframe = ( u8 * ) ( pmgntframe - > buf_addr ) + TXDESC_OFFSET ;
pwlanhdr = ( struct rtw_ieee80211_hdr * ) pframe ;
fctrl = & ( pwlanhdr - > frame_ctl ) ;
* ( fctrl ) = 0 ;
2014-12-11 21:15:04 +00:00
if ( ( pmlmeinfo - > state & 0x03 ) = = WIFI_FW_AP_STATE )
{
2013-05-08 21:45:39 +00:00
SetFrDs ( fctrl ) ;
2014-12-11 21:15:04 +00:00
}
else if ( ( pmlmeinfo - > state & 0x03 ) = = WIFI_FW_STATION_STATE )
{
2013-05-08 21:45:39 +00:00
SetToDs ( fctrl ) ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
if ( pattrib - > mdata )
2013-05-08 21:45:39 +00:00
SetMData ( fctrl ) ;
qc = ( unsigned short * ) ( pframe + pattrib - > hdrlen - 2 ) ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
SetPriority ( qc , tid ) ;
SetEOSP ( qc , pattrib - > eosp ) ;
SetAckpolicy ( qc , pattrib - > ack_policy ) ;
2015-02-19 20:50:04 +00:00
memcpy ( pwlanhdr - > addr1 , da , ETH_ALEN ) ;
memcpy ( pwlanhdr - > addr2 , myid ( & ( padapter - > eeprompriv ) ) , ETH_ALEN ) ;
memcpy ( pwlanhdr - > addr3 , get_my_bssid ( & ( pmlmeinfo - > network ) ) , ETH_ALEN ) ;
2013-05-08 21:45:39 +00:00
SetSeqNum ( pwlanhdr , pmlmeext - > mgnt_seq ) ;
pmlmeext - > mgnt_seq + + ;
SetFrameSubType ( pframe , WIFI_QOS_DATA_NULL ) ;
pframe + = sizeof ( struct rtw_ieee80211_hdr_3addr_qos ) ;
pattrib - > pktlen = sizeof ( struct rtw_ieee80211_hdr_3addr_qos ) ;
pattrib - > last_txcmdsz = pattrib - > pktlen ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
if ( wait_ack )
{
2013-05-08 21:45:39 +00:00
ret = dump_mgntframe_and_wait_ack ( padapter , pmgntframe ) ;
2014-12-11 21:15:04 +00:00
}
else
{
2013-05-08 21:45:39 +00:00
dump_mgntframe ( padapter , pmgntframe ) ;
ret = _SUCCESS ;
}
exit :
return ret ;
}
2015-02-19 21:34:32 +00:00
/* when wait_ms >0 , this function shoule be called at process context */
/* da == NULL for station mode */
2014-12-17 23:13:53 +00:00
int issue_qos_nulldata ( struct adapter * padapter , unsigned char * da , u16 tid , int try_cnt , int wait_ms )
2013-05-08 21:45:39 +00:00
{
int ret ;
int i = 0 ;
u32 start = rtw_get_current_time ( ) ;
struct mlme_ext_priv * pmlmeext = & ( padapter - > mlmeextpriv ) ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
/* da == NULL, assum it's null data for sta to ap*/
if ( da = = NULL )
da = get_my_bssid ( & ( pmlmeinfo - > network ) ) ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
do
{
2014-12-29 02:13:24 +00:00
ret = _issue_qos_nulldata ( padapter , da , tid , wait_ms > 0 ? true : false ) ;
2013-05-08 21:45:39 +00:00
i + + ;
if ( padapter - > bDriverStopped | | padapter - > bSurpriseRemoved )
break ;
2014-12-11 21:15:04 +00:00
if ( i < try_cnt & & wait_ms > 0 & & ret = = _FAIL )
2013-05-08 21:45:39 +00:00
rtw_msleep_os ( wait_ms ) ;
2014-12-11 21:15:04 +00:00
} while ( ( i < try_cnt ) & & ( ( ret = = _FAIL ) | | ( wait_ms = = 0 ) ) ) ;
2013-05-08 21:45:39 +00:00
if ( ret ! = _FAIL ) {
ret = _SUCCESS ;
2014-12-11 21:15:04 +00:00
# ifndef DBG_XMIT_ACK
2013-05-08 21:45:39 +00:00
goto exit ;
2014-12-11 21:15:04 +00:00
# endif
2013-05-08 21:45:39 +00:00
}
if ( try_cnt & & wait_ms ) {
if ( da )
2014-12-11 21:15:04 +00:00
DBG_871X ( FUNC_ADPT_FMT " to " MAC_FMT " , ch:%u%s, %d/%d in %u ms \n " ,
FUNC_ADPT_ARG ( padapter ) , MAC_ARG ( da ) , rtw_get_oper_ch ( padapter ) ,
ret = = _SUCCESS ? " , acked " : " " , i , try_cnt , rtw_get_passing_time_ms ( start ) ) ;
2013-05-08 21:45:39 +00:00
else
2014-12-11 21:15:04 +00:00
DBG_871X ( FUNC_ADPT_FMT " , ch:%u%s, %d/%d in %u ms \n " ,
2013-05-08 21:45:39 +00:00
FUNC_ADPT_ARG ( padapter ) , rtw_get_oper_ch ( padapter ) ,
2014-12-11 21:15:04 +00:00
ret = = _SUCCESS ? " , acked " : " " , i , try_cnt , rtw_get_passing_time_ms ( start ) ) ;
2013-05-08 21:45:39 +00:00
}
exit :
return ret ;
}
2014-12-17 23:13:53 +00:00
static int _issue_deauth ( struct adapter * padapter , unsigned char * da , unsigned short reason , u8 wait_ack )
2013-05-08 21:45:39 +00:00
{
struct xmit_frame * pmgntframe ;
struct pkt_attrib * pattrib ;
unsigned char * pframe ;
struct rtw_ieee80211_hdr * pwlanhdr ;
2014-12-19 04:28:04 +00:00
__le16 * fctrl ;
2013-05-08 21:45:39 +00:00
struct xmit_priv * pxmitpriv = & ( padapter - > xmitpriv ) ;
struct mlme_ext_priv * pmlmeext = & ( padapter - > mlmeextpriv ) ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
int ret = _FAIL ;
2015-02-18 17:42:22 +00:00
__le16 le_tmp ;
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_P2P
struct wifidirect_info * pwdinfo = & ( padapter - > wdinfo ) ;
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_P2P */
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* DBG_871X("%s to "MAC_FMT"\n", __func__, MAC_ARG(da)); */
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_P2P
if ( ! ( rtw_p2p_chk_state ( pwdinfo , P2P_STATE_NONE ) ) & & ( pwdinfo - > rx_invitereq_info . scan_op_ch_only ) )
{
_cancel_timer_ex ( & pwdinfo - > reset_ch_sitesurvey ) ;
_set_timer ( & pwdinfo - > reset_ch_sitesurvey , 10 ) ;
2013-05-08 21:45:39 +00:00
}
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_P2P */
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
if ( ( pmgntframe = alloc_mgtxmitframe ( pxmitpriv ) ) = = NULL )
{
2013-05-08 21:45:39 +00:00
goto exit ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* update attribute */
2013-05-08 21:45:39 +00:00
pattrib = & pmgntframe - > attrib ;
update_mgntframe_attrib ( padapter , pattrib ) ;
2014-12-29 02:13:24 +00:00
pattrib - > retry_ctrl = false ;
2013-05-08 21:45:39 +00:00
2015-02-19 20:58:09 +00:00
memset ( pmgntframe - > buf_addr , 0 , WLANHDR_OFFSET + TXDESC_OFFSET ) ;
2013-05-08 21:45:39 +00:00
pframe = ( u8 * ) ( pmgntframe - > buf_addr ) + TXDESC_OFFSET ;
pwlanhdr = ( struct rtw_ieee80211_hdr * ) pframe ;
fctrl = & ( pwlanhdr - > frame_ctl ) ;
* ( fctrl ) = 0 ;
2015-02-19 20:50:04 +00:00
memcpy ( pwlanhdr - > addr1 , da , ETH_ALEN ) ;
memcpy ( pwlanhdr - > addr2 , myid ( & ( padapter - > eeprompriv ) ) , ETH_ALEN ) ;
memcpy ( pwlanhdr - > addr3 , get_my_bssid ( & ( pmlmeinfo - > network ) ) , ETH_ALEN ) ;
2013-05-08 21:45:39 +00:00
SetSeqNum ( pwlanhdr , pmlmeext - > mgnt_seq ) ;
pmlmeext - > mgnt_seq + + ;
SetFrameSubType ( pframe , WIFI_DEAUTH ) ;
pframe + = sizeof ( struct rtw_ieee80211_hdr_3addr ) ;
pattrib - > pktlen = sizeof ( struct rtw_ieee80211_hdr_3addr ) ;
2015-02-18 17:42:22 +00:00
le_tmp = cpu_to_le16 ( reason ) ;
pframe = rtw_set_fixed_ie ( pframe , _RSON_CODE_ , ( unsigned char * ) & le_tmp , & ( pattrib - > pktlen ) ) ;
2013-05-08 21:45:39 +00:00
pattrib - > last_txcmdsz = pattrib - > pktlen ;
2014-12-11 21:15:04 +00:00
if ( wait_ack )
{
2013-05-08 21:45:39 +00:00
ret = dump_mgntframe_and_wait_ack ( padapter , pmgntframe ) ;
2014-12-11 21:15:04 +00:00
}
else
{
2013-05-08 21:45:39 +00:00
dump_mgntframe ( padapter , pmgntframe ) ;
ret = _SUCCESS ;
}
exit :
return ret ;
}
2014-12-17 23:13:53 +00:00
int issue_deauth ( struct adapter * padapter , unsigned char * da , unsigned short reason )
2013-05-08 21:45:39 +00:00
{
2014-12-11 21:15:04 +00:00
DBG_871X ( " %s to " MAC_FMT " \n " , __func__ , MAC_ARG ( da ) ) ;
2014-12-29 02:13:24 +00:00
return _issue_deauth ( padapter , da , reason , false ) ;
2013-05-08 21:45:39 +00:00
}
2014-12-17 23:13:53 +00:00
int issue_deauth_ex ( struct adapter * padapter , u8 * da , unsigned short reason , int try_cnt ,
2013-05-08 21:45:39 +00:00
int wait_ms )
{
int ret ;
int i = 0 ;
u32 start = rtw_get_current_time ( ) ;
2014-12-11 21:15:04 +00:00
do
{
2014-12-29 02:13:24 +00:00
ret = _issue_deauth ( padapter , da , reason , wait_ms > 0 ? true : false ) ;
2013-05-08 21:45:39 +00:00
i + + ;
if ( padapter - > bDriverStopped | | padapter - > bSurpriseRemoved )
break ;
2014-12-11 21:15:04 +00:00
if ( i < try_cnt & & wait_ms > 0 & & ret = = _FAIL )
2013-05-08 21:45:39 +00:00
rtw_msleep_os ( wait_ms ) ;
2014-12-11 21:15:04 +00:00
} while ( ( i < try_cnt ) & & ( ( ret = = _FAIL ) | | ( wait_ms = = 0 ) ) ) ;
2013-05-08 21:45:39 +00:00
if ( ret ! = _FAIL ) {
ret = _SUCCESS ;
2014-12-11 21:15:04 +00:00
# ifndef DBG_XMIT_ACK
2013-05-08 21:45:39 +00:00
goto exit ;
2014-12-11 21:15:04 +00:00
# endif
2013-05-08 21:45:39 +00:00
}
if ( try_cnt & & wait_ms ) {
if ( da )
2014-12-11 21:15:04 +00:00
DBG_871X ( FUNC_ADPT_FMT " to " MAC_FMT " , ch:%u%s, %d/%d in %u ms \n " ,
FUNC_ADPT_ARG ( padapter ) , MAC_ARG ( da ) , rtw_get_oper_ch ( padapter ) ,
ret = = _SUCCESS ? " , acked " : " " , i , try_cnt , rtw_get_passing_time_ms ( start ) ) ;
2013-05-08 21:45:39 +00:00
else
2014-12-11 21:15:04 +00:00
DBG_871X ( FUNC_ADPT_FMT " , ch:%u%s, %d/%d in %u ms \n " ,
2013-05-08 21:45:39 +00:00
FUNC_ADPT_ARG ( padapter ) , rtw_get_oper_ch ( padapter ) ,
2014-12-11 21:15:04 +00:00
ret = = _SUCCESS ? " , acked " : " " , i , try_cnt , rtw_get_passing_time_ms ( start ) ) ;
2013-05-08 21:45:39 +00:00
}
exit :
return ret ;
}
2014-12-17 23:13:53 +00:00
void issue_action_spct_ch_switch ( struct adapter * padapter , u8 * ra , u8 new_ch , u8 ch_offset )
2014-12-19 06:59:46 +00:00
{
2014-12-11 21:15:04 +00:00
_irqL irqL ;
_list * plist , * phead ;
2013-05-08 21:45:39 +00:00
struct xmit_frame * pmgntframe ;
struct pkt_attrib * pattrib ;
unsigned char * pframe ;
struct rtw_ieee80211_hdr * pwlanhdr ;
2014-12-19 04:28:04 +00:00
__le16 * fctrl ;
2013-05-08 21:45:39 +00:00
struct xmit_priv * pxmitpriv = & ( padapter - > xmitpriv ) ;
2014-12-11 21:15:04 +00:00
struct mlme_priv * pmlmepriv = & padapter - > mlmepriv ;
2013-05-08 21:45:39 +00:00
struct mlme_ext_priv * pmlmeext = & ( padapter - > mlmeextpriv ) ;
2014-12-11 21:15:04 +00:00
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
DBG_871X ( FUNC_NDEV_FMT " ra= " MAC_FMT " , ch:%u, offset:%u \n " ,
FUNC_NDEV_ARG ( padapter - > pnetdev ) , MAC_ARG ( ra ) , new_ch , ch_offset ) ;
if ( ( pmgntframe = alloc_mgtxmitframe ( pxmitpriv ) ) = = NULL )
2013-05-08 21:45:39 +00:00
return ;
2015-02-19 21:34:32 +00:00
/* update attribute */
2013-05-08 21:45:39 +00:00
pattrib = & pmgntframe - > attrib ;
update_mgntframe_attrib ( padapter , pattrib ) ;
2015-02-19 20:58:09 +00:00
memset ( pmgntframe - > buf_addr , 0 , WLANHDR_OFFSET + TXDESC_OFFSET ) ;
2013-05-08 21:45:39 +00:00
pframe = ( u8 * ) ( pmgntframe - > buf_addr ) + TXDESC_OFFSET ;
pwlanhdr = ( struct rtw_ieee80211_hdr * ) pframe ;
fctrl = & ( pwlanhdr - > frame_ctl ) ;
* ( fctrl ) = 0 ;
2015-02-19 20:50:04 +00:00
memcpy ( pwlanhdr - > addr1 , ra , ETH_ALEN ) ; /* RA */
memcpy ( pwlanhdr - > addr2 , myid ( & ( padapter - > eeprompriv ) ) , ETH_ALEN ) ; /* TA */
memcpy ( pwlanhdr - > addr3 , ra , ETH_ALEN ) ; /* DA = RA */
2013-05-08 21:45:39 +00:00
SetSeqNum ( pwlanhdr , pmlmeext - > mgnt_seq ) ;
pmlmeext - > mgnt_seq + + ;
SetFrameSubType ( pframe , WIFI_ACTION ) ;
pframe + = sizeof ( struct rtw_ieee80211_hdr_3addr ) ;
pattrib - > pktlen = sizeof ( struct rtw_ieee80211_hdr_3addr ) ;
/* category, action */
{
u8 category , action ;
category = RTW_WLAN_CATEGORY_SPECTRUM_MGMT ;
action = RTW_WLAN_ACTION_SPCT_CHL_SWITCH ;
pframe = rtw_set_fixed_ie ( pframe , 1 , & ( category ) , & ( pattrib - > pktlen ) ) ;
pframe = rtw_set_fixed_ie ( pframe , 1 , & ( action ) , & ( pattrib - > pktlen ) ) ;
}
2014-12-11 21:15:04 +00:00
pframe = rtw_set_ie_ch_switch ( pframe , & ( pattrib - > pktlen ) , 0 , new_ch , 0 ) ;
2013-05-08 21:45:39 +00:00
pframe = rtw_set_ie_secondary_ch_offset ( pframe , & ( pattrib - > pktlen ) ,
hal_ch_offset_to_secondary_ch_offset ( ch_offset ) ) ;
pattrib - > last_txcmdsz = pattrib - > pktlen ;
dump_mgntframe ( padapter , pmgntframe ) ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_IEEE80211W
2014-12-17 23:13:53 +00:00
void issue_action_SA_Query ( struct adapter * padapter , unsigned char * raddr , unsigned char action , unsigned short tid )
2013-05-08 21:45:39 +00:00
{
2014-12-11 21:15:04 +00:00
u8 category = RTW_WLAN_CATEGORY_SA_QUERY ;
u16 reason_code ;
struct xmit_frame * pmgntframe ;
struct pkt_attrib * pattrib ;
u8 * pframe ;
struct rtw_ieee80211_hdr * pwlanhdr ;
u16 * fctrl ;
struct xmit_priv * pxmitpriv = & ( padapter - > xmitpriv ) ;
struct mlme_ext_priv * pmlmeext = & ( padapter - > mlmeextpriv ) ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
struct sta_info * psta ;
struct sta_priv * pstapriv = & padapter - > stapriv ;
2014-12-19 06:59:46 +00:00
struct registry_priv * pregpriv = & padapter - > registrypriv ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
DBG_871X ( " %s \n " , __FUNCTION__ ) ;
if ( ( pmgntframe = alloc_mgtxmitframe ( pxmitpriv ) ) = = NULL )
{
DBG_871X ( " %s: alloc_mgtxmitframe fail \n " , __FUNCTION__ ) ;
2013-05-08 21:45:39 +00:00
return ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* update attribute */
2013-05-08 21:45:39 +00:00
pattrib = & pmgntframe - > attrib ;
update_mgntframe_attrib ( padapter , pattrib ) ;
2015-02-19 20:58:09 +00:00
memset ( pmgntframe - > buf_addr , 0 , WLANHDR_OFFSET + TXDESC_OFFSET ) ;
2013-05-08 21:45:39 +00:00
pframe = ( u8 * ) ( pmgntframe - > buf_addr ) + TXDESC_OFFSET ;
pwlanhdr = ( struct rtw_ieee80211_hdr * ) pframe ;
fctrl = & ( pwlanhdr - > frame_ctl ) ;
* ( fctrl ) = 0 ;
2014-12-11 21:15:04 +00:00
if ( raddr )
2015-02-19 20:50:04 +00:00
memcpy ( pwlanhdr - > addr1 , raddr , ETH_ALEN ) ;
2014-12-11 21:15:04 +00:00
else
2015-02-19 20:50:04 +00:00
memcpy ( pwlanhdr - > addr1 , get_my_bssid ( & ( pmlmeinfo - > network ) ) , ETH_ALEN ) ;
memcpy ( pwlanhdr - > addr2 , myid ( & ( padapter - > eeprompriv ) ) , ETH_ALEN ) ;
memcpy ( pwlanhdr - > addr3 , get_my_bssid ( & ( pmlmeinfo - > network ) ) , ETH_ALEN ) ;
2013-05-08 21:45:39 +00:00
SetSeqNum ( pwlanhdr , pmlmeext - > mgnt_seq ) ;
pmlmeext - > mgnt_seq + + ;
SetFrameSubType ( pframe , WIFI_ACTION ) ;
pframe + = sizeof ( struct rtw_ieee80211_hdr_3addr ) ;
pattrib - > pktlen = sizeof ( struct rtw_ieee80211_hdr_3addr ) ;
2014-12-11 21:15:04 +00:00
pframe = rtw_set_fixed_ie ( pframe , 1 , & category , & pattrib - > pktlen ) ;
pframe = rtw_set_fixed_ie ( pframe , 1 , & action , & pattrib - > pktlen ) ;
2013-05-19 04:28:07 +00:00
2014-12-11 21:15:04 +00:00
switch ( action )
{
2015-02-19 21:34:32 +00:00
case 0 : /* SA Query req */
2014-12-11 21:15:04 +00:00
pframe = rtw_set_fixed_ie ( pframe , 2 , ( unsigned char * ) & pmlmeext - > sa_query_seq , & pattrib - > pktlen ) ;
pmlmeext - > sa_query_seq + + ;
2015-02-19 21:34:32 +00:00
/* send sa query request to AP, AP should reply sa query response in 1 second */
2014-12-11 21:15:04 +00:00
set_sa_query_timer ( pmlmeext , 1000 ) ;
2013-06-07 14:43:09 +00:00
break ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
case 1 : /* SA Query rsp */
2014-12-11 21:15:04 +00:00
tid = cpu_to_le16 ( tid ) ;
pframe = rtw_set_fixed_ie ( pframe , 2 , ( unsigned char * ) & tid , & pattrib - > pktlen ) ;
2013-06-07 14:43:09 +00:00
break ;
default :
break ;
2013-05-08 21:45:39 +00:00
}
pattrib - > last_txcmdsz = pattrib - > pktlen ;
dump_mgntframe ( padapter , pmgntframe ) ;
}
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_IEEE80211W */
2013-05-08 21:45:39 +00:00
2014-12-19 04:28:04 +00:00
static void issue_action_BA ( struct adapter * padapter , unsigned char * raddr ,
unsigned char action , u16 status )
2013-05-19 04:28:07 +00:00
{
2014-12-11 21:15:04 +00:00
u8 category = RTW_WLAN_CATEGORY_BACK ;
u16 start_seq ;
u16 BA_para_set ;
2014-12-19 04:28:04 +00:00
__le16 le_tmp ;
2014-12-11 21:15:04 +00:00
u16 reason_code ;
u16 BA_timeout_value ;
u16 BA_starting_seqctrl ;
HT_CAP_AMPDU_FACTOR max_rx_ampdu_factor ;
struct xmit_frame * pmgntframe ;
struct pkt_attrib * pattrib ;
2014-12-19 04:28:04 +00:00
u8 * pframe ;
2013-05-08 21:45:39 +00:00
struct rtw_ieee80211_hdr * pwlanhdr ;
2014-12-19 04:28:04 +00:00
__le16 * fctrl ;
2014-12-11 21:15:04 +00:00
struct xmit_priv * pxmitpriv = & ( padapter - > xmitpriv ) ;
2013-05-08 21:45:39 +00:00
struct mlme_ext_priv * pmlmeext = & ( padapter - > mlmeextpriv ) ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
2014-12-11 21:15:04 +00:00
struct sta_info * psta ;
struct sta_priv * pstapriv = & padapter - > stapriv ;
2014-12-19 06:59:46 +00:00
struct registry_priv * pregpriv = & padapter - > registrypriv ;
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_BT_COEXIST
u8 tendaAPMac [ ] = { 0xC8 , 0x3A , 0x35 } ;
# endif
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
DBG_871X ( " %s, category=%d, action=%d, status=%d \n " , __FUNCTION__ , category , action , status ) ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
if ( ( pmgntframe = alloc_mgtxmitframe ( pxmitpriv ) ) = = NULL )
{
2013-05-08 21:45:39 +00:00
return ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* update attribute */
2013-05-08 21:45:39 +00:00
pattrib = & pmgntframe - > attrib ;
update_mgntframe_attrib ( padapter , pattrib ) ;
2015-02-19 20:58:09 +00:00
memset ( pmgntframe - > buf_addr , 0 , WLANHDR_OFFSET + TXDESC_OFFSET ) ;
2013-05-08 21:45:39 +00:00
pframe = ( u8 * ) ( pmgntframe - > buf_addr ) + TXDESC_OFFSET ;
pwlanhdr = ( struct rtw_ieee80211_hdr * ) pframe ;
fctrl = & ( pwlanhdr - > frame_ctl ) ;
* ( fctrl ) = 0 ;
2015-02-19 21:34:32 +00:00
/* memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); */
2015-02-19 20:50:04 +00:00
memcpy ( pwlanhdr - > addr1 , raddr , ETH_ALEN ) ;
memcpy ( pwlanhdr - > addr2 , myid ( & ( padapter - > eeprompriv ) ) , ETH_ALEN ) ;
memcpy ( pwlanhdr - > addr3 , get_my_bssid ( & ( pmlmeinfo - > network ) ) , ETH_ALEN ) ;
2013-05-08 21:45:39 +00:00
SetSeqNum ( pwlanhdr , pmlmeext - > mgnt_seq ) ;
pmlmeext - > mgnt_seq + + ;
SetFrameSubType ( pframe , WIFI_ACTION ) ;
pframe + = sizeof ( struct rtw_ieee80211_hdr_3addr ) ;
pattrib - > pktlen = sizeof ( struct rtw_ieee80211_hdr_3addr ) ;
pframe = rtw_set_fixed_ie ( pframe , 1 , & ( category ) , & ( pattrib - > pktlen ) ) ;
pframe = rtw_set_fixed_ie ( pframe , 1 , & ( action ) , & ( pattrib - > pktlen ) ) ;
2014-12-19 04:28:04 +00:00
if ( category = = 3 ) {
switch ( action ) {
2015-02-19 21:34:32 +00:00
case 0 : /* ADDBA req */
2014-12-19 04:28:04 +00:00
do {
pmlmeinfo - > dialogToken + + ;
} while ( pmlmeinfo - > dialogToken = = 0 ) ;
pframe = rtw_set_fixed_ie ( pframe , 1 , & ( pmlmeinfo - > dialogToken ) , & ( pattrib - > pktlen ) ) ;
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_BT_COEXIST
2014-12-29 02:13:24 +00:00
if ( ( BT_1Ant ( padapter ) = = true ) & &
2014-12-19 04:28:04 +00:00
( ( pmlmeinfo - > assoc_AP_vendor ! = broadcomAP ) | |
2014-12-29 02:13:24 +00:00
( _rtw_memcmp ( raddr , tendaAPMac , 3 ) = = false ) ) ) {
2015-02-19 21:34:32 +00:00
/* A-MSDU NOT Supported */
2014-12-19 04:28:04 +00:00
BA_para_set = 0 ;
2015-02-19 21:34:32 +00:00
/* immediate Block Ack */
2014-12-19 04:28:04 +00:00
BA_para_set | = ( 1 < < 1 ) & IEEE80211_ADDBA_PARAM_POLICY_MASK ;
2015-02-19 21:34:32 +00:00
/* TID */
2014-12-19 04:28:04 +00:00
BA_para_set | = ( status < < 2 ) & IEEE80211_ADDBA_PARAM_TID_MASK ;
2015-02-19 21:34:32 +00:00
/* max buffer size is 8 MSDU */
2014-12-19 04:28:04 +00:00
BA_para_set | = ( 8 < < 6 ) & RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK ;
} else
2014-12-11 21:15:04 +00:00
# endif
2014-12-19 04:28:04 +00:00
{
2015-02-19 21:34:32 +00:00
BA_para_set = ( 0x1002 | ( ( status & 0xf ) < < 2 ) ) ; /* immediate ack & 64 buffer size */
2014-12-19 04:28:04 +00:00
}
le_tmp = cpu_to_le16 ( BA_para_set ) ;
pframe = rtw_set_fixed_ie ( pframe , 2 , ( unsigned char * ) ( & ( le_tmp ) ) , & ( pattrib - > pktlen ) ) ;
2014-12-11 21:15:04 +00:00
2015-02-19 21:34:32 +00:00
BA_timeout_value = 5000 ; /* 5ms */
2014-12-19 04:28:04 +00:00
le_tmp = cpu_to_le16 ( BA_timeout_value ) ;
pframe = rtw_set_fixed_ie ( pframe , 2 , ( unsigned char * ) ( & ( le_tmp ) ) , & ( pattrib - > pktlen ) ) ;
2014-12-11 21:15:04 +00:00
2015-02-19 21:34:32 +00:00
/* if ((psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress)) != NULL) */
2014-12-19 04:28:04 +00:00
if ( ( psta = rtw_get_stainfo ( pstapriv , raddr ) ) ! = NULL ) {
start_seq = ( psta - > sta_xmitpriv . txseq_tid [ status & 0x07 ] & 0xfff ) + 1 ;
2014-12-11 21:15:04 +00:00
2014-12-19 04:28:04 +00:00
DBG_871X ( " BA_starting_seqctrl = %d for TID=%d \n " , start_seq , status & 0x07 ) ;
2014-12-19 06:59:46 +00:00
2014-12-19 04:28:04 +00:00
psta - > BA_starting_seqctrl [ status & 0x07 ] = start_seq ;
2014-12-19 06:59:46 +00:00
2014-12-19 04:28:04 +00:00
BA_starting_seqctrl = start_seq < < 4 ;
}
2014-12-19 06:59:46 +00:00
2014-12-19 04:28:04 +00:00
le_tmp = cpu_to_le16 ( BA_starting_seqctrl ) ;
pframe = rtw_set_fixed_ie ( pframe , 2 , ( unsigned char * ) ( & ( le_tmp ) ) , & ( pattrib - > pktlen ) ) ;
break ;
2014-12-11 21:15:04 +00:00
2015-02-19 21:34:32 +00:00
case 1 : /* ADDBA rsp */
2014-12-19 04:28:04 +00:00
pframe = rtw_set_fixed_ie ( pframe , 1 , & ( pmlmeinfo - > ADDBA_req . dialog_token ) , & ( pattrib - > pktlen ) ) ;
pframe = rtw_set_fixed_ie ( pframe , 2 , ( unsigned char * ) ( & status ) , & ( pattrib - > pktlen ) ) ;
rtw_hal_get_def_var ( padapter , HW_VAR_MAX_RX_AMPDU_FACTOR , & max_rx_ampdu_factor ) ;
if ( MAX_AMPDU_FACTOR_64K = = max_rx_ampdu_factor )
2015-02-19 21:34:32 +00:00
BA_para_set = ( ( le16_to_cpu ( pmlmeinfo - > ADDBA_req . BA_para_set ) & 0x3f ) | 0x1000 ) ; /* 64 buffer size */
2014-12-19 04:28:04 +00:00
else if ( MAX_AMPDU_FACTOR_32K = = max_rx_ampdu_factor )
2015-02-19 21:34:32 +00:00
BA_para_set = ( ( le16_to_cpu ( pmlmeinfo - > ADDBA_req . BA_para_set ) & 0x3f ) | 0x0800 ) ; /* 32 buffer size */
2014-12-19 04:28:04 +00:00
else if ( MAX_AMPDU_FACTOR_16K = = max_rx_ampdu_factor )
2015-02-19 21:34:32 +00:00
BA_para_set = ( ( le16_to_cpu ( pmlmeinfo - > ADDBA_req . BA_para_set ) & 0x3f ) | 0x0400 ) ; /* 16 buffer size */
2014-12-19 04:28:04 +00:00
else if ( MAX_AMPDU_FACTOR_8K = = max_rx_ampdu_factor )
2015-02-19 21:34:32 +00:00
BA_para_set = ( ( le16_to_cpu ( pmlmeinfo - > ADDBA_req . BA_para_set ) & 0x3f ) | 0x0200 ) ; /* 8 buffer size */
2014-12-19 04:28:04 +00:00
else
2015-02-19 21:34:32 +00:00
BA_para_set = ( ( le16_to_cpu ( pmlmeinfo - > ADDBA_req . BA_para_set ) & 0x3f ) | 0x1000 ) ; /* 64 buffer size */
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_BT_COEXIST
2014-12-29 02:13:24 +00:00
if ( ( BT_1Ant ( padapter ) = = true ) & &
2014-12-19 04:28:04 +00:00
( ( pmlmeinfo - > assoc_AP_vendor ! = broadcomAP ) | |
2014-12-29 02:13:24 +00:00
( _rtw_memcmp ( raddr , tendaAPMac , 3 ) = = false ) ) ) {
2015-02-19 21:34:32 +00:00
/* max buffer size is 8 MSDU */
2014-12-19 04:28:04 +00:00
BA_para_set & = ~ RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK ;
BA_para_set | = ( 8 < < 6 ) & RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK ;
}
2014-12-11 21:15:04 +00:00
# endif
2015-02-19 21:34:32 +00:00
if ( pregpriv - > ampdu_amsdu = = 0 ) /* disabled */
2014-12-19 04:28:04 +00:00
le_tmp = cpu_to_le16 ( BA_para_set & ~ BIT ( 0 ) ) ;
2015-02-19 21:34:32 +00:00
else if ( pregpriv - > ampdu_amsdu = = 1 ) /* enabled */
2014-12-19 04:28:04 +00:00
le_tmp = cpu_to_le16 ( BA_para_set | BIT ( 0 ) ) ;
2015-02-19 21:34:32 +00:00
else /* auto */
2014-12-19 04:28:04 +00:00
le_tmp = cpu_to_le16 ( BA_para_set ) ;
2014-12-19 06:59:46 +00:00
2014-12-19 04:28:04 +00:00
pframe = rtw_set_fixed_ie ( pframe , 2 , ( unsigned char * ) ( & ( le_tmp ) ) , & ( pattrib - > pktlen ) ) ;
pframe = rtw_set_fixed_ie ( pframe , 2 , ( unsigned char * ) ( & ( pmlmeinfo - > ADDBA_req . BA_timeout_value ) ) , & ( pattrib - > pktlen ) ) ;
break ;
2015-02-19 21:34:32 +00:00
case 2 : /* DELBA */
2014-12-19 04:28:04 +00:00
BA_para_set = ( status & 0x1F ) < < 3 ;
2014-12-19 06:59:46 +00:00
le_tmp = cpu_to_le16 ( BA_para_set ) ;
2014-12-19 04:28:04 +00:00
pframe = rtw_set_fixed_ie ( pframe , 2 , ( unsigned char * ) ( & ( le_tmp ) ) , & ( pattrib - > pktlen ) ) ;
2015-02-19 21:34:32 +00:00
reason_code = 37 ; /* Requested from peer STA as it does not want to use the mechanism */
2014-12-19 04:28:04 +00:00
le_tmp = cpu_to_le16 ( reason_code ) ;
pframe = rtw_set_fixed_ie ( pframe , 2 , ( unsigned char * ) ( & ( le_tmp ) ) , & ( pattrib - > pktlen ) ) ;
break ;
default :
break ;
2014-12-11 21:15:04 +00:00
}
}
pattrib - > last_txcmdsz = pattrib - > pktlen ;
dump_mgntframe ( padapter , pmgntframe ) ;
}
2014-12-17 23:13:53 +00:00
static void issue_action_BSSCoexistPacket ( struct adapter * padapter )
2014-12-19 06:59:46 +00:00
{
2014-12-11 21:15:04 +00:00
_irqL irqL ;
_list * plist , * phead ;
unsigned char category , action ;
struct xmit_frame * pmgntframe ;
struct pkt_attrib * pattrib ;
unsigned char * pframe ;
struct rtw_ieee80211_hdr * pwlanhdr ;
2014-12-19 04:28:04 +00:00
__le16 * fctrl ;
2014-12-11 21:15:04 +00:00
struct wlan_network * pnetwork = NULL ;
struct xmit_priv * pxmitpriv = & ( padapter - > xmitpriv ) ;
struct mlme_priv * pmlmepriv = & padapter - > mlmepriv ;
struct mlme_ext_priv * pmlmeext = & ( padapter - > mlmeextpriv ) ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
_queue * queue = & ( pmlmepriv - > scanned_queue ) ;
u8 InfoContent [ 16 ] = { 0 } ;
u8 ICS [ 8 ] [ 15 ] ;
if ( ( pmlmepriv - > num_FortyMHzIntolerant = = 0 ) | | ( pmlmepriv - > num_sta_no_ht = = 0 ) )
return ;
2014-12-29 02:13:24 +00:00
if ( true = = pmlmeinfo - > bwmode_updated )
2014-12-11 21:15:04 +00:00
return ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
DBG_871X ( " %s \n " , __FUNCTION__ ) ;
category = RTW_WLAN_CATEGORY_PUBLIC ;
action = ACT_PUBLIC_BSSCOEXIST ;
if ( ( pmgntframe = alloc_mgtxmitframe ( pxmitpriv ) ) = = NULL )
{
return ;
}
2015-02-19 21:34:32 +00:00
/* update attribute */
2014-12-11 21:15:04 +00:00
pattrib = & pmgntframe - > attrib ;
update_mgntframe_attrib ( padapter , pattrib ) ;
2015-02-19 20:58:09 +00:00
memset ( pmgntframe - > buf_addr , 0 , WLANHDR_OFFSET + TXDESC_OFFSET ) ;
2014-12-11 21:15:04 +00:00
pframe = ( u8 * ) ( pmgntframe - > buf_addr ) + TXDESC_OFFSET ;
pwlanhdr = ( struct rtw_ieee80211_hdr * ) pframe ;
fctrl = & ( pwlanhdr - > frame_ctl ) ;
* ( fctrl ) = 0 ;
2015-02-19 20:50:04 +00:00
memcpy ( pwlanhdr - > addr1 , get_my_bssid ( & ( pmlmeinfo - > network ) ) , ETH_ALEN ) ;
memcpy ( pwlanhdr - > addr2 , myid ( & ( padapter - > eeprompriv ) ) , ETH_ALEN ) ;
memcpy ( pwlanhdr - > addr3 , get_my_bssid ( & ( pmlmeinfo - > network ) ) , ETH_ALEN ) ;
2014-12-11 21:15:04 +00:00
SetSeqNum ( pwlanhdr , pmlmeext - > mgnt_seq ) ;
pmlmeext - > mgnt_seq + + ;
SetFrameSubType ( pframe , WIFI_ACTION ) ;
pframe + = sizeof ( struct rtw_ieee80211_hdr_3addr ) ;
pattrib - > pktlen = sizeof ( struct rtw_ieee80211_hdr_3addr ) ;
pframe = rtw_set_fixed_ie ( pframe , 1 , & ( category ) , & ( pattrib - > pktlen ) ) ;
pframe = rtw_set_fixed_ie ( pframe , 1 , & ( action ) , & ( pattrib - > pktlen ) ) ;
2015-02-19 21:34:32 +00:00
/* */
2014-12-11 21:15:04 +00:00
if ( pmlmepriv - > num_FortyMHzIntolerant > 0 )
{
u8 iedata = 0 ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
iedata | = BIT ( 2 ) ; /* 20 MHz BSS Width Request */
2014-12-11 21:15:04 +00:00
pframe = rtw_set_ie ( pframe , EID_BSSCoexistence , 1 , & iedata , & ( pattrib - > pktlen ) ) ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
}
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
2015-02-19 21:34:32 +00:00
/* */
2015-02-19 20:58:09 +00:00
memset ( ICS , 0 , sizeof ( ICS ) ) ;
2014-12-11 21:15:04 +00:00
if ( pmlmepriv - > num_sta_no_ht > 0 )
2014-12-19 06:59:46 +00:00
{
2013-05-08 21:45:39 +00:00
int i ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
_enter_critical_bh ( & ( pmlmepriv - > scanned_queue . lock ) , & irqL ) ;
2013-05-08 21:45:39 +00:00
phead = get_list_head ( queue ) ;
plist = get_next ( phead ) ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
while ( 1 )
{
2013-05-08 21:45:39 +00:00
int len ;
u8 * p ;
2014-12-11 21:15:04 +00:00
WLAN_BSSID_EX * pbss_network ;
2014-12-19 06:59:46 +00:00
2014-12-29 02:13:24 +00:00
if ( rtw_end_of_queue_search ( phead , plist ) = = true )
2014-12-19 06:59:46 +00:00
break ;
pnetwork = LIST_CONTAINOR ( plist , struct wlan_network , list ) ;
2013-05-08 21:45:39 +00:00
plist = get_next ( plist ) ;
2014-12-11 21:15:04 +00:00
pbss_network = ( WLAN_BSSID_EX * ) & pnetwork - > network ;
2013-05-08 21:45:39 +00:00
p = rtw_get_ie ( pbss_network - > IEs + _FIXED_IE_LENGTH_ , _HT_CAPABILITY_IE_ , & len , pbss_network - > IELength - _FIXED_IE_LENGTH_ ) ;
2015-02-19 21:34:32 +00:00
if ( ( p = = NULL ) | | ( len = = 0 ) ) /* non-HT */
2014-12-11 21:15:04 +00:00
{
if ( ( pbss_network - > Configuration . DSConfig < = 0 ) | | ( pbss_network - > Configuration . DSConfig > 14 ) )
2013-05-08 21:45:39 +00:00
continue ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
ICS [ 0 ] [ pbss_network - > Configuration . DSConfig ] = 1 ;
if ( ICS [ 0 ] [ 0 ] = = 0 )
2014-12-19 06:59:46 +00:00
ICS [ 0 ] [ 0 ] = 1 ;
}
}
2013-05-19 04:28:07 +00:00
2014-12-11 21:15:04 +00:00
_exit_critical_bh ( & ( pmlmepriv - > scanned_queue . lock ) , & irqL ) ;
2013-05-19 04:28:07 +00:00
2014-12-11 21:15:04 +00:00
for ( i = 0 ; i < 8 ; i + + )
{
if ( ICS [ i ] [ 0 ] = = 1 )
{
2013-05-08 21:45:39 +00:00
int j , k = 0 ;
2014-12-19 06:59:46 +00:00
InfoContent [ k ] = i ;
2015-02-19 21:34:32 +00:00
/* SET_BSS_INTOLERANT_ELE_REG_CLASS(InfoContent,i); */
2013-05-08 21:45:39 +00:00
k + + ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
for ( j = 1 ; j < = 14 ; j + + )
{
if ( ICS [ i ] [ j ] = = 1 )
{
if ( k < 16 )
{
2015-02-19 21:34:32 +00:00
InfoContent [ k ] = j ; /* channel number */
/* SET_BSS_INTOLERANT_ELE_CHANNEL(InfoContent+k, j); */
2013-05-08 21:45:39 +00:00
k + + ;
2014-12-19 06:59:46 +00:00
}
}
}
2013-05-08 21:45:39 +00:00
pframe = rtw_set_ie ( pframe , EID_BSSIntolerantChlReport , k , InfoContent , & ( pattrib - > pktlen ) ) ;
}
}
}
pattrib - > last_txcmdsz = pattrib - > pktlen ;
dump_mgntframe ( padapter , pmgntframe ) ;
}
2014-12-17 23:13:53 +00:00
unsigned int send_delba ( struct adapter * padapter , u8 initiator , u8 * addr )
2013-05-08 21:45:39 +00:00
{
struct sta_priv * pstapriv = & padapter - > stapriv ;
struct sta_info * psta = NULL ;
2015-02-19 21:34:32 +00:00
/* struct recv_reorder_ctrl *preorder_ctrl; */
2013-05-08 21:45:39 +00:00
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
u16 tid ;
2014-12-19 06:59:46 +00:00
if ( ( pmlmeinfo - > state & 0x03 ) ! = WIFI_FW_AP_STATE )
2013-05-08 21:45:39 +00:00
if ( ! ( pmlmeinfo - > state & WIFI_FW_ASSOC_SUCCESS ) )
return _SUCCESS ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
psta = rtw_get_stainfo ( pstapriv , addr ) ;
2014-12-11 21:15:04 +00:00
if ( psta = = NULL )
2013-05-08 21:45:39 +00:00
return _SUCCESS ;
2015-02-19 21:34:32 +00:00
/* DBG_871X("%s:%s\n", __FUNCTION__, (initiator==0)?"RX_DIR":"TX_DIR"); */
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
if ( initiator = = 0 ) /* recipient */
2014-12-11 21:15:04 +00:00
{
for ( tid = 0 ; tid < MAXTID ; tid + + )
{
2014-12-29 02:13:24 +00:00
if ( psta - > recvreorder_ctrl [ tid ] . enable = = true )
2014-12-11 21:15:04 +00:00
{
DBG_871X ( " rx agg disable tid(%d) \n " , tid ) ;
2014-12-19 04:28:04 +00:00
issue_action_BA ( padapter , addr , RTW_WLAN_ACTION_DELBA ,
( ( ( tid < < 1 ) | initiator ) & 0x1F ) ) ;
2014-12-29 02:13:24 +00:00
psta - > recvreorder_ctrl [ tid ] . enable = false ;
2013-05-08 21:45:39 +00:00
psta - > recvreorder_ctrl [ tid ] . indicate_seq = 0xffff ;
2014-12-11 21:15:04 +00:00
# ifdef DBG_RX_SEQ
DBG_871X ( " DBG_RX_SEQ %s:%d indicate_seq:%u \n " , __FUNCTION__ , __LINE__ ,
psta - > recvreorder_ctrl [ tid ] . indicate_seq ) ;
# endif
2014-12-19 06:59:46 +00:00
}
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
}
2015-02-19 21:34:32 +00:00
else if ( initiator = = 1 ) /* originator */
2014-12-11 21:15:04 +00:00
{
2015-02-19 21:34:32 +00:00
/* DBG_871X("tx agg_enable_bitmap(0x%08x)\n", psta->htpriv.agg_enable_bitmap); */
2014-12-11 21:15:04 +00:00
for ( tid = 0 ; tid < MAXTID ; tid + + )
{
if ( psta - > htpriv . agg_enable_bitmap & BIT ( tid ) )
{
DBG_871X ( " tx agg disable tid(%d) \n " , tid ) ;
2014-12-19 04:28:04 +00:00
issue_action_BA ( padapter , addr , RTW_WLAN_ACTION_DELBA ,
( ( ( tid < < 1 ) | initiator ) & 0x1F ) ) ;
2013-05-08 21:45:39 +00:00
psta - > htpriv . agg_enable_bitmap & = ~ BIT ( tid ) ;
psta - > htpriv . candidate_tid_bitmap & = ~ BIT ( tid ) ;
2014-12-19 06:59:46 +00:00
}
2013-05-08 21:45:39 +00:00
}
}
return _SUCCESS ;
}
2014-12-17 23:13:53 +00:00
unsigned int send_beacon ( struct adapter * padapter )
2013-05-08 21:45:39 +00:00
{
2014-12-29 02:13:24 +00:00
u8 bxmitok = false ;
2014-12-11 21:15:04 +00:00
int issue = 0 ;
2013-05-08 21:45:39 +00:00
int poll = 0 ;
u32 start = rtw_get_current_time ( ) ;
rtw_hal_set_hwreg ( padapter , HW_VAR_BCN_VALID , NULL ) ;
2014-12-11 21:15:04 +00:00
do {
2013-05-08 21:45:39 +00:00
issue_beacon ( padapter , 100 ) ;
issue + + ;
do {
rtw_yield_os ( ) ;
rtw_hal_get_hwreg ( padapter , HW_VAR_BCN_VALID , ( u8 * ) ( & bxmitok ) ) ;
poll + + ;
2014-12-29 02:13:24 +00:00
} while ( ( poll % 10 ) ! = 0 & & false = = bxmitok & & ! padapter - > bSurpriseRemoved & & ! padapter - > bDriverStopped ) ;
2014-12-11 21:15:04 +00:00
2014-12-29 02:13:24 +00:00
} while ( false = = bxmitok & & issue < 100 & & ! padapter - > bSurpriseRemoved & & ! padapter - > bDriverStopped ) ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
if ( padapter - > bSurpriseRemoved | | padapter - > bDriverStopped )
{
2013-05-08 21:45:39 +00:00
return _FAIL ;
2014-12-11 21:15:04 +00:00
}
2014-12-19 06:59:46 +00:00
2014-12-29 02:13:24 +00:00
if ( false = = bxmitok )
2014-12-11 21:15:04 +00:00
{
DBG_871X ( " %s fail! %u ms \n " , __FUNCTION__ , rtw_get_passing_time_ms ( start ) ) ;
2013-05-08 21:45:39 +00:00
return _FAIL ;
2014-12-11 21:15:04 +00:00
}
else
{
2013-05-08 21:45:39 +00:00
u32 passing_time = rtw_get_passing_time_ms ( start ) ;
2014-12-11 21:15:04 +00:00
if ( passing_time > 100 | | issue > 3 )
DBG_871X ( " %s success, issue:%d, poll:%d, %u ms \n " , __FUNCTION__ , issue , poll , rtw_get_passing_time_ms ( start ) ) ;
2015-02-19 21:34:32 +00:00
/* else */
/* DBG_871X("%s success, issue:%d, poll:%d, %u ms\n", __FUNCTION__, issue, poll, rtw_get_passing_time_ms(start)); */
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
return _SUCCESS ;
}
}
/****************************************************************************
Following are some utitity fuctions for WiFi MLME
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2014-12-11 21:15:04 +00:00
BOOLEAN IsLegal5GChannel (
2014-12-17 23:13:53 +00:00
IN struct adapter * Adapter ,
2014-12-11 21:15:04 +00:00
IN u8 channel )
{
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
int i = 0 ;
u8 Channel_5G [ 45 ] = { 36 , 38 , 40 , 42 , 44 , 46 , 48 , 50 , 52 , 54 , 56 , 58 ,
60 , 62 , 64 , 100 , 102 , 104 , 106 , 108 , 110 , 112 , 114 , 116 , 118 , 120 , 122 ,
124 , 126 , 128 , 130 , 132 , 134 , 136 , 138 , 140 , 149 , 151 , 153 , 155 , 157 , 159 ,
161 , 163 , 165 } ;
for ( i = 0 ; i < sizeof ( Channel_5G ) ; i + + )
if ( channel = = Channel_5G [ i ] )
2014-12-29 02:13:24 +00:00
return true ;
return false ;
2014-12-11 21:15:04 +00:00
}
2014-12-17 23:13:53 +00:00
void site_survey ( struct adapter * padapter )
2013-05-08 21:45:39 +00:00
{
unsigned char survey_channel = 0 , val8 ;
2014-12-11 21:15:04 +00:00
RT_SCAN_TYPE ScanType = SCAN_PASSIVE ;
2013-05-08 21:45:39 +00:00
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
u32 initialgain = 0 ;
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_P2P
struct wifidirect_info * pwdinfo = & ( padapter - > wdinfo ) ;
static unsigned char prev_survey_channel = 0 ;
2014-12-19 06:59:46 +00:00
static unsigned int p2p_scan_count = 0 ;
2014-12-11 21:15:04 +00:00
if ( ( pwdinfo - > rx_invitereq_info . scan_op_ch_only ) | | ( pwdinfo - > p2p_info . scan_op_ch_only ) )
{
if ( pwdinfo - > rx_invitereq_info . scan_op_ch_only )
{
2013-05-08 21:45:39 +00:00
survey_channel = pwdinfo - > rx_invitereq_info . operation_ch [ pmlmeext - > sitesurvey_res . channel_idx ] ;
2014-12-11 21:15:04 +00:00
}
else
{
2013-05-08 21:45:39 +00:00
survey_channel = pwdinfo - > p2p_info . operation_ch [ pmlmeext - > sitesurvey_res . channel_idx ] ;
}
ScanType = SCAN_ACTIVE ;
2014-12-11 21:15:04 +00:00
}
else if ( rtw_p2p_findphase_ex_is_social ( pwdinfo ) )
{
2015-02-19 21:34:32 +00:00
/* Commented by Albert 2011/06/03 */
/* The driver is in the find phase, it should go through the social channel. */
2013-05-08 21:45:39 +00:00
int ch_set_idx ;
survey_channel = pwdinfo - > social_chan [ pmlmeext - > sitesurvey_res . channel_idx ] ;
ch_set_idx = rtw_ch_set_search_ch ( pmlmeext - > channel_set , survey_channel ) ;
if ( ch_set_idx > = 0 )
ScanType = pmlmeext - > channel_set [ ch_set_idx ] . ScanType ;
else
ScanType = SCAN_ACTIVE ;
2014-12-11 21:15:04 +00:00
}
else
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_P2P */
2013-05-08 21:45:39 +00:00
{
struct rtw_ieee80211_channel * ch ;
if ( pmlmeext - > sitesurvey_res . channel_idx < pmlmeext - > sitesurvey_res . ch_num ) {
ch = & pmlmeext - > sitesurvey_res . ch [ pmlmeext - > sitesurvey_res . channel_idx ] ;
survey_channel = ch - > hw_value ;
ScanType = ( ch - > flags & RTW_IEEE80211_CHAN_PASSIVE_SCAN ) ? SCAN_PASSIVE : SCAN_ACTIVE ;
}
}
2014-12-11 21:15:04 +00:00
if ( 0 ) {
DBG_871X ( FUNC_ADPT_FMT " ch:%u (cnt:%u,idx:%d) at %dms, %c%c%c \n "
, FUNC_ADPT_ARG ( padapter )
, survey_channel
, pwdinfo - > find_phase_state_exchange_cnt , pmlmeext - > sitesurvey_res . channel_idx
, rtw_get_passing_time_ms ( padapter - > mlmepriv . scan_start_time )
, ScanType ? ' A ' : ' P ' , pmlmeext - > sitesurvey_res . scan_mode ? ' A ' : ' P '
2014-12-19 06:59:46 +00:00
, pmlmeext - > sitesurvey_res . ssid [ 0 ] . SsidLength ? ' S ' : ' '
2014-12-11 21:15:04 +00:00
) ;
# ifdef DBG_FIXED_CHAN
DBG_871X ( FUNC_ADPT_FMT " fixed_chan:%u \n " , pmlmeext - > fixed_chan ) ;
# endif
}
if ( survey_channel ! = 0 )
{
2015-02-19 21:34:32 +00:00
/* PAUSE 4-AC Queue when site_survey */
/* rtw_hal_get_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8)); */
/* val8 |= 0x0f; */
/* rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8)); */
2014-12-11 21:15:04 +00:00
if ( pmlmeext - > sitesurvey_res . channel_idx = = 0 )
{
# ifdef DBG_FIXED_CHAN
if ( pmlmeext - > fixed_chan ! = 0xff )
set_channel_bwmode ( padapter , pmlmeext - > fixed_chan , HAL_PRIME_CHNL_OFFSET_DONT_CARE , HT_CHANNEL_WIDTH_20 ) ;
2014-12-19 06:59:46 +00:00
else
2014-12-11 21:15:04 +00:00
# endif
set_channel_bwmode ( padapter , survey_channel , HAL_PRIME_CHNL_OFFSET_DONT_CARE , HT_CHANNEL_WIDTH_20 ) ;
}
2013-05-08 21:45:39 +00:00
else
2014-12-11 21:15:04 +00:00
{
# ifdef DBG_FIXED_CHAN
if ( pmlmeext - > fixed_chan ! = 0xff )
SelectChannel ( padapter , pmlmeext - > fixed_chan ) ;
2014-12-19 06:59:46 +00:00
else
2014-12-11 21:15:04 +00:00
# endif
SelectChannel ( padapter , survey_channel ) ;
}
# ifdef CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
if ( stay_buddy_ch = = 1 )
{
2015-02-19 21:34:32 +00:00
val8 = 0 ; /* survey done */
2014-12-11 21:15:04 +00:00
rtw_hal_set_hwreg ( padapter , HW_VAR_MLME_SITESURVEY , ( u8 * ) ( & val8 ) ) ;
if ( check_buddy_mlmeinfo_state ( padapter , WIFI_FW_AP_STATE ) & &
check_buddy_fwstate ( padapter , _FW_LINKED ) )
{
2014-12-29 02:13:24 +00:00
update_beacon ( padapter - > pbuddy_adapter , 0 , NULL , true ) ;
2014-12-11 21:15:04 +00:00
}
}
else if ( stay_buddy_ch = = 2 )
{
2015-02-19 21:34:32 +00:00
val8 = 1 ; /* under site survey */
2014-12-11 21:15:04 +00:00
rtw_hal_set_hwreg ( padapter , HW_VAR_MLME_SITESURVEY , ( u8 * ) ( & val8 ) ) ;
}
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_STA_MODE_SCAN_UNDER_AP_MODE */
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
if ( ScanType = = SCAN_ACTIVE ) /* obey the channel plan setting... */
2014-12-11 21:15:04 +00:00
{
# ifdef CONFIG_P2P
2014-12-19 06:59:46 +00:00
if ( rtw_p2p_chk_state ( pwdinfo , P2P_STATE_SCAN ) | |
2014-12-11 21:15:04 +00:00
rtw_p2p_chk_state ( pwdinfo , P2P_STATE_FIND_PHASE_SEARCH )
)
{
2013-05-08 21:45:39 +00:00
issue_probereq_p2p ( padapter , NULL ) ;
issue_probereq_p2p ( padapter , NULL ) ;
issue_probereq_p2p ( padapter , NULL ) ;
2014-12-11 21:15:04 +00:00
}
else
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_P2P */
2013-05-08 21:45:39 +00:00
{
int i ;
2014-12-11 21:15:04 +00:00
for ( i = 0 ; i < RTW_SSID_SCAN_AMOUNT ; i + + ) {
if ( pmlmeext - > sitesurvey_res . ssid [ i ] . SsidLength ) {
2015-02-19 21:34:32 +00:00
/* todo: to issue two probe req??? */
2013-05-08 21:45:39 +00:00
issue_probereq ( padapter , & ( pmlmeext - > sitesurvey_res . ssid [ i ] ) , NULL ) ;
2015-02-19 21:34:32 +00:00
/* rtw_msleep_os(SURVEY_TO>>1); */
2013-05-08 21:45:39 +00:00
issue_probereq ( padapter , & ( pmlmeext - > sitesurvey_res . ssid [ i ] ) , NULL ) ;
}
}
2014-12-11 21:15:04 +00:00
if ( pmlmeext - > sitesurvey_res . scan_mode = = SCAN_ACTIVE ) {
2015-02-19 21:34:32 +00:00
/* todo: to issue two probe req??? */
2013-05-08 21:45:39 +00:00
issue_probereq ( padapter , NULL , NULL ) ;
2015-02-19 21:34:32 +00:00
/* rtw_msleep_os(SURVEY_TO>>1); */
2013-05-08 21:45:39 +00:00
issue_probereq ( padapter , NULL , NULL ) ;
}
}
}
2014-12-11 21:15:04 +00:00
{
# ifdef CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
if ( stay_buddy_ch = = 1 )
set_survey_timer ( pmlmeext , pmlmeext - > chan_scan_time * RTW_STAY_AP_CH_MILLISECOND ) ;
else
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_STA_MODE_SCAN_UNDER_AP_MODE */
2014-12-11 21:15:04 +00:00
set_survey_timer ( pmlmeext , pmlmeext - > chan_scan_time ) ;
}
2015-02-15 20:31:30 +00:00
} else {
2015-02-19 21:34:32 +00:00
/* channel number is 0 or this channel is not valid. */
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_P2P
if ( rtw_p2p_chk_state ( pwdinfo , P2P_STATE_SCAN ) | | rtw_p2p_chk_state ( pwdinfo , P2P_STATE_FIND_PHASE_SEARCH ) )
{
if ( ( pwdinfo - > rx_invitereq_info . scan_op_ch_only ) | | ( pwdinfo - > p2p_info . scan_op_ch_only ) )
{
2015-02-19 21:34:32 +00:00
/* Set the find_phase_state_exchange_cnt to P2P_FINDPHASE_EX_CNT. */
/* This will let the following flow to run the scanning end. */
2013-05-08 21:45:39 +00:00
rtw_p2p_findphase_ex_set ( pwdinfo , P2P_FINDPHASE_EX_MAX ) ;
}
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_DBG_P2P
DBG_871X ( " [%s] find phase exchange cnt = %d \n " , __FUNCTION__ , pwdinfo - > find_phase_state_exchange_cnt ) ;
# endif
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
if ( rtw_p2p_findphase_ex_is_needed ( pwdinfo ) )
{
2015-02-19 21:34:32 +00:00
/* Set the P2P State to the listen state of find phase and set the current channel to the listen channel */
2013-05-08 21:45:39 +00:00
set_channel_bwmode ( padapter , pwdinfo - > listen_channel , HAL_PRIME_CHNL_OFFSET_DONT_CARE , HT_CHANNEL_WIDTH_20 ) ;
rtw_p2p_set_state ( pwdinfo , P2P_STATE_FIND_PHASE_LISTEN ) ;
pmlmeext - > sitesurvey_res . state = SCAN_DISABLE ;
2015-02-19 21:34:32 +00:00
initialgain = 0xff ; /* restore RX GAIN */
2014-12-19 06:59:46 +00:00
rtw_hal_set_hwreg ( padapter , HW_VAR_INITIAL_GAIN , ( u8 * ) ( & initialgain ) ) ;
2015-02-19 21:34:32 +00:00
/* turn on dynamic functions */
2013-05-08 21:45:39 +00:00
Restore_DM_Func_Flag ( padapter ) ;
2015-02-19 21:34:32 +00:00
/* Switch_DM_Func(padapter, DYNAMIC_FUNC_DIG|DYNAMIC_FUNC_HP|DYNAMIC_FUNC_SS, true); */
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
_set_timer ( & pwdinfo - > find_phase_timer , ( u32 ) ( ( u32 ) ( pwdinfo - > listen_dwell ) * 100 ) ) ;
}
else
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_P2P */
2013-05-08 21:45:39 +00:00
{
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
pmlmeinfo - > scan_cnt = 0 ;
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_DMP_STA_NODE_SCAN_UNDER_AP_MODE */
2014-12-11 21:15:04 +00:00
2015-02-19 21:34:32 +00:00
/* 20100721:Interrupt scan operation here. */
/* For SW antenna diversity before link, it needs to switch to another antenna and scan again. */
/* It compares the scan result and select beter one to do connection. */
2014-12-11 21:15:04 +00:00
if ( rtw_hal_antdiv_before_linked ( padapter ) )
2014-12-19 06:59:46 +00:00
{
2013-05-08 21:45:39 +00:00
pmlmeext - > sitesurvey_res . bss_cnt = 0 ;
pmlmeext - > sitesurvey_res . channel_idx = - 1 ;
2014-12-19 06:59:46 +00:00
pmlmeext - > chan_scan_time = SURVEY_TO / 2 ;
2013-05-08 21:45:39 +00:00
set_survey_timer ( pmlmeext , pmlmeext - > chan_scan_time ) ;
return ;
}
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_P2P
if ( rtw_p2p_chk_state ( pwdinfo , P2P_STATE_SCAN ) | | rtw_p2p_chk_state ( pwdinfo , P2P_STATE_FIND_PHASE_SEARCH ) )
rtw_p2p_set_state ( pwdinfo , rtw_p2p_pre_state ( pwdinfo ) ) ;
2013-05-08 21:45:39 +00:00
rtw_p2p_findphase_ex_set ( pwdinfo , P2P_FINDPHASE_EX_NONE ) ;
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_P2P */
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
pmlmeext - > sitesurvey_res . state = SCAN_COMPLETE ;
2015-02-19 21:34:32 +00:00
/* switch back to the original channel */
/* SelectChannel(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset); */
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
{
if ( pwdinfo - > driver_interface = = DRIVER_WEXT )
{
if ( rtw_p2p_chk_state ( pwdinfo , P2P_STATE_LISTEN ) )
{
set_channel_bwmode ( padapter , pwdinfo - > listen_channel , HAL_PRIME_CHNL_OFFSET_DONT_CARE , HT_CHANNEL_WIDTH_20 ) ;
}
else
set_channel_bwmode ( padapter , pmlmeext - > cur_channel , pmlmeext - > cur_ch_offset , pmlmeext - > cur_bwmode ) ;
}
else if ( pwdinfo - > driver_interface = = DRIVER_CFG80211 )
{
set_channel_bwmode ( padapter , pmlmeext - > cur_channel , pmlmeext - > cur_ch_offset , pmlmeext - > cur_bwmode ) ;
}
}
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* flush 4-AC Queue after site_survey */
/* val8 = 0; */
/* rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8)); */
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* config MSR */
2013-05-08 21:45:39 +00:00
Set_MSR ( padapter , ( pmlmeinfo - > state & 0x3 ) ) ;
2015-02-19 21:34:32 +00:00
initialgain = 0xff ; /* restore RX GAIN */
2014-12-19 06:59:46 +00:00
rtw_hal_set_hwreg ( padapter , HW_VAR_INITIAL_GAIN , ( u8 * ) ( & initialgain ) ) ;
2015-02-19 21:34:32 +00:00
/* turn on dynamic functions */
2013-05-08 21:45:39 +00:00
Restore_DM_Func_Flag ( padapter ) ;
2015-02-19 21:34:32 +00:00
/* Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, true); */
2013-05-08 21:45:39 +00:00
2014-12-29 02:13:24 +00:00
if ( is_client_associated_to_ap ( padapter ) = = true )
2013-05-08 21:45:39 +00:00
issue_nulldata ( padapter , NULL , 0 , 3 , 500 ) ;
2015-02-19 21:34:32 +00:00
val8 = 0 ; /* survey done */
2013-05-08 21:45:39 +00:00
rtw_hal_set_hwreg ( padapter , HW_VAR_MLME_SITESURVEY , ( u8 * ) ( & val8 ) ) ;
report_surveydone_event ( padapter ) ;
pmlmeext - > chan_scan_time = SURVEY_TO ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
pmlmeext - > sitesurvey_res . state = SCAN_DISABLE ;
issue_action_BSSCoexistPacket ( padapter ) ;
issue_action_BSSCoexistPacket ( padapter ) ;
issue_action_BSSCoexistPacket ( padapter ) ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
}
2013-07-12 03:50:49 +00:00
}
return ;
}
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* collect bss info from Beacon and Probe request/response frames. */
2014-12-17 23:13:53 +00:00
u8 collect_bss_info ( struct adapter * padapter , union recv_frame * precv_frame , WLAN_BSSID_EX * bssid )
2013-05-08 21:45:39 +00:00
{
int i ;
u32 len ;
2014-12-11 21:15:04 +00:00
u8 * p ;
u16 val16 , subtype ;
u8 * pframe = precv_frame - > u . hdr . rx_data ;
2013-05-08 21:45:39 +00:00
u32 packet_len = precv_frame - > u . hdr . len ;
u8 ie_offset ;
2014-12-19 04:28:04 +00:00
__le32 le_tmp ;
2014-12-19 06:59:46 +00:00
struct registry_priv * pregistrypriv = & padapter - > registrypriv ;
2013-05-08 21:45:39 +00:00
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
len = packet_len - sizeof ( struct rtw_ieee80211_hdr_3addr ) ;
if ( len > MAX_IE_SZ )
2014-12-11 21:15:04 +00:00
{
2015-02-19 21:34:32 +00:00
/* DBG_871X("IE too long for survey event\n"); */
2013-05-08 21:45:39 +00:00
return _FAIL ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
2015-02-19 20:58:09 +00:00
memset ( bssid , 0 , sizeof ( WLAN_BSSID_EX ) ) ;
2013-05-08 21:45:39 +00:00
subtype = GetFrameSubType ( pframe ) ;
2014-12-11 21:15:04 +00:00
if ( subtype = = WIFI_BEACON ) {
2013-05-08 21:45:39 +00:00
bssid - > Reserved [ 0 ] = 1 ;
ie_offset = _BEACON_IE_OFFSET_ ;
} else {
2015-02-19 21:34:32 +00:00
/* FIXME : more type */
2014-12-11 21:15:04 +00:00
if ( subtype = = WIFI_PROBERSP ) {
2013-05-08 21:45:39 +00:00
ie_offset = _PROBERSP_IE_OFFSET_ ;
bssid - > Reserved [ 0 ] = 3 ;
2014-12-11 21:15:04 +00:00
} else if ( subtype = = WIFI_PROBEREQ ) {
ie_offset = _PROBEREQ_IE_OFFSET_ ;
bssid - > Reserved [ 0 ] = 2 ;
2013-05-08 21:45:39 +00:00
} else {
bssid - > Reserved [ 0 ] = 0 ;
ie_offset = _FIXED_IE_LENGTH_ ;
}
}
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
bssid - > Length = sizeof ( WLAN_BSSID_EX ) - MAX_IE_SZ + len ;
2013-05-19 04:28:07 +00:00
2015-02-19 21:34:32 +00:00
/* below is to copy the information element */
2013-05-08 21:45:39 +00:00
bssid - > IELength = len ;
2015-02-19 20:50:04 +00:00
memcpy ( bssid - > IEs , ( pframe + sizeof ( struct rtw_ieee80211_hdr_3addr ) ) , bssid - > IELength ) ;
2014-12-11 21:15:04 +00:00
2015-02-19 21:34:32 +00:00
/* get the signal strength */
bssid - > Rssi = precv_frame - > u . hdr . attrib . phy_info . RecvSignalPower ; /* in dBM.raw data */
bssid - > PhyInfo . SignalQuality = precv_frame - > u . hdr . attrib . phy_info . SignalQuality ; /* in percentage */
bssid - > PhyInfo . SignalStrength = precv_frame - > u . hdr . attrib . phy_info . SignalStrength ; /* in percentage */
2013-05-08 21:45:39 +00:00
rtw_hal_get_def_var ( padapter , HAL_DEF_CURRENT_ANTENNA , & bssid - > PhyInfo . Optimum_antenna ) ;
2015-02-19 21:34:32 +00:00
/* checking SSID */
2014-12-11 21:15:04 +00:00
if ( ( p = rtw_get_ie ( bssid - > IEs + ie_offset , _SSID_IE_ , & len , bssid - > IELength - ie_offset ) ) = = NULL )
{
DBG_871X ( " marc: cannot find SSID for survey event \n " ) ;
2013-05-08 21:45:39 +00:00
return _FAIL ;
}
2014-12-11 21:15:04 +00:00
if ( * ( p + 1 ) )
{
if ( len > NDIS_802_11_LENGTH_SSID )
{
DBG_871X ( " %s()-%d: IE too long (%d) for survey event \n " , __FUNCTION__ , __LINE__ , len ) ;
2013-05-08 21:45:39 +00:00
return _FAIL ;
}
2015-02-19 20:50:04 +00:00
memcpy ( bssid - > Ssid . Ssid , ( p + 2 ) , * ( p + 1 ) ) ;
2013-05-08 21:45:39 +00:00
bssid - > Ssid . SsidLength = * ( p + 1 ) ;
2014-12-11 21:15:04 +00:00
}
else
{
2013-05-08 21:45:39 +00:00
bssid - > Ssid . SsidLength = 0 ;
}
2015-02-19 20:58:09 +00:00
memset ( bssid - > SupportedRates , 0 , NDIS_802_11_LENGTH_RATES_EX ) ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* checking rate info... */
2013-05-08 21:45:39 +00:00
i = 0 ;
p = rtw_get_ie ( bssid - > IEs + ie_offset , _SUPPORTEDRATES_IE_ , & len , bssid - > IELength - ie_offset ) ;
2014-12-11 21:15:04 +00:00
if ( p ! = NULL )
{
if ( len > NDIS_802_11_LENGTH_RATES_EX )
{
DBG_871X ( " %s()-%d: IE too long (%d) for survey event \n " , __FUNCTION__ , __LINE__ , len ) ;
2013-05-08 21:45:39 +00:00
return _FAIL ;
}
2015-02-19 20:50:04 +00:00
memcpy ( bssid - > SupportedRates , ( p + 2 ) , len ) ;
2013-05-08 21:45:39 +00:00
i = len ;
}
p = rtw_get_ie ( bssid - > IEs + ie_offset , _EXT_SUPPORTEDRATES_IE_ , & len , bssid - > IELength - ie_offset ) ;
2014-12-11 21:15:04 +00:00
if ( p ! = NULL )
{
if ( len > ( NDIS_802_11_LENGTH_RATES_EX - i ) )
{
DBG_871X ( " %s()-%d: IE too long (%d) for survey event \n " , __FUNCTION__ , __LINE__ , len ) ;
2013-05-08 21:45:39 +00:00
return _FAIL ;
}
2015-02-19 20:50:04 +00:00
memcpy ( bssid - > SupportedRates + i , ( p + 2 ) , len ) ;
2013-05-08 21:45:39 +00:00
}
2015-02-19 21:34:32 +00:00
/* todo: */
2014-12-29 02:00:11 +00:00
bssid - > NetworkTypeInUse = Ndis802_11OFDM24 ;
2013-05-08 21:45:39 +00:00
if ( bssid - > IELength < 12 )
return _FAIL ;
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_P2P
if ( subtype = = WIFI_PROBEREQ ) {
u8 * p2p_ie ;
u32 p2p_ielen ;
2015-02-19 21:34:32 +00:00
/* Set Listion Channel */
2014-12-11 21:15:04 +00:00
if ( ( p2p_ie = rtw_get_p2p_ie ( bssid - > IEs , bssid - > IELength , NULL , & p2p_ielen ) ) ) {
u32 attr_contentlen = 0 ;
u8 listen_ch [ 5 ] = { 0x00 } ;
rtw_get_p2p_attr_content ( p2p_ie , p2p_ielen , P2P_ATTR_LISTEN_CH , listen_ch , & attr_contentlen ) ;
bssid - > Configuration . DSConfig = listen_ch [ 4 ] ;
}
2015-02-19 21:34:32 +00:00
else { /* use current channel */
2014-12-11 21:15:04 +00:00
bssid - > Configuration . DSConfig = rtw_get_oper_ch ( padapter ) ;
DBG_871X ( " %s()-%d: Cannot get p2p_ie. set DSconfig to op_ch(%d) \n " , __FUNCTION__ , __LINE__ , bssid - > Configuration . DSConfig ) ;
}
2015-02-19 21:34:32 +00:00
/* FIXME */
2014-12-11 21:15:04 +00:00
bssid - > InfrastructureMode = Ndis802_11Infrastructure ;
2015-02-19 20:50:04 +00:00
memcpy ( bssid - > MacAddress , GetAddr2Ptr ( pframe ) , ETH_ALEN ) ;
2014-12-11 21:15:04 +00:00
bssid - > Privacy = 1 ;
return _SUCCESS ;
}
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_P2P */
2014-12-11 21:15:04 +00:00
2015-02-19 21:34:32 +00:00
/* Checking for DSConfig */
2013-05-08 21:45:39 +00:00
p = rtw_get_ie ( bssid - > IEs + ie_offset , _DSSET_IE_ , & len , bssid - > IELength - ie_offset ) ;
bssid - > Configuration . DSConfig = 0 ;
bssid - > Configuration . Length = 0 ;
2014-12-11 21:15:04 +00:00
if ( p )
{
2013-05-08 21:45:39 +00:00
bssid - > Configuration . DSConfig = * ( p + 2 ) ;
2014-12-11 21:15:04 +00:00
}
else
2015-02-19 21:34:32 +00:00
{ /* In 5G, some ap do not have DSSET IE */
/* checking HT info for channel */
2013-05-08 21:45:39 +00:00
p = rtw_get_ie ( bssid - > IEs + ie_offset , _HT_ADD_INFO_IE_ , & len , bssid - > IELength - ie_offset ) ;
2014-12-11 21:15:04 +00:00
if ( p )
{
2013-05-08 21:45:39 +00:00
struct HT_info_element * HT_info = ( struct HT_info_element * ) ( p + 2 ) ;
bssid - > Configuration . DSConfig = HT_info - > primary_channel ;
2014-12-11 21:15:04 +00:00
}
else
2015-02-19 21:34:32 +00:00
{ /* use current channel */
2013-05-08 21:45:39 +00:00
bssid - > Configuration . DSConfig = rtw_get_oper_ch ( padapter ) ;
}
}
2015-02-19 20:50:04 +00:00
memcpy ( & le_tmp , rtw_get_beacon_interval_from_ie ( bssid - > IEs ) , 2 ) ;
2014-12-19 04:28:04 +00:00
bssid - > Configuration . BeaconPeriod = le32_to_cpu ( le_tmp ) ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
val16 = rtw_get_capability ( ( WLAN_BSSID_EX * ) bssid ) ;
2013-05-08 21:45:39 +00:00
2014-12-19 04:28:04 +00:00
if ( val16 & BIT ( 0 ) ) {
2013-05-08 21:45:39 +00:00
bssid - > InfrastructureMode = Ndis802_11Infrastructure ;
2015-02-19 20:50:04 +00:00
memcpy ( bssid - > MacAddress , GetAddr2Ptr ( pframe ) , ETH_ALEN ) ;
2014-12-19 04:28:04 +00:00
} else {
2013-05-08 21:45:39 +00:00
bssid - > InfrastructureMode = Ndis802_11IBSS ;
2015-02-19 20:50:04 +00:00
memcpy ( bssid - > MacAddress , GetAddr3Ptr ( pframe ) , ETH_ALEN ) ;
2013-05-08 21:45:39 +00:00
}
if ( val16 & BIT ( 4 ) )
bssid - > Privacy = 1 ;
else
bssid - > Privacy = 0 ;
bssid - > Configuration . ATIMWindow = 0 ;
2015-02-19 21:34:32 +00:00
/* 20/40 BSS Coexistence check */
2014-12-29 02:13:24 +00:00
if ( ( pregistrypriv - > wifi_spec = = 1 ) & & ( false = = pmlmeinfo - > bwmode_updated ) )
2014-12-19 06:59:46 +00:00
{
2013-05-08 21:45:39 +00:00
struct mlme_priv * pmlmepriv = & padapter - > mlmepriv ;
p = rtw_get_ie ( bssid - > IEs + ie_offset , _HT_CAPABILITY_IE_ , & len , bssid - > IELength - ie_offset ) ;
2014-12-19 04:28:04 +00:00
if ( p & & len > 0 ) {
2013-05-08 21:45:39 +00:00
struct HT_caps_element * pHT_caps ;
2014-12-11 21:15:04 +00:00
pHT_caps = ( struct HT_caps_element * ) ( p + 2 ) ;
2014-12-19 06:59:46 +00:00
2014-12-19 04:28:04 +00:00
if ( le16_to_cpu ( pHT_caps - > u . HT_cap_element . HT_caps_info ) & BIT ( 14 ) )
2013-05-08 21:45:39 +00:00
pmlmepriv - > num_FortyMHzIntolerant + + ;
2014-12-19 04:28:04 +00:00
} else {
2013-05-08 21:45:39 +00:00
pmlmepriv - > num_sta_no_ht + + ;
}
2014-12-11 21:15:04 +00:00
}
# ifdef CONFIG_INTEL_WIDI
2015-02-19 21:34:32 +00:00
/* process_intel_widi_query_or_tigger(padapter, bssid); */
2014-12-11 21:15:04 +00:00
if ( process_intel_widi_query_or_tigger ( padapter , bssid ) )
{
return _FAIL ;
}
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_INTEL_WIDI */
2014-12-11 21:15:04 +00:00
# if defined(DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) & 1
if ( strcmp ( bssid - > Ssid . Ssid , DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED ) = = 0 ) {
DBG_871X ( " Receiving %s( " MAC_FMT " , DSConfig:%u) from ch%u with ss:%3u, sq:%3u, RawRSSI:%3ld \n "
, bssid - > Ssid . Ssid , MAC_ARG ( bssid - > MacAddress ) , bssid - > Configuration . DSConfig
, rtw_get_oper_ch ( padapter )
, bssid - > PhyInfo . SignalStrength , bssid - > PhyInfo . SignalQuality , bssid - > Rssi
) ;
}
# endif
2015-02-19 21:34:32 +00:00
/* mark bss info receving from nearby channel as SignalQuality 101 */
2014-12-11 21:15:04 +00:00
if ( bssid - > Configuration . DSConfig ! = rtw_get_oper_ch ( padapter ) )
{
bssid - > PhyInfo . SignalQuality = 101 ;
2013-05-08 21:45:39 +00:00
}
return _SUCCESS ;
}
2014-12-17 23:13:53 +00:00
void start_create_ibss ( struct adapter * padapter )
2013-05-08 21:45:39 +00:00
{
unsigned short caps ;
2014-12-11 21:15:04 +00:00
u8 val8 ;
u8 join_type ;
2013-05-08 21:45:39 +00:00
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
2014-12-11 21:15:04 +00:00
WLAN_BSSID_EX * pnetwork = ( WLAN_BSSID_EX * ) ( & ( pmlmeinfo - > network ) ) ;
2013-05-08 21:45:39 +00:00
pmlmeext - > cur_channel = ( u8 ) pnetwork - > Configuration . DSConfig ;
pmlmeinfo - > bcn_interval = get_beacon_interval ( pnetwork ) ;
2015-02-19 21:34:32 +00:00
/* update wireless mode */
2013-05-08 21:45:39 +00:00
update_wireless_mode ( padapter ) ;
2015-02-19 21:34:32 +00:00
/* udpate capability */
2014-12-11 21:15:04 +00:00
caps = rtw_get_capability ( ( WLAN_BSSID_EX * ) pnetwork ) ;
2013-05-08 21:45:39 +00:00
update_capinfo ( padapter , caps ) ;
2015-02-19 21:34:32 +00:00
if ( caps & cap_IBSS ) /* adhoc master */
2014-12-11 21:15:04 +00:00
{
2013-05-08 21:45:39 +00:00
val8 = 0xcf ;
rtw_hal_set_hwreg ( padapter , HW_VAR_SEC_CFG , ( u8 * ) ( & val8 ) ) ;
2015-02-19 21:34:32 +00:00
/* switch channel */
/* SelectChannel(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE); */
2013-05-08 21:45:39 +00:00
set_channel_bwmode ( padapter , pmlmeext - > cur_channel , HAL_PRIME_CHNL_OFFSET_DONT_CARE , HT_CHANNEL_WIDTH_20 ) ;
beacon_timing_control ( padapter ) ;
2015-02-19 21:34:32 +00:00
/* set msr to WIFI_FW_ADHOC_STATE */
2013-05-08 21:45:39 +00:00
pmlmeinfo - > state = WIFI_FW_ADHOC_STATE ;
Set_MSR ( padapter , ( pmlmeinfo - > state & 0x3 ) ) ;
2015-02-19 21:34:32 +00:00
/* issue beacon */
2014-12-11 21:15:04 +00:00
if ( send_beacon ( padapter ) = = _FAIL )
{
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_err_ , ( " issuing beacon frame fail.... \n " ) ) ;
2013-05-08 21:45:39 +00:00
report_join_res ( padapter , - 1 ) ;
pmlmeinfo - > state = WIFI_FW_NULL_STATE ;
2014-12-11 21:15:04 +00:00
}
else
{
2013-05-08 21:45:39 +00:00
rtw_hal_set_hwreg ( padapter , HW_VAR_BSSID , padapter - > registrypriv . dev_network . MacAddress ) ;
join_type = 0 ;
rtw_hal_set_hwreg ( padapter , HW_VAR_MLME_JOIN , ( u8 * ) ( & join_type ) ) ;
report_join_res ( padapter , 1 ) ;
pmlmeinfo - > state | = WIFI_FW_ASSOC_SUCCESS ;
2014-11-19 20:32:12 +00:00
rtw_indicate_connect ( padapter ) ;
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
}
else
{
DBG_871X ( " start_create_ibss, invalid cap:%x \n " , caps ) ;
2013-05-08 21:45:39 +00:00
return ;
}
2015-02-19 21:34:32 +00:00
/* update bc/mc sta_info */
2014-11-19 20:32:12 +00:00
update_bmc_sta ( padapter ) ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-17 23:13:53 +00:00
void start_clnt_join ( struct adapter * padapter )
2013-05-08 21:45:39 +00:00
{
unsigned short caps ;
2014-12-11 21:15:04 +00:00
u8 val8 ;
2013-05-08 21:45:39 +00:00
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
2014-12-11 21:15:04 +00:00
WLAN_BSSID_EX * pnetwork = ( WLAN_BSSID_EX * ) ( & ( pmlmeinfo - > network ) ) ;
2013-05-08 21:45:39 +00:00
int beacon_timeout ;
2015-02-19 21:34:32 +00:00
/* update wireless mode */
2013-05-08 21:45:39 +00:00
update_wireless_mode ( padapter ) ;
2015-02-19 21:34:32 +00:00
/* udpate capability */
2014-12-11 21:15:04 +00:00
caps = rtw_get_capability ( ( WLAN_BSSID_EX * ) pnetwork ) ;
2013-05-08 21:45:39 +00:00
update_capinfo ( padapter , caps ) ;
2014-12-11 21:15:04 +00:00
if ( caps & cap_ESS )
{
2013-05-08 21:45:39 +00:00
Set_MSR ( padapter , WIFI_FW_STATION_STATE ) ;
2014-12-11 21:15:04 +00:00
val8 = ( pmlmeinfo - > auth_algo = = dot11AuthAlgrthm_8021X ) ? 0xcc : 0xcf ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_WAPI_SUPPORT
if ( padapter - > wapiInfo . bWapiEnable & & pmlmeinfo - > auth_algo = = dot11AuthAlgrthm_WAPI )
{
2015-02-19 21:34:32 +00:00
/* Disable TxUseDefaultKey, RxUseDefaultKey, RxBroadcastUseDefaultKey. */
2014-12-11 21:15:04 +00:00
val8 = 0x4c ;
}
# endif
2013-05-08 21:45:39 +00:00
rtw_hal_set_hwreg ( padapter , HW_VAR_SEC_CFG , ( u8 * ) ( & val8 ) ) ;
2015-02-19 21:34:32 +00:00
/* Because of AP's not receiving deauth before */
/* AP may: 1)not response auth or 2)deauth us after link is complete */
/* issue deauth before issuing auth to deal with the situation */
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* Commented by Albert 2012/07/21 */
/* For the Win8 P2P connection, it will be hard to have a successful connection if this Wi-Fi doesn't connect to it. */
2014-12-11 21:15:04 +00:00
{
# ifdef CONFIG_P2P
_queue * queue = & ( padapter - > mlmepriv . scanned_queue ) ;
_list * head = get_list_head ( queue ) ;
_list * pos = get_next ( head ) ;
struct wlan_network * scanned = NULL ;
u8 ie_offset = 0 ;
_irqL irqL ;
2014-12-29 02:13:24 +00:00
bool has_p2p_ie = false ;
2014-12-11 21:15:04 +00:00
_enter_critical_bh ( & ( padapter - > mlmepriv . scanned_queue . lock ) , & irqL ) ;
for ( pos = get_next ( head ) ; ! rtw_end_of_queue_search ( head , pos ) ; pos = get_next ( pos ) ) {
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
scanned = LIST_CONTAINOR ( pos , struct wlan_network , list ) ;
if ( scanned = = NULL )
rtw_warn_on ( 1 ) ;
2014-12-29 02:13:24 +00:00
if ( _rtw_memcmp ( & ( scanned - > network . Ssid ) , & ( pnetwork - > Ssid ) , sizeof ( NDIS_802_11_SSID ) ) = = true
& & _rtw_memcmp ( scanned - > network . MacAddress , pnetwork - > MacAddress , sizeof ( NDIS_802_11_MAC_ADDRESS ) ) = = true
2014-12-11 21:15:04 +00:00
) {
ie_offset = ( scanned - > network . Reserved [ 0 ] = = 2 ? 0 : 12 ) ;
if ( rtw_get_p2p_ie ( scanned - > network . IEs + ie_offset , scanned - > network . IELength - ie_offset , NULL , NULL ) )
2014-12-29 02:13:24 +00:00
has_p2p_ie = true ;
2014-12-11 21:15:04 +00:00
break ;
}
}
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
_exit_critical_bh ( & ( padapter - > mlmepriv . scanned_queue . lock ) , & irqL ) ;
2013-05-19 04:28:07 +00:00
2014-12-29 02:13:24 +00:00
if ( scanned = = NULL | | rtw_end_of_queue_search ( head , pos ) | | has_p2p_ie = = false )
2014-12-11 21:15:04 +00:00
# endif /* CONFIG_P2P */
issue_deauth_ex ( padapter , pnetwork - > MacAddress , WLAN_REASON_DEAUTH_LEAVING , 5 , 100 ) ;
}
2015-02-19 21:34:32 +00:00
/* here wait for receiving the beacon to start auth */
/* and enable a timer */
2014-12-11 21:15:04 +00:00
beacon_timeout = decide_wait_for_beacon_timeout ( pmlmeinfo - > bcn_interval ) ;
2014-12-19 06:59:46 +00:00
set_link_timer ( pmlmeext , beacon_timeout ) ;
_set_timer ( & padapter - > mlmepriv . assoc_timer ,
2014-12-11 21:15:04 +00:00
( REAUTH_TO * REAUTH_LIMIT ) + ( REASSOC_TO * REASSOC_LIMIT ) + beacon_timeout ) ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
pmlmeinfo - > state = WIFI_FW_AUTH_NULL | WIFI_FW_STATION_STATE ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
{ /* only for STA mode */
2014-12-11 21:15:04 +00:00
u16 media_status ;
u8 mac_id = 0 ;
2015-02-19 21:34:32 +00:00
media_status = ( mac_id < < 8 ) | 1 ; /* MACID|OPMODE:1 connect */
2014-12-19 06:59:46 +00:00
rtw_hal_set_hwreg ( padapter , HW_VAR_H2C_MEDIA_STATUS_RPT , ( u8 * ) & media_status ) ;
}
2014-12-11 21:15:04 +00:00
}
2015-02-19 21:34:32 +00:00
else if ( caps & cap_IBSS ) /* adhoc client */
2014-12-11 21:15:04 +00:00
{
2013-05-08 21:45:39 +00:00
Set_MSR ( padapter , WIFI_FW_ADHOC_STATE ) ;
val8 = 0xcf ;
rtw_hal_set_hwreg ( padapter , HW_VAR_SEC_CFG , ( u8 * ) ( & val8 ) ) ;
beacon_timing_control ( padapter ) ;
pmlmeinfo - > state = WIFI_FW_ADHOC_STATE ;
report_join_res ( padapter , 1 ) ;
2014-12-11 21:15:04 +00:00
}
else
{
2015-02-19 21:34:32 +00:00
/* DBG_871X("marc: invalid cap:%x\n", caps); */
2013-05-08 21:45:39 +00:00
return ;
}
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-17 23:13:53 +00:00
void start_clnt_auth ( struct adapter * padapter )
2013-05-08 21:45:39 +00:00
{
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
_cancel_timer_ex ( & pmlmeext - > link_timer ) ;
pmlmeinfo - > state & = ( ~ WIFI_FW_AUTH_NULL ) ;
pmlmeinfo - > state | = WIFI_FW_AUTH_STATE ;
pmlmeinfo - > auth_seq = 1 ;
pmlmeinfo - > reauth_count = 0 ;
pmlmeinfo - > reassoc_count = 0 ;
pmlmeinfo - > link_count = 0 ;
pmlmeext - > retry = 0 ;
2014-12-11 21:15:04 +00:00
DBG_871X_LEVEL ( _drv_always_ , " start auth \n " ) ;
2013-05-08 21:45:39 +00:00
issue_auth ( padapter , NULL , 0 ) ;
set_link_timer ( pmlmeext , REAUTH_TO ) ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
2014-12-17 23:13:53 +00:00
void start_clnt_assoc ( struct adapter * padapter )
2013-05-08 21:45:39 +00:00
{
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
_cancel_timer_ex ( & pmlmeext - > link_timer ) ;
pmlmeinfo - > state & = ( ~ ( WIFI_FW_AUTH_NULL | WIFI_FW_AUTH_STATE ) ) ;
pmlmeinfo - > state | = ( WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE ) ;
issue_assocreq ( padapter ) ;
set_link_timer ( pmlmeext , REASSOC_TO ) ;
}
2014-12-17 23:13:53 +00:00
unsigned int receive_disconnect ( struct adapter * padapter , unsigned char * MacAddr , unsigned short reason )
2013-05-08 21:45:39 +00:00
{
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
2015-02-19 21:34:32 +00:00
/* check A3 */
2013-05-08 21:45:39 +00:00
if ( ! ( _rtw_memcmp ( MacAddr , get_my_bssid ( & pmlmeinfo - > network ) , ETH_ALEN ) ) )
return _SUCCESS ;
2014-12-11 21:15:04 +00:00
DBG_871X ( " %s \n " , __FUNCTION__ ) ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
if ( ( pmlmeinfo - > state & 0x03 ) = = WIFI_FW_STATION_STATE )
{
if ( pmlmeinfo - > state & WIFI_FW_ASSOC_SUCCESS )
{
2013-05-08 21:45:39 +00:00
pmlmeinfo - > state = WIFI_FW_NULL_STATE ;
report_del_sta_event ( padapter , MacAddr , reason ) ;
2014-12-11 21:15:04 +00:00
}
else if ( pmlmeinfo - > state & WIFI_FW_LINKING_STATE )
{
2013-05-08 21:45:39 +00:00
pmlmeinfo - > state = WIFI_FW_NULL_STATE ;
report_join_res ( padapter , - 2 ) ;
}
}
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
return _SUCCESS ;
}
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_80211D
2014-12-17 23:13:53 +00:00
static void process_80211d ( struct adapter * padapter , WLAN_BSSID_EX * bssid )
2013-05-08 21:45:39 +00:00
{
struct registry_priv * pregistrypriv ;
struct mlme_ext_priv * pmlmeext ;
2014-12-11 21:15:04 +00:00
RT_CHANNEL_INFO * chplan_new ;
2013-05-08 21:45:39 +00:00
u8 channel ;
u8 i ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
pregistrypriv = & padapter - > registrypriv ;
pmlmeext = & padapter - > mlmeextpriv ;
2015-02-19 21:34:32 +00:00
/* Adjust channel plan by AP Country IE */
2013-05-08 21:45:39 +00:00
if ( pregistrypriv - > enable80211d & &
2014-12-11 21:15:04 +00:00
( ! pmlmeext - > update_channel_plan_by_ap_done ) )
{
2013-05-08 21:45:39 +00:00
u8 * ie , * p ;
u32 len ;
2014-12-11 21:15:04 +00:00
RT_CHANNEL_PLAN chplan_ap ;
RT_CHANNEL_INFO chplan_sta [ MAX_CHANNEL_NUM ] ;
2013-05-08 21:45:39 +00:00
u8 country [ 4 ] ;
2015-02-19 21:34:32 +00:00
u8 fcn ; /* first channel number */
u8 noc ; /* number of channel */
2013-05-08 21:45:39 +00:00
u8 j , k ;
ie = rtw_get_ie ( bssid - > IEs + _FIXED_IE_LENGTH_ , _COUNTRY_IE_ , & len , bssid - > IELength - _FIXED_IE_LENGTH_ ) ;
2014-12-11 21:15:04 +00:00
if ( ! ie ) return ;
if ( len < 6 ) return ;
2013-05-08 21:45:39 +00:00
ie + = 2 ;
p = ie ;
ie + = len ;
2015-02-19 20:58:09 +00:00
memset ( country , 0 , 4 ) ;
2015-02-19 20:50:04 +00:00
memcpy ( country , p , 3 ) ;
2013-05-08 21:45:39 +00:00
p + = 3 ;
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_notice_ ,
2014-12-11 21:15:04 +00:00
( " %s: 802.11d country=%s \n " , __FUNCTION__ , country ) ) ;
2013-05-08 21:45:39 +00:00
i = 0 ;
2014-12-11 21:15:04 +00:00
while ( ( ie - p ) > = 3 )
{
2013-05-08 21:45:39 +00:00
fcn = * ( p + + ) ;
noc = * ( p + + ) ;
p + + ;
2014-12-11 21:15:04 +00:00
for ( j = 0 ; j < noc ; j + + )
{
2015-02-19 21:34:32 +00:00
if ( fcn < = 14 ) channel = fcn + j ; /* 2.4 GHz */
else channel = fcn + j * 4 ; /* 5 GHz */
2013-05-08 21:45:39 +00:00
chplan_ap . Channel [ i + + ] = channel ;
}
}
chplan_ap . Len = i ;
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_DEBUG_RTL871X
i = 0 ;
DBG_871X ( " %s: AP[%s] channel plan { " , __func__ , bssid - > Ssid . Ssid ) ;
while ( ( i < chplan_ap . Len ) & & ( chplan_ap . Channel [ i ] ! = 0 ) )
{
DBG_8192C ( " %02d, " , chplan_ap . Channel [ i ] ) ;
i + + ;
}
DBG_871X ( " } \n " ) ;
# endif
2015-02-19 20:50:04 +00:00
memcpy ( chplan_sta , pmlmeext - > channel_set , sizeof ( chplan_sta ) ) ;
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_DEBUG_RTL871X
i = 0 ;
DBG_871X ( " %s: STA channel plan { " , __func__ ) ;
while ( ( i < MAX_CHANNEL_NUM ) & & ( chplan_sta [ i ] . ChannelNum ! = 0 ) )
{
DBG_871X ( " %02d(%c), " , chplan_sta [ i ] . ChannelNum , chplan_sta [ i ] . ScanType = = SCAN_PASSIVE ? ' p ' : ' a ' ) ;
i + + ;
}
DBG_871X ( " } \n " ) ;
# endif
2013-05-08 21:45:39 +00:00
2015-02-19 20:58:09 +00:00
memset ( pmlmeext - > channel_set , 0 , sizeof ( pmlmeext - > channel_set ) ) ;
2013-05-08 21:45:39 +00:00
chplan_new = pmlmeext - > channel_set ;
2014-12-11 21:15:04 +00:00
i = j = k = 0 ;
if ( pregistrypriv - > wireless_mode & WIRELESS_11G )
{
2013-05-08 21:45:39 +00:00
do {
if ( ( i = = MAX_CHANNEL_NUM ) | |
2014-12-11 21:15:04 +00:00
( chplan_sta [ i ] . ChannelNum = = 0 ) | |
( chplan_sta [ i ] . ChannelNum > 14 ) )
2013-05-08 21:45:39 +00:00
break ;
if ( ( j = = chplan_ap . Len ) | | ( chplan_ap . Channel [ j ] > 14 ) )
break ;
2014-12-11 21:15:04 +00:00
if ( chplan_sta [ i ] . ChannelNum = = chplan_ap . Channel [ j ] )
{
2013-05-08 21:45:39 +00:00
chplan_new [ k ] . ChannelNum = chplan_ap . Channel [ j ] ;
chplan_new [ k ] . ScanType = SCAN_ACTIVE ;
i + + ;
j + + ;
k + + ;
2014-12-11 21:15:04 +00:00
}
else if ( chplan_sta [ i ] . ChannelNum < chplan_ap . Channel [ j ] )
{
2013-05-08 21:45:39 +00:00
chplan_new [ k ] . ChannelNum = chplan_sta [ i ] . ChannelNum ;
2015-02-19 21:34:32 +00:00
/* chplan_new[k].ScanType = chplan_sta[i].ScanType; */
2013-05-08 21:45:39 +00:00
chplan_new [ k ] . ScanType = SCAN_PASSIVE ;
i + + ;
k + + ;
2014-12-11 21:15:04 +00:00
}
else if ( chplan_sta [ i ] . ChannelNum > chplan_ap . Channel [ j ] )
{
2013-05-08 21:45:39 +00:00
chplan_new [ k ] . ChannelNum = chplan_ap . Channel [ j ] ;
chplan_new [ k ] . ScanType = SCAN_ACTIVE ;
j + + ;
k + + ;
}
} while ( 1 ) ;
2015-02-19 21:34:32 +00:00
/* change AP not support channel to Passive scan */
2013-05-08 21:45:39 +00:00
while ( ( i < MAX_CHANNEL_NUM ) & &
2014-12-11 21:15:04 +00:00
( chplan_sta [ i ] . ChannelNum ! = 0 ) & &
( chplan_sta [ i ] . ChannelNum < = 14 ) )
{
2013-05-08 21:45:39 +00:00
chplan_new [ k ] . ChannelNum = chplan_sta [ i ] . ChannelNum ;
2015-02-19 21:34:32 +00:00
/* chplan_new[k].ScanType = chplan_sta[i].ScanType; */
2013-05-08 21:45:39 +00:00
chplan_new [ k ] . ScanType = SCAN_PASSIVE ;
i + + ;
k + + ;
}
2015-02-19 21:34:32 +00:00
/* add channel AP supported */
2014-12-11 21:15:04 +00:00
while ( ( j < chplan_ap . Len ) & & ( chplan_ap . Channel [ j ] < = 14 ) )
{
2013-05-08 21:45:39 +00:00
chplan_new [ k ] . ChannelNum = chplan_ap . Channel [ j ] ;
chplan_new [ k ] . ScanType = SCAN_ACTIVE ;
j + + ;
k + + ;
}
2014-12-11 21:15:04 +00:00
}
else
{
2015-02-19 21:34:32 +00:00
/* keep original STA 2.4G channel plan */
2013-05-08 21:45:39 +00:00
while ( ( i < MAX_CHANNEL_NUM ) & &
2014-12-11 21:15:04 +00:00
( chplan_sta [ i ] . ChannelNum ! = 0 ) & &
( chplan_sta [ i ] . ChannelNum < = 14 ) )
{
2013-05-08 21:45:39 +00:00
chplan_new [ k ] . ChannelNum = chplan_sta [ i ] . ChannelNum ;
chplan_new [ k ] . ScanType = chplan_sta [ i ] . ScanType ;
i + + ;
k + + ;
}
2015-02-19 21:34:32 +00:00
/* skip AP 2.4G channel plan */
2013-05-08 21:45:39 +00:00
while ( ( j < chplan_ap . Len ) & & ( chplan_ap . Channel [ j ] < = 14 ) )
2014-12-11 21:15:04 +00:00
{
2013-05-08 21:45:39 +00:00
j + + ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
if ( pregistrypriv - > wireless_mode & WIRELESS_11A )
{
do {
if ( ( i = = MAX_CHANNEL_NUM ) | |
( chplan_sta [ i ] . ChannelNum = = 0 ) )
break ;
if ( ( j = = chplan_ap . Len ) | | ( chplan_ap . Channel [ j ] = = 0 ) )
break ;
if ( chplan_sta [ i ] . ChannelNum = = chplan_ap . Channel [ j ] )
{
chplan_new [ k ] . ChannelNum = chplan_ap . Channel [ j ] ;
chplan_new [ k ] . ScanType = SCAN_ACTIVE ;
i + + ;
j + + ;
k + + ;
}
else if ( chplan_sta [ i ] . ChannelNum < chplan_ap . Channel [ j ] )
{
chplan_new [ k ] . ChannelNum = chplan_sta [ i ] . ChannelNum ;
2015-02-19 21:34:32 +00:00
/* chplan_new[k].ScanType = chplan_sta[i].ScanType; */
2014-12-11 21:15:04 +00:00
chplan_new [ k ] . ScanType = SCAN_PASSIVE ;
i + + ;
k + + ;
}
else if ( chplan_sta [ i ] . ChannelNum > chplan_ap . Channel [ j ] )
{
chplan_new [ k ] . ChannelNum = chplan_ap . Channel [ j ] ;
chplan_new [ k ] . ScanType = SCAN_ACTIVE ;
j + + ;
k + + ;
}
} while ( 1 ) ;
2015-02-19 21:34:32 +00:00
/* change AP not support channel to Passive scan */
2014-12-11 21:15:04 +00:00
while ( ( i < MAX_CHANNEL_NUM ) & & ( chplan_sta [ i ] . ChannelNum ! = 0 ) )
{
chplan_new [ k ] . ChannelNum = chplan_sta [ i ] . ChannelNum ;
2015-02-19 21:34:32 +00:00
/* chplan_new[k].ScanType = chplan_sta[i].ScanType; */
2014-12-11 21:15:04 +00:00
chplan_new [ k ] . ScanType = SCAN_PASSIVE ;
i + + ;
k + + ;
}
2015-02-19 21:34:32 +00:00
/* add channel AP supported */
2014-12-11 21:15:04 +00:00
while ( ( j < chplan_ap . Len ) & & ( chplan_ap . Channel [ j ] ! = 0 ) )
{
chplan_new [ k ] . ChannelNum = chplan_ap . Channel [ j ] ;
chplan_new [ k ] . ScanType = SCAN_ACTIVE ;
j + + ;
k + + ;
}
}
else
{
2015-02-19 21:34:32 +00:00
/* keep original STA 5G channel plan */
2014-12-11 21:15:04 +00:00
while ( ( i < MAX_CHANNEL_NUM ) & & ( chplan_sta [ i ] . ChannelNum ! = 0 ) )
{
chplan_new [ k ] . ChannelNum = chplan_sta [ i ] . ChannelNum ;
chplan_new [ k ] . ScanType = chplan_sta [ i ] . ScanType ;
i + + ;
k + + ;
}
2013-05-08 21:45:39 +00:00
}
pmlmeext - > update_channel_plan_by_ap_done = 1 ;
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_DEBUG_RTL871X
k = 0 ;
DBG_871X ( " %s: new STA channel plan { " , __func__ ) ;
while ( ( k < MAX_CHANNEL_NUM ) & & ( chplan_new [ k ] . ChannelNum ! = 0 ) )
{
DBG_871X ( " %02d(%c), " , chplan_new [ k ] . ChannelNum , chplan_new [ k ] . ScanType = = SCAN_PASSIVE ? ' p ' : ' c ' ) ;
k + + ;
}
DBG_871X ( " } \n " ) ;
# endif
2013-05-08 21:45:39 +00:00
}
2015-02-19 21:34:32 +00:00
/* If channel is used by AP, set channel scan type to active */
2013-05-08 21:45:39 +00:00
channel = bssid - > Configuration . DSConfig ;
chplan_new = pmlmeext - > channel_set ;
i = 0 ;
2014-12-11 21:15:04 +00:00
while ( ( i < MAX_CHANNEL_NUM ) & & ( chplan_new [ i ] . ChannelNum ! = 0 ) )
{
if ( chplan_new [ i ] . ChannelNum = = channel )
{
if ( chplan_new [ i ] . ScanType = = SCAN_PASSIVE )
{
2015-02-19 21:34:32 +00:00
/* 5G Bnad 2, 3 (DFS) doesn't change to active scan */
2014-12-11 21:15:04 +00:00
if ( channel > = 52 & & channel < = 144 )
break ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
chplan_new [ i ] . ScanType = SCAN_ACTIVE ;
RT_TRACE ( _module_rtl871x_mlme_c_ , _drv_notice_ ,
2014-12-11 21:15:04 +00:00
( " %s: change channel %d scan type from passive to active \n " ,
__FUNCTION__ , channel ) ) ;
2013-05-08 21:45:39 +00:00
}
break ;
}
i + + ;
}
}
2014-12-11 21:15:04 +00:00
# endif
2013-05-08 21:45:39 +00:00
/****************************************************************************
Following are the functions to report events
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2014-12-17 23:13:53 +00:00
void report_survey_event ( struct adapter * padapter , union recv_frame * precv_frame )
2013-05-08 21:45:39 +00:00
{
struct cmd_obj * pcmd_obj ;
2014-12-11 21:15:04 +00:00
u8 * pevtcmd ;
2013-05-08 21:45:39 +00:00
u32 cmdsz ;
struct survey_event * psurvey_evt ;
struct C2HEvent_Header * pc2h_evt_hdr ;
struct mlme_ext_priv * pmlmeext ;
struct cmd_priv * pcmdpriv ;
2015-02-19 21:34:32 +00:00
/* u8 *pframe = precv_frame->u.hdr.rx_data; */
/* uint len = precv_frame->u.hdr.len; */
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
if ( ! padapter )
2013-05-08 21:45:39 +00:00
return ;
pmlmeext = & padapter - > mlmeextpriv ;
pcmdpriv = & padapter - > cmdpriv ;
2014-12-19 06:59:46 +00:00
2013-05-19 04:28:07 +00:00
2014-12-11 21:15:04 +00:00
if ( ( pcmd_obj = ( struct cmd_obj * ) rtw_zmalloc ( sizeof ( struct cmd_obj ) ) ) = = NULL )
{
2013-05-08 21:45:39 +00:00
return ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
cmdsz = ( sizeof ( struct survey_event ) + sizeof ( struct C2HEvent_Header ) ) ;
2014-12-11 21:15:04 +00:00
if ( ( pevtcmd = ( u8 * ) rtw_zmalloc ( cmdsz ) ) = = NULL )
{
rtw_mfree ( ( u8 * ) pcmd_obj , sizeof ( struct cmd_obj ) ) ;
2013-05-08 21:45:39 +00:00
return ;
}
_rtw_init_listhead ( & pcmd_obj - > list ) ;
pcmd_obj - > cmdcode = GEN_CMD_CODE ( _Set_MLME_EVT ) ;
pcmd_obj - > cmdsz = cmdsz ;
pcmd_obj - > parmbuf = pevtcmd ;
pcmd_obj - > rsp = NULL ;
pcmd_obj - > rspsz = 0 ;
2014-12-11 21:15:04 +00:00
pc2h_evt_hdr = ( struct C2HEvent_Header * ) ( pevtcmd ) ;
2013-05-08 21:45:39 +00:00
pc2h_evt_hdr - > len = sizeof ( struct survey_event ) ;
pc2h_evt_hdr - > ID = GEN_EVT_CODE ( _Survey ) ;
pc2h_evt_hdr - > seq = ATOMIC_INC_RETURN ( & pmlmeext - > event_seq ) ;
2014-12-11 21:15:04 +00:00
psurvey_evt = ( struct survey_event * ) ( pevtcmd + sizeof ( struct C2HEvent_Header ) ) ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
if ( collect_bss_info ( padapter , precv_frame , ( WLAN_BSSID_EX * ) & psurvey_evt - > bss ) = = _FAIL )
{
rtw_mfree ( ( u8 * ) pcmd_obj , sizeof ( struct cmd_obj ) ) ;
rtw_mfree ( ( u8 * ) pevtcmd , cmdsz ) ;
2013-05-08 21:45:39 +00:00
return ;
}
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_80211D
2013-05-08 21:45:39 +00:00
process_80211d ( padapter , & psurvey_evt - > bss ) ;
2014-12-11 21:15:04 +00:00
# endif
2013-05-08 21:45:39 +00:00
rtw_enqueue_cmd ( pcmdpriv , pcmd_obj ) ;
pmlmeext - > sitesurvey_res . bss_cnt + + ;
return ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-17 23:13:53 +00:00
void report_surveydone_event ( struct adapter * padapter )
2013-05-08 21:45:39 +00:00
{
struct cmd_obj * pcmd_obj ;
2014-12-11 21:15:04 +00:00
u8 * pevtcmd ;
2013-05-08 21:45:39 +00:00
u32 cmdsz ;
struct surveydone_event * psurveydone_evt ;
struct C2HEvent_Header * pc2h_evt_hdr ;
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
struct cmd_priv * pcmdpriv = & padapter - > cmdpriv ;
2014-12-11 21:15:04 +00:00
if ( ( pcmd_obj = ( struct cmd_obj * ) rtw_zmalloc ( sizeof ( struct cmd_obj ) ) ) = = NULL )
{
2013-05-08 21:45:39 +00:00
return ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
cmdsz = ( sizeof ( struct surveydone_event ) + sizeof ( struct C2HEvent_Header ) ) ;
2014-12-11 21:15:04 +00:00
if ( ( pevtcmd = ( u8 * ) rtw_zmalloc ( cmdsz ) ) = = NULL )
{
rtw_mfree ( ( u8 * ) pcmd_obj , sizeof ( struct cmd_obj ) ) ;
2013-05-08 21:45:39 +00:00
return ;
}
_rtw_init_listhead ( & pcmd_obj - > list ) ;
pcmd_obj - > cmdcode = GEN_CMD_CODE ( _Set_MLME_EVT ) ;
pcmd_obj - > cmdsz = cmdsz ;
pcmd_obj - > parmbuf = pevtcmd ;
pcmd_obj - > rsp = NULL ;
pcmd_obj - > rspsz = 0 ;
2014-12-11 21:15:04 +00:00
pc2h_evt_hdr = ( struct C2HEvent_Header * ) ( pevtcmd ) ;
2013-05-08 21:45:39 +00:00
pc2h_evt_hdr - > len = sizeof ( struct surveydone_event ) ;
pc2h_evt_hdr - > ID = GEN_EVT_CODE ( _SurveyDone ) ;
pc2h_evt_hdr - > seq = ATOMIC_INC_RETURN ( & pmlmeext - > event_seq ) ;
2014-12-11 21:15:04 +00:00
psurveydone_evt = ( struct surveydone_event * ) ( pevtcmd + sizeof ( struct C2HEvent_Header ) ) ;
2013-05-08 21:45:39 +00:00
psurveydone_evt - > bss_cnt = pmlmeext - > sitesurvey_res . bss_cnt ;
2014-12-11 21:15:04 +00:00
DBG_871X ( " survey done event(%x) \n " , psurveydone_evt - > bss_cnt ) ;
2013-05-08 21:45:39 +00:00
rtw_enqueue_cmd ( pcmdpriv , pcmd_obj ) ;
return ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-17 23:13:53 +00:00
void report_join_res ( struct adapter * padapter , int res )
2013-05-08 21:45:39 +00:00
{
struct cmd_obj * pcmd_obj ;
2014-12-11 21:15:04 +00:00
u8 * pevtcmd ;
2013-05-08 21:45:39 +00:00
u32 cmdsz ;
struct joinbss_event * pjoinbss_evt ;
struct C2HEvent_Header * pc2h_evt_hdr ;
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
struct cmd_priv * pcmdpriv = & padapter - > cmdpriv ;
2014-12-11 21:15:04 +00:00
if ( ( pcmd_obj = ( struct cmd_obj * ) rtw_zmalloc ( sizeof ( struct cmd_obj ) ) ) = = NULL )
{
2013-05-08 21:45:39 +00:00
return ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
cmdsz = ( sizeof ( struct joinbss_event ) + sizeof ( struct C2HEvent_Header ) ) ;
2014-12-11 21:15:04 +00:00
if ( ( pevtcmd = ( u8 * ) rtw_zmalloc ( cmdsz ) ) = = NULL )
{
rtw_mfree ( ( u8 * ) pcmd_obj , sizeof ( struct cmd_obj ) ) ;
2013-05-08 21:45:39 +00:00
return ;
}
_rtw_init_listhead ( & pcmd_obj - > list ) ;
pcmd_obj - > cmdcode = GEN_CMD_CODE ( _Set_MLME_EVT ) ;
pcmd_obj - > cmdsz = cmdsz ;
pcmd_obj - > parmbuf = pevtcmd ;
pcmd_obj - > rsp = NULL ;
pcmd_obj - > rspsz = 0 ;
2014-12-11 21:15:04 +00:00
pc2h_evt_hdr = ( struct C2HEvent_Header * ) ( pevtcmd ) ;
2013-05-08 21:45:39 +00:00
pc2h_evt_hdr - > len = sizeof ( struct joinbss_event ) ;
pc2h_evt_hdr - > ID = GEN_EVT_CODE ( _JoinBss ) ;
pc2h_evt_hdr - > seq = ATOMIC_INC_RETURN ( & pmlmeext - > event_seq ) ;
2014-12-11 21:15:04 +00:00
pjoinbss_evt = ( struct joinbss_event * ) ( pevtcmd + sizeof ( struct C2HEvent_Header ) ) ;
2015-02-19 20:50:04 +00:00
memcpy ( ( unsigned char * ) ( & ( pjoinbss_evt - > network . network ) ) , & ( pmlmeinfo - > network ) , sizeof ( WLAN_BSSID_EX ) ) ;
2014-12-19 06:59:46 +00:00
pjoinbss_evt - > network . join_res = pjoinbss_evt - > network . aid = res ;
2013-05-19 04:28:07 +00:00
2014-12-11 21:15:04 +00:00
DBG_871X ( " report_join_res(%d) \n " , res ) ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
rtw_joinbss_event_prehandle ( padapter , ( u8 * ) & pjoinbss_evt - > network ) ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
rtw_enqueue_cmd ( pcmdpriv , pcmd_obj ) ;
return ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-17 23:13:53 +00:00
void report_del_sta_event ( struct adapter * padapter , unsigned char * MacAddr , unsigned short reason )
2013-05-08 21:45:39 +00:00
{
struct cmd_obj * pcmd_obj ;
2014-12-11 21:15:04 +00:00
u8 * pevtcmd ;
2013-05-08 21:45:39 +00:00
u32 cmdsz ;
struct sta_info * psta ;
int mac_id ;
struct stadel_event * pdel_sta_evt ;
struct C2HEvent_Header * pc2h_evt_hdr ;
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
struct cmd_priv * pcmdpriv = & padapter - > cmdpriv ;
2014-12-11 21:15:04 +00:00
if ( ( pcmd_obj = ( struct cmd_obj * ) rtw_zmalloc ( sizeof ( struct cmd_obj ) ) ) = = NULL )
{
2013-05-08 21:45:39 +00:00
return ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
cmdsz = ( sizeof ( struct stadel_event ) + sizeof ( struct C2HEvent_Header ) ) ;
2014-12-11 21:15:04 +00:00
if ( ( pevtcmd = ( u8 * ) rtw_zmalloc ( cmdsz ) ) = = NULL )
{
rtw_mfree ( ( u8 * ) pcmd_obj , sizeof ( struct cmd_obj ) ) ;
2013-05-08 21:45:39 +00:00
return ;
}
_rtw_init_listhead ( & pcmd_obj - > list ) ;
pcmd_obj - > cmdcode = GEN_CMD_CODE ( _Set_MLME_EVT ) ;
pcmd_obj - > cmdsz = cmdsz ;
pcmd_obj - > parmbuf = pevtcmd ;
pcmd_obj - > rsp = NULL ;
pcmd_obj - > rspsz = 0 ;
2014-12-11 21:15:04 +00:00
pc2h_evt_hdr = ( struct C2HEvent_Header * ) ( pevtcmd ) ;
2013-05-08 21:45:39 +00:00
pc2h_evt_hdr - > len = sizeof ( struct stadel_event ) ;
pc2h_evt_hdr - > ID = GEN_EVT_CODE ( _DelSTA ) ;
pc2h_evt_hdr - > seq = ATOMIC_INC_RETURN ( & pmlmeext - > event_seq ) ;
2014-12-11 21:15:04 +00:00
pdel_sta_evt = ( struct stadel_event * ) ( pevtcmd + sizeof ( struct C2HEvent_Header ) ) ;
2015-02-19 20:50:04 +00:00
memcpy ( ( unsigned char * ) ( & ( pdel_sta_evt - > macaddr ) ) , MacAddr , ETH_ALEN ) ;
memcpy ( ( unsigned char * ) ( pdel_sta_evt - > rsvd ) , ( unsigned char * ) ( & reason ) , 2 ) ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
psta = rtw_get_stainfo ( & padapter - > stapriv , MacAddr ) ;
2014-12-11 21:15:04 +00:00
if ( psta )
2014-12-19 06:59:46 +00:00
mac_id = ( int ) psta - > mac_id ;
2013-05-08 21:45:39 +00:00
else
mac_id = ( - 1 ) ;
pdel_sta_evt - > mac_id = mac_id ;
2014-12-11 21:15:04 +00:00
DBG_871X ( " report_del_sta_event: delete STA, mac_id=%d \n " , mac_id ) ;
2013-05-08 21:45:39 +00:00
rtw_enqueue_cmd ( pcmdpriv , pcmd_obj ) ;
return ;
}
2014-12-17 23:13:53 +00:00
void report_add_sta_event ( struct adapter * padapter , unsigned char * MacAddr , int cam_idx )
2013-05-08 21:45:39 +00:00
{
struct cmd_obj * pcmd_obj ;
2014-12-11 21:15:04 +00:00
u8 * pevtcmd ;
2013-05-08 21:45:39 +00:00
u32 cmdsz ;
struct stassoc_event * padd_sta_evt ;
struct C2HEvent_Header * pc2h_evt_hdr ;
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
struct cmd_priv * pcmdpriv = & padapter - > cmdpriv ;
2014-12-11 21:15:04 +00:00
if ( ( pcmd_obj = ( struct cmd_obj * ) rtw_zmalloc ( sizeof ( struct cmd_obj ) ) ) = = NULL )
{
2013-05-08 21:45:39 +00:00
return ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
cmdsz = ( sizeof ( struct stassoc_event ) + sizeof ( struct C2HEvent_Header ) ) ;
2014-12-11 21:15:04 +00:00
if ( ( pevtcmd = ( u8 * ) rtw_zmalloc ( cmdsz ) ) = = NULL )
{
rtw_mfree ( ( u8 * ) pcmd_obj , sizeof ( struct cmd_obj ) ) ;
2013-05-08 21:45:39 +00:00
return ;
}
_rtw_init_listhead ( & pcmd_obj - > list ) ;
pcmd_obj - > cmdcode = GEN_CMD_CODE ( _Set_MLME_EVT ) ;
pcmd_obj - > cmdsz = cmdsz ;
pcmd_obj - > parmbuf = pevtcmd ;
pcmd_obj - > rsp = NULL ;
pcmd_obj - > rspsz = 0 ;
2014-12-11 21:15:04 +00:00
pc2h_evt_hdr = ( struct C2HEvent_Header * ) ( pevtcmd ) ;
2013-05-08 21:45:39 +00:00
pc2h_evt_hdr - > len = sizeof ( struct stassoc_event ) ;
pc2h_evt_hdr - > ID = GEN_EVT_CODE ( _AddSTA ) ;
pc2h_evt_hdr - > seq = ATOMIC_INC_RETURN ( & pmlmeext - > event_seq ) ;
2014-12-11 21:15:04 +00:00
padd_sta_evt = ( struct stassoc_event * ) ( pevtcmd + sizeof ( struct C2HEvent_Header ) ) ;
2015-02-19 20:50:04 +00:00
memcpy ( ( unsigned char * ) ( & ( padd_sta_evt - > macaddr ) ) , MacAddr , ETH_ALEN ) ;
2013-05-08 21:45:39 +00:00
padd_sta_evt - > cam_id = cam_idx ;
2014-12-11 21:15:04 +00:00
DBG_871X ( " report_add_sta_event: add STA \n " ) ;
2013-05-08 21:45:39 +00:00
rtw_enqueue_cmd ( pcmdpriv , pcmd_obj ) ;
return ;
}
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
/****************************************************************************
Following are the event callback functions
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2015-02-19 21:34:32 +00:00
/* for sta/adhoc mode */
2014-12-17 23:13:53 +00:00
void update_sta_info ( struct adapter * padapter , struct sta_info * psta )
2013-05-08 21:45:39 +00:00
{
struct mlme_priv * pmlmepriv = & ( padapter - > mlmepriv ) ;
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
2015-02-19 21:34:32 +00:00
/* ERP */
2013-05-08 21:45:39 +00:00
VCS_update ( padapter , psta ) ;
2015-02-19 21:34:32 +00:00
/* HT */
2014-12-11 21:15:04 +00:00
if ( pmlmepriv - > htpriv . ht_option )
{
2014-12-29 02:13:24 +00:00
psta - > htpriv . ht_option = true ;
2013-05-08 21:45:39 +00:00
psta - > htpriv . ampdu_enable = pmlmepriv - > htpriv . ampdu_enable ;
if ( support_short_GI ( padapter , & ( pmlmeinfo - > HT_caps ) ) )
2014-12-29 02:13:24 +00:00
psta - > htpriv . sgi = true ;
2013-05-08 21:45:39 +00:00
2014-12-29 02:13:24 +00:00
psta - > qos_option = true ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
}
else
{
2014-12-29 02:13:24 +00:00
psta - > htpriv . ht_option = false ;
2013-05-08 21:45:39 +00:00
2014-12-29 02:13:24 +00:00
psta - > htpriv . ampdu_enable = false ;
2014-12-19 06:59:46 +00:00
2014-12-29 02:13:24 +00:00
psta - > htpriv . sgi = false ;
psta - > qos_option = false ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
}
psta - > htpriv . bwmode = pmlmeext - > cur_bwmode ;
psta - > htpriv . ch_offset = pmlmeext - > cur_ch_offset ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
psta - > htpriv . agg_enable_bitmap = 0x0 ; /* reset */
psta - > htpriv . candidate_tid_bitmap = 0x0 ; /* reset */
2013-05-19 04:28:07 +00:00
2015-02-19 21:34:32 +00:00
/* QoS */
2014-12-11 21:15:04 +00:00
if ( pmlmepriv - > qospriv . qos_option )
2014-12-29 02:13:24 +00:00
psta - > qos_option = true ;
2014-12-19 06:59:46 +00:00
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
psta - > state = _FW_LINKED ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-17 23:13:53 +00:00
void mlmeext_joinbss_event_callback ( struct adapter * padapter , int join_res )
2013-05-08 21:45:39 +00:00
{
struct sta_info * psta , * psta_bmc ;
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
2014-12-19 06:59:46 +00:00
WLAN_BSSID_EX * cur_network = & ( pmlmeinfo - > network ) ;
2013-05-08 21:45:39 +00:00
struct sta_priv * pstapriv = & padapter - > stapriv ;
2014-12-11 21:15:04 +00:00
u8 join_type ;
2013-05-08 21:45:39 +00:00
u16 media_status ;
2014-12-11 21:15:04 +00:00
psta = rtw_get_stainfo ( pstapriv , cur_network - > MacAddress ) ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
if ( join_res < 0 )
{
2013-05-08 21:45:39 +00:00
join_type = 1 ;
rtw_hal_set_hwreg ( padapter , HW_VAR_MLME_JOIN , ( u8 * ) ( & join_type ) ) ;
rtw_hal_set_hwreg ( padapter , HW_VAR_BSSID , null_addr ) ;
2015-02-19 21:34:32 +00:00
/* restore to initial setting. */
2013-05-08 21:45:39 +00:00
update_tx_basic_rate ( padapter , padapter - > registrypriv . wireless_mode ) ;
2015-02-19 21:34:32 +00:00
if ( psta ) { /* only for STA mode */
media_status = ( psta - > mac_id < < 8 ) | 0 ; /* MACID|OPMODE:1 connect */
2014-12-19 06:59:46 +00:00
rtw_hal_set_hwreg ( padapter , HW_VAR_H2C_MEDIA_STATUS_RPT , ( u8 * ) & media_status ) ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
goto exit_mlmeext_joinbss_event_callback ;
}
2014-12-11 21:15:04 +00:00
if ( ( pmlmeinfo - > state & 0x03 ) = = WIFI_FW_ADHOC_STATE )
{
2015-02-19 21:34:32 +00:00
/* for bc/mc */
2013-05-08 21:45:39 +00:00
psta_bmc = rtw_get_bcmc_stainfo ( padapter ) ;
2014-12-11 21:15:04 +00:00
if ( psta_bmc )
{
2013-05-08 21:45:39 +00:00
pmlmeinfo - > FW_sta_info [ psta_bmc - > mac_id ] . psta = psta_bmc ;
update_bmc_sta_support_rate ( padapter , psta_bmc - > mac_id ) ;
2014-12-11 21:15:04 +00:00
Update_RA_Entry ( padapter , psta_bmc ) ;
2013-05-08 21:45:39 +00:00
}
2015-02-19 21:34:32 +00:00
/* update bc/mc sta_info */
2014-12-11 21:15:04 +00:00
update_bmc_sta ( padapter ) ;
2013-05-08 21:45:39 +00:00
}
2015-02-19 21:34:32 +00:00
/* turn on dynamic functions */
2014-12-29 02:13:24 +00:00
Switch_DM_Func ( padapter , DYNAMIC_ALL_FUNC_ENABLE , true ) ;
2014-12-11 21:15:04 +00:00
2015-02-19 21:34:32 +00:00
/* update IOT-releated issue */
2013-05-08 21:45:39 +00:00
update_IOT_info ( padapter ) ;
rtw_hal_set_hwreg ( padapter , HW_VAR_BASIC_RATE , cur_network - > SupportedRates ) ;
2015-02-19 21:34:32 +00:00
/* BCN interval */
2013-05-08 21:45:39 +00:00
rtw_hal_set_hwreg ( padapter , HW_VAR_BEACON_INTERVAL , ( u8 * ) ( & pmlmeinfo - > bcn_interval ) ) ;
2015-02-19 21:34:32 +00:00
/* udpate capability */
2013-05-08 21:45:39 +00:00
update_capinfo ( padapter , pmlmeinfo - > capability ) ;
2015-02-19 21:34:32 +00:00
/* WMM, Update EDCA param */
2013-05-08 21:45:39 +00:00
WMMOnAssocRsp ( padapter ) ;
2015-02-19 21:34:32 +00:00
/* HT */
2013-05-08 21:45:39 +00:00
HTOnAssocRsp ( padapter ) ;
set_channel_bwmode ( padapter , pmlmeext - > cur_channel , pmlmeext - > cur_ch_offset , pmlmeext - > cur_bwmode ) ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
if ( psta ) /* only for infra. mode */
2014-12-11 21:15:04 +00:00
{
2013-05-08 21:45:39 +00:00
pmlmeinfo - > FW_sta_info [ psta - > mac_id ] . psta = psta ;
2015-02-19 21:34:32 +00:00
/* DBG_871X("set_sta_rate\n"); */
2013-05-19 04:28:07 +00:00
2014-12-11 21:15:04 +00:00
psta - > wireless_mode = pmlmeext - > cur_wireless_mode ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* set per sta rate after updating HT cap. */
2013-05-08 21:45:39 +00:00
set_sta_rate ( padapter , psta ) ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
rtw_sta_media_status_rpt ( padapter , psta , 1 ) ;
2013-05-08 21:45:39 +00:00
}
join_type = 2 ;
rtw_hal_set_hwreg ( padapter , HW_VAR_MLME_JOIN , ( u8 * ) ( & join_type ) ) ;
2014-12-11 21:15:04 +00:00
if ( ( pmlmeinfo - > state & 0x03 ) = = WIFI_FW_STATION_STATE )
{
2015-02-19 21:34:32 +00:00
/* correcting TSF */
2013-05-08 21:45:39 +00:00
correct_TSF ( padapter , pmlmeext ) ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* set_link_timer(pmlmeext, DISCONNECT_TO); */
2013-05-08 21:45:39 +00:00
}
rtw_lps_ctrl_wk_cmd ( padapter , LPS_CTRL_CONNECT , 0 ) ;
exit_mlmeext_joinbss_event_callback :
2014-12-11 21:15:04 +00:00
DBG_871X ( " =>%s \n " , __FUNCTION__ ) ;
2013-05-08 21:45:39 +00:00
}
2014-12-17 23:13:53 +00:00
void mlmeext_sta_add_event_callback ( struct adapter * padapter , struct sta_info * psta )
2013-05-08 21:45:39 +00:00
{
struct mlme_ext_priv * pmlmeext = & ( padapter - > mlmeextpriv ) ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
2014-12-11 21:15:04 +00:00
u8 join_type ;
DBG_871X ( " %s \n " , __FUNCTION__ ) ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
if ( ( pmlmeinfo - > state & 0x03 ) = = WIFI_FW_ADHOC_STATE )
{
2015-02-19 21:34:32 +00:00
if ( pmlmeinfo - > state & WIFI_FW_ASSOC_SUCCESS ) /* adhoc master or sta_count>1 */
2014-12-11 21:15:04 +00:00
{
2015-02-19 21:34:32 +00:00
/* nothing to do */
2014-12-11 21:15:04 +00:00
}
2015-02-19 21:34:32 +00:00
else /* adhoc client */
2014-12-11 21:15:04 +00:00
{
2015-02-19 21:34:32 +00:00
/* update TSF Value */
/* update_TSF(pmlmeext, pframe, len); */
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* correcting TSF */
2013-05-08 21:45:39 +00:00
correct_TSF ( padapter , pmlmeext ) ;
2015-02-19 21:34:32 +00:00
/* start beacon */
2014-12-11 21:15:04 +00:00
if ( send_beacon ( padapter ) = = _FAIL )
{
2013-05-08 21:45:39 +00:00
pmlmeinfo - > FW_sta_info [ psta - > mac_id ] . status = 0 ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
pmlmeinfo - > state ^ = WIFI_FW_ADHOC_STATE ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
return ;
}
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
pmlmeinfo - > state | = WIFI_FW_ASSOC_SUCCESS ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
}
join_type = 2 ;
rtw_hal_set_hwreg ( padapter , HW_VAR_MLME_JOIN , ( u8 * ) ( & join_type ) ) ;
}
pmlmeinfo - > FW_sta_info [ psta - > mac_id ] . psta = psta ;
2015-02-19 21:34:32 +00:00
/* rate radaptive */
2014-12-11 21:15:04 +00:00
Update_RA_Entry ( padapter , psta ) ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* update adhoc sta_info */
2013-05-08 21:45:39 +00:00
update_sta_info ( padapter , psta ) ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-17 23:13:53 +00:00
void mlmeext_sta_del_event_callback ( struct adapter * padapter )
2013-05-08 21:45:39 +00:00
{
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
2014-12-11 21:15:04 +00:00
if ( is_client_associated_to_ap ( padapter ) | | is_IBSS_empty ( padapter ) )
{
2015-02-19 21:34:32 +00:00
/* set_opmode_cmd(padapter, infra_client_with_mlme); */
2014-12-11 21:15:04 +00:00
2014-12-19 04:28:04 +00:00
rtw_hal_set_hwreg ( padapter , HW_VAR_MLME_DISCONNECT , NULL ) ;
2013-05-08 21:45:39 +00:00
rtw_hal_set_hwreg ( padapter , HW_VAR_BSSID , null_addr ) ;
2015-02-19 21:34:32 +00:00
/* restore to initial setting. */
2013-05-08 21:45:39 +00:00
update_tx_basic_rate ( padapter , padapter - > registrypriv . wireless_mode ) ;
2015-02-19 21:34:32 +00:00
/* switch to the 20M Hz mode after disconnect */
2013-05-08 21:45:39 +00:00
pmlmeext - > cur_bwmode = HT_CHANNEL_WIDTH_20 ;
pmlmeext - > cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE ;
2015-02-19 21:34:32 +00:00
/* SelectChannel(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset); */
2013-05-08 21:45:39 +00:00
set_channel_bwmode ( padapter , pmlmeext - > cur_channel , pmlmeext - > cur_ch_offset , pmlmeext - > cur_bwmode ) ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
flush_all_cam_entry ( padapter ) ;
pmlmeinfo - > state = WIFI_FW_NULL_STATE ;
2015-02-19 21:34:32 +00:00
/* set MSR to no link state -> infra. mode */
2013-05-08 21:45:39 +00:00
Set_MSR ( padapter , _HW_STATE_STATION_ ) ;
_cancel_timer_ex ( & pmlmeext - > link_timer ) ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
}
/****************************************************************************
Following are the functions for the timer handlers
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2014-12-17 23:13:53 +00:00
void _linked_rx_signal_strehgth_display ( struct adapter * padapter ) ;
void _linked_rx_signal_strehgth_display ( struct adapter * padapter )
2013-05-08 21:45:39 +00:00
{
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
u8 mac_id ;
int UndecoratedSmoothedPWDB ;
2014-12-11 21:15:04 +00:00
if ( ( pmlmeinfo - > state & 0x03 ) = = WIFI_FW_STATION_STATE )
{
mac_id = 0 ;
}
else if ( ( pmlmeinfo - > state & 0x03 ) = = _HW_STATE_AP_ )
{
2014-12-19 06:59:46 +00:00
mac_id = 2 ;
2014-12-11 21:15:04 +00:00
}
2014-12-19 06:59:46 +00:00
rtw_hal_get_def_var ( padapter , HW_DEF_RA_INFO_DUMP , & mac_id ) ;
2013-05-08 21:45:39 +00:00
}
2014-12-19 04:28:04 +00:00
static u8 chk_ap_is_alive ( struct adapter * padapter , struct sta_info * psta )
2013-05-08 21:45:39 +00:00
{
2014-12-29 02:13:24 +00:00
u8 ret = false ;
2014-12-11 21:15:04 +00:00
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
# ifdef DBG_EXPIRATION_CHK
DBG_871X ( FUNC_ADPT_FMT " rx: " STA_PKTS_FMT " , beacon:%llu, probersp_to_self:%llu "
/*", probersp_bm:%llu, probersp_uo:%llu, probereq:%llu, BI:%u"*/
" , retry:%u \n "
, FUNC_ADPT_ARG ( padapter )
, STA_RX_PKTS_DIFF_ARG ( psta )
, psta - > sta_stats . rx_beacon_pkts - psta - > sta_stats . last_rx_beacon_pkts
, psta - > sta_stats . rx_probersp_pkts - psta - > sta_stats . last_rx_probersp_pkts
/*, psta->sta_stats.rx_probersp_bm_pkts - psta->sta_stats.last_rx_probersp_bm_pkts
, psta - > sta_stats . rx_probersp_uo_pkts - psta - > sta_stats . last_rx_probersp_uo_pkts
, psta - > sta_stats . rx_probereq_pkts - psta - > sta_stats . last_rx_probereq_pkts
, pmlmeinfo - > bcn_interval */
, pmlmeext - > retry
) ;
DBG_871X ( FUNC_ADPT_FMT " tx_pkts:%llu, link_count:%u \n " , FUNC_ADPT_ARG ( padapter )
, padapter - > xmitpriv . tx_pkts
, pmlmeinfo - > link_count
) ;
# endif
if ( ( sta_rx_data_pkts ( psta ) = = sta_last_rx_data_pkts ( psta ) )
& & sta_rx_beacon_pkts ( psta ) = = sta_last_rx_beacon_pkts ( psta )
& & sta_rx_probersp_pkts ( psta ) = = sta_last_rx_probersp_pkts ( psta )
)
{
2014-12-29 02:13:24 +00:00
ret = false ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
else
2014-12-11 21:15:04 +00:00
{
2014-12-29 02:13:24 +00:00
ret = true ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
sta_update_last_rx_pkts ( psta ) ;
return ret ;
}
2014-12-17 23:13:53 +00:00
void linked_status_chk ( struct adapter * padapter )
2013-05-08 21:45:39 +00:00
{
u32 i ;
struct sta_info * psta ;
struct xmit_priv * pxmitpriv = & ( padapter - > xmitpriv ) ;
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
struct sta_priv * pstapriv = & padapter - > stapriv ;
2014-12-11 21:15:04 +00:00
if ( padapter - > bRxRSSIDisplay )
_linked_rx_signal_strehgth_display ( padapter ) ;
2013-05-08 21:45:39 +00:00
2014-12-19 06:59:46 +00:00
# ifdef DBG_CONFIG_ERROR_DETECT
2013-05-08 21:45:39 +00:00
rtw_hal_sreset_linked_status_check ( padapter ) ;
2014-12-11 21:15:04 +00:00
# endif
2013-05-08 21:45:39 +00:00
2015-02-21 02:07:27 +00:00
if ( is_client_associated_to_ap ( padapter ) ) {
2015-02-19 21:34:32 +00:00
/* linked infrastructure client mode */
2013-05-08 21:45:39 +00:00
int tx_chk = _SUCCESS , rx_chk = _SUCCESS ;
int rx_chk_limit ;
rx_chk_limit = 4 ;
2014-12-11 21:15:04 +00:00
2015-02-19 21:34:32 +00:00
/* Marked by Kurt 20130715 */
/* For WiDi 3.5 and latered on, they don't ask WiDi sink to do roaming, so we could not check rx limit that strictly. */
/* todo: To check why we under miracast session, rx_chk would be false */
/* ifdef CONFIG_INTEL_WIDI */
/* if (padapter->mlmepriv.widi_state != INTEL_WIDI_STATE_NONE) */
/* rx_chk_limit = 1; */
/* endif */
2014-12-11 21:15:04 +00:00
if ( ( psta = rtw_get_stainfo ( pstapriv , pmlmeinfo - > network . MacAddress ) ) ! = NULL )
{
2014-12-29 02:13:24 +00:00
bool is_p2p_enable = false ;
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_P2P
2013-05-08 21:45:39 +00:00
is_p2p_enable = ! rtw_p2p_chk_state ( & padapter - > wdinfo , P2P_STATE_NONE ) ;
# endif
2014-12-19 06:59:46 +00:00
2014-12-29 02:13:24 +00:00
if ( chk_ap_is_alive ( padapter , psta ) = = false )
2013-05-08 21:45:39 +00:00
rx_chk = _FAIL ;
if ( pxmitpriv - > last_tx_pkts = = pxmitpriv - > tx_pkts )
tx_chk = _FAIL ;
if ( pmlmeext - > active_keep_alive_check & & ( rx_chk = = _FAIL | | tx_chk = = _FAIL ) ) {
2014-12-11 21:15:04 +00:00
u8 backup_oper_channel = 0 ;
2013-05-08 21:45:39 +00:00
/* switch to correct channel of current network before issue keep-alive frames */
if ( rtw_get_oper_ch ( padapter ) ! = pmlmeext - > cur_channel ) {
backup_oper_channel = rtw_get_oper_ch ( padapter ) ;
SelectChannel ( padapter , pmlmeext - > cur_channel ) ;
}
if ( rx_chk ! = _SUCCESS )
issue_probereq_ex ( padapter , & pmlmeinfo - > network . Ssid , psta - > hwaddr , 3 , 1 ) ;
if ( ( tx_chk ! = _SUCCESS & & pmlmeinfo - > link_count + + = = 0xf ) | | rx_chk ! = _SUCCESS ) {
tx_chk = issue_nulldata ( padapter , psta - > hwaddr , 0 , 3 , 1 ) ;
/* if tx acked and p2p disabled, set rx_chk _SUCCESS to reset retry count */
if ( tx_chk = = _SUCCESS & & ! is_p2p_enable )
rx_chk = _SUCCESS ;
}
/* back to the original operation channel */
2014-12-11 21:15:04 +00:00
if ( backup_oper_channel > 0 )
2013-05-08 21:45:39 +00:00
SelectChannel ( padapter , backup_oper_channel ) ;
2015-02-21 02:07:27 +00:00
} else {
2013-05-08 21:45:39 +00:00
if ( rx_chk ! = _SUCCESS ) {
if ( pmlmeext - > retry = = 0 ) {
2014-12-11 21:15:04 +00:00
# ifdef DBG_EXPIRATION_CHK
DBG_871X ( " issue_probereq to trigger probersp, retry=%d \n " , pmlmeext - > retry ) ;
# endif
2013-05-08 21:45:39 +00:00
issue_probereq ( padapter , & pmlmeinfo - > network . Ssid , pmlmeinfo - > network . MacAddress ) ;
issue_probereq ( padapter , & pmlmeinfo - > network . Ssid , pmlmeinfo - > network . MacAddress ) ;
issue_probereq ( padapter , & pmlmeinfo - > network . Ssid , pmlmeinfo - > network . MacAddress ) ;
}
}
if ( tx_chk ! = _SUCCESS & & pmlmeinfo - > link_count + + = = 0xf ) {
2014-12-11 21:15:04 +00:00
# ifdef DBG_EXPIRATION_CHK
DBG_871X ( " %s issue_nulldata 0 \n " , __FUNCTION__ ) ;
# endif
2013-05-08 21:45:39 +00:00
tx_chk = issue_nulldata ( padapter , NULL , 0 , 1 , 0 ) ;
}
}
if ( rx_chk = = _FAIL ) {
pmlmeext - > retry + + ;
if ( pmlmeext - > retry > rx_chk_limit ) {
2014-12-11 21:15:04 +00:00
DBG_871X_LEVEL ( _drv_always_ , FUNC_ADPT_FMT " disconnect or roaming \n " ,
FUNC_ADPT_ARG ( padapter ) ) ;
receive_disconnect ( padapter , pmlmeinfo - > network . MacAddress
, WLAN_REASON_EXPIRATION_CHK ) ;
2013-05-08 21:45:39 +00:00
return ;
}
} else {
pmlmeext - > retry = 0 ;
}
if ( tx_chk = = _FAIL ) {
pmlmeinfo - > link_count & = 0xf ;
} else {
pxmitpriv - > last_tx_pkts = pxmitpriv - > tx_pkts ;
pmlmeinfo - > link_count = 0 ;
}
2014-12-11 21:15:04 +00:00
2015-02-19 21:34:32 +00:00
} /* end of if ((psta = rtw_get_stainfo(pstapriv, passoc_res->network.MacAddress)) != NULL) */
2014-12-11 21:15:04 +00:00
}
else if ( is_client_associated_to_ibss ( padapter ) )
{
2015-02-19 21:34:32 +00:00
/* linked IBSS mode */
/* for each assoc list entry to check the rx pkt counter */
2014-12-11 21:15:04 +00:00
for ( i = IBSS_START_MAC_ID ; i < NUM_STA ; i + + )
{
if ( pmlmeinfo - > FW_sta_info [ i ] . status = = 1 )
{
2013-05-08 21:45:39 +00:00
psta = pmlmeinfo - > FW_sta_info [ i ] . psta ;
2014-12-11 21:15:04 +00:00
if ( NULL = = psta ) continue ;
if ( pmlmeinfo - > FW_sta_info [ i ] . rx_pkt = = sta_rx_pkts ( psta ) )
{
if ( pmlmeinfo - > FW_sta_info [ i ] . retry < 3 )
{
2013-05-08 21:45:39 +00:00
pmlmeinfo - > FW_sta_info [ i ] . retry + + ;
2014-12-11 21:15:04 +00:00
}
else
{
2013-05-08 21:45:39 +00:00
pmlmeinfo - > FW_sta_info [ i ] . retry = 0 ;
pmlmeinfo - > FW_sta_info [ i ] . status = 0 ;
report_del_sta_event ( padapter , psta - > hwaddr
2015-02-19 21:34:32 +00:00
, 65535 /* indicate disconnect caused by no rx */
2014-12-11 21:15:04 +00:00
) ;
2014-12-19 06:59:46 +00:00
}
2014-12-11 21:15:04 +00:00
}
else
{
2013-05-08 21:45:39 +00:00
pmlmeinfo - > FW_sta_info [ i ] . retry = 0 ;
pmlmeinfo - > FW_sta_info [ i ] . rx_pkt = ( u32 ) sta_rx_pkts ( psta ) ;
}
}
}
2014-12-11 21:15:04 +00:00
2015-02-19 21:34:32 +00:00
/* set_link_timer(pmlmeext, DISCONNECT_TO); */
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-17 23:13:53 +00:00
void survey_timer_hdl ( struct adapter * padapter )
2013-05-08 21:45:39 +00:00
{
struct cmd_obj * ph2c ;
struct sitesurvey_parm * psurveyPara ;
2014-12-11 21:15:04 +00:00
struct cmd_priv * pcmdpriv = & padapter - > cmdpriv ;
2014-12-19 06:59:46 +00:00
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_P2P
struct wifidirect_info * pwdinfo = & ( padapter - > wdinfo ) ;
2013-05-08 21:45:39 +00:00
# endif
2015-02-19 21:34:32 +00:00
/* issue rtw_sitesurvey_cmd */
2014-12-11 21:15:04 +00:00
if ( pmlmeext - > sitesurvey_res . state > SCAN_START )
{
if ( pmlmeext - > sitesurvey_res . state = = SCAN_PROCESS )
{
# ifdef CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
if ( padapter - > mlmeextpriv . mlmext_info . scan_cnt ! = RTW_SCAN_NUM_OF_CH )
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_STA_MODE_SCAN_UNDER_AP_MODE */
2014-12-11 21:15:04 +00:00
pmlmeext - > sitesurvey_res . channel_idx + + ;
}
2013-05-08 21:45:39 +00:00
2014-12-29 02:13:24 +00:00
if ( pmlmeext - > scan_abort = = true )
2014-12-11 21:15:04 +00:00
{
# ifdef CONFIG_P2P
if ( ! rtw_p2p_chk_state ( & padapter - > wdinfo , P2P_STATE_NONE ) )
{
2013-05-08 21:45:39 +00:00
rtw_p2p_findphase_ex_set ( pwdinfo , P2P_FINDPHASE_EX_MAX ) ;
pmlmeext - > sitesurvey_res . channel_idx = 3 ;
2014-12-11 21:15:04 +00:00
DBG_871X ( " %s idx:%d, cnt:%u \n " , __FUNCTION__
2013-05-08 21:45:39 +00:00
, pmlmeext - > sitesurvey_res . channel_idx
, pwdinfo - > find_phase_state_exchange_cnt
2014-12-11 21:15:04 +00:00
) ;
}
else
2013-05-08 21:45:39 +00:00
# endif
{
pmlmeext - > sitesurvey_res . channel_idx = pmlmeext - > sitesurvey_res . ch_num ;
2014-12-11 21:15:04 +00:00
DBG_871X ( " %s idx:%d \n " , __FUNCTION__
2013-05-08 21:45:39 +00:00
, pmlmeext - > sitesurvey_res . channel_idx
2014-12-11 21:15:04 +00:00
) ;
2013-05-08 21:45:39 +00:00
}
2015-02-19 21:34:32 +00:00
pmlmeext - > scan_abort = false ; /* reset */
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
if ( ( ph2c = ( struct cmd_obj * ) rtw_zmalloc ( sizeof ( struct cmd_obj ) ) ) = = NULL )
{
2013-05-08 21:45:39 +00:00
goto exit_survey_timer_hdl ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
if ( ( psurveyPara = ( struct sitesurvey_parm * ) rtw_zmalloc ( sizeof ( struct sitesurvey_parm ) ) ) = = NULL )
{
rtw_mfree ( ( unsigned char * ) ph2c , sizeof ( struct cmd_obj ) ) ;
2013-05-08 21:45:39 +00:00
goto exit_survey_timer_hdl ;
}
init_h2fwcmd_w_parm_no_rsp ( ph2c , psurveyPara , GEN_CMD_CODE ( _SiteSurvey ) ) ;
rtw_enqueue_cmd ( pcmdpriv , ph2c ) ;
}
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
exit_survey_timer_hdl :
return ;
}
2014-12-17 23:13:53 +00:00
void link_timer_hdl ( struct adapter * padapter )
2013-05-08 21:45:39 +00:00
{
2015-02-19 21:34:32 +00:00
/* static unsigned int rx_pkt = 0; */
/* static u64 tx_cnt = 0; */
/* struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); */
2013-05-08 21:45:39 +00:00
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
2015-02-19 21:34:32 +00:00
/* struct sta_priv *pstapriv = &padapter->stapriv; */
2014-12-11 21:15:04 +00:00
if ( pmlmeinfo - > state & WIFI_FW_AUTH_NULL )
{
DBG_871X ( " link_timer_hdl:no beacon while connecting \n " ) ;
2013-05-08 21:45:39 +00:00
pmlmeinfo - > state = WIFI_FW_NULL_STATE ;
report_join_res ( padapter , - 3 ) ;
2014-12-11 21:15:04 +00:00
}
else if ( pmlmeinfo - > state & WIFI_FW_AUTH_STATE )
{
2015-02-19 21:34:32 +00:00
/* re-auth timer */
2014-12-11 21:15:04 +00:00
if ( + + pmlmeinfo - > reauth_count > REAUTH_LIMIT )
{
2015-02-19 21:34:32 +00:00
/* if (pmlmeinfo->auth_algo != dot11AuthAlgrthm_Auto) */
/* */
2014-12-11 21:15:04 +00:00
pmlmeinfo - > state = 0 ;
report_join_res ( padapter , - 1 ) ;
return ;
2015-02-19 21:34:32 +00:00
/* */
/* else */
/* */
/* pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared; */
/* pmlmeinfo->reauth_count = 0; */
/* */
2013-05-08 21:45:39 +00:00
}
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
DBG_871X ( " link_timer_hdl: auth timeout and try again \n " ) ;
2013-05-08 21:45:39 +00:00
pmlmeinfo - > auth_seq = 1 ;
issue_auth ( padapter , NULL , 0 ) ;
set_link_timer ( pmlmeext , REAUTH_TO ) ;
2014-12-11 21:15:04 +00:00
}
else if ( pmlmeinfo - > state & WIFI_FW_ASSOC_STATE )
{
2015-02-19 21:34:32 +00:00
/* re-assoc timer */
2014-12-11 21:15:04 +00:00
if ( + + pmlmeinfo - > reassoc_count > REASSOC_LIMIT )
{
2013-05-08 21:45:39 +00:00
pmlmeinfo - > state = WIFI_FW_NULL_STATE ;
report_join_res ( padapter , - 2 ) ;
return ;
}
2014-12-11 21:15:04 +00:00
DBG_871X ( " link_timer_hdl: assoc timeout and try again \n " ) ;
2013-05-08 21:45:39 +00:00
issue_assocreq ( padapter ) ;
set_link_timer ( pmlmeext , REASSOC_TO ) ;
}
return ;
}
void addba_timer_hdl ( struct sta_info * psta )
{
struct ht_priv * phtpriv ;
2014-12-11 21:15:04 +00:00
if ( ! psta )
2013-05-08 21:45:39 +00:00
return ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
phtpriv = & psta - > htpriv ;
2014-12-29 02:13:24 +00:00
if ( ( phtpriv - > ht_option = = true ) & & ( phtpriv - > ampdu_enable = = true ) )
2014-12-11 21:15:04 +00:00
{
if ( phtpriv - > candidate_tid_bitmap )
phtpriv - > candidate_tid_bitmap = 0x0 ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
}
}
# ifdef CONFIG_IEEE80211W
2014-12-17 23:13:53 +00:00
void sa_query_timer_hdl ( struct adapter * padapter )
2014-12-11 21:15:04 +00:00
{
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
struct mlme_priv * pmlmepriv = & padapter - > mlmepriv ;
_irqL irqL ;
2015-02-19 21:34:32 +00:00
/* disconnect */
2014-12-11 21:15:04 +00:00
_enter_critical_bh ( & pmlmepriv - > lock , & irqL ) ;
2014-12-29 02:13:24 +00:00
if ( check_fwstate ( pmlmepriv , _FW_LINKED ) = = true )
2014-12-11 21:15:04 +00:00
{
2014-12-29 02:13:24 +00:00
rtw_disassoc_cmd ( padapter , 0 , true ) ;
2014-12-11 21:15:04 +00:00
rtw_indicate_disconnect ( padapter ) ;
2014-12-19 06:59:46 +00:00
rtw_free_assoc_resources ( padapter , 1 ) ;
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
_exit_critical_bh ( & pmlmepriv - > lock , & irqL ) ;
DBG_871X ( " SA query timeout disconnect \n " ) ;
2013-05-08 21:45:39 +00:00
}
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_IEEE80211W */
2013-05-08 21:45:39 +00:00
2014-12-17 23:13:53 +00:00
u8 NULL_hdl ( struct adapter * padapter , u8 * pbuf )
2013-05-08 21:45:39 +00:00
{
return H2C_SUCCESS ;
}
2014-12-17 23:13:53 +00:00
u8 setopmode_hdl ( struct adapter * padapter , u8 * pbuf )
2013-05-08 21:45:39 +00:00
{
2014-12-11 21:15:04 +00:00
u8 type ;
2013-05-08 21:45:39 +00:00
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
struct setopmode_parm * psetop = ( struct setopmode_parm * ) pbuf ;
2014-12-11 21:15:04 +00:00
if ( psetop - > mode = = Ndis802_11APMode )
{
2013-05-08 21:45:39 +00:00
pmlmeinfo - > state = WIFI_FW_AP_STATE ;
type = _HW_STATE_AP_ ;
2014-12-11 21:15:04 +00:00
}
else if ( psetop - > mode = = Ndis802_11Infrastructure )
{
2015-02-19 21:34:32 +00:00
pmlmeinfo - > state & = ~ ( BIT ( 0 ) | BIT ( 1 ) ) ; /* clear state */
pmlmeinfo - > state | = WIFI_FW_STATION_STATE ; /* set to STATION_STATE */
2013-05-08 21:45:39 +00:00
type = _HW_STATE_STATION_ ;
2014-12-11 21:15:04 +00:00
}
else if ( psetop - > mode = = Ndis802_11IBSS )
{
2013-05-08 21:45:39 +00:00
type = _HW_STATE_ADHOC_ ;
2014-12-11 21:15:04 +00:00
}
else
{
2013-05-08 21:45:39 +00:00
type = _HW_STATE_NOLINK_ ;
}
rtw_hal_set_hwreg ( padapter , HW_VAR_SET_OPMODE , ( u8 * ) ( & type ) ) ;
2015-02-19 21:34:32 +00:00
/* Set_NETYPE0_MSR(padapter, type); */
2013-05-08 21:45:39 +00:00
return H2C_SUCCESS ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-17 23:13:53 +00:00
u8 createbss_hdl ( struct adapter * padapter , u8 * pbuf )
2013-05-08 21:45:39 +00:00
{
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
2014-12-11 21:15:04 +00:00
WLAN_BSSID_EX * pnetwork = ( WLAN_BSSID_EX * ) ( & ( pmlmeinfo - > network ) ) ;
2013-05-08 21:45:39 +00:00
struct joinbss_parm * pparm = ( struct joinbss_parm * ) pbuf ;
2015-02-19 21:34:32 +00:00
/* u32 initialgain; */
2013-05-19 04:28:07 +00:00
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
if ( pparm - > network . InfrastructureMode = = Ndis802_11APMode )
{
# ifdef CONFIG_AP_MODE
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
if ( pmlmeinfo - > state = = WIFI_FW_AP_STATE )
2014-12-19 06:59:46 +00:00
{
2015-02-19 21:34:32 +00:00
/* todo: */
2014-12-19 06:59:46 +00:00
return H2C_SUCCESS ;
}
2013-05-08 21:45:39 +00:00
# endif
}
2015-02-19 21:34:32 +00:00
/* below is for ad-hoc master */
2014-12-11 21:15:04 +00:00
if ( pparm - > network . InfrastructureMode = = Ndis802_11IBSS )
{
2013-05-08 21:45:39 +00:00
rtw_joinbss_reset ( padapter ) ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
pmlmeext - > cur_bwmode = HT_CHANNEL_WIDTH_20 ;
2014-12-19 06:59:46 +00:00
pmlmeext - > cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE ;
2013-05-08 21:45:39 +00:00
pmlmeinfo - > ERP_enable = 0 ;
pmlmeinfo - > WMM_enable = 0 ;
pmlmeinfo - > HT_enable = 0 ;
pmlmeinfo - > HT_caps_enable = 0 ;
pmlmeinfo - > HT_info_enable = 0 ;
pmlmeinfo - > agg_enable_bitmap = 0 ;
pmlmeinfo - > candidate_tid_bitmap = 0 ;
2015-02-19 21:34:32 +00:00
/* disable dynamic functions, such as high power, DIG */
2013-05-08 21:45:39 +00:00
Save_DM_Func_Flag ( padapter ) ;
2014-12-29 02:13:24 +00:00
Switch_DM_Func ( padapter , DYNAMIC_FUNC_DISABLE , false ) ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* config the initial gain under linking, need to write the BB registers */
/* initialgain = 0x1E; */
/* rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain)); */
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* cancel link timer */
2013-05-08 21:45:39 +00:00
_cancel_timer_ex ( & pmlmeext - > link_timer ) ;
2015-02-19 21:34:32 +00:00
/* clear CAM */
2014-12-19 06:59:46 +00:00
flush_all_cam_entry ( padapter ) ;
2013-05-08 21:45:39 +00:00
2015-02-19 20:50:04 +00:00
memcpy ( pnetwork , pbuf , FIELD_OFFSET ( WLAN_BSSID_EX , IELength ) ) ;
2014-12-11 21:15:04 +00:00
pnetwork - > IELength = ( ( WLAN_BSSID_EX * ) pbuf ) - > IELength ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
if ( pnetwork - > IELength > MAX_IE_SZ ) /* Check pbuf->IELength */
2013-05-08 21:45:39 +00:00
return H2C_PARAMETERS_ERROR ;
2015-02-19 20:50:04 +00:00
memcpy ( pnetwork - > IEs , ( ( WLAN_BSSID_EX * ) pbuf ) - > IEs , pnetwork - > IELength ) ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
start_create_ibss ( padapter ) ;
2014-12-11 21:15:04 +00:00
2014-12-19 06:59:46 +00:00
}
2013-05-08 21:45:39 +00:00
return H2C_SUCCESS ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-17 23:13:53 +00:00
u8 join_cmd_hdl ( struct adapter * padapter , u8 * pbuf )
2013-05-08 21:45:39 +00:00
{
2014-12-11 21:15:04 +00:00
u8 join_type ;
PNDIS_802_11_VARIABLE_IEs pIE ;
2013-05-08 21:45:39 +00:00
struct registry_priv * pregpriv = & padapter - > registrypriv ;
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
2014-12-11 21:15:04 +00:00
WLAN_BSSID_EX * pnetwork = ( WLAN_BSSID_EX * ) ( & ( pmlmeinfo - > network ) ) ;
2013-05-08 21:45:39 +00:00
struct joinbss_parm * pparm = ( struct joinbss_parm * ) pbuf ;
u32 i ;
2015-02-19 21:34:32 +00:00
/* u32 initialgain; */
/* u32 acparm; */
2014-12-11 21:15:04 +00:00
u8 ch , bw , offset ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* check already connecting to AP or not */
2015-02-25 21:41:18 +00:00
if ( pmlmeinfo - > state & WIFI_FW_ASSOC_SUCCESS ) {
2013-05-08 21:45:39 +00:00
if ( pmlmeinfo - > state & WIFI_FW_STATION_STATE )
issue_deauth_ex ( padapter , pnetwork - > MacAddress , WLAN_REASON_DEAUTH_LEAVING , 5 , 100 ) ;
pmlmeinfo - > state = WIFI_FW_NULL_STATE ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* clear CAM */
2014-12-19 06:59:46 +00:00
flush_all_cam_entry ( padapter ) ;
2013-05-08 21:45:39 +00:00
_cancel_timer_ex ( & pmlmeext - > link_timer ) ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* set MSR to nolink -> infra. mode */
/* Set_MSR(padapter, _HW_STATE_NOLINK_); */
2014-12-19 06:59:46 +00:00
Set_MSR ( padapter , _HW_STATE_STATION_ ) ;
2013-05-19 04:28:07 +00:00
2014-12-19 04:28:04 +00:00
rtw_hal_set_hwreg ( padapter , HW_VAR_MLME_DISCONNECT , NULL ) ;
2013-05-08 21:45:39 +00:00
}
2014-12-29 02:13:24 +00:00
rtw_antenna_select_cmd ( padapter , pparm - > network . PhyInfo . Optimum_antenna , false ) ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_WAPI_SUPPORT
rtw_wapi_clear_all_cam_entry ( padapter ) ;
# endif
2013-05-19 04:28:07 +00:00
2014-12-11 21:15:04 +00:00
rtw_joinbss_reset ( padapter ) ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
pmlmeext - > cur_bwmode = HT_CHANNEL_WIDTH_20 ;
2014-12-19 06:59:46 +00:00
pmlmeext - > cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE ;
2013-05-08 21:45:39 +00:00
pmlmeinfo - > ERP_enable = 0 ;
pmlmeinfo - > WMM_enable = 0 ;
pmlmeinfo - > HT_enable = 0 ;
pmlmeinfo - > HT_caps_enable = 0 ;
pmlmeinfo - > HT_info_enable = 0 ;
pmlmeinfo - > agg_enable_bitmap = 0 ;
pmlmeinfo - > candidate_tid_bitmap = 0 ;
2014-12-29 02:13:24 +00:00
pmlmeinfo - > bwmode_updated = false ;
2015-02-19 21:34:32 +00:00
/* pmlmeinfo->assoc_AP_vendor = HT_IOT_PEER_MAX; */
2013-05-08 21:45:39 +00:00
2015-02-19 20:50:04 +00:00
memcpy ( pnetwork , pbuf , FIELD_OFFSET ( WLAN_BSSID_EX , IELength ) ) ;
2014-12-11 21:15:04 +00:00
pnetwork - > IELength = ( ( WLAN_BSSID_EX * ) pbuf ) - > IELength ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
if ( pnetwork - > IELength > MAX_IE_SZ ) /* Check pbuf->IELength */
2014-12-19 06:59:46 +00:00
return H2C_PARAMETERS_ERROR ;
2015-02-19 20:50:04 +00:00
memcpy ( pnetwork - > IEs , ( ( WLAN_BSSID_EX * ) pbuf ) - > IEs , pnetwork - > IELength ) ;
2013-05-19 04:28:07 +00:00
2014-12-11 21:15:04 +00:00
pmlmeext - > cur_channel = ( u8 ) pnetwork - > Configuration . DSConfig ;
pmlmeinfo - > bcn_interval = get_beacon_interval ( pnetwork ) ;
2013-05-19 04:28:07 +00:00
2015-02-19 21:34:32 +00:00
/* Check AP vendor to move rtw_joinbss_cmd() */
/* pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pnetwork->IEs, pnetwork->IELength); */
2014-12-11 21:15:04 +00:00
for ( i = sizeof ( NDIS_802_11_FIXED_IEs ) ; i < pnetwork - > IELength ; )
{
pIE = ( PNDIS_802_11_VARIABLE_IEs ) ( pnetwork - > IEs + i ) ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
switch ( pIE - > ElementID )
{
2015-02-19 21:34:32 +00:00
case _VENDOR_SPECIFIC_IE_ : /* Get WMM IE. */
2014-12-11 21:15:04 +00:00
if ( _rtw_memcmp ( pIE - > data , WMM_OUI , 4 ) )
{
pmlmeinfo - > WMM_enable = 1 ;
}
break ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
case _HT_CAPABILITY_IE_ : /* Get HT Cap IE. */
2014-12-11 21:15:04 +00:00
pmlmeinfo - > HT_caps_enable = 1 ;
break ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
case _HT_EXTRA_INFO_IE_ : /* Get HT Info IE. */
2014-12-11 21:15:04 +00:00
pmlmeinfo - > HT_info_enable = 1 ;
2015-02-19 21:34:32 +00:00
/* spec case only for cisco's ap because cisco's ap issue assoc rsp using mcs rate @40MHz or @20MHz */
2014-12-19 06:59:46 +00:00
{
2014-12-11 21:15:04 +00:00
struct HT_info_element * pht_info = ( struct HT_info_element * ) ( pIE - > data ) ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
if ( ( pregpriv - > cbw40_enable ) & & ( pht_info - > infos [ 0 ] & BIT ( 2 ) ) )
{
2015-02-19 21:34:32 +00:00
/* switch to the 40M Hz mode according to the AP */
2014-12-11 21:15:04 +00:00
pmlmeext - > cur_bwmode = HT_CHANNEL_WIDTH_40 ;
switch ( pht_info - > infos [ 0 ] & 0x3 )
{
case 1 :
pmlmeext - > cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER ;
break ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
case 3 :
pmlmeext - > cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER ;
break ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
default :
pmlmeext - > cur_bwmode = HT_CHANNEL_WIDTH_20 ;
pmlmeext - > cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE ;
break ;
}
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
DBG_871X ( " set ch/bw before connected \n " ) ;
}
2013-08-01 02:12:42 +00:00
}
2014-12-11 21:15:04 +00:00
break ;
default :
break ;
2013-05-08 21:45:39 +00:00
}
i + = ( pIE - > Length + 2 ) ;
}
2014-12-11 21:15:04 +00:00
/* check channel, bandwidth, offset and switch */
if ( rtw_chk_start_clnt_join ( padapter , & ch , & bw , & offset ) = = _FAIL ) {
report_join_res ( padapter , ( - 4 ) ) ;
return H2C_SUCCESS ;
}
2015-02-19 21:34:32 +00:00
/* disable dynamic functions, such as high power, DIG */
/* Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, false); */
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* config the initial gain under linking, need to write the BB registers */
/* initialgain = 0x1E; */
/* rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain)); */
2013-05-08 21:45:39 +00:00
rtw_hal_set_hwreg ( padapter , HW_VAR_BSSID , pmlmeinfo - > network . MacAddress ) ;
join_type = 0 ;
rtw_hal_set_hwreg ( padapter , HW_VAR_MLME_JOIN , ( u8 * ) ( & join_type ) ) ;
2014-12-11 21:15:04 +00:00
set_channel_bwmode ( padapter , ch , offset , bw ) ;
2013-05-19 04:28:07 +00:00
2015-02-19 21:34:32 +00:00
/* cancel link timer */
2014-12-11 21:15:04 +00:00
_cancel_timer_ex ( & pmlmeext - > link_timer ) ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
start_clnt_join ( padapter ) ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
return H2C_SUCCESS ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-17 23:13:53 +00:00
u8 disconnect_hdl ( struct adapter * padapter , unsigned char * pbuf )
2013-05-08 21:45:39 +00:00
{
struct disconnect_parm * param = ( struct disconnect_parm * ) pbuf ;
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
2014-12-11 21:15:04 +00:00
WLAN_BSSID_EX * pnetwork = ( WLAN_BSSID_EX * ) ( & ( pmlmeinfo - > network ) ) ;
u8 val8 ;
2013-05-08 21:45:39 +00:00
if ( is_client_associated_to_ap ( padapter ) )
2014-12-11 21:15:04 +00:00
{
2013-05-08 21:45:39 +00:00
issue_deauth_ex ( padapter , pnetwork - > MacAddress , WLAN_REASON_DEAUTH_LEAVING , param - > deauth_timeout_ms / 100 , 100 ) ;
2014-12-11 21:15:04 +00:00
}
2015-02-19 21:34:32 +00:00
/* set_opmode_cmd(padapter, infra_client_with_mlme); */
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* pmlmeinfo->state = WIFI_FW_NULL_STATE; */
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
2014-12-19 04:28:04 +00:00
rtw_hal_set_hwreg ( padapter , HW_VAR_MLME_DISCONNECT , NULL ) ;
2013-05-08 21:45:39 +00:00
rtw_hal_set_hwreg ( padapter , HW_VAR_BSSID , null_addr ) ;
2015-02-19 21:34:32 +00:00
/* restore to initial setting. */
2013-05-08 21:45:39 +00:00
update_tx_basic_rate ( padapter , padapter - > registrypriv . wireless_mode ) ;
2014-12-11 21:15:04 +00:00
if ( ( ( pmlmeinfo - > state & 0x03 ) = = WIFI_FW_ADHOC_STATE ) | | ( ( pmlmeinfo - > state & 0x03 ) = = WIFI_FW_AP_STATE ) )
{
2015-02-19 21:34:32 +00:00
/* Stop BCN */
2013-05-08 21:45:39 +00:00
val8 = 0 ;
rtw_hal_set_hwreg ( padapter , HW_VAR_BCN_FUNC , ( u8 * ) ( & val8 ) ) ;
}
2014-12-11 21:15:04 +00:00
2015-02-19 21:34:32 +00:00
/* set MSR to no link state -> infra. mode */
2013-05-08 21:45:39 +00:00
Set_MSR ( padapter , _HW_STATE_STATION_ ) ;
pmlmeinfo - > state = WIFI_FW_NULL_STATE ;
2015-02-19 21:34:32 +00:00
/* switch to the 20M Hz mode after disconnect */
2015-02-15 20:31:30 +00:00
pmlmeext - > cur_bwmode = HT_CHANNEL_WIDTH_20 ;
pmlmeext - > cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE ;
2013-05-08 21:45:39 +00:00
2015-02-15 20:31:30 +00:00
set_channel_bwmode ( padapter , pmlmeext - > cur_channel , pmlmeext - > cur_ch_offset , pmlmeext - > cur_bwmode ) ;
2013-05-08 21:45:39 +00:00
flush_all_cam_entry ( padapter ) ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
_cancel_timer_ex ( & pmlmeext - > link_timer ) ;
rtw_free_uc_swdec_pending_queue ( padapter ) ;
2014-12-19 06:59:46 +00:00
return H2C_SUCCESS ;
2013-05-08 21:45:39 +00:00
}
2014-12-19 04:28:04 +00:00
static int rtw_scan_ch_decision ( struct adapter * padapter , struct rtw_ieee80211_channel * out ,
2013-05-08 21:45:39 +00:00
u32 out_num , struct rtw_ieee80211_channel * in , u32 in_num )
{
int i , j ;
2014-12-11 21:15:04 +00:00
int scan_ch_num = 0 ;
2013-05-08 21:45:39 +00:00
int set_idx ;
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
/* clear out first */
2015-02-19 20:58:09 +00:00
memset ( out , 0 , sizeof ( struct rtw_ieee80211_channel ) * out_num ) ;
2013-05-08 21:45:39 +00:00
/* acquire channels from in */
j = 0 ;
2014-12-11 21:15:04 +00:00
for ( i = 0 ; i < in_num ; i + + ) {
if ( 0 )
DBG_871X ( FUNC_ADPT_FMT " " CHAN_FMT " \n " , FUNC_ADPT_ARG ( padapter ) , CHAN_ARG ( & in [ i ] ) ) ;
if ( in [ i ] . hw_value & & ! ( in [ i ] . flags & RTW_IEEE80211_CHAN_DISABLED )
& & ( set_idx = rtw_ch_set_search_ch ( pmlmeext - > channel_set , in [ i ] . hw_value ) ) > = 0
)
{
2015-02-19 20:50:04 +00:00
memcpy ( & out [ j ] , & in [ i ] , sizeof ( struct rtw_ieee80211_channel ) ) ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
if ( pmlmeext - > channel_set [ set_idx ] . ScanType = = SCAN_PASSIVE )
out [ j ] . flags | = RTW_IEEE80211_CHAN_PASSIVE_SCAN ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
j + + ;
}
2014-12-11 21:15:04 +00:00
if ( j > = out_num )
2013-05-08 21:45:39 +00:00
break ;
}
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
/* if out is empty, use channel_set as default */
2014-12-11 21:15:04 +00:00
if ( j = = 0 ) {
for ( i = 0 ; i < pmlmeext - > max_chan_nums ; i + + ) {
2013-05-08 21:45:39 +00:00
out [ i ] . hw_value = pmlmeext - > channel_set [ i ] . ChannelNum ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
if ( pmlmeext - > channel_set [ i ] . ScanType = = SCAN_PASSIVE )
out [ i ] . flags | = RTW_IEEE80211_CHAN_PASSIVE_SCAN ;
2013-05-08 21:45:39 +00:00
j + + ;
}
}
2015-02-19 21:34:32 +00:00
if ( padapter - > setband = = GHZ_24 ) { /* 2.4G */
2014-12-11 21:15:04 +00:00
for ( i = 0 ; i < j ; i + + ) {
2014-12-19 06:59:46 +00:00
if ( out [ i ] . hw_value > 35 )
2015-02-19 20:58:09 +00:00
memset ( & out [ i ] , 0 , sizeof ( struct rtw_ieee80211_channel ) ) ;
2014-12-11 21:15:04 +00:00
else
scan_ch_num + + ;
}
j = scan_ch_num ;
2015-02-19 21:34:32 +00:00
} else if ( padapter - > setband = = GHZ_50 ) { /* 5G */
2014-12-11 21:15:04 +00:00
for ( i = 0 ; i < j ; i + + ) {
if ( out [ i ] . hw_value > 35 ) {
2015-02-19 20:50:04 +00:00
memcpy ( & out [ scan_ch_num + + ] , & out [ i ] , sizeof ( struct rtw_ieee80211_channel ) ) ;
2014-12-11 21:15:04 +00:00
}
}
j = scan_ch_num ;
} else
{ }
2013-05-08 21:45:39 +00:00
return j ;
}
2014-12-17 23:13:53 +00:00
u8 sitesurvey_cmd_hdl ( struct adapter * padapter , u8 * pbuf )
2013-05-08 21:45:39 +00:00
{
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
struct sitesurvey_parm * pparm = ( struct sitesurvey_parm * ) pbuf ;
2014-12-29 02:13:24 +00:00
u8 bdelayscan = false ;
2014-12-11 21:15:04 +00:00
u8 val8 ;
2013-05-08 21:45:39 +00:00
u32 initialgain ;
u32 i ;
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_P2P
struct wifidirect_info * pwdinfo = & padapter - > wdinfo ;
2013-05-08 21:45:39 +00:00
# endif
2014-12-11 21:15:04 +00:00
if ( pmlmeext - > sitesurvey_res . state = = SCAN_DISABLE )
{
2013-05-08 21:45:39 +00:00
pmlmeext - > sitesurvey_res . state = SCAN_START ;
pmlmeext - > sitesurvey_res . bss_cnt = 0 ;
pmlmeext - > sitesurvey_res . channel_idx = 0 ;
2014-12-11 21:15:04 +00:00
for ( i = 0 ; i < RTW_SSID_SCAN_AMOUNT ; i + + ) {
if ( pparm - > ssid [ i ] . SsidLength ) {
2015-02-19 20:50:04 +00:00
memcpy ( pmlmeext - > sitesurvey_res . ssid [ i ] . Ssid , pparm - > ssid [ i ] . Ssid , IW_ESSID_MAX_SIZE ) ;
2014-12-11 21:15:04 +00:00
pmlmeext - > sitesurvey_res . ssid [ i ] . SsidLength = pparm - > ssid [ i ] . SsidLength ;
2013-05-08 21:45:39 +00:00
} else {
2014-12-11 21:15:04 +00:00
pmlmeext - > sitesurvey_res . ssid [ i ] . SsidLength = 0 ;
2013-05-08 21:45:39 +00:00
}
}
pmlmeext - > sitesurvey_res . ch_num = rtw_scan_ch_decision ( padapter
, pmlmeext - > sitesurvey_res . ch , RTW_CHANNEL_SCAN_AMOUNT
, pparm - > ch , pparm - > ch_num
2014-12-11 21:15:04 +00:00
) ;
2013-05-08 21:45:39 +00:00
pmlmeext - > sitesurvey_res . scan_mode = pparm - > scan_mode ;
2015-02-19 21:34:32 +00:00
/* issue null data if associating to the AP */
2014-12-29 02:13:24 +00:00
if ( is_client_associated_to_ap ( padapter ) = = true )
2014-12-11 21:15:04 +00:00
{
pmlmeext - > sitesurvey_res . state = SCAN_TXNULL ;
/* switch to correct channel of current network before issue keep-alive frames */
if ( rtw_get_oper_ch ( padapter ) ! = pmlmeext - > cur_channel ) {
SelectChannel ( padapter , pmlmeext - > cur_channel ) ;
}
2013-05-08 21:45:39 +00:00
issue_nulldata ( padapter , NULL , 1 , 3 , 500 ) ;
2014-12-29 02:13:24 +00:00
bdelayscan = true ;
2014-12-11 21:15:04 +00:00
}
if ( bdelayscan )
{
2015-02-19 21:34:32 +00:00
/* delay 50ms to protect nulldata(1). */
2013-05-08 21:45:39 +00:00
set_survey_timer ( pmlmeext , 50 ) ;
return H2C_SUCCESS ;
}
}
2014-12-11 21:15:04 +00:00
if ( ( pmlmeext - > sitesurvey_res . state = = SCAN_START ) | | ( pmlmeext - > sitesurvey_res . state = = SCAN_TXNULL ) )
{
2015-02-19 21:34:32 +00:00
/* disable dynamic functions, such as high power, DIG */
2013-05-08 21:45:39 +00:00
Save_DM_Func_Flag ( padapter ) ;
2014-12-29 02:13:24 +00:00
Switch_DM_Func ( padapter , DYNAMIC_FUNC_DISABLE , false ) ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* config the initial gain under scaning, need to write the BB registers */
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_P2P
2014-12-29 02:13:24 +00:00
if ( ( wdev_to_priv ( padapter - > rtw_wdev ) ) - > p2p_enabled = = true & & pwdinfo - > driver_interface = = DRIVER_CFG80211 )
2014-12-11 21:15:04 +00:00
initialgain = 0x30 ;
2013-05-08 21:45:39 +00:00
else
2014-12-11 21:15:04 +00:00
if ( ! rtw_p2p_chk_state ( pwdinfo , P2P_STATE_NONE ) )
2013-05-08 21:45:39 +00:00
initialgain = 0x28 ;
2014-12-11 21:15:04 +00:00
else
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_P2P */
2014-12-11 21:15:04 +00:00
initialgain = 0x1e ;
2013-05-08 21:45:39 +00:00
rtw_hal_set_hwreg ( padapter , HW_VAR_INITIAL_GAIN , ( u8 * ) ( & initialgain ) ) ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* set MSR to no link state */
2013-05-08 21:45:39 +00:00
Set_MSR ( padapter , _HW_STATE_NOLINK_ ) ;
2015-02-19 21:34:32 +00:00
val8 = 1 ; /* under site survey */
2013-05-08 21:45:39 +00:00
rtw_hal_set_hwreg ( padapter , HW_VAR_MLME_SITESURVEY , ( u8 * ) ( & val8 ) ) ;
pmlmeext - > sitesurvey_res . state = SCAN_PROCESS ;
}
site_survey ( padapter ) ;
return H2C_SUCCESS ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-17 23:13:53 +00:00
u8 setauth_hdl ( struct adapter * padapter , unsigned char * pbuf )
2013-05-08 21:45:39 +00:00
{
struct setauth_parm * pparm = ( struct setauth_parm * ) pbuf ;
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
if ( pparm - > mode < 4 )
2014-12-11 21:15:04 +00:00
{
2013-05-08 21:45:39 +00:00
pmlmeinfo - > auth_algo = pparm - > mode ;
2014-12-11 21:15:04 +00:00
}
2014-12-19 06:59:46 +00:00
return H2C_SUCCESS ;
2013-05-08 21:45:39 +00:00
}
2014-12-17 23:13:53 +00:00
u8 setkey_hdl ( struct adapter * padapter , u8 * pbuf )
2013-05-08 21:45:39 +00:00
{
unsigned short ctrl ;
struct setkey_parm * pparm = ( struct setkey_parm * ) pbuf ;
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
unsigned char null_sta [ ] = { 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 } ;
2015-02-19 21:34:32 +00:00
/* main tx key for wep. */
2014-12-11 21:15:04 +00:00
if ( pparm - > set_tx )
2013-05-08 21:45:39 +00:00
pmlmeinfo - > key_index = pparm - > keyid ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* write cam */
2014-12-19 06:59:46 +00:00
ctrl = BIT ( 15 ) | ( ( pparm - > algorithm ) < < 2 ) | pparm - > keyid ;
2013-05-19 04:28:07 +00:00
2014-12-11 21:15:04 +00:00
DBG_871X_LEVEL ( _drv_always_ , " set group key to hw: alg:%d(WEP40-1 WEP104-5 TKIP-2 AES-4) "
2013-05-08 21:45:39 +00:00
" keyid:%d \n " , pparm - > algorithm , pparm - > keyid ) ;
write_cam ( padapter , pparm - > keyid , ctrl , null_sta , pparm - > key ) ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* allow multicast packets to driver */
2014-12-11 21:15:04 +00:00
padapter - > HalFunc . SetHwRegHandler ( padapter , HW_VAR_ON_RCR_AM , null_addr ) ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
return H2C_SUCCESS ;
}
2014-12-17 23:13:53 +00:00
u8 set_stakey_hdl ( struct adapter * padapter , u8 * pbuf )
2013-05-08 21:45:39 +00:00
{
2014-12-11 21:15:04 +00:00
u16 ctrl = 0 ;
2015-02-19 21:34:32 +00:00
u8 cam_id ; /* cam_entry */
2013-05-08 21:45:39 +00:00
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
struct set_stakey_parm * pparm = ( struct set_stakey_parm * ) pbuf ;
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_TDLS
struct tdls_info * ptdlsinfo = & padapter - > tdlsinfo ;
struct sta_priv * pstapriv = & padapter - > stapriv ;
struct sta_info * psta ;
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_TDLS */
2014-12-11 21:15:04 +00:00
2015-02-19 21:34:32 +00:00
/* cam_entry: */
/* 0~3 for default key */
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* for concurrent mode (ap+sta): */
/* default key is disable, using sw encrypt/decrypt */
/* cam_entry = 4 for sta mode (macid=0) */
/* cam_entry(macid+3) = 5 ~ N for ap mode (aid=1~N, macid=2 ~N) */
2014-12-11 21:15:04 +00:00
2015-02-19 21:34:32 +00:00
/* for concurrent mode (sta+sta): */
/* default key is disable, using sw encrypt/decrypt */
/* cam_entry = 4 mapping to macid=0 */
/* cam_entry = 5 mapping to macid=2 */
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
cam_id = 4 ;
2014-12-11 21:15:04 +00:00
DBG_871X_LEVEL ( _drv_always_ , " set pairwise key to hw: alg:%d(WEP40-1 WEP104-5 TKIP-2 AES-4) camid:%d \n " ,
2014-12-19 06:59:46 +00:00
pparm - > algorithm , cam_id ) ;
2014-12-11 21:15:04 +00:00
if ( ( pmlmeinfo - > state & 0x03 ) = = WIFI_FW_AP_STATE )
{
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
struct sta_info * psta ;
struct sta_priv * pstapriv = & padapter - > stapriv ;
2015-02-19 21:34:32 +00:00
if ( pparm - > algorithm = = _NO_PRIVACY_ ) /* clear cam entry */
2014-12-11 21:15:04 +00:00
{
2013-05-08 21:45:39 +00:00
clear_cam_entry ( padapter , pparm - > id ) ;
return H2C_SUCCESS_RSP ;
}
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
psta = rtw_get_stainfo ( pstapriv , pparm - > addr ) ;
2014-12-11 21:15:04 +00:00
if ( psta )
2014-12-19 06:59:46 +00:00
{
2013-05-08 21:45:39 +00:00
ctrl = ( BIT ( 15 ) | ( ( pparm - > algorithm ) < < 2 ) ) ;
2014-12-11 21:15:04 +00:00
DBG_871X ( " r871x_set_stakey_hdl(): enc_algorithm=%d \n " , pparm - > algorithm ) ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
if ( ( psta - > mac_id < 1 ) | | ( psta - > mac_id > ( NUM_STA - 4 ) ) )
{
DBG_871X ( " r871x_set_stakey_hdl():set_stakey failed, mac_id(aid)=%d \n " , psta - > mac_id ) ;
2013-05-08 21:45:39 +00:00
return H2C_REJECTED ;
2014-12-19 06:59:46 +00:00
}
2015-02-19 21:34:32 +00:00
cam_id = ( psta - > mac_id + 3 ) ; /* 0~3 for default key, cmd_id=macid + 3, macid=aid+1; */
2013-05-19 04:28:07 +00:00
2014-12-19 06:59:46 +00:00
DBG_871X ( " Write CAM, mac_addr=%x:%x:%x:%x:%x:%x, cam_entry=%d \n " , pparm - > addr [ 0 ] ,
2014-12-11 21:15:04 +00:00
pparm - > addr [ 1 ] , pparm - > addr [ 2 ] , pparm - > addr [ 3 ] , pparm - > addr [ 4 ] ,
pparm - > addr [ 5 ] , cam_id ) ;
2013-05-08 21:45:39 +00:00
write_cam ( padapter , cam_id , ctrl , pparm - > addr , pparm - > key ) ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
return H2C_SUCCESS_RSP ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
}
else
{
DBG_871X ( " r871x_set_stakey_hdl(): sta has been free \n " ) ;
2013-05-08 21:45:39 +00:00
return H2C_REJECTED ;
}
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
}
2015-02-19 21:34:32 +00:00
/* below for sta mode */
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
if ( pparm - > algorithm = = _NO_PRIVACY_ ) /* clear cam entry */
2014-12-11 21:15:04 +00:00
{
2013-05-08 21:45:39 +00:00
clear_cam_entry ( padapter , pparm - > id ) ;
return H2C_SUCCESS ;
}
2014-12-19 06:59:46 +00:00
ctrl = BIT ( 15 ) | ( ( pparm - > algorithm ) < < 2 ) ;
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_TDLS
if ( ptdlsinfo - > clear_cam ! = 0 ) {
clear_cam_entry ( padapter , ptdlsinfo - > clear_cam ) ;
ptdlsinfo - > clear_cam = 0 ;
return H2C_SUCCESS ;
}
2015-02-19 21:34:32 +00:00
psta = rtw_get_stainfo ( pstapriv , pparm - > addr ) ; /* Get TDLS Peer STA */
2014-12-11 21:15:04 +00:00
if ( psta - > tdls_sta_state & TDLS_LINKED_STATE ) {
write_cam ( padapter , psta - > mac_id , ctrl , pparm - > addr , pparm - > key ) ;
}
else
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_TDLS */
2013-05-08 21:45:39 +00:00
write_cam ( padapter , cam_id , ctrl , pparm - > addr , pparm - > key ) ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
pmlmeinfo - > enc_algo = pparm - > algorithm ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
return H2C_SUCCESS ;
}
2014-12-17 23:13:53 +00:00
u8 add_ba_hdl ( struct adapter * padapter , unsigned char * pbuf )
2013-05-08 21:45:39 +00:00
{
2014-12-19 06:59:46 +00:00
struct addBaReq_parm * pparm = ( struct addBaReq_parm * ) pbuf ;
2013-05-08 21:45:39 +00:00
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
struct sta_info * psta = rtw_get_stainfo ( & padapter - > stapriv , pparm - > addr ) ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
if ( ! psta )
2014-12-19 06:59:46 +00:00
return H2C_SUCCESS ;
2013-05-08 21:45:39 +00:00
if ( ( ( pmlmeinfo - > state & WIFI_FW_ASSOC_SUCCESS ) & & ( pmlmeinfo - > HT_enable ) ) | |
2014-12-11 21:15:04 +00:00
( ( pmlmeinfo - > state & 0x03 ) = = WIFI_FW_AP_STATE ) )
{
2015-02-19 21:34:32 +00:00
/* pmlmeinfo->ADDBA_retry_count = 0; */
/* pmlmeinfo->candidate_tid_bitmap |= (0x1 << pparm->tid); */
/* psta->htpriv.candidate_tid_bitmap |= BIT(pparm->tid); */
2014-12-19 04:28:04 +00:00
issue_action_BA ( padapter , pparm - > addr , RTW_WLAN_ACTION_ADDBA_REQ ,
2014-12-19 06:59:46 +00:00
pparm - > tid ) ;
2015-02-19 21:34:32 +00:00
/* _set_timer(&pmlmeext->ADDBA_timer, ADDBA_TO); */
2013-05-08 21:45:39 +00:00
_set_timer ( & psta - > addba_retry_timer , ADDBA_TO ) ;
}
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_TDLS
2014-12-19 06:59:46 +00:00
else if ( ( psta - > tdls_sta_state & TDLS_LINKED_STATE ) & &
2014-12-29 02:13:24 +00:00
( psta - > htpriv . ht_option = = true ) & &
( psta - > htpriv . ampdu_enable = = true ) )
2014-12-11 21:15:04 +00:00
{
2014-12-19 04:28:04 +00:00
issue_action_BA ( padapter , pparm - > addr , RTW_WLAN_ACTION_ADDBA_REQ ,
2014-12-19 06:59:46 +00:00
pparm - > tid ) ;
2015-02-19 21:34:32 +00:00
/* _set_timer(&pmlmeext->ADDBA_timer, ADDBA_TO); */
2014-12-11 21:15:04 +00:00
_set_timer ( & psta - > addba_retry_timer , ADDBA_TO ) ;
}
2015-02-19 21:34:32 +00:00
# endif /* CONFIG */
2014-12-11 21:15:04 +00:00
else
2014-12-19 06:59:46 +00:00
{
psta - > htpriv . candidate_tid_bitmap & = ~ BIT ( pparm - > tid ) ;
2014-12-11 21:15:04 +00:00
}
2014-12-19 06:59:46 +00:00
return H2C_SUCCESS ;
2013-05-08 21:45:39 +00:00
}
2014-12-17 23:13:53 +00:00
u8 set_tx_beacon_cmd ( struct adapter * padapter )
2013-05-08 21:45:39 +00:00
{
struct cmd_obj * ph2c ;
2014-12-19 06:59:46 +00:00
struct Tx_Beacon_param * ptxBeacon_parm ;
2013-05-08 21:45:39 +00:00
struct cmd_priv * pcmdpriv = & ( padapter - > cmdpriv ) ;
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
2014-12-11 21:15:04 +00:00
u8 res = _SUCCESS ;
2013-05-08 21:45:39 +00:00
int len_diff = 0 ;
2014-12-19 06:59:46 +00:00
2015-01-26 22:20:25 +00:00
;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
if ( ( ph2c = ( struct cmd_obj * ) rtw_zmalloc ( sizeof ( struct cmd_obj ) ) ) = = NULL )
{
res = _FAIL ;
2013-05-08 21:45:39 +00:00
goto exit ;
}
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
if ( ( ptxBeacon_parm = ( struct Tx_Beacon_param * ) rtw_zmalloc ( sizeof ( struct Tx_Beacon_param ) ) ) = = NULL )
{
rtw_mfree ( ( unsigned char * ) ph2c , sizeof ( struct cmd_obj ) ) ;
res = _FAIL ;
2013-05-08 21:45:39 +00:00
goto exit ;
}
2015-02-19 20:50:04 +00:00
memcpy ( & ( ptxBeacon_parm - > network ) , & ( pmlmeinfo - > network ) , sizeof ( WLAN_BSSID_EX ) ) ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
len_diff = update_hidden_ssid (
ptxBeacon_parm - > network . IEs + _BEACON_IE_OFFSET_
, ptxBeacon_parm - > network . IELength - _BEACON_IE_OFFSET_
, pmlmeinfo - > hidden_ssid_mode
) ;
2013-05-08 21:45:39 +00:00
ptxBeacon_parm - > network . IELength + = len_diff ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
init_h2fwcmd_w_parm_no_rsp ( ph2c , ptxBeacon_parm , GEN_CMD_CODE ( _TX_Beacon ) ) ;
res = rtw_enqueue_cmd ( pcmdpriv , ph2c ) ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
exit :
2014-12-19 06:59:46 +00:00
2015-01-26 22:20:25 +00:00
;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
return res ;
}
2014-12-11 21:15:04 +00:00
2014-12-17 23:13:53 +00:00
u8 mlme_evt_hdl ( struct adapter * padapter , unsigned char * pbuf )
2013-05-08 21:45:39 +00:00
{
2014-12-11 21:15:04 +00:00
u8 evt_code , evt_seq ;
2013-05-08 21:45:39 +00:00
u16 evt_sz ;
2014-12-19 06:59:46 +00:00
uint * peventbuf ;
2014-12-17 23:13:53 +00:00
void ( * event_callback ) ( struct adapter * dev , u8 * pbuf ) ;
2013-05-08 21:45:39 +00:00
struct evt_priv * pevt_priv = & ( padapter - > evtpriv ) ;
2014-12-11 21:15:04 +00:00
peventbuf = ( uint * ) pbuf ;
2013-05-08 21:45:39 +00:00
evt_sz = ( u16 ) ( * peventbuf & 0xffff ) ;
2014-12-11 21:15:04 +00:00
evt_seq = ( u8 ) ( ( * peventbuf > > 24 ) & 0x7f ) ;
2013-05-08 21:45:39 +00:00
evt_code = ( u8 ) ( ( * peventbuf > > 16 ) & 0xff ) ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
# ifdef CHECK_EVENT_SEQ
2015-02-19 21:34:32 +00:00
/* checking event sequence... */
2014-12-11 21:15:04 +00:00
if ( evt_seq ! = ( ATOMIC_READ ( & pevt_priv - > event_seq ) & 0x7f ) )
{
RT_TRACE ( _module_rtl871x_cmd_c_ , _drv_info_ , ( " Evetn Seq Error! %d vs %d \n " , ( evt_seq & 0x7f ) , ( ATOMIC_READ ( & pevt_priv - > event_seq ) & 0x7f ) ) ) ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
pevt_priv - > event_seq = ( evt_seq + 1 ) & 0x7f ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
goto _abort_event_ ;
}
2014-12-11 21:15:04 +00:00
# endif
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
/* checking if event code is valid */
2014-12-11 21:15:04 +00:00
if ( evt_code > = MAX_C2HEVT )
{
RT_TRACE ( _module_rtl871x_cmd_c_ , _drv_err_ , ( " \n Event Code(%d) mismatch! \n " , evt_code ) ) ;
2013-05-19 04:28:07 +00:00
goto _abort_event_ ;
2013-05-08 21:45:39 +00:00
}
2015-02-19 21:34:32 +00:00
/* checking if event size match the event parm size */
2014-12-19 06:59:46 +00:00
if ( ( wlanevents [ evt_code ] . parmsize ! = 0 ) & &
2014-12-11 21:15:04 +00:00
( wlanevents [ evt_code ] . parmsize ! = evt_sz ) )
{
2014-12-19 06:59:46 +00:00
RT_TRACE ( _module_rtl871x_cmd_c_ , _drv_err_ , ( " \n Event(%d) Parm Size mismatch (%d vs %d)! \n " ,
2014-12-11 21:15:04 +00:00
evt_code , wlanevents [ evt_code ] . parmsize , evt_sz ) ) ;
2014-12-19 06:59:46 +00:00
goto _abort_event_ ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
ATOMIC_INC ( & pevt_priv - > event_seq ) ;
peventbuf + = 2 ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
if ( peventbuf )
{
2013-05-08 21:45:39 +00:00
event_callback = wlanevents [ evt_code ] . event_callback ;
2014-12-11 21:15:04 +00:00
event_callback ( padapter , ( u8 * ) peventbuf ) ;
2013-05-08 21:45:39 +00:00
pevt_priv - > evt_done_cnt + + ;
}
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
_abort_event_ :
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
return H2C_SUCCESS ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-17 23:13:53 +00:00
u8 h2c_msg_hdl ( struct adapter * padapter , unsigned char * pbuf )
2013-05-08 21:45:39 +00:00
{
2014-12-11 21:15:04 +00:00
if ( ! pbuf )
2013-05-08 21:45:39 +00:00
return H2C_PARAMETERS_ERROR ;
return H2C_SUCCESS ;
}
2014-12-17 23:13:53 +00:00
u8 tx_beacon_hdl ( struct adapter * padapter , unsigned char * pbuf )
2013-05-08 21:45:39 +00:00
{
2014-12-11 21:15:04 +00:00
if ( send_beacon ( padapter ) = = _FAIL )
{
DBG_871X ( " issue_beacon, fail! \n " ) ;
2013-05-08 21:45:39 +00:00
return H2C_PARAMETERS_ERROR ;
}
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_AP_MODE
2015-02-19 21:34:32 +00:00
else /* tx bc/mc frames after update TIM */
2014-12-19 06:59:46 +00:00
{
2014-12-11 21:15:04 +00:00
_irqL irqL ;
2013-05-08 21:45:39 +00:00
struct sta_info * psta_bmc ;
2014-12-11 21:15:04 +00:00
_list * xmitframe_plist , * xmitframe_phead ;
struct xmit_frame * pxmitframe = NULL ;
struct xmit_priv * pxmitpriv = & padapter - > xmitpriv ;
2013-05-08 21:45:39 +00:00
struct sta_priv * pstapriv = & padapter - > stapriv ;
2014-12-19 06:59:46 +00:00
2015-02-19 21:34:32 +00:00
/* for BC/MC Frames */
2013-05-08 21:45:39 +00:00
psta_bmc = rtw_get_bcmc_stainfo ( padapter ) ;
2014-12-11 21:15:04 +00:00
if ( ! psta_bmc )
2013-05-08 21:45:39 +00:00
return H2C_SUCCESS ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
if ( ( pstapriv - > tim_bitmap & BIT ( 0 ) ) & & ( psta_bmc - > sleepq_len > 0 ) )
2014-12-19 06:59:46 +00:00
{
2015-02-19 21:34:32 +00:00
rtw_msleep_os ( 10 ) ; /* 10ms, ATIM(HIQ) Windows */
2014-12-11 21:15:04 +00:00
_enter_critical_bh ( & pxmitpriv - > lock , & irqL ) ;
2013-05-08 21:45:39 +00:00
xmitframe_phead = get_list_head ( & psta_bmc - > sleep_q ) ;
xmitframe_plist = get_next ( xmitframe_phead ) ;
2014-12-29 02:13:24 +00:00
while ( ( rtw_end_of_queue_search ( xmitframe_phead , xmitframe_plist ) ) = = false )
2014-12-19 06:59:46 +00:00
{
2013-05-08 21:45:39 +00:00
pxmitframe = LIST_CONTAINOR ( xmitframe_plist , struct xmit_frame , list ) ;
xmitframe_plist = get_next ( xmitframe_plist ) ;
rtw_list_delete ( & pxmitframe - > list ) ;
psta_bmc - > sleepq_len - - ;
2014-12-11 21:15:04 +00:00
if ( psta_bmc - > sleepq_len > 0 )
2013-05-08 21:45:39 +00:00
pxmitframe - > attrib . mdata = 1 ;
else
pxmitframe - > attrib . mdata = 0 ;
2014-12-11 21:15:04 +00:00
pxmitframe - > attrib . triggered = 1 ;
2013-05-08 21:45:39 +00:00
2015-02-19 21:34:32 +00:00
pxmitframe - > attrib . qsel = 0x11 ; /* HIQ */
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
rtw_hal_xmitframe_enqueue ( padapter , pxmitframe ) ;
2014-12-19 06:59:46 +00:00
}
2014-12-11 21:15:04 +00:00
_exit_critical_bh ( & pxmitpriv - > lock , & irqL ) ;
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
}
# endif
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
return H2C_SUCCESS ;
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-17 23:13:53 +00:00
int rtw_chk_start_clnt_join ( struct adapter * padapter , u8 * ch , u8 * bw , u8 * offset )
2014-12-11 21:15:04 +00:00
{
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
unsigned char cur_ch = pmlmeext - > cur_channel ;
unsigned char cur_bw = pmlmeext - > cur_bwmode ;
unsigned char cur_ch_offset = pmlmeext - > cur_ch_offset ;
2014-12-29 02:13:24 +00:00
bool chbw_allow = true ;
bool connect_allow = true ;
2014-12-11 21:15:04 +00:00
if ( ! ch | | ! bw | | ! offset ) {
rtw_warn_on ( 1 ) ;
2014-12-29 02:13:24 +00:00
connect_allow = false ;
2014-12-11 21:15:04 +00:00
}
2014-12-29 02:13:24 +00:00
if ( connect_allow = = true ) {
2014-12-11 21:15:04 +00:00
DBG_871X ( " start_join_set_ch_bw: ch=%d, bwmode=%d, ch_offset=%d \n " , cur_ch , cur_bw , cur_ch_offset ) ;
* ch = cur_ch ;
* bw = cur_bw ;
* offset = cur_ch_offset ;
}
2014-12-29 02:13:24 +00:00
return connect_allow = = true ? _SUCCESS : _FAIL ;
2014-12-11 21:15:04 +00:00
}
/* Find union about ch, bw, ch_offset of all linked interfaces */
2014-12-17 23:13:53 +00:00
int rtw_get_ch_setting_union ( struct adapter * adapter , u8 * ch , u8 * bw , u8 * offset )
2014-12-11 21:15:04 +00:00
{
struct dvobj_priv * dvobj = adapter_to_dvobj ( adapter ) ;
2014-12-17 23:13:53 +00:00
struct adapter * iface ;
2014-12-11 21:15:04 +00:00
struct mlme_ext_priv * mlmeext ;
int i ;
u8 ch_ret = 0 ;
u8 bw_ret = HT_CHANNEL_WIDTH_20 ;
u8 offset_ret = HAL_PRIME_CHNL_OFFSET_DONT_CARE ;
int num = 0 ;
if ( ch ) * ch = 0 ;
if ( bw ) * bw = HT_CHANNEL_WIDTH_20 ;
if ( offset ) * offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE ;
for ( i = 0 ; i < dvobj - > iface_nums ; i + + ) {
iface = dvobj - > padapters [ i ] ;
mlmeext = & iface - > mlmeextpriv ;
if ( ! check_fwstate ( & iface - > mlmepriv , _FW_LINKED ) )
continue ;
if ( num = = 0 ) {
ch_ret = mlmeext - > cur_channel ;
bw_ret = mlmeext - > cur_bwmode ;
offset_ret = mlmeext - > cur_ch_offset ;
num + + ;
continue ;
}
if ( ch_ret ! = mlmeext - > cur_channel ) {
num = 0 ;
break ;
}
if ( bw_ret < mlmeext - > cur_bwmode ) {
bw_ret = mlmeext - > cur_bwmode ;
offset_ret = mlmeext - > cur_ch_offset ;
} else if ( bw_ret = = mlmeext - > cur_bwmode & & offset_ret ! = mlmeext - > cur_ch_offset ) {
num = 0 ;
break ;
}
num + + ;
}
if ( num ) {
if ( ch ) * ch = ch_ret ;
if ( bw ) * bw = bw_ret ;
if ( offset ) * offset = offset_ret ;
}
return num ;
}
2014-12-17 23:13:53 +00:00
u8 set_ch_hdl ( struct adapter * padapter , u8 * pbuf )
2014-12-11 21:15:04 +00:00
{
struct set_ch_parm * set_ch_parm ;
struct mlme_priv * pmlmepriv = & padapter - > mlmepriv ;
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
if ( ! pbuf )
return H2C_PARAMETERS_ERROR ;
set_ch_parm = ( struct set_ch_parm * ) pbuf ;
DBG_871X ( FUNC_NDEV_FMT " ch:%u, bw:%u, ch_offset:%u \n " ,
FUNC_NDEV_ARG ( padapter - > pnetdev ) ,
set_ch_parm - > ch , set_ch_parm - > bw , set_ch_parm - > ch_offset ) ;
pmlmeext - > cur_channel = set_ch_parm - > ch ;
pmlmeext - > cur_ch_offset = set_ch_parm - > ch_offset ;
pmlmeext - > cur_bwmode = set_ch_parm - > bw ;
set_channel_bwmode ( padapter , set_ch_parm - > ch , set_ch_parm - > ch_offset , set_ch_parm - > bw ) ;
2014-12-19 06:59:46 +00:00
return H2C_SUCCESS ;
2014-12-11 21:15:04 +00:00
}
2014-12-17 23:13:53 +00:00
u8 set_chplan_hdl ( struct adapter * padapter , unsigned char * pbuf )
2014-12-11 21:15:04 +00:00
{
struct SetChannelPlan_param * setChannelPlan_param ;
struct mlme_priv * pmlmepriv = & padapter - > mlmepriv ;
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
if ( ! pbuf )
return H2C_PARAMETERS_ERROR ;
setChannelPlan_param = ( struct SetChannelPlan_param * ) pbuf ;
pmlmeext - > max_chan_nums = init_channel_set ( padapter , setChannelPlan_param - > channel_plan , pmlmeext - > channel_set ) ;
2014-12-19 06:59:46 +00:00
init_channel_list ( padapter , pmlmeext - > channel_set , pmlmeext - > max_chan_nums , & pmlmeext - > channel_list ) ;
2014-12-11 21:15:04 +00:00
2014-12-19 06:59:46 +00:00
return H2C_SUCCESS ;
2014-12-11 21:15:04 +00:00
}
2014-12-17 23:13:53 +00:00
u8 led_blink_hdl ( struct adapter * padapter , unsigned char * pbuf )
2014-12-11 21:15:04 +00:00
{
struct LedBlink_param * ledBlink_param ;
if ( ! pbuf )
return H2C_PARAMETERS_ERROR ;
ledBlink_param = ( struct LedBlink_param * ) pbuf ;
# ifdef CONFIG_LED_HANDLED_BY_CMD_THREAD
BlinkHandler ( ledBlink_param - > pLed ) ;
# endif
2014-12-19 06:59:46 +00:00
return H2C_SUCCESS ;
2014-12-11 21:15:04 +00:00
}
2014-12-17 23:13:53 +00:00
u8 set_csa_hdl ( struct adapter * padapter , unsigned char * pbuf )
2014-12-11 21:15:04 +00:00
{
# ifdef CONFIG_DFS
struct SetChannelSwitch_param * setChannelSwitch_param ;
struct mlme_priv * pmlmepriv = & padapter - > mlmepriv ;
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
struct mlme_ext_info * pmlmeinfo = & pmlmeext - > mlmext_info ;
u8 new_ch_no ;
u8 gval8 = 0x00 , sval8 = 0xff ;
if ( ! pbuf )
return H2C_PARAMETERS_ERROR ;
setChannelSwitch_param = ( struct SetChannelSwitch_param * ) pbuf ;
new_ch_no = setChannelSwitch_param - > new_ch_no ;
rtw_hal_get_hwreg ( padapter , HW_VAR_TXPAUSE , & gval8 ) ;
rtw_hal_set_hwreg ( padapter , HW_VAR_TXPAUSE , & sval8 ) ;
DBG_871X ( " DFS detected! Swiching channel to %d! \n " , new_ch_no ) ;
SelectChannel ( padapter , new_ch_no ) ;
rtw_hal_set_hwreg ( padapter , HW_VAR_TXPAUSE , & gval8 ) ;
2014-12-29 02:13:24 +00:00
rtw_free_network_queue ( padapter , true ) ;
2014-12-11 21:15:04 +00:00
rtw_indicate_disconnect ( padapter ) ;
if ( ( ( new_ch_no > = 52 ) & & ( new_ch_no < = 64 ) ) | | ( ( new_ch_no > = 100 ) & & ( new_ch_no < = 140 ) ) ) {
DBG_871X ( " Switched to DFS band (ch %02x) again!! \n " , new_ch_no ) ;
}
2014-12-19 06:59:46 +00:00
return H2C_SUCCESS ;
2014-12-11 21:15:04 +00:00
# else
return H2C_REJECTED ;
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_DFS */
}
/* TDLS_WRCR : write RCR DATA BIT */
/* TDLS_SD_PTI : issue peer traffic indication */
/* TDLS_CS_OFF : go back to the channel linked with AP, terminating channel switch procedure */
/* TDLS_INIT_CH_SEN : init channel sensing, receive all data and mgnt frame */
/* TDLS_DONE_CH_SEN: channel sensing and report candidate channel */
/* TDLS_OFF_CH : first time set channel to off channel */
/* TDLS_BASE_CH : go back tp the channel linked with AP when set base channel as target channel */
/* TDLS_P_OFF_CH : periodically go to off channel */
/* TDLS_P_BASE_CH : periodically go back to base channel */
/* TDLS_RS_RCR : restore RCR */
/* TDLS_CKALV_PH1 : check alive timer phase1 */
/* TDLS_CKALV_PH2 : check alive timer phase2 */
/* TDLS_FREE_STA : free tdls sta */
2014-12-17 23:13:53 +00:00
u8 tdls_hdl ( struct adapter * padapter , unsigned char * pbuf )
2014-12-11 21:15:04 +00:00
{
# ifdef CONFIG_TDLS
_irqL irqL ;
struct tdls_info * ptdlsinfo = & padapter - > tdlsinfo ;
struct TDLSoption_param * TDLSoption ;
struct sta_info * ptdls_sta ;
struct mlme_ext_priv * pmlmeext = & padapter - > mlmeextpriv ;
struct mlme_ext_info * pmlmeinfo = & pmlmeext - > mlmext_info ;
u8 survey_channel , i , min , option ;
if ( ! pbuf )
return H2C_PARAMETERS_ERROR ;
TDLSoption = ( struct TDLSoption_param * ) pbuf ;
ptdls_sta = rtw_get_stainfo ( & ( padapter - > stapriv ) , TDLSoption - > addr ) ;
option = TDLSoption - > option ;
if ( ptdls_sta = = NULL )
{
if ( option ! = TDLS_RS_RCR )
return H2C_REJECTED ;
}
2015-02-19 21:34:32 +00:00
/* _enter_critical_bh(&(ptdlsinfo->hdl_lock), &irqL); */
2014-12-11 21:15:04 +00:00
DBG_871X ( " [%s] option:%d \n " , __FUNCTION__ , option ) ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
switch ( option ) {
case TDLS_WRCR :
2015-02-19 21:34:32 +00:00
/* As long as TDLS handshake success, we should set RCR_CBSSID_DATA bit to 0 */
/* such we can receive all kinds of data frames. */
2014-12-11 21:15:04 +00:00
rtw_hal_set_hwreg ( padapter , HW_VAR_TDLS_WRCR , 0 ) ;
DBG_871X ( " TDLS with " MAC_FMT " \n " , MAC_ARG ( ptdls_sta - > hwaddr ) ) ;
pmlmeinfo - > FW_sta_info [ ptdls_sta - > mac_id ] . psta = ptdls_sta ;
2015-02-19 21:34:32 +00:00
/* set TDLS sta rate. */
2014-12-11 21:15:04 +00:00
set_sta_rate ( padapter , ptdls_sta ) ;
break ;
case TDLS_SD_PTI :
issue_tdls_peer_traffic_indication ( padapter , ptdls_sta ) ;
break ;
case TDLS_CS_OFF :
_cancel_timer_ex ( & ptdls_sta - > base_ch_timer ) ;
_cancel_timer_ex ( & ptdls_sta - > off_ch_timer ) ;
SelectChannel ( padapter , pmlmeext - > cur_channel ) ;
2014-12-19 06:59:46 +00:00
ptdls_sta - > tdls_sta_state & = ~ ( TDLS_CH_SWITCH_ON_STATE |
TDLS_PEER_AT_OFF_STATE |
2014-12-11 21:15:04 +00:00
TDLS_AT_OFF_CH_STATE ) ;
DBG_871X ( " go back to base channel \n " ) ;
issue_nulldata ( padapter , NULL , 0 , 0 , 0 ) ;
break ;
case TDLS_INIT_CH_SEN :
rtw_hal_set_hwreg ( padapter , HW_VAR_TDLS_INIT_CH_SEN , 0 ) ;
pmlmeext - > sitesurvey_res . channel_idx = 0 ;
ptdls_sta - > option = TDLS_DONE_CH_SEN ;
rtw_tdls_cmd ( padapter , ptdls_sta - > hwaddr , TDLS_DONE_CH_SEN ) ;
break ;
case TDLS_DONE_CH_SEN :
survey_channel = pmlmeext - > channel_set [ pmlmeext - > sitesurvey_res . channel_idx ] . ChannelNum ;
if ( survey_channel ) {
SelectChannel ( padapter , survey_channel ) ;
ptdlsinfo - > cur_channel = survey_channel ;
pmlmeext - > sitesurvey_res . channel_idx + + ;
_set_timer ( & ptdls_sta - > option_timer , SURVEY_TO ) ;
} else {
SelectChannel ( padapter , pmlmeext - > cur_channel ) ;
rtw_hal_set_hwreg ( padapter , HW_VAR_TDLS_DONE_CH_SEN , 0 ) ;
if ( ptdlsinfo - > ch_sensing = = 1 ) {
ptdlsinfo - > ch_sensing = 0 ;
ptdlsinfo - > cur_channel = 1 ;
min = ptdlsinfo - > collect_pkt_num [ 0 ] ;
for ( i = 1 ; i < MAX_CHANNEL_NUM - 1 ; i + + ) {
if ( min > ptdlsinfo - > collect_pkt_num [ i ] ) {
ptdlsinfo - > cur_channel = i + 1 ;
min = ptdlsinfo - > collect_pkt_num [ i ] ;
}
ptdlsinfo - > collect_pkt_num [ i ] = 0 ;
}
ptdlsinfo - > collect_pkt_num [ 0 ] = 0 ;
ptdlsinfo - > candidate_ch = ptdlsinfo - > cur_channel ;
DBG_871X ( " TDLS channel sensing done, candidate channel: %02x \n " , ptdlsinfo - > candidate_ch ) ;
ptdlsinfo - > cur_channel = 0 ;
}
if ( ptdls_sta - > tdls_sta_state & TDLS_PEER_SLEEP_STATE ) {
ptdls_sta - > tdls_sta_state | = TDLS_APSD_CHSW_STATE ;
} else {
2015-02-19 21:34:32 +00:00
/* send null data with pwrbit==1 before send ch_switching_req to peer STA. */
2014-12-11 21:15:04 +00:00
issue_nulldata ( padapter , NULL , 1 , 0 , 0 ) ;
ptdls_sta - > tdls_sta_state | = TDLS_CH_SW_INITIATOR_STATE ;
issue_tdls_ch_switch_req ( padapter , ptdls_sta - > hwaddr ) ;
DBG_871X ( " issue tdls ch switch req \n " ) ;
}
}
break ;
case TDLS_OFF_CH :
issue_nulldata ( padapter , NULL , 1 , 0 , 0 ) ;
SelectChannel ( padapter , ptdls_sta - > off_ch ) ;
DBG_871X ( " change channel to tar ch:%02x \n " , ptdls_sta - > off_ch ) ;
ptdls_sta - > tdls_sta_state | = TDLS_AT_OFF_CH_STATE ;
ptdls_sta - > tdls_sta_state & = ~ ( TDLS_PEER_AT_OFF_STATE ) ;
_set_timer ( & ptdls_sta - > option_timer , ( u32 ) ptdls_sta - > ch_switch_time ) ;
break ;
case TDLS_BASE_CH :
_cancel_timer_ex ( & ptdls_sta - > base_ch_timer ) ;
_cancel_timer_ex ( & ptdls_sta - > off_ch_timer ) ;
SelectChannel ( padapter , pmlmeext - > cur_channel ) ;
2014-12-19 06:59:46 +00:00
ptdls_sta - > tdls_sta_state & = ~ ( TDLS_CH_SWITCH_ON_STATE |
TDLS_PEER_AT_OFF_STATE |
2014-12-11 21:15:04 +00:00
TDLS_AT_OFF_CH_STATE ) ;
DBG_871X ( " go back to base channel \n " ) ;
issue_nulldata ( padapter , NULL , 0 , 0 , 0 ) ;
_set_timer ( & ptdls_sta - > option_timer , ( u32 ) ptdls_sta - > ch_switch_time ) ;
break ;
case TDLS_P_OFF_CH :
SelectChannel ( padapter , pmlmeext - > cur_channel ) ;
issue_nulldata ( padapter , NULL , 0 , 0 , 0 ) ;
DBG_871X ( " change channel to base ch:%02x \n " , pmlmeext - > cur_channel ) ;
ptdls_sta - > tdls_sta_state & = ~ ( TDLS_PEER_AT_OFF_STATE | TDLS_AT_OFF_CH_STATE ) ;
_set_timer ( & ptdls_sta - > off_ch_timer , TDLS_STAY_TIME ) ;
break ;
case TDLS_P_BASE_CH :
issue_nulldata ( ptdls_sta - > padapter , NULL , 1 , 0 , 0 ) ;
SelectChannel ( padapter , ptdls_sta - > off_ch ) ;
DBG_871X ( " change channel to off ch:%02x \n " , ptdls_sta - > off_ch ) ;
ptdls_sta - > tdls_sta_state | = TDLS_AT_OFF_CH_STATE ;
if ( ( ptdls_sta - > tdls_sta_state & TDLS_PEER_AT_OFF_STATE ) ! = TDLS_PEER_AT_OFF_STATE ) {
issue_nulldata_to_TDLS_peer_STA ( padapter , ptdls_sta , 0 ) ;
}
2014-12-19 06:59:46 +00:00
_set_timer ( & ptdls_sta - > base_ch_timer , TDLS_STAY_TIME ) ;
2014-12-11 21:15:04 +00:00
break ;
case TDLS_RS_RCR :
rtw_hal_set_hwreg ( padapter , HW_VAR_TDLS_RS_RCR , 0 ) ;
DBG_871X ( " wirte REG_RCR, set bit6 on \n " ) ;
break ;
case TDLS_CKALV_PH1 :
_set_timer ( & ptdls_sta - > alive_timer2 , TDLS_ALIVE_TIMER_PH2 ) ;
break ;
case TDLS_CKALV_PH2 :
_set_timer ( & ptdls_sta - > alive_timer1 , TDLS_ALIVE_TIMER_PH1 ) ;
break ;
case TDLS_FREE_STA :
free_tdls_sta ( padapter , ptdls_sta ) ;
break ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
}
2015-02-19 21:34:32 +00:00
/* _exit_critical_bh(&(ptdlsinfo->hdl_lock), &irqL); */
2014-12-11 21:15:04 +00:00
return H2C_SUCCESS ;
# else
return H2C_REJECTED ;
2015-02-19 21:34:32 +00:00
# endif /* CONFIG_TDLS */
2014-12-11 21:15:04 +00:00
}