Jeff Johnson | 295189b | 2012-06-20 16:38:30 -0700 | [diff] [blame] | 1 | /* |
Jeff Johnson | 32d95a3 | 2012-09-10 13:15:23 -0700 | [diff] [blame] | 2 | * Copyright (c) 2012, The Linux Foundation. All rights reserved. |
Jeff Johnson | 295189b | 2012-06-20 16:38:30 -0700 | [diff] [blame] | 3 | * |
| 4 | * Previously licensed under the ISC license by Qualcomm Atheros, Inc. |
| 5 | * |
| 6 | * |
| 7 | * Permission to use, copy, modify, and/or distribute this software for |
| 8 | * any purpose with or without fee is hereby granted, provided that the |
| 9 | * above copyright notice and this permission notice appear in all |
| 10 | * copies. |
| 11 | * |
| 12 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL |
| 13 | * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED |
| 14 | * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE |
| 15 | * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL |
| 16 | * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR |
| 17 | * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER |
| 18 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
| 19 | * PERFORMANCE OF THIS SOFTWARE. |
| 20 | */ |
| 21 | |
| 22 | /**========================================================================= |
| 23 | * |
| 24 | * \file wlan_qct_wdi_dts.c |
| 25 | * |
| 26 | * \brief Data Transport Service API |
| 27 | * |
| 28 | * WLAN Device Abstraction layer External API for Dataservice |
| 29 | * DESCRIPTION |
| 30 | * This file contains the external API implemntation exposed by the |
| 31 | * wlan device abstarction layer module. |
| 32 | * |
| 33 | * Copyright (c) 2008 QUALCOMM Incorporated. All Rights Reserved. |
| 34 | * Qualcomm Confidential and Proprietary |
| 35 | */ |
| 36 | |
| 37 | |
| 38 | #include "wlan_qct_wdi.h" |
| 39 | #include "wlan_qct_dxe.h" |
| 40 | #include "wlan_qct_wdi_ds.h" |
| 41 | #include "wlan_qct_wdi_ds_i.h" |
| 42 | #include "wlan_qct_wdi_dts.h" |
| 43 | #include "wlan_qct_wdi_dp.h" |
| 44 | #include "wlan_qct_wdi_sta.h" |
| 45 | |
| 46 | static WDTS_TransportDriverTrype gTransportDriver = { |
| 47 | WLANDXE_Open, |
| 48 | WLANDXE_Start, |
| 49 | WLANDXE_ClientRegistration, |
| 50 | WLANDXE_TxFrame, |
| 51 | WLANDXE_CompleteTX, |
| 52 | WLANDXE_SetPowerState, |
Madan Mohan Koyyalamudi | 8cb5398 | 2012-09-28 14:34:47 -0700 | [diff] [blame] | 53 | WLANDXE_ChannelDebug, |
Jeff Johnson | 295189b | 2012-06-20 16:38:30 -0700 | [diff] [blame] | 54 | WLANDXE_Stop, |
| 55 | WLANDXE_Close, |
| 56 | WLANDXE_GetFreeTxDataResNumber |
| 57 | }; |
| 58 | |
| 59 | static WDTS_SetPowerStateCbInfoType gSetPowerStateCbInfo; |
| 60 | |
| 61 | /* DTS Tx packet complete function. |
| 62 | * This function should be invoked by the transport device to indicate |
| 63 | * transmit complete for a frame. |
| 64 | * Parameters: |
| 65 | * pContext:Cookie that should be passed back to the caller |
| 66 | * pFrame:Refernce to PAL frame. |
| 67 | * Return Value: SUCCESS Completed successfully. |
| 68 | * FAILURE_XXX Request was rejected due XXX Reason. |
| 69 | * |
| 70 | */ |
| 71 | wpt_status WDTS_TxPacketComplete(void *pContext, wpt_packet *pFrame, wpt_status status) |
| 72 | { |
| 73 | WDI_DS_ClientDataType *pClientData = (WDI_DS_ClientDataType*)(pContext); |
| 74 | WDI_DS_TxMetaInfoType *pTxMetadata; |
| 75 | void *pvBDHeader, *physBDHeader; |
| 76 | wpt_uint8 staIndex; |
| 77 | |
| 78 | // Do Sanity checks |
| 79 | if(NULL == pContext || NULL == pFrame){ |
| 80 | return eWLAN_PAL_STATUS_E_FAILURE; |
| 81 | } |
| 82 | |
| 83 | |
| 84 | // extract metadata from PAL packet |
| 85 | pTxMetadata = WDI_DS_ExtractTxMetaData(pFrame); |
| 86 | pTxMetadata->txCompleteStatus = status; |
| 87 | |
| 88 | // Free BD header from pool |
| 89 | WDI_GetBDPointers(pFrame, &pvBDHeader, &physBDHeader); |
| 90 | switch(pTxMetadata->frmType) |
| 91 | { |
| 92 | case WDI_MAC_DATA_FRAME: |
Madan Mohan Koyyalamudi | 1541a5b | 2012-10-29 16:18:21 -0700 | [diff] [blame] | 93 | /* note that EAPOL frame hasn't incremented ReserveCount. see |
| 94 | WDI_DS_TxPacket() in wlan_qct_wdi_ds.c |
| 95 | */ |
| 96 | if(!pTxMetadata->isEapol) |
| 97 | { |
Jeff Johnson | 295189b | 2012-06-20 16:38:30 -0700 | [diff] [blame] | 98 | /* SWAP BD header to get STA index for completed frame */ |
| 99 | WDI_SwapTxBd(pvBDHeader); |
| 100 | staIndex = (wpt_uint8)WDI_TX_BD_GET_STA_ID(pvBDHeader); |
| 101 | WDI_DS_MemPoolFree(&(pClientData->dataMemPool), pvBDHeader, physBDHeader); |
| 102 | WDI_DS_MemPoolDecreaseReserveCount(&(pClientData->dataMemPool), staIndex); |
| 103 | break; |
Madan Mohan Koyyalamudi | 1541a5b | 2012-10-29 16:18:21 -0700 | [diff] [blame] | 104 | } |
| 105 | // intentional fall-through to handle eapol packet as mgmt |
Jeff Johnson | 295189b | 2012-06-20 16:38:30 -0700 | [diff] [blame] | 106 | case WDI_MAC_MGMT_FRAME: |
| 107 | WDI_DS_MemPoolFree(&(pClientData->mgmtMemPool), pvBDHeader, physBDHeader); |
| 108 | break; |
| 109 | } |
| 110 | WDI_SetBDPointers(pFrame, 0, 0); |
| 111 | |
| 112 | // Invoke Tx complete callback |
| 113 | pClientData->txCompleteCB(pClientData->pCallbackContext, pFrame); |
| 114 | return eWLAN_PAL_STATUS_SUCCESS; |
| 115 | |
| 116 | } |
| 117 | |
| 118 | |
| 119 | /*=============================================================================== |
| 120 | FUNCTION WLANTL_GetReplayCounterFromRxBD |
| 121 | |
| 122 | DESCRIPTION This function extracts 48-bit replay packet number from RX BD |
| 123 | |
| 124 | DEPENDENCIES Validity of replay check must be done before the function |
| 125 | is called |
| 126 | |
| 127 | PARAMETERS pucRxHeader pointer to RX BD header |
| 128 | |
| 129 | RETRUN v_U64_t Packet number extarcted from RX BD |
| 130 | |
| 131 | SIDE EFFECTS none |
| 132 | ===============================================================================*/ |
| 133 | v_U64_t |
| 134 | WDTS_GetReplayCounterFromRxBD |
| 135 | ( |
| 136 | v_U8_t *pucRxBDHeader |
| 137 | ) |
| 138 | { |
| 139 | v_U64_t ullcurrentReplayCounter = 0; |
| 140 | /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ |
| 141 | /* 48-bit replay counter is created as follows |
| 142 | from RX BD 6 byte PMI command: |
| 143 | Addr : AES/TKIP |
| 144 | 0x38 : pn3/tsc3 |
| 145 | 0x39 : pn2/tsc2 |
| 146 | 0x3a : pn1/tsc1 |
| 147 | 0x3b : pn0/tsc0 |
| 148 | |
| 149 | 0x3c : pn5/tsc5 |
| 150 | 0x3d : pn4/tsc4 */ |
| 151 | |
| 152 | #ifdef ANI_BIG_BYTE_ENDIAN |
| 153 | /* Getting 48-bit replay counter from the RX BD */ |
| 154 | ullcurrentReplayCounter = WDI_RX_BD_GET_PMICMD_20TO23(pucRxBDHeader); |
| 155 | ullcurrentReplayCounter <<= 16; |
| 156 | ullcurrentReplayCounter |= (( WDI_RX_BD_GET_PMICMD_24TO25(pucRxBDHeader) & 0xFFFF0000) >> 16); |
| 157 | return ullcurrentReplayCounter; |
| 158 | #else |
| 159 | /* Getting 48-bit replay counter from the RX BD */ |
| 160 | ullcurrentReplayCounter = (WDI_RX_BD_GET_PMICMD_24TO25(pucRxBDHeader) & 0x0000FFFF); |
| 161 | ullcurrentReplayCounter <<= 32; |
| 162 | ullcurrentReplayCounter |= WDI_RX_BD_GET_PMICMD_20TO23(pucRxBDHeader); |
| 163 | return ullcurrentReplayCounter; |
| 164 | #endif |
| 165 | } |
| 166 | |
| 167 | |
| 168 | /* DTS Rx packet function. |
| 169 | * This function should be invoked by the transport device to indicate |
| 170 | * reception of a frame. |
| 171 | * Parameters: |
| 172 | * pContext:Cookie that should be passed back to the caller |
| 173 | * pFrame:Refernce to PAL frame. |
| 174 | * Return Value: SUCCESS Completed successfully. |
| 175 | * FAILURE_XXX Request was rejected due XXX Reason. |
| 176 | * |
| 177 | */ |
| 178 | wpt_status WDTS_RxPacket (void *pContext, wpt_packet *pFrame, WDTS_ChannelType channel) |
| 179 | { |
| 180 | WDI_DS_ClientDataType *pClientData = |
| 181 | (WDI_DS_ClientDataType*)(pContext); |
| 182 | wpt_boolean bASF, bFSF, bLSF, bAEF; |
| 183 | wpt_uint8 ucMPDUHOffset, ucMPDUHLen, ucTid; |
| 184 | wpt_uint8 *pBDHeader; |
| 185 | wpt_uint16 usMPDUDOffset, usMPDULen; |
| 186 | WDI_DS_RxMetaInfoType *pRxMetadata; |
| 187 | wpt_uint8 isFcBd = 0; |
| 188 | |
| 189 | tpSirMacFrameCtl pMacFrameCtl; |
| 190 | // Do Sanity checks |
| 191 | if(NULL == pContext || NULL == pFrame){ |
| 192 | return eWLAN_PAL_STATUS_E_FAILURE; |
| 193 | } |
| 194 | |
| 195 | /*------------------------------------------------------------------------ |
| 196 | Extract BD header and check if valid |
| 197 | ------------------------------------------------------------------------*/ |
| 198 | pBDHeader = (wpt_uint8*)wpalPacketGetRawBuf(pFrame); |
| 199 | if(NULL == pBDHeader) |
| 200 | { |
| 201 | DTI_TRACE( DTI_TRACE_LEVEL_ERROR, |
| 202 | "WLAN TL:BD header received NULL - dropping packet"); |
| 203 | wpalPacketFree(pFrame); |
| 204 | return eWLAN_PAL_STATUS_E_FAILURE; |
| 205 | } |
| 206 | WDI_SwapRxBd(pBDHeader); |
| 207 | |
| 208 | ucMPDUHOffset = (wpt_uint8)WDI_RX_BD_GET_MPDU_H_OFFSET(pBDHeader); |
| 209 | usMPDUDOffset = (wpt_uint16)WDI_RX_BD_GET_MPDU_D_OFFSET(pBDHeader); |
| 210 | usMPDULen = (wpt_uint16)WDI_RX_BD_GET_MPDU_LEN(pBDHeader); |
| 211 | ucMPDUHLen = (wpt_uint8)WDI_RX_BD_GET_MPDU_H_LEN(pBDHeader); |
| 212 | ucTid = (wpt_uint8)WDI_RX_BD_GET_TID(pBDHeader); |
| 213 | |
| 214 | /*------------------------------------------------------------------------ |
| 215 | Gather AMSDU information |
| 216 | ------------------------------------------------------------------------*/ |
| 217 | bASF = WDI_RX_BD_GET_ASF(pBDHeader); |
| 218 | bAEF = WDI_RX_BD_GET_AEF(pBDHeader); |
| 219 | bFSF = WDI_RX_BD_GET_ESF(pBDHeader); |
| 220 | bLSF = WDI_RX_BD_GET_LSF(pBDHeader); |
| 221 | isFcBd = WDI_RX_FC_BD_GET_FC(pBDHeader); |
| 222 | |
| 223 | DTI_TRACE( DTI_TRACE_LEVEL_INFO, |
| 224 | "WLAN TL:BD header processing data: HO %d DO %d Len %d HLen %d" |
| 225 | " Tid %d BD %d", |
| 226 | ucMPDUHOffset, usMPDUDOffset, usMPDULen, ucMPDUHLen, ucTid, |
| 227 | WDI_RX_BD_HEADER_SIZE); |
| 228 | |
| 229 | if(!isFcBd) |
| 230 | { |
| 231 | if(usMPDUDOffset <= ucMPDUHOffset || usMPDULen < ucMPDUHLen) { |
| 232 | DTI_TRACE( DTI_TRACE_LEVEL_ERROR, |
| 233 | "WLAN TL:BD header corrupted - dropping packet"); |
| 234 | /* Drop packet ???? */ |
| 235 | wpalPacketFree(pFrame); |
| 236 | return eWLAN_PAL_STATUS_SUCCESS; |
| 237 | } |
| 238 | |
| 239 | if((ucMPDUHOffset < WDI_RX_BD_HEADER_SIZE) && (!(bASF && !bFSF))){ |
| 240 | /* AMSDU case, ucMPDUHOffset = 0 it should be hancdled seperatly */ |
| 241 | /* Drop packet ???? */ |
| 242 | wpalPacketFree(pFrame); |
| 243 | return eWLAN_PAL_STATUS_SUCCESS; |
| 244 | } |
| 245 | |
| 246 | /* AMSDU frame, but not first sub-frame |
| 247 | * No MPDU header, MPDU header offset is 0 |
| 248 | * Total frame size is actual frame size + MPDU data offset */ |
| 249 | if((ucMPDUHOffset < WDI_RX_BD_HEADER_SIZE) && (bASF && !bFSF)){ |
| 250 | ucMPDUHOffset = usMPDUDOffset; |
| 251 | } |
| 252 | |
| 253 | if(VPKT_SIZE_BUFFER < (usMPDULen+ucMPDUHOffset)){ |
| 254 | DTI_TRACE( DTI_TRACE_LEVEL_FATAL, |
| 255 | "Invalid Frame size, might memory corrupted"); |
| 256 | wpalPacketFree(pFrame); |
| 257 | return eWLAN_PAL_STATUS_SUCCESS; |
| 258 | } |
| 259 | wpalPacketSetRxLength(pFrame, usMPDULen+ucMPDUHOffset); |
| 260 | wpalPacketRawTrimHead(pFrame, ucMPDUHOffset); |
| 261 | |
| 262 | |
| 263 | |
| 264 | pRxMetadata = WDI_DS_ExtractRxMetaData(pFrame); |
| 265 | |
| 266 | pRxMetadata->fc = isFcBd; |
| 267 | pRxMetadata->staId = WDI_RX_BD_GET_STA_ID(pBDHeader); |
| 268 | pRxMetadata->addr3Idx = WDI_RX_BD_GET_ADDR3_IDX(pBDHeader); |
| 269 | pRxMetadata->rxChannel = WDI_RX_BD_GET_RX_CHANNEL(pBDHeader); |
| 270 | pRxMetadata->rtsf = WDI_RX_BD_GET_RTSF(pBDHeader); |
| 271 | pRxMetadata->bsf = WDI_RX_BD_GET_BSF(pBDHeader); |
| 272 | pRxMetadata->scan = WDI_RX_BD_GET_SCAN(pBDHeader); |
| 273 | pRxMetadata->dpuSig = WDI_RX_BD_GET_DPU_SIG(pBDHeader); |
| 274 | pRxMetadata->ft = WDI_RX_BD_GET_FT(pBDHeader); |
| 275 | pRxMetadata->ne = WDI_RX_BD_GET_NE(pBDHeader); |
| 276 | pRxMetadata->llcr = WDI_RX_BD_GET_LLCR(pBDHeader); |
| 277 | pRxMetadata->bcast = WDI_RX_BD_GET_UB(pBDHeader); |
| 278 | pRxMetadata->tid = ucTid; |
| 279 | pRxMetadata->dpuFeedback = WDI_RX_BD_GET_DPU_FEEDBACK(pBDHeader); |
| 280 | pRxMetadata->rateIndex = WDI_RX_BD_GET_RATEINDEX(pBDHeader); |
| 281 | pRxMetadata->rxpFlags = WDI_RX_BD_GET_RXPFLAGS(pBDHeader); |
| 282 | pRxMetadata->mclkRxTimestamp = WDI_RX_BD_GET_TIMESTAMP(pBDHeader); |
| 283 | |
| 284 | /* typeSubtype in BD doesn't look like correct. Fill from frame ctrl |
| 285 | TL does it for Volans but TL does not know BD for Prima. WDI should do it */ |
| 286 | if ( 0 == WDI_RX_BD_GET_FT(pBDHeader) ) { |
| 287 | if ( bASF ) { |
| 288 | pRxMetadata->subtype = WDI_MAC_DATA_QOS_DATA; |
| 289 | pRxMetadata->type = WDI_MAC_DATA_FRAME; |
| 290 | } else { |
| 291 | pMacFrameCtl = (tpSirMacFrameCtl)(((wpt_uint8*)pBDHeader) + ucMPDUHOffset); |
| 292 | pRxMetadata->subtype = pMacFrameCtl->subType; |
| 293 | pRxMetadata->type = pMacFrameCtl->type; |
| 294 | } |
| 295 | } else { |
| 296 | pMacFrameCtl = (tpSirMacFrameCtl)(((wpt_uint8*)pBDHeader) + WDI_RX_BD_HEADER_SIZE); |
| 297 | pRxMetadata->subtype = pMacFrameCtl->subType; |
| 298 | pRxMetadata->type = pMacFrameCtl->type; |
| 299 | } |
| 300 | |
| 301 | pRxMetadata->mpduHeaderPtr = pBDHeader + ucMPDUHOffset; |
| 302 | pRxMetadata->mpduDataPtr = pBDHeader + usMPDUDOffset; |
| 303 | pRxMetadata->mpduLength = usMPDULen; |
| 304 | pRxMetadata->mpduHeaderLength = ucMPDUHLen; |
| 305 | |
| 306 | /*------------------------------------------------------------------------ |
| 307 | Gather AMPDU information |
| 308 | ------------------------------------------------------------------------*/ |
| 309 | pRxMetadata->ampdu_reorderOpcode = (wpt_uint8)WDI_RX_BD_GET_BA_OPCODE(pBDHeader); |
| 310 | pRxMetadata->ampdu_reorderSlotIdx = (wpt_uint8)WDI_RX_BD_GET_BA_SI(pBDHeader); |
| 311 | pRxMetadata->ampdu_reorderFwdIdx = (wpt_uint8)WDI_RX_BD_GET_BA_FI(pBDHeader); |
| 312 | pRxMetadata->currentPktSeqNo = (wpt_uint8)WDI_RX_BD_GET_BA_CSN(pBDHeader); |
| 313 | |
| 314 | |
| 315 | /*------------------------------------------------------------------------ |
| 316 | Gather AMSDU information |
| 317 | ------------------------------------------------------------------------*/ |
| 318 | pRxMetadata->amsdu_asf = bASF; |
| 319 | pRxMetadata->amsdu_aef = bAEF; |
| 320 | pRxMetadata->amsdu_esf = bFSF; |
| 321 | pRxMetadata->amsdu_lsf = bLSF; |
| 322 | pRxMetadata->amsdu_size = WDI_RX_BD_GET_AMSDU_SIZE(pBDHeader); |
| 323 | |
| 324 | pRxMetadata->rssi0 = WDI_RX_BD_GET_RSSI0(pBDHeader); |
| 325 | pRxMetadata->rssi1 = WDI_RX_BD_GET_RSSI1(pBDHeader); |
| 326 | |
| 327 | |
| 328 | /* Missing: |
| 329 | wpt_uint32 fcSTATxQStatus:8; |
| 330 | wpt_uint32 fcSTAThreshIndMask:8; |
| 331 | wpt_uint32 fcSTAPwrSaveStateMask:8; |
| 332 | wpt_uint32 fcSTAValidMask:8; |
| 333 | |
| 334 | wpt_uint8 fcSTATxQLen[8]; // one byte per STA. |
| 335 | wpt_uint8 fcSTACurTxRate[8]; // current Tx rate for each sta. |
| 336 | unknownUcastPkt |
| 337 | */ |
| 338 | |
| 339 | pRxMetadata->replayCount = WDTS_GetReplayCounterFromRxBD(pBDHeader); |
| 340 | pRxMetadata->snr = WDI_RX_BD_GET_SNR(pBDHeader); |
| 341 | |
| 342 | /* |
| 343 | * PAL BD pointer information needs to be populated |
| 344 | */ |
| 345 | WPAL_PACKET_SET_BD_POINTER(pFrame, pBDHeader); |
| 346 | WPAL_PACKET_SET_BD_LENGTH(pFrame, sizeof(WDI_RxBdType)); |
| 347 | |
| 348 | // Invoke Rx complete callback |
| 349 | pClientData->receiveFrameCB(pClientData->pCallbackContext, pFrame); |
| 350 | } |
| 351 | else |
| 352 | { |
| 353 | wpalPacketSetRxLength(pFrame, usMPDULen+ucMPDUHOffset); |
| 354 | wpalPacketRawTrimHead(pFrame, ucMPDUHOffset); |
| 355 | |
| 356 | pRxMetadata = WDI_DS_ExtractRxMetaData(pFrame); |
| 357 | //flow control related |
| 358 | pRxMetadata->fc = isFcBd; |
| 359 | pRxMetadata->fcStaTxDisabledBitmap = WDI_RX_FC_BD_GET_STA_TX_DISABLED_BITMAP(pBDHeader); |
| 360 | pRxMetadata->fcSTAValidMask = WDI_RX_FC_BD_GET_STA_VALID_MASK(pBDHeader); |
| 361 | // Invoke Rx complete callback |
| 362 | pClientData->receiveFrameCB(pClientData->pCallbackContext, pFrame); |
| 363 | } |
| 364 | return eWLAN_PAL_STATUS_SUCCESS; |
| 365 | |
| 366 | } |
| 367 | |
| 368 | |
| 369 | |
| 370 | /* DTS Out of Resource packet function. |
| 371 | * This function should be invoked by the transport device to indicate |
| 372 | * the device is out of resources. |
| 373 | * Parameters: |
| 374 | * pContext:Cookie that should be passed back to the caller |
| 375 | * priority: indicates which channel is out of resource. |
| 376 | * Return Value: SUCCESS Completed successfully. |
| 377 | * FAILURE_XXX Request was rejected due XXX Reason. |
| 378 | */ |
| 379 | wpt_status WDTS_OOResourceNotification(void *pContext, WDTS_ChannelType channel, wpt_boolean on) |
| 380 | { |
| 381 | WDI_DS_ClientDataType *pClientData = |
| 382 | (WDI_DS_ClientDataType *) pContext; |
| 383 | static wpt_uint8 ac_mask = 0x1f; |
| 384 | |
| 385 | // Do Sanity checks |
| 386 | if(NULL == pContext){ |
| 387 | return eWLAN_PAL_STATUS_E_FAILURE; |
| 388 | } |
| 389 | |
| 390 | if(on){ |
| 391 | ac_mask |= channel == WDTS_CHANNEL_TX_LOW_PRI? 0x0f : 0x10; |
| 392 | } else { |
| 393 | ac_mask &= channel == WDTS_CHANNEL_TX_LOW_PRI? 0x10 : 0x0f; |
| 394 | } |
| 395 | |
| 396 | |
| 397 | // Invoke OOR callback |
| 398 | pClientData->txResourceCB(pClientData->pCallbackContext, ac_mask); |
| 399 | return eWLAN_PAL_STATUS_SUCCESS; |
| 400 | |
| 401 | } |
| 402 | |
| 403 | /* DTS open function. |
| 404 | * On open the transport device should initialize itself. |
| 405 | * Parameters: |
| 406 | * pContext:Cookie that should be passed back to the caller along |
| 407 | * with the callback. |
| 408 | * |
| 409 | * Return Value: SUCCESS Completed successfully. |
| 410 | * FAILURE_XXX Request was rejected due XXX Reason. |
| 411 | * |
| 412 | */ |
| 413 | wpt_status WDTS_openTransport( void *pContext) |
| 414 | { |
| 415 | void *pDTDriverContext; |
| 416 | WDI_DS_ClientDataType *pClientData; |
| 417 | WDI_Status sWdiStatus = WDI_STATUS_SUCCESS; |
| 418 | |
| 419 | pClientData = (WDI_DS_ClientDataType*) wpalMemoryAllocate(sizeof(WDI_DS_ClientDataType)); |
| 420 | if (!pClientData){ |
| 421 | return eWLAN_PAL_STATUS_E_NOMEM; |
| 422 | } |
| 423 | |
| 424 | pClientData->suspend = 0; |
| 425 | WDI_DS_AssignDatapathContext(pContext, (void*)pClientData); |
| 426 | |
| 427 | pDTDriverContext = gTransportDriver.open(); |
| 428 | if( NULL == pDTDriverContext ) |
| 429 | { |
Madan Mohan Koyyalamudi | 87054ba | 2012-11-02 13:24:12 -0700 | [diff] [blame] | 430 | DTI_TRACE( DTI_TRACE_LEVEL_ERROR, " %s fail from transport open", __func__); |
Jeff Johnson | 295189b | 2012-06-20 16:38:30 -0700 | [diff] [blame] | 431 | return eWLAN_PAL_STATUS_E_FAILURE; |
| 432 | } |
| 433 | WDT_AssignTransportDriverContext(pContext, pDTDriverContext); |
| 434 | gTransportDriver.register_client(pDTDriverContext, WDTS_RxPacket, WDTS_TxPacketComplete, |
| 435 | WDTS_OOResourceNotification, (void*)pClientData); |
| 436 | |
| 437 | /* Create a memory pool for Mgmt BDheaders.*/ |
| 438 | sWdiStatus = WDI_DS_MemPoolCreate(&pClientData->mgmtMemPool, WDI_DS_MAX_CHUNK_SIZE, |
| 439 | WDI_DS_HI_PRI_RES_NUM); |
| 440 | if (WDI_STATUS_SUCCESS != sWdiStatus){ |
| 441 | return eWLAN_PAL_STATUS_E_NOMEM; |
| 442 | } |
| 443 | |
| 444 | /* Create a memory pool for Data BDheaders.*/ |
| 445 | sWdiStatus = WDI_DS_MemPoolCreate(&pClientData->dataMemPool, WDI_DS_MAX_CHUNK_SIZE, |
| 446 | WDI_DS_LO_PRI_RES_NUM); |
| 447 | if (WDI_STATUS_SUCCESS != sWdiStatus){ |
| 448 | return eWLAN_PAL_STATUS_E_NOMEM; |
| 449 | } |
| 450 | |
| 451 | return eWLAN_PAL_STATUS_SUCCESS; |
| 452 | |
| 453 | } |
| 454 | |
| 455 | |
| 456 | |
| 457 | /* DTS start function. |
| 458 | * On start the transport device should start running. |
| 459 | * Parameters: |
| 460 | * pContext:Cookie that should be passed back to the caller along |
| 461 | * with the callback. |
| 462 | * |
| 463 | * Return Value: SUCCESS Completed successfully. |
| 464 | * FAILURE_XXX Request was rejected due XXX Reason. |
| 465 | * |
| 466 | */ |
| 467 | wpt_status WDTS_startTransport( void *pContext) |
| 468 | { |
| 469 | void *pDTDriverContext = WDT_GetTransportDriverContext(pContext); |
| 470 | gTransportDriver.start(pDTDriverContext); |
| 471 | return eWLAN_PAL_STATUS_SUCCESS; |
| 472 | |
| 473 | } |
| 474 | |
| 475 | |
| 476 | /* DTS Tx packet function. |
| 477 | * This function should be invoked by the DAL Dataservice to schedule transmit frame through DXE/SDIO. |
| 478 | * Parameters: |
| 479 | * pContext:Cookie that should be passed back to the caller along with the callback. |
| 480 | * pFrame:Refernce to PAL frame. |
| 481 | * Return Value: SUCCESS Completed successfully. |
| 482 | * FAILURE_XXX Request was rejected due XXX Reason. |
| 483 | * |
| 484 | */ |
| 485 | wpt_status WDTS_TxPacket(void *pContext, wpt_packet *pFrame) |
| 486 | { |
| 487 | void *pDTDriverContext = WDT_GetTransportDriverContext(pContext); |
| 488 | WDI_DS_TxMetaInfoType *pTxMetadata; |
| 489 | WDTS_ChannelType channel = WDTS_CHANNEL_TX_LOW_PRI; |
| 490 | wpt_status status = eWLAN_PAL_STATUS_SUCCESS; |
| 491 | |
| 492 | // extract metadata from PAL packet |
| 493 | pTxMetadata = WDI_DS_ExtractTxMetaData(pFrame); |
| 494 | |
| 495 | // assign MDPU to correct channel?? |
| 496 | channel = (pTxMetadata->frmType & WDI_MAC_DATA_FRAME)? |
Madan Mohan Koyyalamudi | 1541a5b | 2012-10-29 16:18:21 -0700 | [diff] [blame] | 497 | /* EAPOL frame uses TX_HIGH_PRIORITY DXE channel |
| 498 | To make sure EAPOL (for second session) is pushed even if TX_LO channel |
| 499 | already reached to low resource condition |
| 500 | This can happen especially in MCC, high data traffic TX in first session |
| 501 | */ |
| 502 | ((pTxMetadata->isEapol) ? WDTS_CHANNEL_TX_HIGH_PRI : WDTS_CHANNEL_TX_LOW_PRI) : WDTS_CHANNEL_TX_HIGH_PRI; |
Jeff Johnson | 295189b | 2012-06-20 16:38:30 -0700 | [diff] [blame] | 503 | // Send packet to Transport Driver. |
| 504 | status = gTransportDriver.xmit(pDTDriverContext, pFrame, channel); |
| 505 | return status; |
| 506 | } |
| 507 | |
| 508 | /* DTS Tx Complete function. |
| 509 | * This function should be invoked by the DAL Dataservice to notify tx completion to DXE/SDIO. |
| 510 | * Parameters: |
| 511 | * pContext:Cookie that should be passed back to the caller along with the callback. |
| 512 | * ucTxResReq:TX resource number required by TL |
| 513 | * Return Value: SUCCESS Completed successfully. |
| 514 | * FAILURE_XXX Request was rejected due XXX Reason. |
| 515 | * |
| 516 | */ |
| 517 | wpt_status WDTS_CompleteTx(void *pContext, wpt_uint32 ucTxResReq) |
| 518 | { |
| 519 | void *pDTDriverContext = WDT_GetTransportDriverContext(pContext); |
| 520 | |
| 521 | // Notify completion to Transport Driver. |
| 522 | return gTransportDriver.txComplete(pDTDriverContext, ucTxResReq); |
| 523 | } |
| 524 | |
| 525 | /* DXE Set power state ACK callback. |
| 526 | * This callback function should be invoked by the DXE to notify WDI that set |
| 527 | * power state request is complete. |
| 528 | * Parameters: |
| 529 | * status: status of the set operation |
| 530 | * Return Value: None. |
| 531 | * |
| 532 | */ |
| 533 | void WDTS_SetPowerStateCb(wpt_status status, unsigned int dxePhyAddr) |
| 534 | { |
| 535 | //print a msg |
| 536 | if(NULL != gSetPowerStateCbInfo.cback) |
| 537 | { |
| 538 | gSetPowerStateCbInfo.cback(status, dxePhyAddr, gSetPowerStateCbInfo.pUserData); |
| 539 | } |
| 540 | } |
| 541 | |
| 542 | |
| 543 | /* DTS Set power state function. |
| 544 | * This function should be invoked by the DAL to notify the WLAN device power state. |
| 545 | * Parameters: |
| 546 | * pContext:Cookie that should be passed back to the caller along with the callback. |
| 547 | * powerState:Power state of the WLAN device. |
| 548 | * Return Value: SUCCESS Set successfully in DXE control blk. |
| 549 | * FAILURE_XXX Request was rejected due XXX Reason. |
| 550 | * |
| 551 | */ |
| 552 | wpt_status WDTS_SetPowerState(void *pContext, WDTS_PowerStateType powerState, |
| 553 | WDTS_SetPowerStateCbType cback) |
| 554 | { |
| 555 | void *pDTDriverContext = WDT_GetTransportDriverContext(pContext); |
| 556 | wpt_status status = eWLAN_PAL_STATUS_SUCCESS; |
| 557 | |
| 558 | if( cback ) |
| 559 | { |
| 560 | //save the cback & cookie |
| 561 | gSetPowerStateCbInfo.pUserData = pContext; |
| 562 | gSetPowerStateCbInfo.cback = cback; |
| 563 | status = gTransportDriver.setPowerState(pDTDriverContext, powerState, |
| 564 | WDTS_SetPowerStateCb); |
| 565 | } |
| 566 | else |
| 567 | { |
| 568 | status = gTransportDriver.setPowerState(pDTDriverContext, powerState, |
| 569 | NULL); |
| 570 | } |
| 571 | |
| 572 | return status; |
| 573 | } |
| 574 | |
Madan Mohan Koyyalamudi | 8cb5398 | 2012-09-28 14:34:47 -0700 | [diff] [blame] | 575 | /* DTS Transport Channel Debug |
| 576 | * Display DXE Channel debugging information |
| 577 | * User may request to display DXE channel snapshot |
| 578 | * Or if host driver detects any abnormal stcuk may display |
| 579 | * Parameters: |
Jeff Johnson | b88db98 | 2012-12-10 13:34:59 -0800 | [diff] [blame^] | 580 | * displaySnapshot : Display DXE snapshot option |
Madan Mohan Koyyalamudi | 8cb5398 | 2012-09-28 14:34:47 -0700 | [diff] [blame] | 581 | * enableStallDetect : Enable stall detect feature |
| 582 | This feature will take effect to data performance |
| 583 | Not integrate till fully verification |
| 584 | * Return Value: NONE |
| 585 | * |
| 586 | */ |
Jeff Johnson | b88db98 | 2012-12-10 13:34:59 -0800 | [diff] [blame^] | 587 | void WDTS_ChannelDebug(wpt_boolean displaySnapshot, wpt_boolean toggleStallDetect) |
Madan Mohan Koyyalamudi | 8cb5398 | 2012-09-28 14:34:47 -0700 | [diff] [blame] | 588 | { |
Jeff Johnson | b88db98 | 2012-12-10 13:34:59 -0800 | [diff] [blame^] | 589 | gTransportDriver.channelDebug(displaySnapshot, toggleStallDetect); |
Madan Mohan Koyyalamudi | 8cb5398 | 2012-09-28 14:34:47 -0700 | [diff] [blame] | 590 | return; |
| 591 | } |
| 592 | |
Jeff Johnson | 295189b | 2012-06-20 16:38:30 -0700 | [diff] [blame] | 593 | /* DTS Stop function. |
| 594 | * Stop Transport driver, ie DXE, SDIO |
| 595 | * Parameters: |
| 596 | * pContext:Cookie that should be passed back to the caller along with the callback. |
| 597 | * Return Value: SUCCESS Completed successfully. |
| 598 | * FAILURE_XXX Request was rejected due XXX Reason. |
| 599 | * |
| 600 | */ |
| 601 | wpt_status WDTS_Stop(void *pContext) |
| 602 | { |
| 603 | void *pDTDriverContext = WDT_GetTransportDriverContext(pContext); |
| 604 | wpt_status status = eWLAN_PAL_STATUS_SUCCESS; |
| 605 | |
| 606 | status = gTransportDriver.stop(pDTDriverContext); |
| 607 | |
| 608 | return status; |
| 609 | } |
| 610 | |
| 611 | /* DTS Stop function. |
| 612 | * Stop Transport driver, ie DXE, SDIO |
| 613 | * Parameters: |
| 614 | * pContext:Cookie that should be passed back to the caller along with the callback. |
| 615 | * Return Value: SUCCESS Completed successfully. |
| 616 | * FAILURE_XXX Request was rejected due XXX Reason. |
| 617 | * |
| 618 | */ |
| 619 | wpt_status WDTS_Close(void *pContext) |
| 620 | { |
| 621 | void *pDTDriverContext = WDT_GetTransportDriverContext(pContext); |
| 622 | WDI_DS_ClientDataType *pClientData = WDI_DS_GetDatapathContext(pContext); |
| 623 | wpt_status status = eWLAN_PAL_STATUS_SUCCESS; |
| 624 | |
| 625 | /*Destroy the mem pool for mgmt BD headers*/ |
| 626 | WDI_DS_MemPoolDestroy(&pClientData->mgmtMemPool); |
| 627 | |
| 628 | /*Destroy the mem pool for mgmt BD headers*/ |
| 629 | WDI_DS_MemPoolDestroy(&pClientData->dataMemPool); |
| 630 | |
| 631 | status = gTransportDriver.close(pDTDriverContext); |
| 632 | |
| 633 | wpalMemoryFree(pClientData); |
| 634 | |
| 635 | return status; |
| 636 | } |
| 637 | |
| 638 | /* Get free TX data descriptor number from DXE |
| 639 | * Parameters: |
| 640 | * pContext: Cookie that should be passed back to the caller along with the callback. |
| 641 | * Return Value: number of free descriptors for TX data channel |
| 642 | * |
| 643 | */ |
| 644 | wpt_uint32 WDTS_GetFreeTxDataResNumber(void *pContext) |
| 645 | { |
| 646 | return |
| 647 | gTransportDriver.getFreeTxDataResNumber(WDT_GetTransportDriverContext(pContext)); |
| 648 | } |