You are on page 1of 31

/****************************************************************************

* Ralink Tech Inc.


* Taiwan, R.O.C.
*
* (c) Copyright 2002, Ralink Technology, Inc.
*
* All rights reserved. Ralink's source code is an unpublished work and the
* use of a copyright notice does not imply otherwise. This source code
* contains confidential trade secret material of Ralink Tech. Any attemp
* or participation in deciphering, decoding, reverse engineering or in any
* way altering the source code is stricitly prohibited, unless the prior
* written consent of Ralink Technology, Inc. is obtained.
***************************************************************************/
/****************************************************************************
Abstract:
All related CFG80211 function body.
History:
***************************************************************************/
#ifdef RT_CFG80211_SUPPORT
#include "rt_config.h"
#define RT_CFG80211_DEBUG /* debug use */
#define CFG80211CB
(pAd->pCfg80211_CB)
#ifdef RT_CFG80211_DEBUG
#define CFG80211DBG(__Flg, __pMsg)
#else
#define CFG80211DBG(__Flg, __pMsg)
#endif /* RT_CFG80211_DEBUG */

DBGPRINT(__Flg, __pMsg)

INT CFG80211DRV_IoctlHandle(
IN
VOID
IN
RTMP_IOCTL_INPUT_STRUCT *wrq,
IN
INT
IN
USHORT
IN
VOID
IN
ULONG
{
PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdSrc;

*pAdSrc,
cmd,
subcmd,
*pData,
Data)

switch(cmd)
{
case CMD_RTPRIV_IOCTL_80211_START:
case CMD_RTPRIV_IOCTL_80211_END:
/* nothing to do */
break;
case CMD_RTPRIV_IOCTL_80211_CB_GET:
*(VOID **)pData = (VOID *)(pAd->pCfg80211_CB);

break;
case CMD_RTPRIV_IOCTL_80211_CB_SET:
pAd->pCfg80211_CB = pData;
break;
case CMD_RTPRIV_IOCTL_80211_CHAN_SET:
if (CFG80211DRV_OpsSetChannel(pAd, pData) != TRUE)
return NDIS_STATUS_FAILURE;
break;
case CMD_RTPRIV_IOCTL_80211_VIF_CHG:
if (CFG80211DRV_OpsChgVirtualInf(pAd, pData, Data) != TR
UE)
return NDIS_STATUS_FAILURE;
break;
case CMD_RTPRIV_IOCTL_80211_SCAN:
CFG80211DRV_OpsScan(pAd);
break;
case CMD_RTPRIV_IOCTL_80211_IBSS_JOIN:
CFG80211DRV_OpsJoinIbss(pAd, pData);
break;
case CMD_RTPRIV_IOCTL_80211_STA_LEAVE:
CFG80211DRV_OpsLeave(pAd);
break;
case CMD_RTPRIV_IOCTL_80211_STA_GET:
if (CFG80211DRV_StaGet(pAd, pData) != TRUE)
return NDIS_STATUS_FAILURE;
break;
case CMD_RTPRIV_IOCTL_80211_KEY_ADD:
CFG80211DRV_KeyAdd(pAd, pData);
break;
case CMD_RTPRIV_IOCTL_80211_KEY_DEFAULT_SET:
break;
case CMD_RTPRIV_IOCTL_80211_CONNECT_TO:
CFG80211DRV_Connect(pAd, pData);
break;
#ifdef RFKILL_HW_SUPPORT
case CMD_RTPRIV_IOCTL_80211_RFKILL:
{
UINT32 data = 0;
BOOLEAN active;
/* Read GPIO pin2 as Hardware controlled radio state */
RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &data);
active = !!(data & 0x04);
if (!active)
{
RTMPSetLED(pAd, LED_RADIO_OFF);
*(UINT8 *)pData = 0;
}

else
*(UINT8 *)pData = 1;
}
break;
#endif /* RFKILL_HW_SUPPORT */
case CMD_RTPRIV_IOCTL_80211_REG_NOTIFY_TO:
CFG80211DRV_RegNotify(pAd, pData);
break;
case CMD_RTPRIV_IOCTL_80211_UNREGISTER:
CFG80211_UnRegister(pAd, pData);
break;
case CMD_RTPRIV_IOCTL_80211_BANDINFO_GET:
{
CFG80211_BAND *pBandInfo = (CFG80211_BAND *)pData;
CFG80211_BANDINFO_FILL(pAd, pBandInfo);
}
break;
case CMD_RTPRIV_IOCTL_80211_SURVEY_GET:
CFG80211DRV_SurveyGet(pAd, pData);
break;
case CMD_RTPRIV_IOCTL_80211_EXTRA_IES_SET:
CFG80211DRV_OpsExtraIesSet(pAd);
break;
case CMD_RTPRIV_IOCTL_80211_REMAIN_ON_CHAN_SET:
CFG80211DRV_OpsRemainOnChannel(pAd, pData, Data);
break;
case CMD_RTPRIV_IOCTL_80211_CANCEL_REMAIN_ON_CHAN_SET:
CFG80211DRV_OpsCancelRemainOnChannel(pAd, Data);
break;
case CMD_RTPRIV_IOCTL_80211_MGMT_FRAME_REG:
if (Data)
pAd->Cfg80211ProbeReqCount++;
else
{
pAd->Cfg80211ProbeReqCount--;
}
if (pAd->Cfg80211ProbeReqCount > 0)
pAd->Cfg80211RegisterProbeReqFrame = TRUE;
else
pAd->Cfg80211RegisterProbeReqFrame = FALSE;
DBGPRINT(RT_DEBUG_ERROR, ("pAd->Cfg80211RegisterProbeReq
Frame=%d[%d]\n",pAd->Cfg80211RegisterProbeReqFrame, pAd->Cfg80211ProbeReqCount))
;
break;
case CMD_RTPRIV_IOCTL_80211_ACTION_FRAME_REG:
if (Data)
pAd->Cfg80211ActionCount++;
else
pAd->Cfg80211ActionCount--;

if (pAd->Cfg80211ActionCount > 0)
pAd->Cfg80211RegisterActionFrame = TRUE;
else
pAd->Cfg80211RegisterActionFrame = FALSE;
DBGPRINT(RT_DEBUG_TRACE, ("pAd->Cfg80211RegisterActionFr
ame=%d [%d]\n",pAd->Cfg80211RegisterActionFrame, pAd->Cfg80211ActionCount));
break;
case CMD_RTPRIV_IOCTL_80211_CHANNEL_LOCK:
//pAd->CommonCfg.CentralChannel = Data;
//DBGPRINT(RT_DEBUG_TRACE, ("CMD_RTPRIV_IOCTL_80211_CHAN
NEL_LOCK %d\n", Data));
if (pAd->CommonCfg.Channel != Data)
{
pAd->CommonCfg.Channel= Data;
AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, F
ALSE);
AsicLockChannel(pAd, pAd->CommonCfg.Channel);
}
break;
case CMD_RTPRIV_IOCTL_80211_MGMT_FRAME_SEND:
/* send a managment frame */
pAd->TxStatusInUsed = TRUE;
pAd->TxStatusSeq = pAd->Sequence;
if (pData != NULL)
{
#ifdef WFD_SUPPORT
if (pAd->StaCfg.WfdCfg.bSuppInsertWfdIe)
{
PP2P_PUBLIC_FRAME
pFrame = (PP2P_P
UBLIC_FRAME)pData;
ULONG WfdIeLen = 0, WfdIeBitmap = 0;
switch (pFrame->p80211Header.FC.SubType)
{
case
case
case
case

SUBTYPE_BEACON:
SUBTYPE_PROBE_REQ:
SUBTYPE_ASSOC_REQ:
SUBTYPE_REASSOC_REQ:
WfdIeBitmap = (0x1 << SU
BID_WFD_DEVICE_INFO) | (0x1 << SUBID_WFD_ASSOCIATED_BSSID) |
(0x1 << SUBID_WF
D_COUPLED_SINK_INFO);
break;
case SUBTYPE_ASSOC_RSP:
case SUBTYPE_REASSOC_RSP:
WfdIeBitmap = (0x1 << SU
BID_WFD_DEVICE_INFO) | (0x1 << SUBID_WFD_ASSOCIATED_BSSID) |
(0x1 << SUBID_WF
D_COUPLED_SINK_INFO) | (0x1 << SUBID_WFD_SESSION_INFO);
break;
case SUBTYPE_PROBE_RSP:
WfdIeBitmap = (0x1 << SU
BID_WFD_DEVICE_INFO) | (0x1 << SUBID_WFD_ASSOCIATED_BSSID) |
(0x1 << SUBID_WF

D_COUPLED_SINK_INFO) | (0x1 << SUBID_WFD_SESSION_INFO);


break;
case SUBTYPE_ACTION:
if ((pFrame->Category ==
CATEGORY_PUBLIC) &&
(pFrame->Action
== ACTION_WIFI_DIRECT))
{
switch (pFrame->
Subtype)
{
case GO_
NEGOCIATION_REQ:
case GO_
NEGOCIATION_RSP:
case GO_
NEGOCIATION_CONFIRM:
case P2P
_PROVISION_REQ:
WfdIeBitmap = (0x1 << SUBID_WFD_DEVICE_INFO) | (0x1 << SUBID_WFD_ASSOCIATED_BSSI
D) |
(0x1 << SUBID_WFD_COUPLED_SINK_INFO);
break;
case P2P
_INVITE_REQ:
case P2P
_INVITE_RSP:
case P2P
_PROVISION_RSP:
WfdIeBitmap = (0x1 << SUBID_WFD_DEVICE_INFO) | (0x1 << SUBID_WFD_ASSOCIATED_BSSI
D) |
(0x1 << SUBID_WFD_COUPLED_SINK_INFO) | (0x1 << SUBID_WFD_SESSION_INFO);
break;
}
}
break;
}
if (WfdIeBitmap > 0)
{
PUCHAR
pOutBuffer;
NDIS_STATUS NStatus;
NStatus = MlmeAllocateMemory(pAd
, &pOutBuffer); /* Get an unused nonpaged memory */
if (NStatus != NDIS_STATUS_SUCCE
SS)
DBGPRINT(RT_DEBUG_ERROR,
("%s: Allocate memory fail!!!\n", __FUNCTION__));
else
{
memcpy(pOutBuffer, pData

, Data);
WfdMakeWfdIE(pAd, WfdIeB
itmap, pOutBuffer + Data, &WfdIeLen);
Data += WfdIeLen;
if (pAd->pTxStatusBuf !=
NULL)
os_free_mem(NULL
, pAd->pTxStatusBuf);
os_alloc_mem(NULL, (UCHA
R **)&pAd->pTxStatusBuf, Data);
if (pAd->pTxStatusBuf !=
NULL)
{
NdisCopyMemory(p
Ad->pTxStatusBuf, pOutBuffer, Data);
pAd->TxStatusBuf
Len = Data;
}
else
{
DBGPRINT(RT_DEBU
G_TRACE, ("YF_TX_STATUS: MEM ALLOC ERROR\n"));
MlmeFreeMemory(p
Ad, pOutBuffer);
return NDIS_STAT
US_FAILURE;
}
MiniportMMRequest(pAd, 0
, pOutBuffer, Data);
}
}
}
else
#endif /* WFD_SUPPORT */
{
if (pAd->pTxStatusBuf != NULL)
os_free_mem(NULL, pAd->pTxStatus
Buf);
os_alloc_mem(NULL, (UCHAR **)&pAd->pTxSt
atusBuf, Data);
if (pAd->pTxStatusBuf != NULL)
{
NdisCopyMemory(pAd->pTxStatusBuf
, pData, Data);
pAd->TxStatusBufLen = Data;
}
else
{
DBGPRINT(RT_DEBUG_TRACE, ("YF_TX
_STATUS: MEM ALLOC ERROR\n"));
return NDIS_STATUS_FAILURE;
}
// pAd->pTxStatusBuf
// pAd->TxStatusBufLen = Data
//DBGPRINT(RT_DEBUG_TRACE, ("YF_TX_STATU
S: send %d\n", pAd->TxStatusSeq));
MiniportMMRequest(pAd, 0, pData, Data);

//DBGPRINT(RT_DEBUG_TRACE, ("YF_TX_STATU
S: sent %d\n", pAd->TxStatusSeq));
}
}
break;
case CMD_RTPRIV_IOCTL_80211_REMAIN_ON_CHAN_DUR_TIMER_INIT:
DBGPRINT(RT_DEBUG_TRACE, ("ROC TIMER INIT\n"));
RTMPInitTimer(pAd, &pAd->Cfg80211RemainOnChannelDuration
Timer, GET_TIMER_FUNCTION(RemainOnChannelTimeout), pAd, FALSE);
break;
case CMD_RTPRIV_IOCTL_80211_CHANNEL_LIST_SET:
DBGPRINT(RT_DEBUG_TRACE, ("CMD_RTPRIV_IOCTL_80211_CHANNE
L_LIST_SET: %d\n", Data));
UINT32 *pChanList = (UINT32 *) pData;
if (pChanList != NULL)
{
if (pAd->pCfg80211ChanList != NULL)
os_free_mem(NULL, pAd->pCfg80211ChanList
);
os_alloc_mem(NULL, (UINT32 **)&pAd->pCfg80211Cha
nList, sizeof(UINT32 *) * Data);
if (pAd->pCfg80211ChanList != NULL)
{
NdisCopyMemory(pAd->pCfg80211ChanList, p
ChanList, sizeof(UINT32 *) * Data);
pAd->Cfg80211ChanListLan = Data;
}
else
{
return NDIS_STATUS_FAILURE;
}
}
break;
case CMD_RTPRIV_IOCTL_80211_BEACON_SET:
CFG80211DRV_OpsBeaconSet(pAd, pData, 0);
break;
case CMD_RTPRIV_IOCTL_80211_BEACON_ADD:
CFG80211DRV_OpsBeaconSet(pAd, pData, 1);
break;
case CMD_RTPRIV_IOCTL_80211_BEACON_DEL:
#ifdef WFD_SUPPORT
pAd->StaCfg.WfdCfg.bSuppGoOn = FALSE;
#endif /* WFD_SUPPORT */
break;
case CMD_RTPRIV_IOCTL_80211_CHANGE_BSS_PARM:
CFG80211DRV_OpsChangeBssParm(pAd, pData);
break;
case CMD_RTPRIV_IOCTL_80211_AP_PROBE_RSP:
if (pData != NULL)

{
if (pAd->pCfg80211RrobeRsp != NULL)
os_free_mem(NULL, pAd->pCfg80211RrobeRsp
);
os_alloc_mem(NULL, (UCHAR **)&pAd->pCfg80211Rrob
eRsp, Data);
if (pAd->pCfg80211RrobeRsp != NULL)
{
NdisCopyMemory(pAd->pCfg80211RrobeRsp, p
Data, Data);
pAd->Cfg80211AssocRspLen = Data;
}
else
{
DBGPRINT(RT_DEBUG_TRACE, ("YF_AP: MEM AL
LOC ERROR\n"));
return NDIS_STATUS_FAILURE;
}
}
else
return NDIS_STATUS_FAILURE;
break;
case CMD_RTPRIV_IOCTL_80211_PORT_SECURED:
CFG80211_StaPortSecured(pAd, pData, Data);
break;
case CMD_RTPRIV_IOCTL_80211_AP_STA_DEL:
CFG80211_ApStaDel(pAd, pData);
break;
case CMD_RTPRIV_IOCTL_80211_BITRATE_SET:
//
pAd->CommonCfg.PhyMode = PHY_11AN_MIXED;
//
RTMPSetPhyMode(pAd, pAd->CommonCfg.PhyMode);
//Set_WirelessMode_Proc(pAd, PHY_11AGN_MIXED);
break;
#ifdef RT_P2P_SPECIFIC_WIRELESS_EVENT
case CMD_RTPRIV_IOCTL_80211_SEND_WIRELESS_EVENT:
CFG80211_SendWirelessEvent(pAd, pData);
break;
#endif /* RT_P2P_SPECIFIC_WIRELESS_EVENT */
default:
return NDIS_STATUS_FAILURE;
}
return NDIS_STATUS_SUCCESS;
}
static VOID CFG80211DRV_DisableApInterface(
VOID
*pAdOrg)
{
UINT32 Value;
PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdOrg;
pAd->ApCfg.MBSSID[MAIN_MBSSID].bBcnSntReq = FALSE;
/* Disable pre-tbtt interrupt */
RTMP_IO_READ32(pAd, INT_TIMER_EN, &Value);
Value &=0xe;
RTMP_IO_WRITE32(pAd, INT_TIMER_EN, Value);

if (!INFRA_ON(pAd))
{
/* Disable piggyback */
RTMPSetPiggyBack(pAd, FALSE);
AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT|CCKSETPROTECT|OFDMSE
TPROTECT), TRUE, FALSE);
}
if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
{
/*RTMP_ASIC_INTERRUPT_DISABLE(pAd); */
AsicDisableSync(pAd);
#ifdef LED_CONTROL_SUPPORT
/* Set LED */
RTMPSetLED(pAd, LED_LINK_DOWN);
#endif /* LED_CONTROL_SUPPORT */
}
#ifdef RTMP_MAC_USB
/* For RT2870, we need to clear the beacon sync buffer. */
RTUSBBssBeaconExit(pAd);
#endif /* RTMP_MAC_USB */
}
VOID CFG80211DRV_OpsChangeBssParm(
VOID
VOID
{
PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdOrg;
CMD_RTPRIV_IOCTL_80211_BSS_PARM *pBssInfo;
BOOLEAN TxPreamble;

*pAdOrg,
*pData)

CFG80211DBG(RT_DEBUG_TRACE, ("%s\n", __FUNCTION__));


pBssInfo = (CMD_RTPRIV_IOCTL_80211_BSS_PARM *)pData;
/* Short Preamble */
if (pBssInfo->use_short_preamble != -1)
{
CFG80211DBG(RT_DEBUG_TRACE, ("%s: ShortPreamble %d\n", __FUNCTIO
N__, pBssInfo->use_short_preamble));
pAd->CommonCfg.TxPreamble = (pBssInfo->use_short_preamble == 0 ?
Rt802_11PreambleLong : Rt802_11PreambleShort);
TxPreamble = (pAd->CommonCfg.TxPreamble == Rt802_11PreambleLong
? 0 : 1);
MlmeSetTxPreamble(pAd, (USHORT)pAd->CommonCfg.TxPreamble);
}
/* CTS Protection */
if (pBssInfo->use_cts_prot != -1)
{
CFG80211DBG(RT_DEBUG_TRACE, ("%s: CTS Protection %d\n", __FUNCTI
ON__, pBssInfo->use_cts_prot));
}
/* Short Slot */

if (pBssInfo->use_short_slot_time != -1)
{
CFG80211DBG(RT_DEBUG_TRACE, ("%s: Short Slot %d\n", __FUNCTION__
, pBssInfo->use_short_slot_time));
}
}
BOOLEAN CFG80211DRV_OpsSetChannel(
VOID
VOID
{
PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdOrg;
CMD_RTPRIV_IOCTL_80211_CHAN *pChan;
UINT8 ChanId;
UINT8 IfType;
UINT8 ChannelType;
STRING ChStr[5] = { 0 };
#ifdef DOT11_N_SUPPORT
UCHAR BW_Old;
BOOLEAN FlgIsChanged;
#endif /* DOT11_N_SUPPORT */

*pAdOrg,
*pData)

/* init */
pChan = (CMD_RTPRIV_IOCTL_80211_CHAN *)pData;
ChanId = pChan->ChanId;
IfType = pChan->IfType;
ChannelType = pChan->ChanType;
#ifdef DOT11_N_SUPPORT
if (IfType != RT_CMD_80211_IFTYPE_MONITOR)
{
/* get channel BW */
FlgIsChanged = FALSE;
BW_Old = pAd->CommonCfg.RegTransmitSetting.field.BW;
/* set to new channel BW */
if (ChannelType == RT_CMD_80211_CHANTYPE_HT20)
{
pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
FlgIsChanged = TRUE;
}
else if ((ChannelType == RT_CMD_80211_CHANTYPE_HT40MINUS) ||
(ChannelType == RT_CMD_80211_CHANTYPE_HT40PLUS))
{
/* not support NL80211_CHAN_HT40MINUS or NL80211_CHAN_HT
40PLUS */
/* i.e. primary channel = 36, secondary channel must be
40 */
pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40;
FlgIsChanged = TRUE;
} /* End of if */
CFG80211DBG(RT_DEBUG_ERROR, ("80211> New BW = %d\n",
pAd->CommonCfg.RegTransmitSetting.field.
BW));
/* change HT/non-HT mode (do NOT change wireless mode here) */
if (((ChannelType == RT_CMD_80211_CHANTYPE_NOHT) &&
(pAd->CommonCfg.HT_Disable == 0)) ||

((ChannelType != RT_CMD_80211_CHANTYPE_NOHT) &&


(pAd->CommonCfg.HT_Disable == 1)))
{
if (ChannelType == RT_CMD_80211_CHANTYPE_NOHT)
pAd->CommonCfg.HT_Disable = 1;
else
pAd->CommonCfg.HT_Disable = 0;
/* End of if */
FlgIsChanged = TRUE;
CFG80211DBG(RT_DEBUG_ERROR, ("80211> HT Disable = %d\n",
pAd->CommonCfg.HT_Disable));
} /* End of if */
}
else
{
/* for monitor mode */
FlgIsChanged = TRUE;
pAd->CommonCfg.HT_Disable = 0;
pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40;
} /* End of if */
if (FlgIsChanged == TRUE)
SetCommonHT(pAd);
/* End of if */
#endif /* DOT11_N_SUPPORT */
/* switch to the channel */
sprintf(ChStr, "%d", ChanId);
if (Set_Channel_Proc(pAd, ChStr) == FALSE)
{
CFG80211DBG(RT_DEBUG_ERROR, ("80211> Change channel fail!\n"));
} /* End of if */
return TRUE;
}
BOOLEAN CFG80211DRV_OpsChgVirtualInf(
VOID
VOID
UINT8
{

*pAdOrg,
*pFlgFilter,
IfType)

return TRUE;
}
BOOLEAN CFG80211DRV_OpsScan(
VOID
{
PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdOrg;
if (pAd->FlgCfg80211Scanning == TRUE)
return FALSE; /* scanning */
/* End of if */
/* do scan */

*pAdOrg)

pAd->FlgCfg80211Scanning = TRUE;
return TRUE;
}
/* REF: ap_connect.c ApMakeBssBeacon */
BOOLEAN CFG80211DRV_OpsBeaconSet(
VOID
*pAdOrg,
VOID
*pData,
BOOLEAN
isAdd)
{
CFG80211DBG(RT_DEBUG_TRACE, ("80211> CFG80211DRV_OpsBeaconSet ==> %d\n",
isAdd));
PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdOrg;
CMD_RTPRIV_IOCTL_80211_BEACON *pBeacon;
PTXWI_STRUC
pTxWI = &pAd->BeaconTxWI;
HTTRANSMIT_SETTING
BeaconTransmit; /* MGMT frame PHY rate setting
when operatin at Ht rate. */
BCN_TIME_CFG_STRUC csr9;
UCHAR *ptr;
UINT i;
UINT32 longValue;
UINT8 TXWISize = pAd->chipCap.TXWISize;
UINT32 rx_filter_flag;
BOOLEAN TxPreamble, SpectrumMgmt = FALSE;
BOOLEAN bWmmCapable = FALSE;
UCHAR BBPR1 = 0, BBPR3 = 0;
INT idx;
ULONG offset;
CFG80211DBG(RT_DEBUG_TRACE, ("80211> CFG80211DRV_OpsBeaconSet ==> \n"));
pBeacon = (CMD_RTPRIV_IOCTL_80211_BEACON *)pData;
#ifdef WFD_SUPPORT
if (pAd->StaCfg.WfdCfg.bSuppInsertWfdIe)
{
ULONG TmpLen, WfdIeBitmap;
ptr = pBeacon->beacon + pBeacon->beacon_len;
WfdIeBitmap = (0x1 << SUBID_WFD_DEVICE_INFO) | (0x1 << SUBID_WFD
_ASSOCIATED_BSSID) |
(0x1 << SUBID_WFD_COUPLED_SINK_INFO);
WfdMakeWfdIE(pAd, WfdIeBitmap, ptr, &TmpLen);
pBeacon->beacon_len += TmpLen;
}
#endif /* WFD_SUPPORT */
if (isAdd)
{
rx_filter_flag = APNORMAL;
RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, rx_filter_flag);
e RX of DMA block */
pAd->ApCfg.BssidNum = 1;
pAd->MacTab.MsduLifeTime = 20; /* default 5 seconds */
pAd->ApCfg.MBSSID[MAIN_MBSSID].bBcnSntReq = TRUE;
#ifdef INF_AMAZON_SE
printk("YF DEBUG: INF_AMAZON_SE\n");
for (i = 0; i < NUM_OF_TX_RING; i++)
{

/* enabl

pAd->BulkOutDataSizeLimit[i]=24576;
}
#endif /* INF_AMAZON_SE */
AsicDisableSync(pAd);
if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
{
if (pAd->CommonCfg.Channel > 14)
pAd->ApCfg.MBSSID[MAIN_MBSSID].PhyMode = PHY_11A
N_MIXED;
else
pAd->ApCfg.MBSSID[MAIN_MBSSID].PhyMode = PHY_11B
GN_MIXED;
}
else
{
if (pAd->CommonCfg.Channel > 14)
pAd->ApCfg.MBSSID[MAIN_MBSSID].PhyMode = PHY_11A
;
else
pAd->ApCfg.MBSSID[MAIN_MBSSID].PhyMode = PHY_11B
G_MIXED;
}
TxPreamble = (pAd->CommonCfg.TxPreamble == Rt802_11PreambleLong
? 0 : 1);
}
PMULTISSID_STRUCT pMbss = &pAd->ApCfg.MBSSID[MAIN_MBSSID];
const UCHAR *ssid_ie = NULL;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33))
ssid_ie = cfg80211_find_ie(WLAN_EID_SSID, pBeacon->beacon+36, pBeacon->b
eacon_len-36);
#endif
NdisZeroMemory(pMbss->Ssid, pMbss->SsidLen);
if (ssid_ie == NULL)
{
printk("YF Debug: SSID Not Found In Packet\n");
NdisMoveMemory(pMbss->Ssid, "P2P_Linux_AP", 12);
pMbss->SsidLen = 12;
}
else
{
pMbss->SsidLen = ssid_ie[1];
NdisCopyMemory(pMbss->Ssid, ssid_ie+2, pMbss->SsidLen);
printk("YF Debug: SSID: %s, %d\n", pMbss->Ssid, pMbss->SsidLen);
}
if (isAdd)
{
//if (pMbss->bWmmCapable)
//{
bWmmCapable = FALSE;
pMbss->bWmmCapable = FALSE;
//}
pMbss->MSSIDDev = pAd->net_dev;
COPY_MAC_ADDR(pMbss->Bssid, pAd->CurrentAddress);

printk("AP BSSID %02x:%02x:%02x:%02x:%02x:%02x\n", PRINT_MAC(pAd


->CurrentAddress));
/* GO always use WPA2PSK / AES */
pMbss->AuthMode = Ndis802_11AuthModeWPA2PSK;
pMbss->WepStatus = Ndis802_11Encryption3Enabled;
pMbss->WscSecurityMode = WPA2PSKAES;
pMbss->GroupKeyWepStatus = pMbss->WepStatus;
pMbss->CapabilityInfo =
CAP_GENERATE(1, 0, (pMbss->WepStatus != Ndis802_11Encryp
tionDisabled), TxPreamble, pAd->CommonCfg.bUseShortSlotTime, SpectrumMgmt);
RTMPMakeRSNIE(pAd, Ndis802_11AuthModeWPA2PSK, Ndis802_11Encrypti
on3Enabled, MAIN_MBSSID);
#ifdef DOT11_N_SUPPORT
RTMPSetPhyMode(pAd, pAd->CommonCfg.PhyMode);
SetCommonHT(pAd);
if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && (pAd->Antenn
a.field.TxPath == 2))
{
RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BBPR1);
BBPR1 &= (~0x18);
BBPR1 |= 0x10;
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BBPR1);
}
else
#endif /* DOT11_N_SUPPORT */
{
RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BBPR1);
BBPR1 &= (~0x18);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BBPR1);
}
/* Receiver Antenna selection, write to BBP R3(bit4:3) */
RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3);
BBPR3 &= (~0x18);
if(pAd->Antenna.field.RxPath == 3)
{
BBPR3 |= (0x10);
}
else if(pAd->Antenna.field.RxPath == 2)
{
BBPR3 |= (0x8);
}
else if(pAd->Antenna.field.RxPath == 1)
{
BBPR3 |= (0x0);
}
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
if(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
{
if ((pAd->CommonCfg.PhyMode > PHY_11G) || bWmmCapable)
{
/* EDCA parameters used for AP's own transmissio
n */
pAd->CommonCfg.APEdcaParm.bValid = TRUE;
pAd->CommonCfg.APEdcaParm.Aifsn[0] = 3;

pAd->CommonCfg.APEdcaParm.Aifsn[1] = 7;
pAd->CommonCfg.APEdcaParm.Aifsn[2] = 1;
pAd->CommonCfg.APEdcaParm.Aifsn[3] = 1;
pAd->CommonCfg.APEdcaParm.Cwmin[0]
pAd->CommonCfg.APEdcaParm.Cwmin[1]
pAd->CommonCfg.APEdcaParm.Cwmin[2]
pAd->CommonCfg.APEdcaParm.Cwmin[3]

=
=
=
=

4;
4;
3;
2;

pAd->CommonCfg.APEdcaParm.Cwmax[0]
pAd->CommonCfg.APEdcaParm.Cwmax[1]
pAd->CommonCfg.APEdcaParm.Cwmax[2]
pAd->CommonCfg.APEdcaParm.Cwmax[3]

=
=
=
=

6;
10;
4;
3;

pAd->CommonCfg.APEdcaParm.Txop[0] = 0;
pAd->CommonCfg.APEdcaParm.Txop[1] = 0;
pAd->CommonCfg.APEdcaParm.Txop[2] = 94;
/*96; */
pAd->CommonCfg.APEdcaParm.Txop[3] = 47;
/*48; */
AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm)
;
/* EDCA parameters to be annouced in outgoing BE
ACON, used by WMM STA */
pAd->ApCfg.BssEdcaParm.bValid =
pAd->ApCfg.BssEdcaParm.Aifsn[0]
pAd->ApCfg.BssEdcaParm.Aifsn[1]
pAd->ApCfg.BssEdcaParm.Aifsn[2]
pAd->ApCfg.BssEdcaParm.Aifsn[3]

TRUE;
= 3;
= 7;
= 2;
= 2;

pAd->ApCfg.BssEdcaParm.Cwmin[0]
pAd->ApCfg.BssEdcaParm.Cwmin[1]
pAd->ApCfg.BssEdcaParm.Cwmin[2]
pAd->ApCfg.BssEdcaParm.Cwmin[3]

=
=
=
=

4;
4;
3;
2;

pAd->ApCfg.BssEdcaParm.Cwmax[0]
pAd->ApCfg.BssEdcaParm.Cwmax[1]
pAd->ApCfg.BssEdcaParm.Cwmax[2]
pAd->ApCfg.BssEdcaParm.Cwmax[3]

=
=
=
=

10;
10;
4;
3;

pAd->ApCfg.BssEdcaParm.Txop[0]
pAd->ApCfg.BssEdcaParm.Txop[1]
pAd->ApCfg.BssEdcaParm.Txop[2]
pAd->ApCfg.BssEdcaParm.Txop[3]

=
=
=
=

0;
0;
94;
47;

/*96; */
/*48; */

}
else
{
AsicSetEdcaParm(pAd, NULL);
}
}
#ifdef DOT11_N_SUPPORT
if (pAd->CommonCfg.PhyMode < PHY_11ABGN_MIXED)
{
/* Patch UI */
pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth = BW_
20;
}

