📄 wlan_ccx.c
字号:
/** @file wlan_ccx.c * @brief This file contains data structures and functions * for CCX standard * * Copyright (c) Marvell Semiconductor, Inc., 2003-2005 *//*********************************************************Change log: 09/27/05: add comments for Doxygen*********************************************************/#ifdef CCX#include "precomp.h"#include "wlan_ccx.h"// For WinCE +++#define u8 UCHAR#define s8 char#define u16 USHORT#define WLAN_STATUS_SUCCESS (0)#define cpu_to_le16(x) x// For WinCE ---#pragma pack(1)// wlan_types.h +++/** Local Power Capability */typedef struct _MrvlIEtypes_PowerCapability_t { MrvlIEtypesHeader_t Header; s8 MinPower; s8 MaxPower;} MrvlIEtypes_PowerCapability_t;// wlan_types.h ---/** OUI Types encoded in the CCX Vendor specific IE. */typedef enum{ CCX_OUI_TYPE_VERSION = 0x03, CCX_OUI_TYPE_QOS_PARAM = 0x04,} CCX_OUI_Type_t;/** CCX IE types that are checked for in BSS descriptions returned in scans. */typedef enum{ CCX_IE_VERSION = VENDOR_SPECIFIC_221, CCX_IE_CELL_POWER_LIMIT = 0x96,} CCX_IE_Id_t;/** Generic IE Structure containing an OUI and oui type used to encapsulate * CCX Proprietary elements. */typedef struct _CCX_IE_OUT_Hdr{ u8 elemId; u8 len; u8 oui[3]; u8 ouiType;} CCX_IE_OUI_Hdr_t; /** CCX Version IE * Received in beacons/probe responses and sent out in (Re)Assocation * requests as a vendor specific 221 element with the OUI set to 0x004096 * and the ouiType set to 0x03. * One octet specifying the major CCX Version supported. */ typedef struct{ CCX_IE_OUI_Hdr_t ouiHdr; u8 version;} CCX_IE_Version_t;/** CCX Cell Power Limit IE * Received in beacon and probe responses (scans) with a Element ID of 0x96 * with the OUI set to 0x004096 and the ouiType set to 0x00. * One octet containing the maximum transmit power for the STA */typedef struct{ CCX_IE_OUI_Hdr_t ouiHdr; u8 maxPower; u8 reserved;} CCX_IE_Cell_Power_Limit_t;#pragma pack()/******************************************************** Local Variables********************************************************//** * Supported version included in CCX Version IE for (Re)Association requests */static u8 ccx_supported_version = 2U;/** * Cisco OUI parsed in Vendor Specific IEs */static u8 cisco_oui[] = { 0x00, 0x40, 0x96 };/******************************************************** Global Variables********************************************************//******************************************************** Local Functions********************************************************//** * @brief Append a ccx version ie to the buffer and advance * the buffer pointer by the size of the IE appended. * Return the size appended. * * @param ppBuffer pointer to the buffer pointer * @return number of bytes appended to **ppBuffer */ static int append_ccx_version_ie( u8** ppBuffer ){ CCX_IE_Version_t versionIe; /* Null checks */ if (ppBuffer == 0) return 0; if (*ppBuffer == 0) return 0; /* Setup OUI Header information */ versionIe.ouiHdr.elemId = CCX_IE_VERSION; versionIe.ouiHdr.len = sizeof(CCX_IE_Version_t) - 2; /* -2 for len + id */ memcpy(versionIe.ouiHdr.oui, cisco_oui, sizeof(cisco_oui)); versionIe.ouiHdr.ouiType = CCX_OUI_TYPE_VERSION; /* Set version to be internally stored supported version */ versionIe.version = ccx_supported_version; /* Copy the stack versionIe to the returned buffer parameter */ memcpy(*ppBuffer, (u8*)&versionIe, sizeof(versionIe)); /* Advance the buffer pointer by the size we appended */ *ppBuffer += sizeof(versionIe); /* Return appended size */ return (sizeof(versionIe));}/** * @brief Append a marvell power capability TLV to the buffer. * The minimum power should be set to 0. The maximum power is * taken from the CCX Cell Power IE received in the scan results * before association. * * @param ppBuffer pointer to the buffer pointer * @param minPower min power in power capability TLV * @param maxPower max power in power capability TLV * @return number of bytes appended to **ppBuffer */ static int append_mrvl_power_capability(u8** ppBuffer, u8 minPower, u8 maxPower){ MrvlIEtypes_PowerCapability_t powerCapIe; /* Null checks */ if (ppBuffer == 0) return 0; if (*ppBuffer == 0) return 0; /* Set up marvell Power Capability TLV with passed parameters */ powerCapIe.Header.Type = cpu_to_le16(TLV_TYPE_POWER_CAPABILITY); powerCapIe.Header.Len = cpu_to_le16(sizeof(powerCapIe) - sizeof(powerCapIe.Header)); powerCapIe.MinPower = minPower; powerCapIe.MaxPower = maxPower; DBGPRINT(DBG_CCX, ("CCX: Power Cap Added: min(%d), max(%d)\n", minPower, maxPower)); /* Copy the stack powerCapIe to the returned buffer parameter */ memcpy(*ppBuffer, (u8*)&powerCapIe, sizeof(powerCapIe));// HEXDUMP("CCX: PwrCap IE", *ppBuffer, sizeof(powerCapIe)); /* Advance the buffer pointer by the size we appended */ *ppBuffer += sizeof(powerCapIe); /* Return appended size */ return (sizeof(powerCapIe));}/******************************************************** Global Functions********************************************************//** * @brief Call back from the main command module to allow CCX proprietary additions * to the association request sent to the firmware. * * @param ppAssocBuf pointer to the buffer pointer for the assoc req. * @param pCcxBssInfo CCX information of the specific AP from the scan * @param enableCcxPwrLimit boolean CCX transmit power control * @return number of bytes added to the assoc. request */ int wlan_ccx_process_association_req(u8** ppAssocBuf, CCX_BSS_Info_t* pCcxBssInfo, int enableCcxPwrLimit){ u8* pBufSav; u16 passThroughLen = 0; MrvlIEtypesHeader_t ieHeader; DBGPRINT(DBG_CCX, ("CCX: process assoc req: %d, %d\n", pCcxBssInfo->ccxEnabled, enableCcxPwrLimit)); /* Null checks */ if (ppAssocBuf == 0) return 0; if (*ppAssocBuf == 0) return 0; if (pCcxBssInfo == 0) return 0; /* ** Return immediately if CCX support isn't required by this specific AP ** we are attempting to associate with. Flag set during scan result ** processing. */ if (pCcxBssInfo->ccxEnabled == FALSE) { return 0; } /* Save off the original buffer pointer */ pBufSav = *ppAssocBuf; /* Increment the buffer pointer by the size of the Marvell TLV header. ** Skip past the buffer space for the header to append the CCX version ** IE. When we get the size of the version IE, then append the ** marvell TLV header with the appropriate size */ *ppAssocBuf += sizeof(MrvlIEtypesHeader_t); /* ** Append the version IE to the association buffer. passThroughLen holds ** the amount of data inserted (used for the passthrough TLV header len */ passThroughLen += append_ccx_version_ie(ppAssocBuf); /* ** Append the TLV Header to the saved buffer pointer (insert it before ** the version IE that was just appended). Set the TLV ID to the ** PASSTHROUGH type and encode the length as the size of the version IE ** previously added. */ ieHeader.Type = TLV_TYPE_PASSTHROUGH; ieHeader.Len = passThroughLen; memcpy(pBufSav, &ieHeader, sizeof(ieHeader)); /* ** If a CCX power IE was sensed in the scan response, and CCX Power ** limiting is enabled (i.e. no AP 11h support), add a power capability ** TLV to the association request setting the max power to the AP ** specified maximum */ if (pCcxBssInfo->maxPowerValid && enableCcxPwrLimit) { append_mrvl_power_capability(ppAssocBuf, 0, pCcxBssInfo->maxPower); } /* Return the length we've appended to the buffer */ return (*ppAssocBuf - pBufSav);}/** * @brief This function processes an element in a description * * @param pCcxBssInfo CCX information * @param pBssElem BSS IE for CCX relevance evaluation * @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE */int wlan_ccx_process_bss_elem(CCX_BSS_Info_t* pCcxBssInfo, u8* pBssElem){ CCX_IE_Version_t* pVersionIe; CCX_IE_Cell_Power_Limit_t* pCellPowerIe; CCX_IE_OUI_Hdr_t* pOuiHdr = (CCX_IE_OUI_Hdr_t*)pBssElem; int enableBssCcxExt = FALSE; DBGPRINT(DBG_CCX, ("CCX: process bss element: %d (0x%x)\n", pOuiHdr->elemId, pOuiHdr->elemId)); /* ** Switch statement based on the element ID encoded in the Header */ switch (pOuiHdr->elemId) { case VENDOR_SPECIFIC_221: /* ** Vendor Specific Element ID 221 passes information for a variety ** of protocols. The CCX elements are identified by the Cisco ** OUI (0x004096), check for it and then the OUI Type to correctly ** parse a CCX Element */ if (NdisEqualMemory(pOuiHdr->oui, cisco_oui, sizeof(cisco_oui)) == 1) { /* Flag the presence of CCX elements */ enableBssCcxExt = TRUE; switch (pOuiHdr->ouiType) { case CCX_OUI_TYPE_VERSION: /* ** CCX Version IE, just identify it for now. May need ** to customize the CCX behavior in the driver and ** supplicant based on the version of CCX the AP supports */ pVersionIe = (CCX_IE_Version_t*)pOuiHdr; DBGPRINT(DBG_CCX, ("CCX: Version IE found: CCX Version %d\n", pVersionIe->version)); break; case CCX_OUI_TYPE_QOS_PARAM: /* ** No longer used in CCX V2 specification v2.13 */ DBGPRINT(DBG_CCX, ("CCX: QOS Param Set IE found: Deprecated\n")); break; default: /* ** Aironet/Cisco OUI specified, but unidentified subtype */ DBGPRINT(DBG_CCX, ("CCX: unhandled oui type: %x (%d)\n", pOuiHdr->ouiType, pOuiHdr->ouiType)); break; } } break; case CCX_IE_CELL_POWER_LIMIT: if (memcmp(pOuiHdr->oui, cisco_oui, sizeof(cisco_oui)) == 0) { /* Flag the presence of CCX elements */ enableBssCcxExt = TRUE; /* ** Set the max power indicated by the Cell Power Limit IE ** in the CCX BSS information structure for this AP. ** Mark it as valid. Used in association processing. */ pCellPowerIe = (CCX_IE_Cell_Power_Limit_t*)pOuiHdr; pCcxBssInfo->maxPowerValid = TRUE; pCcxBssInfo->maxPower = pCellPowerIe->maxPower; DBGPRINT(DBG_CCX, ("CCX: Cell Power Limit IE found: Max Power = %d\n", pCellPowerIe->maxPower)); } break; default: /* ** Not a CCX element */ DBGPRINT(DBG_CCX, ("CCX: Unhandled IE: %d\n", pOuiHdr->elemId)); break; } /* ** If the parsing routines above find CCX elements, set the enable ** flag in the BSS info structure for this AP. Triggers CCX support ** in association processing. */ pCcxBssInfo->ccxEnabled = enableBssCcxExt; /* Succssful return */ return WLAN_STATUS_SUCCESS;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -