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-11 21:15:04 +00:00
# ifdef _CONFIG_NATIVEAP_MLME_
struct mlme_handler mlme_ap_tbl [ ] = {
{ 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 " , & OnAuth } ,
{ WIFI_DEAUTH , " OnDeAuth " , & OnDeAuth } ,
{ WIFI_ACTION , " OnAction " , & OnAction } ,
} ;
# endif
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 } ,
2014-12-11 21:15:04 +00:00
# endif //CONFIG_IEEE80211W
//add for CONFIG_IEEE80211W
{ 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 } ;
# 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 } ;
2014-12-11 21:15:04 +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 DefaultChannelPlan[RT_CHANNEL_DOMAIN_MAX] = {
{ { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 36 , 40 , 44 , 48 , 52 , 56 , 60 , 64 , 100 , 104 , 108 , 112 , 116 , 132 , 136 , 140 , 149 , 153 , 157 , 161 , 165 } , 32 } , // 0x00, RT_CHANNEL_DOMAIN_FCC
{ { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 36 , 40 , 44 , 48 , 52 , 56 , 60 , 64 , 100 , 104 , 108 , 112 , 116 , 136 , 140 , 149 , 153 , 157 , 161 , 165 } , 31 } , // 0x01, RT_CHANNEL_DOMAIN_IC
{ { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 36 , 40 , 44 , 48 , 52 , 56 , 60 , 64 , 100 , 104 , 108 , 112 , 116 , 120 , 124 , 128 , 132 , 136 , 140 } , 32 } , // 0x02, RT_CHANNEL_DOMAIN_ETSI
{ { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 } , 13 } , // 0x03, RT_CHANNEL_DOMAIN_SPAIN
{ { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 } , 13 } , // 0x04, RT_CHANNEL_DOMAIN_FRANCE
{ { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 } , 13 } , // 0x05, RT_CHANNEL_DOMAIN_MKK
{ { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 } , 13 } , // 0x06, RT_CHANNEL_DOMAIN_MKK1
{ { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 36 , 40 , 44 , 48 , 52 , 56 , 60 , 64 } , 21 } , // 0x07, RT_CHANNEL_DOMAIN_ISRAEL
{ { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 36 , 40 , 44 , 48 , 52 , 56 , 60 , 64 } , 22 } , // 0x08, RT_CHANNEL_DOMAIN_TELEC
{ { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 } , 14 } , // 0x09, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN
{ { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 } , 13 } , // 0x0A, RT_CHANNEL_DOMAIN_WORLD_WIDE_13
{ { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 56 , 60 , 64 , 100 , 104 , 108 , 112 , 116 , 136 , 140 , 149 , 153 , 157 , 161 , 165 } , 26 } , // 0x0B, RT_CHANNEL_DOMAIN_TAIWAN
{ { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 149 , 153 , 157 , 161 , 165 } , 18 } , // 0x0C, RT_CHANNEL_DOMAIN_CHINA
{ { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 36 , 40 , 44 , 48 , 52 , 56 , 60 , 64 , 149 , 153 , 157 , 161 , 165 } , 24 } , // 0x0D, RT_CHANNEL_DOMAIN_SINGAPORE_INDIA_MEXICO
{ { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 36 , 40 , 44 , 48 , 52 , 56 , 60 , 64 , 100 , 104 , 108 , 112 , 116 , 120 , 124 , 149 , 153 , 157 , 161 , 165 } , 31 } , // 0x0E, RT_CHANNEL_DOMAIN_KOREA
{ { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 36 , 40 , 44 , 48 , 52 , 56 , 60 , 64 } , 19 } , // 0x0F, RT_CHANNEL_DOMAIN_TURKEY
{ { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 36 , 40 , 44 , 48 , 52 , 56 , 60 , 64 , 100 , 104 , 108 , 112 , 116 , 120 , 124 , 128 , 132 , 136 , 140 } , 32 } , // 0x10, RT_CHANNEL_DOMAIN_JAPAN
{ { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 36 , 40 , 44 , 48 , 149 , 153 , 157 , 161 , 165 } , 20 } , // 0x11, RT_CHANNEL_DOMAIN_FCC_NO_DFS
{ { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 36 , 40 , 44 , 48 } , 17 } , // 0x12, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS
{ { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 36 , 40 , 44 , 48 , 52 , 56 , 60 , 64 , 100 , 104 , 108 , 112 , 116 , 120 , 124 , 128 , 132 , 136 , 140 , 149 , 153 , 157 , 161 , 165 } , 37 } , // 0x13, RT_CHANNEL_DOMAIN_WORLD_WIDE_5G
{ { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 56 , 60 , 64 , 149 , 153 , 157 , 161 , 165 } , 19 } , // 0x14, RT_CHANNEL_DOMAIN_TAIWAN_NO_DFS
} ; */
static RT_CHANNEL_PLAN_2G RTW_ChannelPlan2G [ RT_CHANNEL_DOMAIN_2G_MAX ] = {
{ { 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
} ;
static RT_CHANNEL_PLAN_5G RTW_ChannelPlan5G [ RT_CHANNEL_DOMAIN_5G_MAX ] = {
{ { } , 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 ] = {
//===== 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
} ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +00:00
//set_opmode_cmd(padapter, infra_client_with_mlme);//removed
2013-05-08 21:45:39 +00:00
set_channel_bwmode ( padapter , pmlmeext - > cur_channel , pmlmeext - > cur_ch_offset , pmlmeext - > cur_bwmode ) ;
2014-12-11 21:15:04 +00:00
2013-05-08 21:45:39 +00:00
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
//unsigned char default_channel_set[MAX_CHANNEL_NUM] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0};
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 ) ;
pmlmeext - > mgnt_seq = 0 ; //reset to zero when disconnect at client mode
# ifdef CONFIG_IEEE80211W
pmlmeext - > sa_query_seq = 0 ;
pmlmeext - > mgnt_80211w_IPN = 0 ;
pmlmeext - > mgnt_80211w_IPN_rx = 0 ;
# 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 20:50:04 +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);
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 ;
_rtw_memset ( pmlmeinfo - > chg_txt , 0 , 128 ) ;
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
2014-12-11 21:15:04 +00:00
_rtw_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 ] ;
2014-12-11 21:15:04 +00:00
if ( ( RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN = = ChannelPlan ) | | //Channel 1~11 is active, and 12~14 is passive
( 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 | |
RT_CHANNEL_DOMAIN_2G_WORLD = = Index2G ) // channel 12~13, passive scan
{
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 )
{
if ( RT_CHANNEL_DOMAIN_WORLD_WIDE_5G = = ChannelPlan ) //passive scan for all 5G channels
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 ] ;
if ( RT_CHANNEL_DOMAIN_WORLD_WIDE_5G = = ChannelPlan ) //passive scan for all 5G channels
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 ) ;
2014-12-11 21:15:04 +00:00
// We don't need to memset padapter->XXX to zero, because adapter is allocated by rtw_zvmalloc().
//_rtw_memset((u8 *)pmlmeext, 0, sizeof(struct mlme_ext_priv));
2013-05-08 21:45:39 +00:00
pmlmeext - > padapter = padapter ;
2014-12-11 21:15:04 +00:00
//fill_fwpriv(padapter, &(pmlmeext->fwpriv));
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-11 21:15:04 +00:00
2014-12-19 06:59:46 +00:00
# ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
2014-12-29 02:13:24 +00:00
pmlmeext - > active_keep_alive_check = true ;
2014-12-11 21:15:04 +00:00
# endif
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
2013-05-08 21:45:39 +00:00
}
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 ) ;
2014-12-11 21:15:04 +00:00
//_cancel_timer_ex(&pmlmeext->ADDBA_timer);
}
}
2014-12-17 23:13:53 +00:00
static u8 cmp_pkt_chnl_diff ( struct adapter * padapter , u8 * pframe , uint packet_len )
2014-12-19 06:59:46 +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 )
{
2014-12-19 06:59:46 +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 ;
2014-12-11 21:15:04 +00:00
# endif //CONFIG_AP_MODE
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 ;
}
2014-12-11 21:15:04 +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 ) {
//category==public (4), action==TDLS_DISCOVERY_RESPONSE
if ( * ( pframe + 24 ) = = 0x04 & & * ( pframe + 25 ) = = TDLS_DISCOVERY_RESPONSE ) {
DBG_871X ( " recv tdls discovery response frame \n " ) ;
On_TDLS_Dis_Rsp ( padapter , precv_frame ) ;
}
}
# endif //CONFIG_TDLS
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 ) )
{
//RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("drop due to decache!\n"));
//return;
}
# 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 ;
//pass through
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 :
2014-12-29 02:13:24 +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
# ifdef CONFIG_IOCTL_CFG80211
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
# endif //CONFIG_IOCTL_CFG80211
if ( padapter - > wdinfo . driver_interface = = DRIVER_WEXT )
{
// do nothing if the device name is empty
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 ;
}
2014-12-11 21:15:04 +00:00
# endif //CONFIG_P2P
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_ATMEL_RC_PATCH
u8 * target_ie = NULL , * wps_ie = NULL ;
u8 * start ;
uint search_len = 0 , wps_ielen = 0 , target_ielen = 0 ;
struct sta_info * psta ;
struct sta_priv * pstapriv = & padapter - > stapriv ;
# 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
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 )
)
{
// 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
// 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
# ifdef CONFIG_WIFI_TEST
if ( pattrib - > mcs_rate < = 3 )
{
wifi_test_chk_rate = 0 ;
}
# 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 ) )
{
# ifndef CONFIG_IOCTL_CFG80211
// FIXME
2013-05-08 21:45:39 +00:00
report_survey_event ( padapter , precv_frame ) ;
2014-12-19 06:59:46 +00:00
# endif
2014-12-11 21:15:04 +00:00
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 :
2014-12-11 21:15:04 +00:00
# endif //CONFIG_P2P
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
2014-12-11 21:15:04 +00:00
//DBG_871X("+OnProbeReq\n");
# ifdef CONFIG_ATMEL_RC_PATCH
if ( ( wps_ie = rtw_get_wps_ie (
pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_ ,
len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_ ,
NULL , & wps_ielen ) ) ) {
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
target_ie = rtw_get_wps_attr_content ( wps_ie , wps_ielen , WPS_ATTR_MANUFACTURER , NULL , & target_ielen ) ;
}
2014-12-29 02:13:24 +00:00
if ( ( target_ie & & ( target_ielen = = 4 ) ) & & ( true = = _rtw_memcmp ( ( void * ) target_ie , " Ozmo " , 4 ) ) ) {
2014-12-11 21:15:04 +00:00
//psta->flag_atmel_rc = 1;
unsigned char * sa_addr = get_sa ( pframe ) ;
DBG_871X ( " %s: Find Ozmo RC -- %02x:%02x:%02x:%02x:%02x:%02x \n \n " ,
__func__ , * sa_addr , * ( sa_addr + 1 ) , * ( sa_addr + 2 ) , * ( sa_addr + 3 ) , * ( sa_addr + 4 ) , * ( sa_addr + 5 ) ) ;
2015-02-19 20:50:04 +00:00
memcpy ( pstapriv - > atmel_rc_pattern , get_sa ( pframe ) , ETH_ALEN ) ;
2014-12-11 21:15:04 +00:00
}
# endif
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_ ) ;
2014-12-11 21:15:04 +00:00
2014-12-19 06:59:46 +00:00
//check (wildcard) SSID
2014-12-11 21:15:04 +00:00
if ( p ! = NULL )
{
2014-12-29 02:13:24 +00:00
if ( is_valid_p2p_probereq = = true )
2014-12-11 21:15:04 +00:00
{
2013-05-08 21:45:39 +00:00
goto _issue_probersp ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
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 ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
_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
{
//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
}
}
}
2014-12-11 21:15:04 +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 )
{
//we should update current network before auth, or some IE is wrong
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
}
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +00:00
//update TSF Value
2013-05-08 21:45:39 +00:00
update_TSF ( pmlmeext , pframe , len ) ;
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +00:00
//Merge from 8712 FW code
2014-12-19 06:59:46 +00:00
if ( cmp_pkt_chnl_diff ( padapter , pframe , len ) ! = 0 )
{ // 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
}
2014-12-11 21:15:04 +00:00
# endif //CONFIG_PATCH_JOIN_WRONG_CHANNEL
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 ;
}
2014-12-11 21:15:04 +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
{
//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
process_csa_ie ( padapter , pframe , len ) ; //channel switch announcement
# endif //CONFIG_DFS
# 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 ) ) ;
2014-12-11 21:15:04 +00:00
# endif //CONFIG_P2P_PS
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 )
{
//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
{
//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
{
//allocate a new CAM entry for IBSS station
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
2014-12-11 21:15:04 +00:00
//get supported rate
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_ ;
}
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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 )
{
// allocate a new one
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
2014-12-11 21:15:04 +00:00
//pstat->flags = 0;
//pstat->capability = 0;
}
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 )
{
//TODO: STA re_auth within expire_to
}
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 ) {
2014-12-19 06:59:46 +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
}
else // shared system or auto authentication
{
if ( seq = = 1 )
{
//prepare for the challenging txt...
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
//get_random_bytes((void *)pstat->chg_txt, 128);//TODO:
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 )
{
//checking for challenging txt...
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 ;
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +00:00
// Now, we are going to issue_auth...
2014-12-19 06:59:46 +00:00
pstat - > auth_seq = seq + 1 ;
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_NATIVEAP_MLME
2013-05-08 21:45:39 +00:00
issue_auth ( padapter , pstat , ( unsigned short ) ( _STATS_SUCCESSFUL_ ) ) ;
# endif
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 ;
_rtw_memset ( ( char * ) pstat , ' \0 ' , sizeof ( stat ) ) ;
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
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_NATIVEAP_MLME
2014-12-19 06:59:46 +00:00
issue_auth ( padapter , pstat , ( unsigned short ) status ) ;
2013-05-08 21:45:39 +00:00
# endif
# 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
2014-12-11 21:15:04 +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 ) ;
if ( status = = 13 ) //&& pmlmeinfo->auth_algo == dot11AuthAlgrthm_Auto)
{
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 ;
2014-12-11 21:15:04 +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 )
{
// 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
{
//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
{
// 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
{
// 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
//pmlmeinfo->state &= ~(WIFI_FW_AUTH_STATE);
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 ;
# endif // CONFIG_WFD
# endif //CONFIG_P2P
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
}
2014-12-11 21:15:04 +00:00
else // WIFI_REASSOCREQ
{
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 ) ;
2014-12-19 06:59:46 +00:00
//capab_info = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
2014-12-11 21:15:04 +00:00
//listen_interval = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN+2));
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
2014-12-11 21:15:04 +00:00
// check if this stat has been successfully authenticated/assocated
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
//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 ;
}
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
{
// 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 ;
2014-12-11 21:15:04 +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 " ) ;
// use our own rate set as statoin used
2015-02-19 20:50:04 +00:00
//memcpy(supportRate, AP_BSSRATE, AP_BSSRATE_LEN);
2014-12-11 21:15:04 +00:00
//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
}
}
2014-12-11 21:15:04 +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
2014-12-19 06:59:46 +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 ) ;
2014-12-11 21:15:04 +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 ;
_rtw_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 )
{
2014-12-19 06:59:46 +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 )
{
2014-12-19 06:59:46 +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 (hapd->conf->wps_state && wpa_ie == NULL) { //todo: to check ap if supporting WPS
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 ;
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
// 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 ;
}
}
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_80211N_HT
2013-05-08 21:45:39 +00:00
/* save HT capabilities in the sta object */
_rtw_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
2014-12-11 21:15:04 +00:00
//status = WLAN_STATUS_CIPHER_REJECTED_PER_POLICY;
//goto OnAssocReqFail;
}
# endif /* CONFIG_80211N_HT */
//
//if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G)//?
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 ;
2014-12-11 21:15:04 +00:00
# endif //CONFIG_P2P
//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
2014-12-11 21:15:04 +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
2014-12-19 06:59:46 +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 ) )
{
# ifdef CONFIG_NATIVEAP_MLME
//.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 ) ;
2014-12-11 21:15:04 +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
# ifdef CONFIG_IOCTL_CFG80211
_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 ) ;
2014-12-11 21:15:04 +00:00
# endif //CONFIG_IOCTL_CFG80211
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +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 ) ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
# endif //CONFIG_NATIVEAP_MLME
2013-05-08 21:45:39 +00:00
}
return _SUCCESS ;
asoc_class2_error :
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_NATIVEAP_MLME
2013-05-08 21:45:39 +00:00
issue_deauth ( padapter , ( void * ) GetAddr2Ptr ( pframe ) , status ) ;
# endif
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
# ifdef CONFIG_NATIVEAP_MLME
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 ) ;
# endif
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 ) ;
2014-12-19 06:59:46 +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
2014-12-11 21:15:04 +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 ) ;
2014-12-11 21:15:04 +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 ;
}
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +00:00
//set slot time
pmlmeinfo - > slotTime = ( pmlmeinfo - > capability & BIT ( 10 ) ) ? 9 : 20 ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
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_ :
if ( _rtw_memcmp ( pIE - > data , WMM_PARA_OUI , 6 ) ) //WMM
{
WMM_param_handler ( padapter , pIE ) ;
}
# if defined(CONFIG_P2P) && defined(CONFIG_WFD)
else if ( _rtw_memcmp ( pIE - > data , WFD_OUI , 4 ) ) //WFD
{
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
case _HT_CAPABILITY_IE_ : //HT caps
HT_caps_handler ( padapter , pIE ) ;
break ;
case _HT_EXTRA_INFO_IE_ : //HT info
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 ;
2014-12-11 21:15:04 +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 ) ;
# endif //CONFIG_P2P
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +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
}
2014-12-11 21:15:04 +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
//_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
2014-12-11 21:15:04 +00:00
//rtw_free_stainfo(padapter, psta);
2014-12-19 06:59:46 +00:00
//_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 ;
2014-12-11 21:15:04 +00:00
// Commented by Albert 20130604
2014-12-19 06:59:46 +00:00
// Before sending the auth frame to start the STA/GC mode connection with AP/GO,
2014-12-11 21:15:04 +00:00
// 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.
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 ) {
// TODO: 802.11r
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 ) ;
# endif //CONFIG_P2P
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +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
}
2014-12-11 21:15:04 +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
//_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
2014-12-11 21:15:04 +00:00
//rtw_free_stainfo(padapter, psta);
2014-12-19 06:59:46 +00:00
//_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 ;
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_80211N_HT
2014-12-19 06:59:46 +00:00
//check RA matches or not
2014-12-11 21:15:04 +00:00
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
/*
//check A1 matches or not
if ( ! _rtw_memcmp ( myid ( & ( padapter - > eeprompriv ) ) , get_da ( pframe ) , ETH_ALEN ) )
return _SUCCESS ;
*/
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 ] ;
2014-12-11 21:15:04 +00:00
if ( category = = RTW_WLAN_CATEGORY_BACK ) // representing Block Ack
{
# 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
{
//do nothing; just don't want to return _SUCCESS;
}
else
# 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 )
{
case RTW_WLAN_ACTION_ADDBA_REQ : //ADDBA request
2015-02-19 20:50:04 +00:00
memcpy ( & ( pmlmeinfo - > ADDBA_req ) , & ( frame_body [ 2 ] ) , sizeof ( struct ADDBA_request ) ) ;
2014-12-11 21:15:04 +00:00
//process_addba_req(padapter, (u8*)&(pmlmeinfo->ADDBA_req), GetAddr3Ptr(pframe));
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 ,
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 ;
case RTW_WLAN_ACTION_ADDBA_RESP : //ADDBA response
//status = frame_body[3] | (frame_body[4] << 8); //endian issue
status = RTW_GET_LE16 ( & frame_body [ 3 ] ) ;
tid = ( ( frame_body [ 5 ] > > 2 ) & 0x7 ) ;
if ( status = = 0 )
2014-12-19 06:59:46 +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
}
//DBG_871X("marc: ADDBA RSP: %x\n", pmlmeinfo->agg_enable_bitmap);
break ;
case RTW_WLAN_ACTION_DELBA : //DELBA
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
2014-12-11 21:15:04 +00:00
//reason_code = frame_body[4] | (frame_body[5] << 8);
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 ) ;
//todo: how to notify the host while receiving DELETE BA
break ;
default :
break ;
2013-05-08 21:45:39 +00:00
}
}
2014-12-11 21:15:04 +00:00
# endif //CONFIG_80211N_HT
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 ) )
{
// Just include the channel 36, 40, 44, 48 channels for 5G low
( * p5gl_cnt ) + + ;
}
else if ( ( pmlmeext - > channel_set [ i ] . ChannelNum > = 149 ) & & ( pmlmeext - > channel_set [ i ] . ChannelNum < = 161 ) )
{
// Just include the channel 149, 153, 157, 161 channels for 5G high
( * 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 ;
2014-12-19 06:59:46 +00:00
# endif //CONFIG_WFD
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__ ) ;
//update attribute
2013-05-08 21:45:39 +00:00
pattrib = & pmgntframe - > attrib ;
update_mgntframe_attrib ( padapter , pattrib ) ;
_rtw_memset ( pmgntframe - > buf_addr , 0 , WLANHDR_OFFSET + TXDESC_OFFSET ) ;
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 ) ) ;
2014-12-11 21:15:04 +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
// WPS Section
2013-05-08 21:45:39 +00:00
wpsielen = 0 ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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
// 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 ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +00:00
// P2P IE Section.
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +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 ;
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:
p2pie [ p2pielen + + ] = P2P_ATTR_CAPABILITY ;
// 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 ;
2014-12-11 21:15:04 +00:00
// Value:
// Device Capability Bitmap, 1 byte
p2pie [ p2pielen + + ] = DMP_P2P_DEVCAP_SUPPORT ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
// Group Capability Bitmap, 1 byte
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
2014-12-11 21:15:04 +00:00
// Group Owner Intent
// Type:
p2pie [ p2pielen + + ] = P2P_ATTR_GO_INTENT ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +00:00
// Value:
// Todo the tie breaker bit.
p2pie [ p2pielen + + ] = ( ( pwdinfo - > intent < < 1 ) | BIT ( 0 ) ) ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
// Configuration Timeout
// Type:
p2pie [ p2pielen + + ] = P2P_ATTR_CONF_TIMEOUT ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +00:00
// Listen Channel
// Type:
p2pie [ p2pielen + + ] = P2P_ATTR_LISTEN_CH ;
2013-05-19 04:28:07 +00:00
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +00:00
// Value:
// Country String
p2pie [ p2pielen + + ] = ' X ' ;
p2pie [ p2pielen + + ] = ' X ' ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
// The third byte should be set to 0x04.
// Described in the "Operating Channel Attribute" section.
p2pie [ p2pielen + + ] = 0x04 ;
// Operating Class
p2pie [ p2pielen + + ] = 0x51 ; // Copy from SD7
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +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
// Extended Listen Timing ATTR
// Type:
p2pie [ p2pielen + + ] = P2P_ATTR_EX_LISTEN_TIMING ;
// 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 ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +00:00
// Intended P2P Interface Address
// Type:
p2pie [ p2pielen + + ] = P2P_ATTR_INTENTED_IF_ADDR ;
// 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 ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +00:00
// Channel List
// Type:
p2pie [ p2pielen + + ] = P2P_ATTR_CH_LIST ;
// 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 ;
2014-12-11 21:15:04 +00:00
// Value:
// Country String
p2pie [ p2pielen + + ] = ' X ' ;
p2pie [ p2pielen + + ] = ' X ' ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
// The third byte should be set to 0x04.
// Described in the "Operating Channel Attribute" section.
p2pie [ p2pielen + + ] = 0x04 ;
2013-05-19 04:28:07 +00:00
2014-12-11 21:15:04 +00:00
// Channel Entry List
{
int i , j ;
2013-05-08 21:45:39 +00:00
for ( j = 0 ; j < pmlmeext - > channel_list . reg_classes ; j + + ) {
2014-12-11 21:15:04 +00:00
// Operating Class
2013-05-08 21:45:39 +00:00
p2pie [ p2pielen + + ] = pmlmeext - > channel_list . reg_class [ j ] . reg_class ;
2014-12-11 21:15:04 +00:00
// Number of Channels
2013-05-08 21:45:39 +00:00
p2pie [ p2pielen + + ] = pmlmeext - > channel_list . reg_class [ j ] . channels ;
2014-12-11 21:15:04 +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-11 21:15:04 +00:00
// Device Info
// Type:
p2pie [ p2pielen + + ] = P2P_ATTR_DEVICE_INFO ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
// Length:
2014-12-19 06:59:46 +00:00
// 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
2014-12-11 21:15:04 +00:00
// + 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-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +00:00
// Number of Secondary Device Types
p2pie [ p2pielen + + ] = 0x00 ; // No Secondary Device Type List
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +00:00
// Operating Channel
// Type:
p2pie [ p2pielen + + ] = P2P_ATTR_OPERATING_CH ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +00:00
// Value:
// Country String
p2pie [ p2pielen + + ] = ' X ' ;
p2pie [ p2pielen + + ] = ' X ' ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
// The third byte should be set to 0x04.
// Described in the "Operating Channel Attribute" section.
p2pie [ p2pielen + + ] = 0x04 ;
// Operating Class
if ( pwdinfo - > operating_channel < = 14 )
{
// Operating Class
p2pie [ p2pielen + + ] = 0x51 ;
}
else if ( ( pwdinfo - > operating_channel > = 36 ) & & ( pwdinfo - > operating_channel < = 48 ) )
{
// Operating Class
p2pie [ p2pielen + + ] = 0x73 ;
}
else
{
// Operating Class
p2pie [ p2pielen + + ] = 0x7c ;
}
2013-08-01 02:12:42 +00:00
2014-12-11 21:15:04 +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 ;
# 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 ;
# endif //CONFIG_WFD
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 ) ;
//update attribute
2013-05-08 21:45:39 +00:00
pattrib = & pmgntframe - > attrib ;
update_mgntframe_attrib ( padapter , pattrib ) ;
_rtw_memset ( pmgntframe - > buf_addr , 0 , WLANHDR_OFFSET + TXDESC_OFFSET ) ;
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 ) ) ;
2014-12-11 21:15:04 +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 ) ) ;
2014-12-11 21:15:04 +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
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
2014-12-11 21:15:04 +00:00
_rtw_memset ( wpsie , 0x00 , 255 ) ;
2013-05-08 21:45:39 +00:00
wpsielen = 0 ;
2014-12-11 21:15:04 +00:00
// WPS Section
2013-05-08 21:45:39 +00:00
wpsielen = 0 ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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
// 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 ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +00:00
// Value:
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 ;
2014-12-11 21:15:04 +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.
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
2014-12-11 21:15:04 +00:00
// P2P IE Section.
// 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 ;
p2pie [ p2pielen + + ] = 0x09 ; // WFA P2P v1.0
// 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 )
// ToDo:
// P2P Status
// Type:
p2pie [ p2pielen + + ] = P2P_ATTR_STATUS ;
// 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 ;
2014-12-11 21:15:04 +00:00
// Value:
p2pie [ p2pielen + + ] = result ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
// P2P Capability
// Type:
p2pie [ p2pielen + + ] = P2P_ATTR_CAPABILITY ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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 ) )
{
// 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
p2pie [ p2pielen + + ] = 0 ;
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
else
{
// Be group owner or meet the error case
p2pie [ p2pielen + + ] = DMP_P2P_DEVCAP_SUPPORT ;
}
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
// Group Capability Bitmap, 1 byte
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
}
2014-12-11 21:15:04 +00:00
// Group Owner Intent
// Type:
p2pie [ p2pielen + + ] = P2P_ATTR_GO_INTENT ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +00:00
// Value:
if ( pwdinfo - > peer_intent & 0x01 )
{
// Peer's tie breaker bit is 1, our tie breaker bit should be 0
p2pie [ p2pielen + + ] = ( pwdinfo - > intent < < 1 ) ;
}
else
{
// Peer's tie breaker bit is 0, our tie breaker bit should be 1
p2pie [ p2pielen + + ] = ( ( pwdinfo - > intent < < 1 ) | BIT ( 0 ) ) ;
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
// Configuration Timeout
// Type:
p2pie [ p2pielen + + ] = P2P_ATTR_CONF_TIMEOUT ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +00:00
// Operating Channel
// Type:
p2pie [ p2pielen + + ] = P2P_ATTR_OPERATING_CH ;
2013-08-01 02:12:42 +00:00
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +00:00
// Value:
// Country String
p2pie [ p2pielen + + ] = ' X ' ;
p2pie [ p2pielen + + ] = ' X ' ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
// The third byte should be set to 0x04.
// Described in the "Operating Channel Attribute" section.
p2pie [ p2pielen + + ] = 0x04 ;
// Operating Class
if ( pwdinfo - > operating_channel < = 14 )
{
// Operating Class
p2pie [ p2pielen + + ] = 0x51 ;
}
else if ( ( pwdinfo - > operating_channel > = 36 ) & & ( pwdinfo - > operating_channel < = 48 ) )
{
// Operating Class
p2pie [ p2pielen + + ] = 0x73 ;
}
else
{
// Operating Class
p2pie [ p2pielen + + ] = 0x7c ;
}
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +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
// Intended P2P Interface Address
2014-12-11 21:15:04 +00:00
// Type:
p2pie [ p2pielen + + ] = P2P_ATTR_INTENTED_IF_ADDR ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +00:00
// Channel List
// Type:
p2pie [ p2pielen + + ] = P2P_ATTR_CH_LIST ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +00:00
// Value:
// Country String
p2pie [ p2pielen + + ] = ' X ' ;
p2pie [ p2pielen + + ] = ' X ' ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
// The third byte should be set to 0x04.
// Described in the "Operating Channel Attribute" section.
p2pie [ p2pielen + + ] = 0x04 ;
// Channel Entry List
{
int i , j ;
for ( j = 0 ; j < pmlmeext - > channel_list . reg_classes ; j + + ) {
// Operating Class
p2pie [ p2pielen + + ] = pmlmeext - > channel_list . reg_class [ j ] . reg_class ;
2013-05-19 04:28:07 +00:00
2014-12-11 21:15:04 +00:00
// Number of Channels
p2pie [ p2pielen + + ] = pmlmeext - > channel_list . reg_class [ j ] . channels ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
// Channel List
for ( i = 0 ; i < pmlmeext - > channel_list . reg_class [ j ] . channels ; i + + ) {
p2pie [ p2pielen + + ] = pmlmeext - > channel_list . reg_class [ j ] . channel [ i ] ;
}
}
}
// Device Info
// Type:
p2pie [ p2pielen + + ] = P2P_ATTR_DEVICE_INFO ;
// Length:
2014-12-19 06:59:46 +00:00
// 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
2014-12-11 21:15:04 +00:00
// + 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 ;
// 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 ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +00:00
// Number of Secondary Device Types
p2pie [ p2pielen + + ] = 0x00 ; // No Secondary Device Type List
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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 ) )
{
// Group ID Attribute
// Type:
p2pie [ p2pielen + + ] = P2P_ATTR_GROUP_ID ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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 ;
# 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 ;
# 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__ ) ;
//update attribute
2013-05-08 21:45:39 +00:00
pattrib = & pmgntframe - > attrib ;
update_mgntframe_attrib ( padapter , pattrib ) ;
_rtw_memset ( pmgntframe - > buf_addr , 0 , WLANHDR_OFFSET + TXDESC_OFFSET ) ;
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
// P2P IE Section.
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +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 ;
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:
p2pie [ p2pielen + + ] = P2P_ATTR_STATUS ;
// 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 ;
2014-12-11 21:15:04 +00:00
// Value:
p2pie [ p2pielen + + ] = result ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
// P2P Capability
// Type:
p2pie [ p2pielen + + ] = P2P_ATTR_CAPABILITY ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +00:00
// Value:
// Device Capability Bitmap, 1 byte
p2pie [ p2pielen + + ] = DMP_P2P_DEVCAP_SUPPORT ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
// Group Capability Bitmap, 1 byte
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
2014-12-11 21:15:04 +00:00
// Operating Channel
// Type:
p2pie [ p2pielen + + ] = P2P_ATTR_OPERATING_CH ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +00:00
// Value:
// Country String
p2pie [ p2pielen + + ] = ' X ' ;
p2pie [ p2pielen + + ] = ' X ' ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
// The third byte should be set to 0x04.
// Described in the "Operating Channel Attribute" section.
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 )
{
// Operating Class
p2pie [ p2pielen + + ] = 0x51 ;
}
else if ( ( pwdinfo - > peer_operating_ch > = 36 ) & & ( pwdinfo - > peer_operating_ch < = 48 ) )
{
// Operating Class
p2pie [ p2pielen + + ] = 0x73 ;
}
else
{
// Operating Class
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 )
{
// Operating Class
p2pie [ p2pielen + + ] = 0x51 ;
}
else if ( ( pwdinfo - > operating_channel > = 36 ) & & ( pwdinfo - > operating_channel < = 48 ) )
{
// Operating Class
p2pie [ p2pielen + + ] = 0x73 ;
}
else
{
// Operating Class
p2pie [ p2pielen + + ] = 0x7c ;
}
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +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
}
2014-12-11 21:15:04 +00:00
// Channel List
// Type:
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 ;
2014-12-11 21:15:04 +00:00
// Country String
p2pie [ p2pielen + + ] = ' X ' ;
p2pie [ p2pielen + + ] = ' X ' ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
// The third byte should be set to 0x04.
// Described in the "Operating Channel Attribute" section.
p2pie [ p2pielen + + ] = 0x04 ;
// Value:
if ( rtw_p2p_chk_role ( pwdinfo , P2P_ROLE_CLIENT ) )
{
if ( pwdinfo - > peer_operating_ch < = 14 )
{
// Operating Class
p2pie [ p2pielen + + ] = 0x51 ;
}
else if ( ( pwdinfo - > peer_operating_ch > = 36 ) & & ( pwdinfo - > peer_operating_ch < = 48 ) )
{
// Operating Class
p2pie [ p2pielen + + ] = 0x73 ;
}
else
{
// Operating Class
p2pie [ p2pielen + + ] = 0x7c ;
}
p2pie [ p2pielen + + ] = 1 ;
p2pie [ p2pielen + + ] = pwdinfo - > peer_operating_ch ;
}
else
{
if ( pwdinfo - > operating_channel < = 14 )
{
// Operating Class
p2pie [ p2pielen + + ] = 0x51 ;
}
else if ( ( pwdinfo - > operating_channel > = 36 ) & & ( pwdinfo - > operating_channel < = 48 ) )
{
// Operating Class
p2pie [ p2pielen + + ] = 0x73 ;
}
else
{
// Operating Class
p2pie [ p2pielen + + ] = 0x7c ;
}
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
// Channel Number
p2pie [ p2pielen + + ] = 1 ;
p2pie [ p2pielen + + ] = pwdinfo - > operating_channel ; // Use the listen channel as the operating channel
}
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 ) )
{
// Group ID Attribute
// Type:
p2pie [ p2pielen + + ] = P2P_ATTR_GROUP_ID ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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 ;
# endif //CONFIG_WFD
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 ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +00:00
//update attribute
2013-05-08 21:45:39 +00:00
pattrib = & pmgntframe - > attrib ;
update_mgntframe_attrib ( padapter , pattrib ) ;
_rtw_memset ( pmgntframe - > buf_addr , 0 , WLANHDR_OFFSET + TXDESC_OFFSET ) ;
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 ) ) ;
2014-12-11 21:15:04 +00:00
// P2P IE Section.
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +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 ;
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:
p2pie [ p2pielen + + ] = P2P_ATTR_CONF_TIMEOUT ;
// 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 ;
2014-12-11 21:15:04 +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
// Invitation Flags
// Type:
p2pie [ p2pielen + + ] = P2P_ATTR_INVITATION_FLAGS ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +00:00
// Value:
p2pie [ p2pielen + + ] = P2P_INVITATION_FLAGS_PERSISTENT ;
2013-05-08 21:45:39 +00:00
2013-05-19 04:28:07 +00:00
2014-12-11 21:15:04 +00:00
// Operating Channel
// Type:
p2pie [ p2pielen + + ] = P2P_ATTR_OPERATING_CH ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +00:00
// Value:
// Country String
p2pie [ p2pielen + + ] = ' X ' ;
p2pie [ p2pielen + + ] = ' X ' ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
// The third byte should be set to 0x04.
// Described in the "Operating Channel Attribute" section.
p2pie [ p2pielen + + ] = 0x04 ;
// Operating Class
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
2014-12-11 21:15:04 +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 ) )
{
// P2P Group BSSID
// Type:
p2pie [ p2pielen + + ] = P2P_ATTR_GROUP_BSSID ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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 ;
}
2014-12-11 21:15:04 +00:00
// Channel List
// Type:
p2pie [ p2pielen + + ] = P2P_ATTR_CH_LIST ;
2013-05-08 21:45:39 +00:00
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +00:00
// Value:
// Country String
p2pie [ p2pielen + + ] = ' X ' ;
p2pie [ p2pielen + + ] = ' X ' ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
// The third byte should be set to 0x04.
// Described in the "Operating Channel Attribute" section.
p2pie [ p2pielen + + ] = 0x04 ;
// Channel Entry List
{
int i , j ;
for ( j = 0 ; j < pmlmeext - > channel_list . reg_classes ; j + + ) {
// Operating Class
p2pie [ p2pielen + + ] = pmlmeext - > channel_list . reg_class [ j ] . reg_class ;
2013-05-19 04:28:07 +00:00
2014-12-11 21:15:04 +00:00
// Number of Channels
p2pie [ p2pielen + + ] = pmlmeext - > channel_list . reg_class [ j ] . channels ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
// Channel List
for ( i = 0 ; i < pmlmeext - > channel_list . reg_class [ j ] . channels ; i + + ) {
p2pie [ p2pielen + + ] = pmlmeext - > channel_list . reg_class [ j ] . channel [ i ] ;
}
}
}
// P2P Group ID
// Type:
p2pie [ p2pielen + + ] = P2P_ATTR_GROUP_ID ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +00:00
// Device Info
// Type:
p2pie [ p2pielen + + ] = P2P_ATTR_DEVICE_INFO ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
// Length:
2014-12-19 06:59:46 +00:00
// 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
2014-12-11 21:15:04 +00:00
// + 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
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +00:00
// Number of Secondary Device Types
p2pie [ p2pielen + + ] = 0x00 ; // No Secondary Device Type List
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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 ;
2014-12-19 06:59:46 +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 ;
# 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
2014-12-11 21:15:04 +00:00
//update attribute
2013-05-08 21:45:39 +00:00
pattrib = & pmgntframe - > attrib ;
update_mgntframe_attrib ( padapter , pattrib ) ;
_rtw_memset ( pmgntframe - > buf_addr , 0 , WLANHDR_OFFSET + TXDESC_OFFSET ) ;
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 ) ) ;
2014-12-11 21:15:04 +00:00
// P2P IE Section.
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +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 ;
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:
p2pie [ p2pielen + + ] = P2P_ATTR_STATUS ;
// 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 ;
2014-12-11 21:15:04 +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.
p2pie [ p2pielen + + ] = status_code ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
// Configuration Timeout
// Type:
p2pie [ p2pielen + + ] = P2P_ATTR_CONF_TIMEOUT ;
// 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 ;
2014-12-11 21:15:04 +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 ) )
{
// 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
2014-12-11 21:15:04 +00:00
// Operating Channel
// Type:
p2pie [ p2pielen + + ] = P2P_ATTR_OPERATING_CH ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +00:00
// Value:
// Country String
p2pie [ p2pielen + + ] = ' X ' ;
p2pie [ p2pielen + + ] = ' X ' ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
// The third byte should be set to 0x04.
// Described in the "Operating Channel Attribute" section.
p2pie [ p2pielen + + ] = 0x04 ;
// Operating Class
p2pie [ p2pielen + + ] = 0x51 ; // Copy from SD7
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +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
// P2P Group BSSID
// Type:
p2pie [ p2pielen + + ] = P2P_ATTR_GROUP_BSSID ;
// 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 ;
2014-12-11 21:15:04 +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
}
2014-12-11 21:15:04 +00:00
// Channel List
// Type:
p2pie [ p2pielen + + ] = P2P_ATTR_CH_LIST ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +00:00
// Value:
// Country String
p2pie [ p2pielen + + ] = ' X ' ;
p2pie [ p2pielen + + ] = ' X ' ;
// The third byte should be set to 0x04.
// Described in the "Operating Channel Attribute" section.
p2pie [ p2pielen + + ] = 0x04 ;
// Channel Entry List
2013-05-08 21:45:39 +00:00
{
int i , j ;
for ( j = 0 ; j < pmlmeext - > channel_list . reg_classes ; j + + ) {
2014-12-11 21:15:04 +00:00
// Operating Class
2013-05-08 21:45:39 +00:00
p2pie [ p2pielen + + ] = pmlmeext - > channel_list . reg_class [ j ] . reg_class ;
2014-12-11 21:15:04 +00:00
// Number of Channels
2013-05-08 21:45:39 +00:00
p2pie [ p2pielen + + ] = pmlmeext - > channel_list . reg_class [ j ] . channels ;
2014-12-11 21:15:04 +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 ;
# 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 ;
2014-12-19 06:59:46 +00:00
# endif //CONFIG_WFD
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__ ) ;
//update attribute
2013-05-08 21:45:39 +00:00
pattrib = & pmgntframe - > attrib ;
update_mgntframe_attrib ( padapter , pattrib ) ;
_rtw_memset ( pmgntframe - > buf_addr , 0 , WLANHDR_OFFSET + TXDESC_OFFSET ) ;
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 ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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
// 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 ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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 ;
# 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 ) ;
2014-12-19 06:59:46 +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 ;
# endif //CONFIG_WFD
# ifdef CONFIG_INTEL_WIDI
u8 zero_array_check [ L2SDTA_SERVICE_VE_LEN ] = { 0x00 } ;
# endif //CONFIG_INTEL_WIDI
//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
2014-12-11 21:15:04 +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 ) ;
2013-05-08 21:45:39 +00:00
_rtw_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
// 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 ;
2014-12-11 21:15:04 +00:00
//timestamp will be inserted by hardware
2013-05-08 21:45:39 +00:00
pframe + = 8 ;
pattrib - > pktlen + = 8 ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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
// SSID
2013-05-08 21:45:39 +00:00
pframe = rtw_set_ie ( pframe , _SSID_IE_ , 7 , pwdinfo - > p2p_wildcard_ssid , & pattrib - > pktlen ) ;
2014-12-11 21:15:04 +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 ) ;
2014-12-11 21:15:04 +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
# ifdef CONFIG_IOCTL_CFG80211
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 )
{
//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 ;
//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 ;
}
}
else
2014-12-19 06:59:46 +00:00
# endif //CONFIG_IOCTL_CFG80211
2014-12-11 21:15:04 +00:00
{
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +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 ;
// 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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
// 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 )
{
//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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
{
// 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 ;
}
}
# endif //CONFIG_INTEL_WIDI
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +00:00
// Value:
wpsie [ wpsielen + + ] = WPS_WSC_STATE_NOT_CONFIG ; // Not Configured.
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +00:00
// Value:
wpsie [ wpsielen + + ] = WPS_RESPONSE_TYPE_8021X ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +00:00
// Value:
if ( pwdinfo - > external_uuid = = 0 ) {
_rtw_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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +00:00
// Value:
wpsie [ wpsielen + + ] = 0x31 ; // character 1
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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 ;
// 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 ;
// Value:
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 ;
}
// 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 ;
// 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 ;
// 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
# ifdef CONFIG_IOCTL_CFG80211
2014-12-29 02:13:24 +00:00
if ( true = = pwdinfo - > wfd_info - > wfd_enable )
2014-12-11 21:15:04 +00:00
# endif //CONFIG_IOCTL_CFG80211
{
wfdielen = build_probe_resp_wfd_ie ( pwdinfo , pframe , 0 ) ;
pframe + = wfdielen ;
pattrib - > pktlen + = wfdielen ;
}
# ifdef CONFIG_IOCTL_CFG80211
else if ( pmlmepriv - > wfd_probe_resp_ie ! = NULL & & pmlmepriv - > wfd_probe_resp_ie_len > 0 )
{
//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
}
# endif //CONFIG_IOCTL_CFG80211
2014-12-19 06:59:46 +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 ;
# 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
2014-12-11 21:15:04 +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
2013-05-08 21:45:39 +00:00
_rtw_memset ( pmgntframe - > buf_addr , 0 , WLANHDR_OFFSET + TXDESC_OFFSET ) ;
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 ) )
{
// 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
{
// 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
}
// 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
# ifdef CONFIG_IOCTL_CFG80211
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 )
{
//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 ;
//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 ;
}
}
else
# endif //CONFIG_IOCTL_CFG80211
{
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +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 ;
// 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
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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 )
{
// 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 ;
// 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 ;
// Value:
if ( pwdinfo - > external_uuid = = 0 ) {
_rtw_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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +00:00
// Value:
2014-12-19 04:28:04 +00:00
* ( __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
2014-12-11 21:15:04 +00:00
// P2P OUI
p2pielen = 0 ;
p2pie [ p2pielen + + ] = 0x50 ;
p2pie [ p2pielen + + ] = 0x6F ;
p2pie [ p2pielen + + ] = 0x9A ;
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:
p2pie [ p2pielen + + ] = P2P_ATTR_CAPABILITY ;
// 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
2014-12-11 21:15:04 +00:00
// Value:
// Device Capability Bitmap, 1 byte
p2pie [ p2pielen + + ] = DMP_P2P_DEVCAP_SUPPORT ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
// Group Capability Bitmap, 1 byte
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
2014-12-11 21:15:04 +00:00
// Listen Channel
// Type:
p2pie [ p2pielen + + ] = P2P_ATTR_LISTEN_CH ;
2013-07-20 18:18:13 +00:00
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +00:00
// Value:
// Country String
p2pie [ p2pielen + + ] = ' X ' ;
p2pie [ p2pielen + + ] = ' X ' ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
// The third byte should be set to 0x04.
// Described in the "Operating Channel Attribute" section.
p2pie [ p2pielen + + ] = 0x04 ;
// Operating Class
p2pie [ p2pielen + + ] = 0x51 ; // Copy from SD7
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +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
// Extended Listen Timing
// Type:
p2pie [ p2pielen + + ] = P2P_ATTR_EX_LISTEN_TIMING ;
// 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
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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 ) )
{
// Operating Channel (if this WiFi is working as the group owner now)
// Type:
p2pie [ p2pielen + + ] = P2P_ATTR_OPERATING_CH ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +00:00
// Value:
// Country String
p2pie [ p2pielen + + ] = ' X ' ;
p2pie [ p2pielen + + ] = ' X ' ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
// The third byte should be set to 0x04.
// Described in the "Operating Channel Attribute" section.
p2pie [ p2pielen + + ] = 0x04 ;
// Operating Class
p2pie [ p2pielen + + ] = 0x51 ; // Copy from SD7
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
// Channel Number
p2pie [ p2pielen + + ] = pwdinfo - > operating_channel ; // operating channel number
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 )
{
//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
# ifdef CONFIG_IOCTL_CFG80211
2014-12-29 02:13:24 +00:00
if ( true = = pwdinfo - > wfd_info - > wfd_enable )
2014-12-11 21:15:04 +00:00
# endif
{
wfdielen = build_probe_req_wfd_ie ( pwdinfo , pframe ) ;
pframe + = wfdielen ;
pattrib - > pktlen + = wfdielen ;
}
# ifdef CONFIG_IOCTL_CFG80211
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
{
//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
}
2014-12-11 21:15:04 +00:00
# endif //CONFIG_IOCTL_CFG80211
# 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 ;
}
2014-12-11 21:15:04 +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 ;
# 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 ) ;
# ifdef CONFIG_IOCTL_CFG80211
if ( wdev_to_priv ( padapter - > rtw_wdev ) - > p2p_enabled & & pwdinfo - > driver_interface = = DRIVER_CFG80211 )
{
rtw_cfg80211_rx_p2p_action_public ( padapter , pframe , len ) ;
}
else
# endif //CONFIG_IOCTL_CFG80211
{
// Do nothing if the driver doesn't enable the P2P function.
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
2014-12-11 21:15:04 +00:00
switch ( frame_body [ 6 ] ) //OUI Subtype
{
case P2P_GO_NEGO_REQ :
{
DBG_871X ( " [%s] Got GO Nego Req Frame \n " , __FUNCTION__ ) ;
_rtw_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 ) )
{
// Commented by Albert 20110526
// In this case, this means the previous nego fail doesn't be reset yet.
_cancel_timer_ex ( & pwdinfo - > restore_p2p_state_timer ) ;
// Restore the previous p2p state
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 ) ) ;
}
2014-12-11 21:15:04 +00:00
// Commented by Kurt 20110902
//Add if statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered.
if ( ! rtw_p2p_chk_state ( pwdinfo , P2P_STATE_GONEGO_ING ) )
rtw_p2p_set_pre_state ( pwdinfo , rtw_p2p_state ( pwdinfo ) ) ;
// Commented by Kurt 20120113
// Get peer_dev_addr here if peer doesn't issue prov_disc frame.
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 ) ;
}
# endif //CONFIG_INTEL_WIDI
// Commented by Albert 20110718
// No matter negotiating or negotiation failure, the driver should set up the restore P2P state timer.
_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 ) )
{
// Commented by Albert 20110425
// The restore timer is enabled when issuing the nego request frame of rtw_p2p_connect function.
_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
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
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
2014-12-11 21:15:04 +00:00
// Reset the dialog token for group negotiation frames.
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
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
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 :
{
// 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 ) ) )
{
// Parse the necessary information from the P2P Invitation Request frame.
// For example: The MAC address of sending this P2P Invitation Request frame.
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_ ) ;
merged_p2pie = rtw_zmalloc ( merged_p2p_ielen + 2 ) ; // 2 is for EID and Length
if ( merged_p2pie = = NULL )
{
DBG_871X ( " [%s] Malloc p2p ie fail \n " , __FUNCTION__ ) ;
goto exit ;
}
2014-12-19 06:59:46 +00:00
_rtw_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 ) ;
// 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.
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 )
{
// Re-invoke the persistent group.
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
_rtw_memset ( & group_id , 0x00 , sizeof ( struct group_id_info ) ) ;
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 ) )
{
// The p2p device sending this p2p invitation request wants this Wi-Fi device to be the persistent GO.
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
{
// The p2p device sending this p2p invitation request wants to be the persistent GO.
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 ] ) )
{
// The operating channel is acceptable for this device.
pwdinfo - > rx_invitereq_info . operation_ch [ 0 ] = operatingch_info [ 4 ] ;
# ifdef P2P_OP_CHECK_SOCIAL_CH
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
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
{
// The operating channel isn't supported by this device.
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
{
// Commented by Albert 20121130
// Intel will use the different P2P IE to store the operating channel information
// Workaround for Intel WiDi 3.5
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 ) ;
# endif //CONFIG_INTEL_WIDI
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
{
// Received the invitation to join a P2P group.
_rtw_memset ( & group_id , 0x00 , sizeof ( struct group_id_info ) ) ;
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 ) )
{
// In this case, the GO can't be myself.
rtw_p2p_set_state ( pwdinfo , P2P_STATE_RECV_INVITE_REQ_DISMATCH ) ;
status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE ;
}
else
{
// 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 ) ;
}
# endif //CONFIG_INTEL_WIDI
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
//20110902 Kurt
//Add the following statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered.
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 ) ;
}
# endif //CONFIG_INTEL_WIDI
break ;
case P2P_PROVISION_DISC_RESP :
// Commented by Albert 20110707
// Should we check the pwdinfo->tx_prov_disc_info.bsent flag here??
DBG_871X ( " [%s] Got Provisioning Discovery Response Frame \n " , __FUNCTION__ ) ;
// Commented by Albert 20110426
// The restore timer is enabled when issuing the provisioing request frame in rtw_p2p_prov_disc function.
_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
}
2014-12-11 21:15:04 +00:00
# endif //CONFIG_P2P
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
# ifdef CONFIG_IOCTL_CFG80211
cnt + = sprintf ( ( msg + cnt ) , " %s(token:%u) " , action_public_str ( action ) , token ) ;
rtw_cfg80211_rx_action ( adapter , pframe , frame_len , msg ) ;
# endif
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 ;
//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 ] )
{
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 ;
case 1 : //SA Query rsp
_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 ;
}
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
# ifdef CONFIG_IOCTL_CFG80211
if ( wdev_to_priv ( padapter - > rtw_wdev ) - > p2p_enabled & & pwdinfo - > driver_interface = = DRIVER_CFG80211 )
{
rtw_cfg80211_rx_action_p2p ( padapter , pframe , len ) ;
return _SUCCESS ;
}
else
# endif //CONFIG_IOCTL_CFG80211
{
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
}
2014-12-11 21:15:04 +00:00
# endif //CONFIG_P2P
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
//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 ) ;
_rtw_memset ( ( u8 * ) ( pattrib ) , 0 , sizeof ( struct pkt_attrib ) ) ;
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 )
pattrib - > raid = 6 ; //b mode
2013-05-08 21:45:39 +00:00
else
2014-12-11 21:15:04 +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
{
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_XMIT_ACK
2013-05-08 21:45:39 +00:00
s32 ret = _FAIL ;
2014-12-11 21:15:04 +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-11 21:15:04 +00:00
# else //!CONFIG_XMIT_ACK
dump_mgntframe ( padapter , pmgntframe ) ;
rtw_msleep_os ( 50 ) ;
return _SUCCESS ;
2014-12-19 06:59:46 +00:00
# endif //!CONFIG_XMIT_ACK
2013-05-08 21:45:39 +00:00
}
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
//DBG_871X("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n", __FUNCTION__, hidden_ssid_mode, ssid_ie, ssid_len_ori);
2014-12-19 06:59:46 +00:00
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 :
_rtw_memset ( & ssid_ie [ 2 ] , 0 , ssid_len_ori ) ;
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 ) ;
2014-12-11 21:15:04 +00:00
# if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
_irqL irqL ;
2013-05-08 21:45:39 +00:00
struct mlme_priv * pmlmepriv = & ( padapter - > mlmepriv ) ;
2014-12-11 21:15:04 +00:00
# endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
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 ) ;
2014-12-11 21:15:04 +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__);
if ( ( pmgntframe = alloc_mgtxmitframe ( pxmitpriv ) ) = = NULL )
{
DBG_871X ( " %s, alloc mgnt frame fail \n " , __FUNCTION__ ) ;
2013-05-08 21:45:39 +00:00
return ;
}
2014-12-11 21:15:04 +00:00
# if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
_enter_critical_bh ( & pmlmepriv - > bcn_update_lock , & irqL ) ;
# endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +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
2013-05-08 21:45:39 +00:00
_rtw_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*/ ) ;
2014-12-11 21:15:04 +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 )
{
//DBG_871X("ie len=%d\n", cur_network->IELength);
# ifdef CONFIG_P2P
// for P2P : Primary Device Type & Device Name
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
# ifdef CONFIG_IOCTL_CFG80211
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 ;
//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 ;
}
}
else
# endif //CONFIG_IOCTL_CFG80211
{
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 ) ;
//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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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 ;
// 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 ;
// 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 ;
// 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 ;
// 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 ;
// 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 ;
//update wsc ie length
* ( pframe_wscie + 1 ) = ( wpsielen - 2 ) + insert_len ;
//pframe move to end
pframe + = insert_len ;
pattrib - > pktlen + = insert_len ;
//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
# 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
# ifdef CONFIG_IOCTL_CFG80211
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 ) ;
2014-12-11 21:15:04 +00:00
}
else
# endif //CONFIG_IOCTL_CFG80211
{
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
# ifdef CONFIG_IOCTL_CFG80211
2014-12-29 02:13:24 +00:00
if ( true = = pwdinfo - > wfd_info - > wfd_enable )
2014-12-11 21:15:04 +00:00
# endif //CONFIG_IOCTL_CFG80211
{
len = build_beacon_wfd_ie ( pwdinfo , pframe ) ;
}
# ifdef CONFIG_IOCTL_CFG80211
else
2014-12-19 06:59:46 +00:00
{
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
# endif //CONFIG_IOCTL_CFG80211
pframe + = len ;
pattrib - > pktlen + = len ;
# endif //CONFIG_WFD
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +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
}
2014-12-11 21:15:04 +00:00
//below for ad-hoc mode
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
//timestamp will be inserted by hardware
2013-05-08 21:45:39 +00:00
pframe + = 8 ;
pattrib - > pktlen + = 8 ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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 ) ;
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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 ) ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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 ) ;
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +00:00
//todo:HT for adhoc
2013-05-19 04:28:07 +00:00
2014-12-11 21:15:04 +00:00
_issue_bcn :
# if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
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 ) ;
2014-12-11 21:15:04 +00:00
# endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
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 ;
2014-12-11 21:15:04 +00:00
//DBG_871X("issue bcn_sz=%d\n", pattrib->last_txcmdsz);
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 ) ;
2014-12-11 21:15:04 +00:00
# if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
2013-05-08 21:45:39 +00:00
u8 * pwps_ie ;
uint wps_ielen ;
struct mlme_priv * pmlmepriv = & padapter - > mlmepriv ;
2014-12-11 21:15:04 +00:00
# endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
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 ;
# endif //CONFIG_WFD
# endif //CONFIG_P2P
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 mgnt frame fail \n " , __FUNCTION__ ) ;
2013-05-08 21:45:39 +00:00
return ;
}
2013-05-19 04:28:07 +00:00
2014-12-11 21:15:04 +00:00
//update attribute
pattrib = & pmgntframe - > attrib ;
2014-12-19 06:59:46 +00:00
update_mgntframe_attrib ( padapter , pattrib ) ;
2013-05-08 21:45:39 +00:00
_rtw_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
2014-12-11 21:15:04 +00:00
# if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
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
2014-12-11 21:15:04 +00:00
//inerset & update wps_probe_resp_ie
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
2014-12-11 21:15:04 +00:00
wps_ielen = ( uint ) pmlmepriv - > wps_probe_resp_ie [ 1 ] ; //to get ie data len
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
2014-12-11 21:15:04 +00:00
//timestamp will be inserted by hardware
2013-05-08 21:45:39 +00:00
pframe + = 8 ;
pattrib - > pktlen + = 8 ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +00:00
//below for ad-hoc mode
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +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 ) ;
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +00:00
// DS parameter set
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 ;
2014-12-11 21:15:04 +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 ) ;
2014-12-11 21:15:04 +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
// 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
}
//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
# ifdef CONFIG_IOCTL_CFG80211
if ( wdev_to_priv ( padapter - > rtw_wdev ) - > p2p_enabled & & pwdinfo - > driver_interface = = DRIVER_CFG80211 )
{
//if pwdinfo->role == P2P_ROLE_DEVICE will call issue_probersp_p2p()
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 ) ;
2014-12-11 21:15:04 +00:00
}
else
# endif //CONFIG_IOCTL_CFG80211
{
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
# ifdef CONFIG_IOCTL_CFG80211
2014-12-29 02:13:24 +00:00
if ( true = = pwdinfo - > wfd_info - > wfd_enable )
2014-12-11 21:15:04 +00:00
# endif //CONFIG_IOCTL_CFG80211
{
len = build_probe_resp_wfd_ie ( pwdinfo , pframe , 0 ) ;
}
# ifdef CONFIG_IOCTL_CFG80211
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
}
2014-12-19 06:59:46 +00:00
# endif //CONFIG_IOCTL_CFG80211
2014-12-11 21:15:04 +00:00
pframe + = len ;
pattrib - > pktlen + = len ;
# endif //CONFIG_WFD
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
# endif //CONFIG_P2P
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
2014-12-11 21:15:04 +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
2013-05-08 21:45:39 +00:00
_rtw_memset ( pmgntframe - > buf_addr , 0 , WLANHDR_OFFSET + TXDESC_OFFSET ) ;
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 )
{
// 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
{
// 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 ) ) ;
}
2014-12-11 21:15:04 +00:00
//add wps_ie for wps2.0
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
//pmlmepriv->wps_probe_req_ie_len = 0 ;//reset to zero
}
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 ;
}
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +00:00
//update attribute
2013-05-08 21:45:39 +00:00
pattrib = & pmgntframe - > attrib ;
update_mgntframe_attrib ( padapter , pattrib ) ;
_rtw_memset ( pmgntframe - > buf_addr , 0 , WLANHDR_OFFSET + TXDESC_OFFSET ) ;
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-16 19:00:49 +00:00
if ( psta ) { // for AP mode
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_NATIVEAP_MLME
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
// 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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +00:00
// added challenging text...
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 ) ) ;
2013-05-08 21:45:39 +00:00
# endif
2014-12-19 06:59:46 +00:00
} 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
// 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
2014-12-11 21:15:04 +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 ;
# endif //CONFIG_WFD
# 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-11 21:15:04 +00:00
# ifdef CONFIG_80211N_HT
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
2014-12-11 21:15:04 +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
}
2014-12-11 21:15:04 +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
}
2014-12-11 21:15:04 +00:00
# endif
2013-05-19 04:28:07 +00:00
2014-12-11 21:15:04 +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 ) ) ;
2014-12-11 21:15:04 +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-19 06:59:46 +00:00
# ifdef CONFIG_IOCTL_CFG80211
2014-12-29 02:13:24 +00:00
& & ( true = = pwdinfo - > wfd_info - > wfd_enable )
2014-12-19 06:59:46 +00:00
# endif //CONFIG_IOCTL_CFG80211
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
}
2014-12-11 21:15:04 +00:00
# endif //CONFIG_WFD
# endif //CONFIG_P2P
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 ;
# endif //CONFIG_WFD
# endif //CONFIG_P2P
# ifdef CONFIG_DFS
u16 cap ;
# endif //CONFIG_DFS
if ( ( pmgntframe = alloc_mgtxmitframe ( pxmitpriv ) ) = = NULL )
2013-05-08 21:45:39 +00:00
goto exit ;
2014-12-11 21:15:04 +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
2013-05-08 21:45:39 +00:00
_rtw_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 ) ;
2014-12-11 21:15:04 +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 ) ;
2014-12-11 21:15:04 +00:00
# endif //CONFIG_DFS
2013-05-08 21:45:39 +00:00
pframe + = 2 ;
pattrib - > pktlen + = 2 ;
2014-12-11 21:15:04 +00:00
//listen interval
//todo: listen interval for power saving
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 ;
2014-12-11 21:15:04 +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 ) ) ;
2014-12-11 21:15:04 +00:00
//supported rate & extended supported rate
2013-05-08 21:45:39 +00:00
get_rate_set ( padapter , sta_bssrate , & sta_bssrate_len ) ;
2014-12-11 21:15:04 +00:00
//DBG_871X("sta_bssrate_len=%d\n", sta_bssrate_len);
2014-12-19 06:59:46 +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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +00:00
// Check if the AP's supported rates are also supported by STA.
for ( j = 0 ; j < sta_bssrate_len ; j + + ) {
// 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 ) ) {
//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 {
//DBG_871X("not match: %02X != %02X\n", (pmlmeinfo->network.SupportedRates[i]|IEEE80211_BASIC_RATE_MASK), (sta_bssrate[j]|IEEE80211_BASIC_RATE_MASK));
}
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 ) {
2014-12-11 21:15:04 +00:00
// the rate is not supported by STA
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 {
2014-12-11 21:15:04 +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 ) ;
2014-12-11 21:15:04 +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 ) ) ;
}
2014-12-11 21:15:04 +00:00
//RSN
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 ) ) ;
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_80211N_HT
//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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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 ) ) ;
2014-12-11 21:15:04 +00:00
//switch (pregpriv->rf_config)
2014-12-19 04:28:04 +00:00
switch ( rf_type ) {
case RF_1T1R :
if ( pregpriv - > rx_stbc )
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 :
2014-12-19 06:59:46 +00:00
if ( ( pregpriv - > rx_stbc = = 0x3 ) | | //enable for 2.4/5 GHz
2014-12-19 04:28:04 +00:00
( ( 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
( pregpriv - > wifi_spec = = 1 ) ) {
DBG_871X ( " declare supporting RX STBC \n " ) ;
pmlmeinfo - > HT_caps . u . HT_cap_element . HT_caps_info | = cpu_to_le16 ( 0x0200 ) ; //RX STBC two spatial stream
}
# 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 ) ;
2014-12-19 04:28:04 +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 ) ;
2014-12-19 04:28:04 +00:00
# endif //CONFIG_DISABLE_MCS13TO15
break ;
2014-12-11 21:15:04 +00:00
}
# ifdef RTL8192C_RECONFIG_TO_1T1R
{
if ( pregpriv - > rx_stbc )
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
{
// set to 8K
pmlmeinfo - > HT_caps . u . HT_cap_element . AMPDU_para & = ( u8 ) ~ IEEE80211_HT_CAP_AMPDU_FACTOR ;
// pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para |= MAX_AMPDU_FACTOR_8K
}
# 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
}
}
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
//vendor specific IE, such as WPA, WMM, WPS
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 )
{
//Commented by Kurt 20110629
//In some older APs, WPS handshake
//would be fail if we append vender extensions informations to AP
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
# ifdef CONFIG_IOCTL_CFG80211
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 ;
}
}
else
# endif //CONFIG_IOCTL_CFG80211
{
if ( ! rtw_p2p_chk_state ( pwdinfo , P2P_STATE_NONE ) & & ! rtw_p2p_chk_state ( pwdinfo , P2P_STATE_IDLE ) )
{
2014-12-19 06:59:46 +00:00
// Should add the P2P IE in the association request frame.
2014-12-11 21:15:04 +00:00
// 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 ;
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:
p2pie [ p2pielen + + ] = P2P_ATTR_CAPABILITY ;
// 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
2014-12-11 21:15:04 +00:00
// Value:
// Device Capability Bitmap, 1 byte
p2pie [ p2pielen + + ] = DMP_P2P_DEVCAP_SUPPORT ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
// Group Capability Bitmap, 1 byte
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
2014-12-11 21:15:04 +00:00
// Extended Listen Timing
// Type:
p2pie [ p2pielen + + ] = P2P_ATTR_EX_LISTEN_TIMING ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +00:00
// Device Info
// Type:
p2pie [ p2pielen + + ] = P2P_ATTR_DEVICE_INFO ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
// Length:
2014-12-19 06:59:46 +00:00
// 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
2014-12-11 21:15:04 +00:00
// + 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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +00:00
// Config Method
// This field should be big endian. Noted by P2P specification.
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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +00:00
// Number of Secondary Device Types
p2pie [ p2pielen + + ] = 0x00 ; // No Secondary Device Type List
2013-07-20 18:18:13 +00:00
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +00:00
// P2P Interface
// Type:
p2pie [ p2pielen + + ] = P2P_ATTR_INTERFACE ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +00:00
// Value:
2015-02-19 20:50:04 +00:00
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
2014-12-11 21:15:04 +00:00
p2pie [ p2pielen + + ] = 1 ; // P2P Interface Address Count
2014-12-19 06:59:46 +00:00
2015-02-19 20:50:04 +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
//wfdielen = build_assoc_req_wfd_ie(pwdinfo, pframe);
//pframe += wfdielen;
//pattrib->pktlen += wfdielen;
# endif //CONFIG_WFD
}
}
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
# endif //CONFIG_P2P
2013-07-20 18:18:13 +00:00
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_WFD
# ifdef CONFIG_IOCTL_CFG80211
2014-12-29 02:13:24 +00:00
if ( true = = pwdinfo - > wfd_info - > wfd_enable )
2014-12-11 21:15:04 +00:00
# endif //CONFIG_IOCTL_CFG80211
{
wfdielen = build_assoc_req_wfd_ie ( pwdinfo , pframe ) ;
pframe + = wfdielen ;
pattrib - > pktlen + = wfdielen ;
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_IOCTL_CFG80211
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
{
//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
}
# endif //CONFIG_IOCTL_CFG80211
2014-12-19 06:59:46 +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 ;
}
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +00:00
//DBG_871X("%s:%d\n", __FUNCTION__, power_mode);
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
2014-12-11 21:15:04 +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
_rtw_memset ( pmgntframe - > buf_addr , 0 , WLANHDR_OFFSET + TXDESC_OFFSET ) ;
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
//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 ;
}
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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 ;
_rtw_memset ( pmgntframe - > buf_addr , 0 , WLANHDR_OFFSET + TXDESC_OFFSET ) ;
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 ;
}
2014-12-11 21:15:04 +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 ) ;
# endif //CONFIG_P2P
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));
# 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
}
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
_rtw_memset ( pmgntframe - > buf_addr , 0 , WLANHDR_OFFSET + TXDESC_OFFSET ) ;
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 ;
2014-12-11 21:15:04 +00:00
//update attribute
2013-05-08 21:45:39 +00:00
pattrib = & pmgntframe - > attrib ;
update_mgntframe_attrib ( padapter , pattrib ) ;
_rtw_memset ( pmgntframe - > buf_addr , 0 , WLANHDR_OFFSET + TXDESC_OFFSET ) ;
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
2014-12-11 21:15:04 +00:00
//update attribute
2013-05-08 21:45:39 +00:00
pattrib = & pmgntframe - > attrib ;
update_mgntframe_attrib ( padapter , pattrib ) ;
_rtw_memset ( pmgntframe - > buf_addr , 0 , WLANHDR_OFFSET + TXDESC_OFFSET ) ;
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 )
{
case 0 : //SA Query req
pframe = rtw_set_fixed_ie ( pframe , 2 , ( unsigned char * ) & pmlmeext - > sa_query_seq , & pattrib - > pktlen ) ;
pmlmeext - > sa_query_seq + + ;
//send sa query request to AP, AP should reply sa query response in 1 second
set_sa_query_timer ( pmlmeext , 1000 ) ;
2013-06-07 14:43:09 +00:00
break ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
case 1 : //SA Query rsp
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 ) ;
}
2014-12-11 21:15:04 +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
# ifdef CONFIG_80211N_HT
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
2014-12-11 21:15:04 +00:00
//update attribute
2013-05-08 21:45:39 +00:00
pattrib = & pmgntframe - > attrib ;
update_mgntframe_attrib ( padapter , pattrib ) ;
_rtw_memset ( pmgntframe - > buf_addr , 0 , WLANHDR_OFFSET + TXDESC_OFFSET ) ;
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 - > 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 ) {
case 0 : //ADDBA req
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 ) ) ) {
2014-12-19 04:28:04 +00:00
// A-MSDU NOT Supported
BA_para_set = 0 ;
// immediate Block Ack
BA_para_set | = ( 1 < < 1 ) & IEEE80211_ADDBA_PARAM_POLICY_MASK ;
// TID
BA_para_set | = ( status < < 2 ) & IEEE80211_ADDBA_PARAM_TID_MASK ;
// max buffer size is 8 MSDU
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
{
BA_para_set = ( 0x1002 | ( ( status & 0xf ) < < 2 ) ) ; //immediate ack & 64 buffer size
}
//sys_mib.BA_para_set = 0x0802; //immediate ack & 32 buffer size
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
2014-12-19 04:28:04 +00:00
//BA_timeout_value = 0xffff;//max: 65535 TUs(~ 65 ms)
BA_timeout_value = 5000 ; //~ 5ms
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
2014-12-19 04:28:04 +00:00
//if ((psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress)) != NULL)
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
2014-12-19 04:28:04 +00:00
case 1 : //ADDBA rsp
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 )
BA_para_set = ( ( le16_to_cpu ( pmlmeinfo - > ADDBA_req . BA_para_set ) & 0x3f ) | 0x1000 ) ; //64 buffer size
else if ( MAX_AMPDU_FACTOR_32K = = max_rx_ampdu_factor )
BA_para_set = ( ( le16_to_cpu ( pmlmeinfo - > ADDBA_req . BA_para_set ) & 0x3f ) | 0x0800 ) ; //32 buffer size
else if ( MAX_AMPDU_FACTOR_16K = = max_rx_ampdu_factor )
BA_para_set = ( ( le16_to_cpu ( pmlmeinfo - > ADDBA_req . BA_para_set ) & 0x3f ) | 0x0400 ) ; //16 buffer size
else if ( MAX_AMPDU_FACTOR_8K = = max_rx_ampdu_factor )
BA_para_set = ( ( le16_to_cpu ( pmlmeinfo - > ADDBA_req . BA_para_set ) & 0x3f ) | 0x0200 ) ; //8 buffer size
else
2014-12-19 06:59:46 +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 ) ) ) {
2014-12-19 04:28:04 +00:00
// max buffer size is 8 MSDU
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
2014-12-19 04:28:04 +00:00
if ( pregpriv - > ampdu_amsdu = = 0 ) //disabled
le_tmp = cpu_to_le16 ( BA_para_set & ~ BIT ( 0 ) ) ;
else if ( pregpriv - > ampdu_amsdu = = 1 ) //enabled
le_tmp = cpu_to_le16 ( BA_para_set | BIT ( 0 ) ) ;
else //auto
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 ;
case 2 : //DELBA
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 ) ) ;
reason_code = 37 ; //Requested from peer STA as it does not want to use the mechanism
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 ) ;
# endif //CONFIG_80211N_HT
}
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 ] ;
2014-12-19 06:59:46 +00:00
# ifdef CONFIG_80211N_HT
2014-12-11 21:15:04 +00:00
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 ;
}
//update attribute
pattrib = & pmgntframe - > attrib ;
update_mgntframe_attrib ( padapter , pattrib ) ;
_rtw_memset ( pmgntframe - > buf_addr , 0 , WLANHDR_OFFSET + TXDESC_OFFSET ) ;
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 ) ) ;
//
if ( pmlmepriv - > num_FortyMHzIntolerant > 0 )
{
u8 iedata = 0 ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
iedata | = BIT ( 2 ) ; //20 MHz BSS Width Request
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
//
2013-05-08 21:45:39 +00:00
_rtw_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_ ) ;
2014-12-11 21:15:04 +00:00
if ( ( p = = NULL ) | | ( len = = 0 ) ) //non-HT
{
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 ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
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
2013-05-08 21:45:39 +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 ;
2014-12-11 21:15:04 +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 )
{
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 ) ) ;
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
}
2014-12-19 06:59:46 +00:00
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-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
# endif //CONFIG_80211N_HT
2013-05-08 21:45:39 +00:00
}
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 ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +00:00
//DBG_871X("%s:%s\n", __FUNCTION__, (initiator==0)?"RX_DIR":"TX_DIR");
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
if ( initiator = = 0 ) // recipient
{
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
}
else if ( initiator = = 1 ) // originator
{
# ifdef CONFIG_80211N_HT
//DBG_871X("tx agg_enable_bitmap(0x%08x)\n", psta->htpriv.agg_enable_bitmap);
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
}
2014-12-11 21:15:04 +00:00
# endif //CONFIG_80211N_HT
2013-05-08 21:45:39 +00:00
}
2014-12-19 06:59:46 +00:00
2013-05-08 21:45:39 +00:00
return _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
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 ) ) ;
//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 ) )
{
// 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
# 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 )
{
//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));
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 )
{
val8 = 0 ; //survey done
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 )
{
val8 = 1 ; //under site survey
rtw_hal_set_hwreg ( padapter , HW_VAR_MLME_SITESURVEY , ( u8 * ) ( & val8 ) ) ;
}
# endif //CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
if ( ScanType = = SCAN_ACTIVE ) //obey the channel plan setting...
{
# 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
# 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 ) {
//todo: to issue two probe req???
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
//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 ) {
//todo: to issue two probe req???
2013-05-08 21:45:39 +00:00
issue_probereq ( padapter , NULL , NULL ) ;
2014-12-11 21:15:04 +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_ATMEL_RC_PATCH
# 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 )
)
# endif //CONFIG_P2P
{
2014-12-19 06:59:46 +00:00
if ( ScanType = = SCAN_ACTIVE ) {
2014-12-29 02:13:24 +00:00
if ( check_fwstate ( pmlmepriv , _FW_LINKED ) = = true ) {
2014-12-19 06:59:46 +00:00
if ( survey_channel = = pmlmeext - > cur_channel )
2014-12-11 21:15:04 +00:00
set_survey_timer ( pmlmeext , 200 ) ;
else
set_survey_timer ( pmlmeext , 20 ) ;
}
else {
set_survey_timer ( pmlmeext , 40 ) ;
}
}
else { //SCAN_PASSIVE
set_survey_timer ( pmlmeext , pmlmeext - > chan_scan_time ) ;
}
}
else
# endif //CONFIG_ATMEL_RC_PATCH
{
# 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
# endif //CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
set_survey_timer ( pmlmeext , pmlmeext - > chan_scan_time ) ;
}
2015-02-15 20:31:30 +00:00
} else {
2014-12-11 21:15:04 +00:00
// channel number is 0 or this channel is not valid.
# 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 ) )
{
// 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 ) )
{
// 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 ;
2014-12-11 21:15:04 +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 ) ) ;
2014-12-11 21:15:04 +00:00
//turn on dynamic functions
2013-05-08 21:45:39 +00:00
Restore_DM_Func_Flag ( padapter ) ;
2014-12-29 02:13:24 +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
# 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 ;
# endif //CONFIG_DMP_STA_NODE_SCAN_UNDER_AP_MODE
# ifdef CONFIG_ANTENNA_DIVERSITY
// 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.
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
# endif
# 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 ) ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +00:00
//config MSR
2013-05-08 21:45:39 +00:00
Set_MSR ( padapter , ( pmlmeinfo - > state & 0x3 ) ) ;
2014-12-11 21:15:04 +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 ) ) ;
2014-12-11 21:15:04 +00:00
//turn on dynamic functions
2013-05-08 21:45:39 +00:00
Restore_DM_Func_Flag ( padapter ) ;
2014-12-29 02:13:24 +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 ) ;
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
{
//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
2014-12-11 21:15:04 +00:00
_rtw_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 {
2014-12-11 21:15:04 +00:00
// FIXME : more type
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
2014-12-11 21:15:04 +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
//get the signal strength
//bssid->Rssi = precv_frame->u.hdr.attrib.SignalStrength; // 0-100 index.
bssid - > Rssi = precv_frame - > u . hdr . attrib . phy_info . RecvSignalPower ; // in dBM.raw data
2014-12-19 06:59:46 +00:00
bssid - > PhyInfo . SignalQuality = precv_frame - > u . hdr . attrib . phy_info . SignalQuality ; //in percentage
2014-12-11 21:15:04 +00:00
bssid - > PhyInfo . SignalStrength = precv_frame - > u . hdr . attrib . phy_info . SignalStrength ; //in percentage
# ifdef CONFIG_ANTENNA_DIVERSITY
//rtw_hal_get_hwreg(padapter, HW_VAR_CURRENT_ANTENNA, (u8 *)(&bssid->PhyInfo.Optimum_antenna));
2013-05-08 21:45:39 +00:00
rtw_hal_get_def_var ( padapter , HAL_DEF_CURRENT_ANTENNA , & bssid - > PhyInfo . Optimum_antenna ) ;
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
// checking SSID
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 ;
}
_rtw_memset ( bssid - > SupportedRates , 0 , NDIS_802_11_LENGTH_RATES_EX ) ;
2014-12-11 21:15:04 +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
}
2014-12-11 21:15:04 +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 ;
// Set Listion Channel
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 ] ;
}
else { // use current channel
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 ) ;
}
// FIXME
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 ;
}
# endif //CONFIG_P2P
// 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
{ // 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
{ // 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 ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_80211N_HT
2013-05-08 21:45:39 +00:00
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
# endif //CONFIG_80211N_HT
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
}
# ifdef CONFIG_INTEL_WIDI
//process_intel_widi_query_or_tigger(padapter, bssid);
if ( process_intel_widi_query_or_tigger ( padapter , bssid ) )
{
return _FAIL ;
}
# endif // CONFIG_INTEL_WIDI
# 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
// mark bss info receving from nearby channel as SignalQuality 101
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 ) ;
2014-12-11 21:15:04 +00:00
//update wireless mode
2013-05-08 21:45:39 +00:00
update_wireless_mode ( padapter ) ;
2014-12-11 21:15:04 +00:00
//udpate capability
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_IBSS ) //adhoc master
{
//set_opmode_cmd(padapter, adhoc);//removed
2013-05-08 21:45:39 +00:00
val8 = 0xcf ;
rtw_hal_set_hwreg ( padapter , HW_VAR_SEC_CFG , ( u8 * ) ( & val8 ) ) ;
2014-12-11 21:15:04 +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 ) ;
2014-12-11 21:15:04 +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 ) ) ;
2014-12-11 21:15:04 +00:00
//issue beacon
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 ;
}
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +00:00
//update wireless mode
2013-05-08 21:45:39 +00:00
update_wireless_mode ( padapter ) ;
2014-12-11 21:15:04 +00:00
//udpate capability
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 )
{
//Disable TxUseDefaultKey, RxUseDefaultKey, RxBroadcastUseDefaultKey.
val8 = 0x4c ;
}
# endif
2013-05-08 21:45:39 +00:00
rtw_hal_set_hwreg ( padapter , HW_VAR_SEC_CFG , ( u8 * ) ( & val8 ) ) ;
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_DEAUTH_BEFORE_CONNECT
// 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
2014-12-11 21:15:04 +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.
{
# 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 ) ;
}
# endif /* CONFIG_DEAUTH_BEFORE_CONNECT */
//here wait for receiving the beacon to start auth
//and enable a timer
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
2014-12-11 21:15:04 +00:00
{ //only for STA mode
u16 media_status ;
u8 mac_id = 0 ;
2014-12-19 06:59:46 +00:00
media_status = ( mac_id < < 8 ) | 1 ; // MACID|OPMODE:1 connect
rtw_hal_set_hwreg ( padapter , HW_VAR_H2C_MEDIA_STATUS_RPT , ( u8 * ) & media_status ) ;
}
2014-12-11 21:15:04 +00:00
}
else if ( caps & cap_IBSS ) //adhoc client
{
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
{
//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 ) ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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 ] ;
2014-12-11 21:15:04 +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 ;
_rtw_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 + + )
{
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
_rtw_memset ( pmlmeext - > channel_set , 0 , sizeof ( pmlmeext - > channel_set ) ) ;
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 ;
2014-12-11 21:15:04 +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 ) ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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
// add channel AP supported
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
{
// 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 + + ;
}
2014-12-11 21:15:04 +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 ;
// chplan_new[k].ScanType = chplan_sta[i].ScanType;
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 ) ;
// change AP not support channel to Passive scan
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;
chplan_new [ k ] . ScanType = SCAN_PASSIVE ;
i + + ;
k + + ;
}
// add channel AP supported
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
{
// keep original STA 5G channel plan
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
}
2014-12-11 21:15:04 +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 )
{
//5G Bnad 2, 3 (DFS) doesn't change to active scan
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 ;
2014-12-11 21:15:04 +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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2014-12-11 21:15:04 +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 ) ;
2014-12-11 21:15:04 +00:00
//ERP
2013-05-08 21:45:39 +00:00
VCS_update ( padapter , psta ) ;
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_80211N_HT
//HT
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
# endif //CONFIG_80211N_HT
{
# ifdef CONFIG_80211N_HT
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 ;
2014-12-11 21:15:04 +00:00
# endif //CONFIG_80211N_HT
2014-12-29 02:13:24 +00:00
psta - > qos_option = false ;
2013-05-19 04:28:07 +00:00
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_80211N_HT
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
2014-12-11 21:15:04 +00:00
psta - > htpriv . agg_enable_bitmap = 0x0 ; //reset
psta - > htpriv . candidate_tid_bitmap = 0x0 ; //reset
# endif //CONFIG_80211N_HT
2013-05-19 04:28:07 +00:00
2014-12-11 21:15:04 +00:00
//QoS
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 ) ;
2014-12-11 21:15:04 +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-19 06:59:46 +00:00
if ( psta ) { //only for STA mode
media_status = ( psta - > mac_id < < 8 ) | 0 ; // MACID|OPMODE:1 connect
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 )
{
//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
}
2014-12-11 21:15:04 +00:00
//update bc/mc sta_info
update_bmc_sta ( padapter ) ;
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +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
// 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 ) ;
2014-12-11 21:15:04 +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 ) ) ;
2014-12-11 21:15:04 +00:00
//udpate capability
2013-05-08 21:45:39 +00:00
update_capinfo ( padapter , pmlmeinfo - > capability ) ;
2014-12-11 21:15:04 +00:00
//WMM, Update EDCA param
2013-05-08 21:45:39 +00:00
WMMOnAssocRsp ( padapter ) ;
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +00:00
if ( psta ) //only for infra. mode
{
2013-05-08 21:45:39 +00:00
pmlmeinfo - > FW_sta_info [ psta - > mac_id ] . psta = psta ;
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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 )
{
// correcting TSF
2013-05-08 21:45:39 +00:00
correct_TSF ( padapter , pmlmeext ) ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
//set_link_timer(pmlmeext, DISCONNECT_TO);
2013-05-08 21:45:39 +00:00
}
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_LPS
2013-05-08 21:45:39 +00:00
rtw_lps_ctrl_wk_cmd ( padapter , LPS_CTRL_CONNECT , 0 ) ;
2014-12-11 21:15:04 +00:00
# endif
2013-05-08 21:45:39 +00:00
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 )
{
if ( pmlmeinfo - > state & WIFI_FW_ASSOC_SUCCESS ) //adhoc master or sta_count>1
{
//nothing to do
}
else //adhoc client
{
//update TSF Value
2014-12-19 06:59:46 +00:00
//update_TSF(pmlmeext, pframe, len);
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
// correcting TSF
2013-05-08 21:45:39 +00:00
correct_TSF ( padapter , pmlmeext ) ;
2014-12-11 21:15:04 +00:00
//start beacon
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 ;
2014-12-11 21:15:04 +00:00
//rate radaptive
Update_RA_Entry ( padapter , psta ) ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +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 ) )
{
//set_opmode_cmd(padapter, infra_client_with_mlme);
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 ) ;
2014-12-11 21:15:04 +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
//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 ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +00:00
if ( is_client_associated_to_ap ( padapter ) )
{
//linked infrastructure client mode
2013-05-08 21:45:39 +00:00
int tx_chk = _SUCCESS , rx_chk = _SUCCESS ;
int rx_chk_limit ;
2014-12-11 21:15:04 +00:00
# if defined(DBG_ROAMING_TEST)
rx_chk_limit = 1 ;
# elif defined(CONFIG_ACTIVE_KEEP_ALIVE_CHECK)
2013-05-08 21:45:39 +00:00
rx_chk_limit = 4 ;
2014-12-11 21:15:04 +00:00
# else
rx_chk_limit = 8 ;
# endif
// 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.
2014-12-29 02:13:24 +00:00
// todo: To check why we under miracast session, rx_chk would be false
2014-12-11 21:15:04 +00:00
//#ifdef CONFIG_INTEL_WIDI
//if (padapter->mlmepriv.widi_state != INTEL_WIDI_STATE_NONE)
// rx_chk_limit = 1;
//#endif
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 ;
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
2013-05-08 21:45:39 +00:00
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 ) ;
2014-12-11 21:15:04 +00:00
}
else
# endif /* CONFIG_ACTIVE_KEEP_ALIVE_CHECK */
{
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
} //end of if ((psta = rtw_get_stainfo(pstapriv, passoc_res->network.MacAddress)) != NULL)
}
else if ( is_client_associated_to_ibss ( padapter ) )
{
//linked IBSS mode
//for each assoc list entry to check the rx pkt counter
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
2014-12-11 21:15:04 +00:00
, 65535 // indicate disconnect caused by no rx
) ;
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
//set_link_timer(pmlmeext, DISCONNECT_TO);
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
2014-12-11 21:15:04 +00:00
//issue rtw_sitesurvey_cmd
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 )
# endif //CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
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
}
2014-12-29 02:13:24 +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
{
2014-12-11 21:15:04 +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 ) ;
2014-12-11 21:15:04 +00:00
//struct sta_priv *pstapriv = &padapter->stapriv;
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 )
{
//re-auth timer
if ( + + pmlmeinfo - > reauth_count > REAUTH_LIMIT )
{
//if (pmlmeinfo->auth_algo != dot11AuthAlgrthm_Auto)
//{
pmlmeinfo - > state = 0 ;
report_join_res ( padapter , - 1 ) ;
return ;
//}
//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 )
{
//re-assoc timer
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 )
{
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_80211N_HT
2013-05-08 21:45:39 +00:00
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
}
# endif //CONFIG_80211N_HT
}
# 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 ;
//disconnect
_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
}
2014-12-11 21:15:04 +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
# ifdef CONFIG_NATIVEAP_MLME
//start_ap_mode(padapter);
# endif
}
else if ( psetop - > mode = = Ndis802_11Infrastructure )
{
pmlmeinfo - > state & = ~ ( BIT ( 0 ) | BIT ( 1 ) ) ; // clear state
2014-12-19 06:59:46 +00:00
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 ) ) ;
2014-12-11 21:15:04 +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 ;
2014-12-11 21:15:04 +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
{
2014-12-11 21:15:04 +00:00
//todo:
2014-12-19 06:59:46 +00:00
return H2C_SUCCESS ;
}
2013-05-08 21:45:39 +00:00
# endif
}
2014-12-11 21:15:04 +00:00
//below is for ad-hoc master
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 ;
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
2014-12-19 06:59:46 +00:00
//cancel link timer
2013-05-08 21:45:39 +00:00
_cancel_timer_ex ( & pmlmeext - > link_timer ) ;
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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 ) ) ;
# ifdef CONFIG_ANTENNA_DIVERSITY
2013-05-08 21:45:39 +00:00
struct joinbss_parm * pparm = ( struct joinbss_parm * ) pbuf ;
2014-12-11 21:15:04 +00:00
# endif //CONFIG_ANTENNA_DIVERSITY
2013-05-08 21:45:39 +00:00
u32 i ;
2014-12-11 21:15:04 +00:00
//u32 initialgain;
//u32 acparm;
u8 ch , bw , offset ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
//check already connecting to AP or not
if ( pmlmeinfo - > state & WIFI_FW_ASSOC_SUCCESS )
{
2013-05-08 21:45:39 +00:00
if ( pmlmeinfo - > state & WIFI_FW_STATION_STATE )
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 , 5 , 100 ) ;
2014-12-11 21:15:04 +00:00
}
2013-05-08 21:45:39 +00:00
pmlmeinfo - > state = WIFI_FW_NULL_STATE ;
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +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
//set MSR to nolink -> infra. mode
2014-12-11 21:15:04 +00:00
//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-11 21:15:04 +00:00
# ifdef CONFIG_ANTENNA_DIVERSITY
2014-12-29 02:13:24 +00:00
rtw_antenna_select_cmd ( padapter , pparm - > network . PhyInfo . Optimum_antenna , false ) ;
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
# 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 ;
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +00:00
//Check AP vendor to move rtw_joinbss_cmd()
//pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pnetwork->IEs, pnetwork->IELength);
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 )
{
case _VENDOR_SPECIFIC_IE_ : //Get WMM IE.
if ( _rtw_memcmp ( pIE - > data , WMM_OUI , 4 ) )
{
pmlmeinfo - > WMM_enable = 1 ;
}
break ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
case _HT_CAPABILITY_IE_ : //Get HT Cap IE.
pmlmeinfo - > HT_caps_enable = 1 ;
break ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
case _HT_EXTRA_INFO_IE_ : //Get HT Info IE.
# ifdef CONFIG_80211N_HT
pmlmeinfo - > HT_info_enable = 1 ;
2014-12-19 06:59:46 +00:00
//spec case only for cisco's ap because cisco's ap issue assoc rsp using mcs rate @40MHz or @20MHz
{
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 ) ) )
{
//switch to the 40M Hz mode according to the AP
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
# endif //CONFIG_80211N_HT
break ;
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +00:00
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 ;
}
//disable dynamic functions, such as high power, DIG
2014-12-29 02:13:24 +00:00
//Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, false);
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +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
2014-12-19 06:59:46 +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
}
//set_opmode_cmd(padapter, infra_client_with_mlme);
2013-05-08 21:45:39 +00:00
2014-12-11 21:15:04 +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 ) ;
2014-12-11 21:15:04 +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 ) )
{
//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
//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-15 20:31:30 +00:00
//switch to the 20M Hz mode after disconnect
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 */
_rtw_memset ( out , 0 , sizeof ( struct rtw_ieee80211_channel ) * out_num ) ;
/* 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 + + ;
}
}
2014-12-11 21:15:04 +00:00
if ( padapter - > setband = = GHZ_24 ) { // 2.4G
for ( i = 0 ; i < j ; i + + ) {
2014-12-19 06:59:46 +00:00
if ( out [ i ] . hw_value > 35 )
2014-12-11 21:15:04 +00:00
_rtw_memset ( & out [ i ] , 0 , sizeof ( struct rtw_ieee80211_channel ) ) ;
else
scan_ch_num + + ;
}
j = scan_ch_num ;
} else if ( padapter - > setband = = GHZ_50 ) { // 5G
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 ;
2014-12-11 21:15:04 +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 )
{
//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 ) )
{
//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
2014-12-11 21:15:04 +00:00
//config the initial gain under scaning, need to write the BB registers
# ifdef CONFIG_P2P
# ifdef CONFIG_IOCTL_CFG80211
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
# endif //CONFIG_IOCTL_CFG80211
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
# endif //CONFIG_P2P
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
2014-12-11 21:15:04 +00:00
//set MSR to no link state
2013-05-08 21:45:39 +00:00
Set_MSR ( padapter , _HW_STATE_NOLINK_ ) ;
2014-12-11 21:15:04 +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 } ;
2014-12-11 21:15:04 +00:00
//main tx key for wep.
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
2014-12-11 21:15:04 +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
2014-12-11 21:15:04 +00:00
//allow multicast packets to driver
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 ;
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 ;
# endif //CONFIG_TDLS
//cam_entry:
//0~3 for default key
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +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)
//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
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 ;
2014-12-11 21:15:04 +00:00
if ( pparm - > algorithm = = _NO_PRIVACY_ ) // clear cam entry
{
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
}
2014-12-11 21:15:04 +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
}
2014-12-11 21:15:04 +00:00
//below for sta mode
2014-12-19 06:59:46 +00:00
2014-12-11 21:15:04 +00:00
if ( pparm - > algorithm = = _NO_PRIVACY_ ) // clear cam entry
{
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 ;
}
psta = rtw_get_stainfo ( pstapriv , pparm - > addr ) ; //Get TDLS Peer STA
if ( psta - > tdls_sta_state & TDLS_LINKED_STATE ) {
write_cam ( padapter , psta - > mac_id , ctrl , pparm - > addr , pparm - > key ) ;
}
else
2014-12-19 06:59:46 +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 ;
2014-12-11 21:15:04 +00:00
# ifdef CONFIG_80211N_HT
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 ) )
{
//pmlmeinfo->ADDBA_retry_count = 0;
2014-12-19 06:59:46 +00:00
//pmlmeinfo->candidate_tid_bitmap |= (0x1 << pparm->tid);
2014-12-11 21:15:04 +00:00
//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 ) ;
2014-12-11 21:15:04 +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 ) ;
2014-12-11 21:15:04 +00:00
//_set_timer(&pmlmeext->ADDBA_timer, ADDBA_TO);
_set_timer ( & psta - > addba_retry_timer , ADDBA_TO ) ;
}
# endif //CONFIG
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
}
# endif //CONFIG_80211N_HT
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
2014-12-19 06:59:46 +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
2014-12-11 21:15:04 +00:00
// checking if event code is valid
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
}
2014-12-19 06:59:46 +00:00
// checking if event size match the event parm size
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
2014-12-19 06:59:46 +00:00
else //tx bc/mc frames after update TIM
{
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
2014-12-11 21:15:04 +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
{
2014-12-11 21:15:04 +00:00
rtw_msleep_os ( 10 ) ; // 10ms, ATIM(HIQ) Windows
_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
2014-12-11 21:15:04 +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 ;
# 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 ;
}
//_enter_critical_bh(&(ptdlsinfo->hdl_lock), &irqL);
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 :
//As long as TDLS handshake success, we should set RCR_CBSSID_DATA bit to 0
//such we can receive all kinds of data frames.
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 ;
//set TDLS sta rate.
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 {
//send null data with pwrbit==1 before send ch_switching_req to peer STA.
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
}
//_exit_critical_bh(&(ptdlsinfo->hdl_lock), &irqL);
return H2C_SUCCESS ;
# else
return H2C_REJECTED ;
# endif //CONFIG_TDLS
}