/* init */
if (pAd->CommonCfg.bRdg)
{
RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RDG_ACTIVE);
AsicEnableRDG(pAd);
}
else
{
RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RDG_ACTIVE);
AsicDisableRDG(pAd);
}
#endif /* DOT11_N_SUPPORT */
//AsicSetBssid(pAd, pAd->CurrentAddress);
AsicSetMcastWC(pAd);
/* In AP mode, First WCID Table in ASIC will never be used. To
prevent it's 0xff-ff-ff-ff-ff-ff, Write 0 here. */
/* p.s ASIC use all 0xff as termination of WCID table search. */
RTMP_IO_WRITE32(pAd, MAC_WCID_BASE, 0x00);
RTMP_IO_WRITE32(pAd, MAC_WCID_BASE+4, 0x0);
/* reset WCID table */
for (idx=2; idx<255; idx++)
{
offset = MAC_WCID_BASE + (idx * HW_WCID_ENTRY_SIZE);
RTMP_IO_WRITE32(pAd, offset, 0x0);
RTMP_IO_WRITE32(pAd, offset+4, 0x0);
}
pAd->MacTab.Content[0].Addr[0] = 0x01;
pAd->MacTab.Content[0].HTPhyMode.field.MODE = MODE_OFDM;
pAd->MacTab.Content[0].HTPhyMode.field.MCS = 3;
AsicBBPAdjust(pAd);
//MlmeSetTxPreamble(pAd, (USHORT)pAd->CommonCfg.TxPreamble);
{
ULONG Addr4;
UINT32 regValue;
PUCHAR pP2PBssid = &pAd->CurrentAddress[0];
Addr4 = (ULONG)(pP2PBssid[0])
|
(ULONG)(pP2PBssid[1] << 8) |
(ULONG)(pP2PBssid[2] << 16) |
(ULONG)(pP2PBssid[3] << 24);
RTMP_IO_WRITE32(pAd, MAC_BSSID_DW0, Addr4);
Addr4 = 0;
Addr4 = (ULONG)(pP2PBssid[4]) | (ULONG)(pP2PBssid[5] <<
8);
RTMP_IO_WRITE32(pAd, MAC_BSSID_DW1, Addr4);
RTMP_IO_READ32(pAd, MAC_BSSID_DW1, &regValue);
regValue &= 0x0000FFFF;
regValue |= (1 << 16);
if (pAd->chipCap.MBSSIDMode == MBSSID_MODE1)

regValue |= (1 << 21);


RTMP_IO_WRITE32(pAd, MAC_BSSID_DW1, regValue);
}
#ifdef RTMP_MAC_USB
printk("YF DEBUG: RTUSBBssBeaconInit\n");
RTUSBBssBeaconInit(pAd);
#endif /* RTMP_MAC_USB */
}
UCHAR apcliIdx, apidx = MAIN_MBSSID;
//pAd->ApCfg.MBSSID[MAIN_MBSSID].PhyMode = PHY_11BGN_MIXED;
printk("YF DEBUG: Beacon Len %d\n", pBeacon->beacon_len);
printk("YF DEBUG: Beacon Interval %d\n", pBeacon->interval);
BeaconTransmit.word = 0;
RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, BSS
0Mcast_WCID,
pBeacon->beacon_len, PID_MGMT, 0, 0,IFS_HTTXOP, FALSE, &BeaconTr
ansmit);
ptr = (PUCHAR)&pAd->BeaconTxWI;
#ifdef RT_BIG_ENDIAN
RTMPWIEndianChange(ptr, TYPE_TXWI);
#endif
for (i=0; i<TXWISize; i+=4) /* 16-byte TXWI field */
{
longValue = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<
24);
RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[0] + i, longValue);
ptr += 4;
}
/* update BEACON frame content. start right after the 16-byte TXWI field
. */
ptr = pBeacon->beacon;
#ifdef RT_BIG_ENDIAN
RTMPFrameEndianChange(pAd, ptr, DIR_WRITE, FALSE);
#endif
for (i= 0; i< pBeacon->beacon_len; i+=4)
{
longValue = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<
24);
RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[0] + TXWISize + i, longVa
lue);
ptr += 4;
}
if (isAdd)
{
/* Enable Bss Sync*/
RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr9.word);
csr9.field.BeaconInterval = (pBeacon->interval) << 4; /* ASIC re
gister in units of 1/16 TU*/

