Files
Linux_Drivers/osdrv/extdrv/wireless/mediatek/mt7603/ap/ap_dls.c
forum_service 213c880673 add driver of tp、wiegand-gpio and wireless
Change-Id: Ie3c11d9d85cf1a05042f5690ac711856fe8b1ad7
2023-12-22 09:56:05 +08:00

352 lines
9.6 KiB
C

/****************************************************************************
* 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:
Handle WMM-DLS state machine.
***************************************************************************/
#include "rt_config.h"
#ifdef QOS_DLS_SUPPORT
/*
========================================================================
Routine Description:
DLS state machine init, including state transition and timer init.
Arguments:
pAd points to our adapter
S pointer to the DLS state machine
Trans[]
Return Value:
None
Note:
The state machine looks like the following
DLS_IDLE
MT2_PEER_DLS_REQ PeerDlsReqAction
MT2_PEER_DLS_RSP PeerDlsRspAction
MT2_PEER_DLS_TEAR_DOWN PeerDlsTearDownAction
========================================================================
*/
VOID APDLSStateMachineInit(
IN PRTMP_ADAPTER pAd,
IN STATE_MACHINE *S,
OUT STATE_MACHINE_FUNC Trans[])
{
StateMachineInit(S, (STATE_MACHINE_FUNC*)Trans, MAX_DLS_STATE, MAX_DLS_MSG,
(STATE_MACHINE_FUNC)Drop, DLS_IDLE, DLS_MACHINE_BASE);
StateMachineSetAction(S, DLS_IDLE, MT2_PEER_DLS_REQ,
(STATE_MACHINE_FUNC)APPeerDlsReqAction);
StateMachineSetAction(S, DLS_IDLE, MT2_PEER_DLS_RSP,
(STATE_MACHINE_FUNC)APPeerDlsRspAction);
StateMachineSetAction(S, DLS_IDLE, MT2_PEER_DLS_TEAR_DOWN,
(STATE_MACHINE_FUNC)APPeerDlsTearDownAction);
}
/*
========================================================================
Routine Description:
Handle peer DLS Request action frame.
Arguments:
pAd points to our adapter
*pElem action frame
Return Value:
None
Note:
========================================================================
*/
VOID APPeerDlsReqAction(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *pElem)
{
PMAC_TABLE_ENTRY pDAEntry, pSAEntry;
UCHAR DA[MAC_ADDR_LEN], SA[MAC_ADDR_LEN];
UINT16 CapabilityInfo;
UINT16 DLSTimeout;
PUCHAR pOutBuffer = NULL;
PFRAME_802_11 Fr;
UINT16 Status;
UINT32 FrameLen = 0;
HEADER_802_11 DlsRspHdr;
UCHAR Category = CATEGORY_DLS;
UCHAR Action = ACTION_DLS_RESPONSE;
UCHAR SupportedRatesLen = 0;
UCHAR SupportedRates[MAX_LEN_OF_SUPPORTED_RATES];
HT_CAPABILITY_IE HtCapability;
UCHAR HtCapabilityLen;
/* frame sanity check */
if (!PeerDlsReqSanity(pAd, pElem->Msg, pElem->MsgLen, DA, SA,
&CapabilityInfo, &DLSTimeout,
&SupportedRatesLen, &SupportedRates[0],
&HtCapabilityLen, &HtCapability))
{
return;
}
/* check whether the source station is legal */
pSAEntry = MacTableLookup(pAd, SA);
if (!pSAEntry)
return;
pSAEntry->bDlsInit = FALSE;
/* check whether the destination station exists in our associated table */
pDAEntry = MacTableLookup(pAd, DA);
if (!pDAEntry)
Status = MLME_DEST_STA_NOT_IN_QBSS;
else if (pDAEntry && (pDAEntry->apidx != pSAEntry->apidx))
Status = MLME_DEST_STA_NOT_IN_QBSS;
else if (pDAEntry && !CLIENT_STATUS_TEST_FLAG(pDAEntry, fCLIENT_STATUS_WMM_CAPABLE))
Status = MLME_DEST_STA_IS_NOT_A_QSTA;
else if (pDAEntry->WepStatus != pSAEntry->WepStatus)
Status = MLME_QOS_UNSPECIFY; /* different security algorithm */
else if (!pAd->ApCfg.MBSSID[pSAEntry->apidx].bDLSCapable)
Status = MLME_DLS_NOT_ALLOW_IN_QBSS;
else
Status = MLME_SUCCESS;
if (pDAEntry)
pDAEntry->bDlsInit = FALSE;
/* forward DLS-Request to real destination */
Fr = (PFRAME_802_11)pElem->Msg;
os_alloc_mem(pAd, (UCHAR **)&pOutBuffer, MAX_LEN_OF_MLME_BUFFER);
if(pOutBuffer == NULL)
return;
#ifdef CONFIG_HOTSPOT
if (pAd->ApCfg.MBSSID[pSAEntry->apidx].HotSpotCtrl.L2Filter)
Status = MLME_DLS_NOT_ALLOW_IN_QBSS;
#endif
/*
If status is successful, forward DLS-Request frame to destination
otherwise send DLS-Response with reason code to originator.
*/
#if 1
if (Status == MLME_SUCCESS)
{
NdisMoveMemory(Fr->Hdr.Addr1, DA, MAC_ADDR_LEN);
NdisMoveMemory(Fr->Hdr.Addr2, pAd->ApCfg.MBSSID[pSAEntry->apidx].wdev.bssid, MAC_ADDR_LEN);
NdisMoveMemory(Fr->Hdr.Addr3, SA, MAC_ADDR_LEN);
NdisMoveMemory(pOutBuffer, pElem->Msg, pElem->MsgLen);
FrameLen = pElem->MsgLen;
}
else
{
#else
{
Status = 0; /* for test */
#endif
/* response error to source station */
MgtMacHeaderInit(pAd, &DlsRspHdr, SUBTYPE_ACTION, 0, SA,
pAd->ApCfg.MBSSID[pSAEntry->apidx].wdev.if_addr,
pAd->ApCfg.MBSSID[pSAEntry->apidx].wdev.bssid);
/*
Capability information and supported rate field are present
only when status code is zero.
*/
MakeOutgoingFrame(pOutBuffer, (ULONG *) &FrameLen,
sizeof(HEADER_802_11), &DlsRspHdr,
1, &Category,
1, &Action,
2, &Status,
6, SA,
6, DA,
END_OF_ARGS);
}
/* transmit the frame */
MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
os_free_mem(NULL, pOutBuffer);
DBGPRINT(RT_DEBUG_TRACE,
("DLS - APPeerDlsReqAction() from %02x:%02x:%02x:%02x:%02x:%02x "
"with Status=%d\n",
SA[0], SA[1], SA[2], SA[3], SA[4], SA[5], Status));
}
/*
========================================================================
Routine Description:
Handle peer DLS Response action frame.
Arguments:
pAd points to our adapter
*pElem action frame
Return Value:
None
Note:
========================================================================
*/
VOID APPeerDlsRspAction(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *pElem)
{
PMAC_TABLE_ENTRY pDAEntry, pSAEntry;
UCHAR DA[MAC_ADDR_LEN], SA[MAC_ADDR_LEN];
UINT16 CapabilityInfo;
UINT16 StatusCode;
PUCHAR pOutBuffer = NULL;
PFRAME_802_11 Fr;
UINT32 FrameLen = 0;
UCHAR SupportedRatesLen = 0;
UCHAR SupportedRates[MAX_LEN_OF_SUPPORTED_RATES];
UCHAR HtCapabilityLen;
HT_CAPABILITY_IE HtCapability;
/* frame sanity check */
if (! PeerDlsRspSanity(pAd, pElem->Msg, pElem->MsgLen, DA, SA,
&CapabilityInfo, &StatusCode,
&SupportedRatesLen, &SupportedRates[0],
&HtCapabilityLen, &HtCapability))
{
return;
}
DBGPRINT(RT_DEBUG_TRACE,
("DLS - PeerDlsRspAction() from %02x:%02x:%02x:%02x:%02x:%02x "
"with StatusCode=%d\n",
SA[0], SA[1], SA[2], SA[3], SA[4], SA[5], StatusCode));
/* check whether the source station is legal */
pSAEntry = MacTableLookup(pAd, SA);
if (!pSAEntry)
return;
pDAEntry = MacTableLookup(pAd, DA);
if (!pDAEntry)
{
DBGPRINT(RT_DEBUG_TRACE, ("Destination station does not exist!\n"));
return;
}
pSAEntry->bDlsInit = FALSE;
/* forward DLS-Request to real destination */
Fr = (PFRAME_802_11)pElem->Msg;
os_alloc_mem(pAd, (UCHAR **)&pOutBuffer, MAX_LEN_OF_MLME_BUFFER);
if (pOutBuffer == NULL)
return; /* fatal error, no available memory */
NdisMoveMemory(Fr->Hdr.Addr1, DA, MAC_ADDR_LEN);
NdisMoveMemory(Fr->Hdr.Addr2, pAd->ApCfg.MBSSID[pSAEntry->apidx].wdev.bssid, MAC_ADDR_LEN);
NdisMoveMemory(Fr->Hdr.Addr3, SA, MAC_ADDR_LEN);
NdisMoveMemory(pOutBuffer, pElem->Msg, pElem->MsgLen);
FrameLen = pElem->MsgLen;
/* transmit the response frame */
MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
os_free_mem(NULL, pOutBuffer);
}
/*
========================================================================
Routine Description:
Handle peer DLS Tear down action frame.
Arguments:
pAd points to our adapter
*pElem action frame
Return Value:
None
Note:
========================================================================
*/
VOID APPeerDlsTearDownAction(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *pElem)
{
PMAC_TABLE_ENTRY pDAEntry, pSAEntry;
UCHAR DA[MAC_ADDR_LEN], SA[MAC_ADDR_LEN];
UINT16 ReasonCode;
PUCHAR pOutBuffer = NULL;
PFRAME_802_11 Fr;
UINT32 FrameLen = 0;
/* frame sanity check */
if (! PeerDlsTearDownSanity(pAd, pElem->Msg, pElem->MsgLen,
DA, SA, &ReasonCode))
{
return;
}
DBGPRINT(RT_DEBUG_TRACE,
("DLS - PeerDlsTearDownAction() from %02x:%02x:%02x:%02x:%02x:%02x\n",
SA[0], SA[1], SA[2], SA[3], SA[4], SA[5]));
pSAEntry = MacTableLookup(pAd, SA);
if (!pSAEntry)
return;
pDAEntry = MacTableLookup(pAd, DA);
if (!pDAEntry)
{
DBGPRINT(RT_DEBUG_TRACE, ("Destination station does not exist!\n"));
return;
}
pSAEntry->bDlsInit = FALSE;
/* forward Tear-down to real destination */
Fr = (PFRAME_802_11)pElem->Msg;
os_alloc_mem(pAd, (UCHAR **)&pOutBuffer, MAX_LEN_OF_MLME_BUFFER);
if (pOutBuffer == NULL)
return; /* fatal error, no available memory */
NdisMoveMemory(Fr->Hdr.Addr1, DA, MAC_ADDR_LEN);
NdisMoveMemory(Fr->Hdr.Addr2, pAd->ApCfg.MBSSID[pSAEntry->apidx].wdev.bssid, MAC_ADDR_LEN);
NdisMoveMemory(Fr->Hdr.Addr3, SA, MAC_ADDR_LEN);
NdisMoveMemory(pOutBuffer, pElem->Msg, pElem->MsgLen);
FrameLen = pElem->MsgLen;
/* transmit the tear down frame */
MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
os_free_mem(NULL, pOutBuffer);
}
#endif /* QOS_DLS_SUPPORT */
/* End of ap_dls.c */