csr9.field.bTsfTicking = 1;
csr9.field.TsfSyncMode = 3;
csr9.field.bTBTTEnable = 1;
csr9.field.bBeaconGen = 1;
RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
pAd->P2pCfg.bSentProbeRSP = TRUE;
#ifdef RTMP_MAC_USB
/*
* Support multiple BulkIn IRP,
* the value on pAd->CommonCfg.NumOfBulkInIRP may be large than
1.
*/
UCHAR num_idx;
for(num_idx=0; num_idx < pAd->CommonCfg.NumOfBulkInIRP; num_idx+
+)
{
RTUSBBulkReceive(pAd);
printk("RTUSBBulkReceive!\n" );
}
#endif /* RTMP_MAC_USB */
}
#ifdef WFD_SUPPORT
pAd->StaCfg.WfdCfg.bSuppGoOn = TRUE;
#endif /* WFD_SUPPORT */
return TRUE;
}
BOOLEAN CFG80211DRV_OpsExtraIesSet(
VOID
{
PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdOrg;

*pAdOrg)

CFG80211_CB *pCfg80211_CB = pAd->pCfg80211_CB;


UINT ie_len = pCfg80211_CB->pCfg80211_ScanReq->ie_len;
CFG80211DBG(RT_DEBUG_ERROR, ("80211> CFG80211DRV_OpsExtraIesSet ==> %d\n", i
e_len));
if (pAd->StaCfg.pWpsProbeReqIe)
{
os_free_mem(NULL, pAd->StaCfg.pWpsProbeReqIe);
pAd->StaCfg.pWpsProbeReqIe = NULL;
}
pAd->StaCfg.WpsProbeReqIeLen = 0;
CFG80211DBG(RT_DEBUG_ERROR, ("80211> is_wpa_supplicant_up ==> %d\n", pAd
->StaCfg.WpaSupplicantUP));
os_alloc_mem(pAd, (UCHAR **)&(pAd->StaCfg.pWpsProbeReqIe), ie_len);
if (pAd->StaCfg.pWpsProbeReqIe)
{
memcpy(pAd->StaCfg.pWpsProbeReqIe, pCfg80211_CB->pCfg80211_ScanR
eq->ie, ie_len);

pAd->StaCfg.WpsProbeReqIeLen = ie_len;
//hex_dump("WpsProbeReqIe", pAd->StaCfg.pWpsProbeReqIe, pAd->Sta
Cfg.WpsProbeReqIeLen);
DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_WPS_PROBE_REQ_IE, WpsProb
eReqIeLen = %d!!\n",
pAd->StaCfg.WpsProbeReqIeLen));
}
else
{
CFG80211DBG(RT_DEBUG_ERROR, ("80211> CFG80211DRV_OpsExtraIesSet
==> allocate fail. \n"));
return FALSE;
}
return TRUE;
}
BOOLEAN CFG80211DRV_OpsJoinIbss(
VOID
VOID
{
return TRUE;
}
BOOLEAN CFG80211DRV_OpsLeave(
VOID
{
return TRUE;
}
BOOLEAN CFG80211DRV_StaGet(
VOID
VOID
{
PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdOrg;
CMD_RTPRIV_IOCTL_80211_STA *pIbssInfo;

*pAdOrg,
*pData)

*pAdOrg)

*pAdOrg,
*pData)

pIbssInfo = (CMD_RTPRIV_IOCTL_80211_STA *)pData;


#ifdef CONFIG_AP_SUPPORT
{
MAC_TABLE_ENTRY *pEntry;
ULONG DataRate = 0;
UINT32 RSSI;
pEntry = MacTableLookup(pAd, pIbssInfo->MAC);
if (pEntry == NULL)
return FALSE;
/* End of if */
/* fill tx rate */
getRate(pEntry->HTPhyMode, &DataRate);
if ((pEntry->HTPhyMode.field.MODE == MODE_HTMIX) ||
(pEntry->HTPhyMode.field.MODE == MODE_HTGREENFIELD))
{

if (pEntry->HTPhyMode.field.BW)
pIbssInfo->TxRateFlags |= RT_CMD_80211_TXRATE_BW_40;
/* End of if */
if (pEntry->HTPhyMode.field.ShortGI)
pIbssInfo->TxRateFlags |= RT_CMD_80211_TXRATE_SHORT_GI;
/* End of if */
pIbssInfo->TxRateMCS = pEntry->HTPhyMode.field.MCS;
}
else
{
pIbssInfo->TxRateFlags = RT_CMD_80211_TXRATE_LEGACY;
pIbssInfo->TxRateMCS = DataRate*1000; /* unit: 100kbps */
} /* End of if */
/* fill signal */
RSSI = (pEntry->RssiSample.AvgRssi0 +
pEntry->RssiSample.AvgRssi1 +
pEntry->RssiSample.AvgRssi2) / 3;
pIbssInfo->Signal = RSSI;
/* fill tx count */
pIbssInfo->TxPacketCnt = pEntry->OneSecTxNoRetryOkCount +
pEntry->OneSecTxRetryOkCount +
pEntry->OneSecTxFailCount;
/* fill inactive time */
pIbssInfo->InactiveTime = pEntry->NoDataIdleCount * 1000; /* unit: ms */
pIbssInfo->InactiveTime *= MLME_TASK_EXEC_MULTIPLE;
pIbssInfo->InactiveTime /= 20;
}
#endif /* CONFIG_AP_SUPPORT */
return TRUE;
}
BOOLEAN CFG80211DRV_KeyAdd(
VOID
VOID
{

*pAdOrg,
*pData)

return TRUE;
}
BOOLEAN CFG80211DRV_Connect(
VOID
VOID
{

*pAdOrg,
*pData)

return TRUE;
}
VOID CFG80211DRV_RegNotify(
VOID
VOID
{

*pAdOrg,
*pData)

PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdOrg;


CMD_RTPRIV_IOCTL_80211_REG_NOTIFY *pRegInfo;
pRegInfo = (CMD_RTPRIV_IOCTL_80211_REG_NOTIFY *)pData;
/* keep Alpha2 and we can re-call the function when interface is up */
pAd->Cfg80211_Alpha2[0] = pRegInfo->Alpha2[0];
pAd->Cfg80211_Alpha2[1] = pRegInfo->Alpha2[1];
/* apply the new regulatory rule */
if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))
{
/* interface is up */
CFG80211_RegRuleApply(pAd, pRegInfo->pWiphy, (UCHAR *)pRegInfo->
Alpha2);
}
else
{
CFG80211DBG(RT_DEBUG_ERROR, ("crda> interface is down!\n"));
} /* End of if */
}
VOID CFG80211DRV_SurveyGet(
VOID
VOID
{
PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdOrg;
CMD_RTPRIV_IOCTL_80211_SURVEY *pSurveyInfo;

*pAdOrg,
*pData)

pSurveyInfo = (CMD_RTPRIV_IOCTL_80211_SURVEY *)pData;


pSurveyInfo->pCfg80211 = pAd->pCfg80211_CB;
#ifdef AP_QLOAD_SUPPORT
pSurveyInfo->ChannelTimeBusy = pAd->QloadLatestChannelBusyTimePri;
pSurveyInfo->ChannelTimeExtBusy = pAd->QloadLatestChannelBusyTimeSec;
#endif /* AP_QLOAD_SUPPORT */
}
VOID CFG80211_UnRegister(
IN VOID
IN VOID
{
PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdOrg;

*pAdOrg,
*pNetDev)

/* sanity check */
if (pAd->pCfg80211_CB == NULL)
return;
/* End of if */
CFG80211OS_UnRegister(pAd->pCfg80211_CB, pNetDev);
pAd->pCfg80211_CB = NULL;
pAd->CommonCfg.HT_Disable = 0;
}

/*
========================================================================
Routine Description:
Parse and handle country region in beacon from associated AP.
Arguments:
pAdCB
pVIE
LenVIE

- WLAN control block pointer


- Beacon elements
- Total length of Beacon elements

Return Value:
NONE
Note:
========================================================================
*/
VOID CFG80211_BeaconCountryRegionParse(
IN VOID
*pAdCB,
IN NDIS_802_11_VARIABLE_IEs
*pVIE,
IN UINT16
LenVIE)
{
PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdCB;
UCHAR *pElement = (UCHAR *)pVIE;
UINT32 LenEmt;
while(LenVIE > 0)
{
pVIE = (NDIS_802_11_VARIABLE_IEs *)pElement;
if (pVIE->ElementID == IE_COUNTRY)
{
/* send command to do regulation hint only when associat
ed */
RTEnqueueInternalCmd(pAd, CMDTHREAD_REG_HINT_11D,
pVIE->data, pVIE
->Length);
break;
} /* End of if */
LenEmt = pVIE->Length + 2;
if (LenVIE <= LenEmt)
break; /* length is not enough */
/* End of if */
pElement += LenEmt;
LenVIE -= LenEmt;
} /* End of while */
} /* End of CFG80211_BeaconCountryRegionParse */
/*
========================================================================
Routine Description:
Hint to the wireless core a regulatory domain from driver.
Arguments:
pAd

- WLAN control block pointer

pCountryIe
CountryIeLen

- pointer to the country IE


- length of the country IE

Return Value:
NONE
Note:
Must call the function in kernel thread.
========================================================================
*/
VOID CFG80211_RegHint(
IN VOID
*pAdCB,
IN UCHAR
*pCountryIe,
IN ULONG
CountryIeLen)
{
PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdCB;
CFG80211OS_RegHint(CFG80211CB, pCountryIe, CountryIeLen);
} /* End of CFG80211_RegHint */
/*
========================================================================
Routine Description:
Hint to the wireless core a regulatory domain from country element.
Arguments:
pAdCB
pCountryIe
CountryIeLen

- WLAN control block pointer


- pointer to the country IE
- length of the country IE

Return Value:
NONE
Note:
Must call the function in kernel thread.
========================================================================
*/
VOID CFG80211_RegHint11D(
IN VOID
*pAdCB,
IN UCHAR
*pCountryIe,
IN ULONG
CountryIeLen)
{
/* no regulatory_hint_11d() in 2.6.32 */
PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdCB;
CFG80211OS_RegHint11D(CFG80211CB, pCountryIe, CountryIeLen);
} /* End of CFG80211_RegHint11D */
/*
========================================================================
Routine Description:
Apply new regulatory rule.
Arguments:
pAdCB
pWiphy

- WLAN control block pointer


- Wireless hardware description

pAlpha2

- Regulation domain (2B)

Return Value:
NONE
Note:
Can only be called when interface is up.
For general mac80211 device, it will be set to new power by Ops->config(
)
In rt2x00/, the settings is done in rt2x00lib_config().
========================================================================
*/
VOID CFG80211_RegRuleApply(
IN VOID
*pAdCB,
IN VOID
*pWiphy,
IN UCHAR
*pAlpha2)
{
PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdCB;
VOID *pBand24G, *pBand5G;
UINT32 IdBand, IdChan, IdPwr;
UINT32 ChanNum, ChanId, Power, RecId, DfsType;
BOOLEAN FlgIsRadar;
ULONG IrqFlags;
#ifdef DFS_SUPPORT
RADAR_DETECT_STRUCT
*pRadarDetect;
#endif /* DFS_SUPPORT */
CFG80211DBG(RT_DEBUG_ERROR, ("crda> CFG80211_RegRuleApply ==>\n"));
/* init */
pBand24G = NULL;
pBand5G = NULL;
if (pAd == NULL)
return;
RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
/* zero first */
NdisZeroMemory(pAd->ChannelList,
MAX_NUM_OF_CHANNELS * sizeof(CHANNEL_TX_
POWER));
/* 2.4GHZ & 5GHz */
RecId = 0;
#ifdef DFS_SUPPORT
pRadarDetect = &pAd->CommonCfg.RadarDetect;
#endif /* DFS_SUPPORT */
/* find the DfsType */
DfsType = CE;
pBand24G = NULL;
pBand5G = NULL;
if (CFG80211OS_BandInfoGet(CFG80211CB, pWiphy, &pBand24G, &pBand5G) == F
ALSE)
return;

#ifdef AUTO_CH_SELECT_ENHANCE
#ifdef EXT_BUILD_CHANNEL_LIST
if ((pAlpha2[0] != '0') && (pAlpha2[1] != '0'))
{
UINT32 IdReg;
if (pBand5G != NULL)
{
for(IdReg=0; ; IdReg++)
{
if (ChRegion[IdReg].CountReg[0] == 0x00)
break;
/* End of if */
if ((pAlpha2[0] == ChRegion[IdReg].CountReg[0])
&&
(pAlpha2[1] == ChRegion[IdReg].CountReg[
1]))
{
if (pAd->CommonCfg.DfsType != MAX_RD_REG
ION)
DfsType = pAd->CommonCfg.DfsType
;
else
DfsType = ChRegion[IdReg].DfsType;
CFG80211DBG(RT_DEBUG_ERROR,
("crda> find reg
ion %c%c, DFS Type %d\n",
pAlpha2[0], pAlp
ha2[1], DfsType));
break;
} /* End of if */
} /* End of for */
} /* End of if */
} /* End of if */
#endif /* EXT_BUILD_CHANNEL_LIST */
#endif /* AUTO_CH_SELECT_ENHANCE */
for(IdBand=0; IdBand<2; IdBand++)
{
if (((IdBand == 0) && (pBand24G == NULL)) ||
((IdBand == 1) && (pBand5G == NULL)))
{
continue;
} /* End of if */
if (IdBand == 0)
{
CFG80211DBG(RT_DEBUG_ERROR, ("crda> reset chan/power for
2.4GHz\n"));
}
else
{
CFG80211DBG(RT_DEBUG_ERROR, ("crda> reset chan/power for
5GHz\n"));
} /* End of if */
ChanNum = CFG80211OS_ChanNumGet(CFG80211CB, pWiphy, IdBand);

for(IdChan=0; IdChan<ChanNum; IdChan++)


{
if (CFG80211OS_ChanInfoGet(CFG80211CB, pWiphy, IdBand, I
dChan,
&ChanId,
&Power, &FlgIsRadar) == FALSE)
{
/* the channel is not allowed in the regulatory
domain */
/* get next channel information */
continue;
}
if (!WMODE_CAP_2G(pAd->CommonCfg.PhyMode))
{
/* 5G-only mode */
if (ChanId <= CFG80211_NUM_OF_CHAN_2GHZ)
continue;
}
if (!WMODE_CAP_5G(pAd->CommonCfg.PhyMode))
{
/* 2.4G-only mode */
if (ChanId > CFG80211_NUM_OF_CHAN_2GHZ)
continue;
}
for(IdPwr=0; IdPwr<MAX_NUM_OF_CHANNELS; IdPwr++)
{
if (ChanId == pAd->TxPower[IdPwr].Channel)
{
/* init the channel info. */
NdisMoveMemory(&pAd->ChannelList[RecId],
&pAd->Tx
Power[IdPwr],
sizeof(C
HANNEL_TX_POWER));
/* keep channel number */
pAd->ChannelList[RecId].Channel = ChanId
;
/* keep maximum tranmission power */
pAd->ChannelList[RecId].MaxTxPwr = Power
;
/* keep DFS flag */
if (FlgIsRadar == TRUE)
pAd->ChannelList[RecId].DfsReq =
TRUE;
else
pAd->ChannelList[RecId].DfsReq =
FALSE;
/* End of if */
/* keep DFS type */
pAd->ChannelList[RecId].RegulatoryDomain
= DfsType;

/* re-set DFS info. */


pAd->CommonCfg.RDDurRegion = DfsType;
CFG80211DBG(RT_DEBUG_ERROR,
("Chan %03d:\tpo
wer %d dBm, "
"DFS %d, DFS Typ
e %d\n",
ChanId, Power,
((FlgIsRadar ==
TRUE)?1:0),
DfsType));
/* change to record next channel info. *
/
RecId ++;
break;
} /* End of if */
} /* End of for */
} /* End of for */
} /* End of for */
pAd->ChannelListNum = RecId;
RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
CFG80211DBG(RT_DEBUG_ERROR, ("crda> Number of channels = %d\n", RecId));
} /* End of CFG80211_RegRuleApply */
/*
========================================================================
Routine Description:
Inform us that a scan is got.
Arguments:
pAdCB

- WLAN control block pointer

Return Value:
NONE
Note:
Call RT_CFG80211_SCANNING_INFORM, not CFG80211_Scaning
========================================================================
*/
VOID CFG80211_Scaning(
IN VOID
*pAdCB,
IN UINT32
BssIdx,
IN UINT32
ChanId,
IN UCHAR
*pFrame,
IN UINT32
FrameLen,
IN INT32
RSSI)
{
} /* End of CFG80211_Scaning */
/*
========================================================================
Routine Description:
Inform us that scan ends.

Arguments:
pAdCB
FlgIsAborted

- WLAN control block pointer


- 1: scan is aborted

Return Value:
NONE
Note:
========================================================================
*/
VOID CFG80211_ScanEnd(
IN VOID
*pAdCB,
IN BOOLEAN
FlgIsAborted)
{
} /* End of CFG80211_ScanEnd */
/*
========================================================================
Routine Description:
Inform CFG80211 about association status.
Arguments:
pAdCB
pBSSID
pReqIe
ame
ReqIeLen
pRspIe
rame
RspIeLen
FlgIsSuccess

- WLAN control block pointer


- the BSSID of the AP
- the element list in the association request fr
- the request element length
- the element list in the association response f
- the response element length
- 1: success; otherwise: fail

Return Value:
None
Note:
========================================================================
*/
VOID CFG80211_ConnectResultInform(
IN VOID
*pAdCB,
IN UCHAR
*pBSSID,
IN UCHAR
*pReqIe,
IN UINT32
ReqIeLen,
IN UCHAR
*pRspIe,
IN UINT32
RspIeLen,
IN UCHAR
FlgIsSuccess)
{
PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdCB;
CFG80211DBG(RT_DEBUG_ERROR, ("80211> CFG80211_ConnectResultInform ==>\n"
));
CFG80211OS_ConnectResultInform(CFG80211CB,
pBSSID,
pReqIe,
ReqIeLen,
pRspIe,
RspIeLen,

FlgIsSuccess);
pAd->FlgCfg80211Connecting = FALSE;
} /* End of CFG80211_ConnectResultInform */
/*
========================================================================
Routine Description:
Re-Initialize wireless channel/PHY in 2.4GHZ and 5GHZ.
Arguments:
pAdCB

- WLAN control block pointer

Return Value:
TRUE
FALSE

- re-init successfully
- re-init fail

Note:
CFG80211_SupBandInit() is called in xx_probe().
But we do not have complete chip information in xx_probe() so we
need to re-init bands in xx_open().
========================================================================
*/
BOOLEAN CFG80211_SupBandReInit(
IN VOID
*pAdCB)
{
PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdCB;
CFG80211_BAND BandInfo;
CFG80211DBG(RT_DEBUG_ERROR, ("80211> re-init bands...\n"));
/* re-init bands */
NdisZeroMemory(&BandInfo, sizeof(BandInfo));
CFG80211_BANDINFO_FILL(pAd, &BandInfo);
return CFG80211OS_SupBandReInit(CFG80211CB, &BandInfo);
} /* End of CFG80211_SupBandReInit */
INT CFG80211_StaPortSecured(
IN VOID
IN UCHAR
IN UINT
{
PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdCB;
MAC_TABLE_ENTRY *pEntry;

*pAdCB,
*pMac,
flag)

pEntry = MacTableLookup(pAd, pMac);


if (!pEntry)
{
printk("Can't find pEntry in CFG80211_StaPortSecured\n");
}
else
{
if (flag)
{
printk("AID:%d, PortSecured\n", pEntry->Aid);
pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;

pEntry->WpaState = AS_PTKINITDONE;
pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
}
else
{
printk("AID:%d, PortNotSecured\n", pEntry->Aid);
pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;
}
}
return 0;
}
INT CFG80211_ApStaDel(
IN VOID
IN UCHAR
{
PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdCB;
MAC_TABLE_ENTRY *pEntry;

*pAdCB,
*pMac)

if (pMac == NULL)
{
MacTableReset(pAd);
}
else
{
pEntry = MacTableLookup(pAd, pMac);
if (pEntry)
{
//
MlmeDeAuthAction(pAd, pEntry, 2, FALSE);
}
else
printk("Can't find pEntry in ApStaDel\n");
}
}
//CMD_RTPRIV_IOCTL_80211_KEY_DEFAULT_SET:
INT CFG80211_setDefaultKey(
IN VOID
IN UINT
)
{
PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdCB;
CFG80211_CB *p80211CB = pAd->pCfg80211_CB;

*pAdCB,
Data

if (p80211CB->pCfg80211_Wdev->iftype == RT_CMD_80211_IFTYPE_AP)
//if (pAd->VifNextMode == RT_CMD_80211_IFTYPE_AP)
{
printk("Set Ap Default Key: %d\n", Data);
pAd->ApCfg.MBSSID[MAIN_MBSSID].DefaultKeyId = Data;
}
else
return 0;
}
#ifdef RT_P2P_SPECIFIC_WIRELESS_EVENT
INT CFG80211_SendWirelessEvent(
IN VOID

*pAdCB,

IN UCHAR

*pMacAddr)

{
PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdCB;
P2pSendWirelessEvent(pAd, RT_P2P_CONNECTED, NULL, pMacAddr);
return 0;
}
#endif /* RT_P2P_SPECIFIC_WIRELESS_EVENT */
#endif /* RT_CFG80211_SUPPORT */
/* End of cfg80211drv.c */