BOOLEAN p2psvc_MatchSvcNameHash( IN PP2PSVC_REQ_INFO_ENTRY pInfoEntry, IN POCTET_STRING posSvcNameHash ) { BOOLEAN bMatch = FALSE; PRT_OBJECT_HEADER pSvcNameHashObj = NULL; u4Byte nHashes = posSvcNameHash->Length / 6; u4Byte iterReqHash = 0; if(NULL == (pSvcNameHashObj = P2PSvc_GetParam(&pInfoEntry->objList, P2PSVC_OBJ_HDR_ID_DATA_SVC_NAME_HASH, 0))) {// shall not happen since we have validated when set this req return FALSE; } RT_PRINT_DATA(COMP_P2P, DBG_TRACE, "adv svc hash:\n", pSvcNameHashObj->Value, pSvcNameHashObj->Length); for(iterReqHash = 0; iterReqHash < nHashes; iterReqHash++) { if(0 == PlatformCompareMemory(posSvcNameHash->Octet + (6 * iterReqHash), pSvcNameHashObj->Value, 6)) { RT_PRINT_DATA(COMP_P2P, DBG_TRACE, "Match svc-name-hash:\n", pSvcNameHashObj->Value, pSvcNameHashObj->Length); bMatch = TRUE; break; } } return bMatch; }
/* * C2H event format: * Field TRIGGER CMD_LEN CONTENT CMD_SEQ CMD_ID * BITS [127:120] [119:112] [111:16] [15:8] [7:0] */ s32 c2h_evt_read_88xx(struct adapter *adapter, u8 *buf) { s32 ret = _FAIL; struct c2h_evt_hdr_88xx *c2h_evt; int i; u8 trigger; if (!buf) goto exit; trigger = rtw_read8(adapter, REG_C2HEVT_CLEAR); if (trigger == C2H_EVT_HOST_CLOSE) goto exit; /* Not ready */ else if (trigger != C2H_EVT_FW_CLOSE) goto clear_evt; /* Not a valid value */ c2h_evt = (struct c2h_evt_hdr_88xx *)buf; memset(c2h_evt, 0, 16); c2h_evt->id = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL); c2h_evt->seq = rtw_read8(adapter, REG_C2HEVT_CMD_SEQ_88XX); c2h_evt->plen = rtw_read8(adapter, REG_C2HEVT_CMD_LEN_88XX); RT_PRINT_DATA( _module_hal_init_c_, _drv_info_, "c2h_evt_read(): ", &c2h_evt, sizeof(c2h_evt) ); DBG_871X( "%s id:%u, len:%u, seq:%u, trigger:0x%02x\n", __func__, c2h_evt->id, c2h_evt->plen, c2h_evt->seq, trigger ); /* Read the content */ for (i = 0; i < c2h_evt->plen; i++) c2h_evt->payload[i] = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i); RT_PRINT_DATA(_module_hal_init_c_, _drv_info_, "c2h_evt_read(): Command Content:\n", c2h_evt->payload, c2h_evt->plen); ret = _SUCCESS; clear_evt: /* * Clear event to notify FW we have read the command. * If this field isn't clear, the FW won't update the next command message. */ c2h_evt_clear(adapter); exit: return ret; }
int c2h_evt_read23a(struct rtw_adapter *adapter, u8 *buf) { int ret = _FAIL; struct c2h_evt_hdr *c2h_evt; int i; u8 trigger; if (buf == NULL) goto exit; trigger = rtl8723au_read8(adapter, REG_C2HEVT_CLEAR); if (trigger == C2H_EVT_HOST_CLOSE) goto exit; /* Not ready */ else if (trigger != C2H_EVT_FW_CLOSE) goto clear_evt; /* Not a valid value */ c2h_evt = (struct c2h_evt_hdr *)buf; memset(c2h_evt, 0, 16); *buf = rtl8723au_read8(adapter, REG_C2HEVT_MSG_NORMAL); *(buf + 1) = rtl8723au_read8(adapter, REG_C2HEVT_MSG_NORMAL + 1); RT_PRINT_DATA(_module_hal_init_c_, _drv_info_, "c2h_evt_read23a(): ", &c2h_evt, sizeof(c2h_evt)); if (0) { DBG_8723A("%s id:%u, len:%u, seq:%u, trigger:0x%02x\n", __func__, c2h_evt->id, c2h_evt->plen, c2h_evt->seq, trigger); } /* Read the content */ for (i = 0; i < c2h_evt->plen; i++) c2h_evt->payload[i] = rtl8723au_read8(adapter, REG_C2HEVT_MSG_NORMAL + sizeof(*c2h_evt) + i); RT_PRINT_DATA(_module_hal_init_c_, _drv_info_, "c2h_evt_read23a(): Command Content:\n", c2h_evt->payload, c2h_evt->plen); ret = _SUCCESS; clear_evt: /* * Clear event to notify FW we have read the command. * If this field isn't clear, the FW won't update the * next command message. */ c2h_evt_clear23a(adapter); exit: return ret; }
// // Parsing Information Elements. // // This function is used to search the WPS Fragment IE // In WPS 2.0. It wil content more then 2 IE is the forment // DD-Len-00-50-f2-04-xxxxx-DD-Len-00-50-f2-04 // u1Byte PacketGetElementNum( IN OCTET_STRING packet, IN ELEMENT_ID ID, IN OUI_TYPE OUIType, IN u1Byte OUISubType ) { u2Byte offset; OCTET_STRING IEs; OCTET_STRING ret={0,0}; // used for return u1Byte IENum = 0; if(!PacketGetIeOffset(&packet, &offset)) { return 0; } if(offset < packet.Length) { pu1Byte pIE; u2Byte IELen = (packet.Length - offset); pIE = (packet.Octet + offset); FillOctetString(IEs, pIE,IELen); RT_PRINT_DATA(COMP_WPS, DBG_TRACE, "The IE in the packet :\n", pIE, IELen); do { ret= IEGetElement(IEs, ID, OUIType, OUISubType); if(ret.Length > 0) { IENum++; RT_TRACE(COMP_WPS, DBG_TRACE,("We find a WPS IE in probe or beacon Fragment num is %d \n",IENum)); IELen = IELen - ((u2Byte)(ret.Octet - pIE) + ret.Length); pIE = (ret.Octet + ret.Length); FillOctetString(IEs, pIE,IELen); RT_PRINT_DATA(COMP_WPS, DBG_TRACE, "The IE after WPS IE in the packet :\n", pIE, IELen); } else { RT_TRACE(COMP_WPS, DBG_TRACE,("There is no WPS IE in the probe or beacon\n")); } } while(ret.Length != 0); return IENum; } else { return IENum; } }
RT_STATUS GAS_OnInitReq( IN PADAPTER pAdapter, IN PRT_RFD pRfd, IN POCTET_STRING posMpdu ) { RT_STATUS RtStatus = RT_STATUS_SUCCESS; pu1Byte pOUI = NULL; FunctionIn(COMP_MLME); PlatformIndicateActionFrame(pAdapter, (PVOID)posMpdu); pOUI = Frame_GAS_QueryReq_OUI(*posMpdu); RT_PRINT_DATA(COMP_MLME, DBG_LOUD, ("GAS Initial request: "), pOUI, 3); if( PlatformCompareMemory(pOUI, WFA_OUI, SIZE_OUI) == 0 ) { pOUI = Frame_GAS_QueryReq_Type(*posMpdu); if(0x09 == *pOUI) P2P_OnSDReq(pAdapter, pRfd, posMpdu); } else { RT_TRACE(COMP_MLME, DBG_WARNING, ("No matched OUI: %2x:%2x:%2x\n", pOUI[0], pOUI[1], pOUI[2])); } FunctionOut(COMP_MLME); return RtStatus; }
VOID WPS_CopyRxEAPPacket( IN PADAPTER Adapter, IN PRT_RFD pRfd ) { PSIMPLE_CONFIG_T pSimpleConfig = GET_SIMPLE_CONFIG(&(GetDefaultAdapter(Adapter)->MgntInfo)); pu1Byte RecieveBufPtrt,RfdBufferPtr; pu1Byte BufferPtr = (pu1Byte)&(pRfd->PacketLength ); RT_TRACE(COMP_WPS, DBG_LOUD, ("In WPS Copy EAP Packet\n")); pRfd->PacketLength -= 18;//18 is the length we don't want PlatformFillMemory(pSimpleConfig->RecieveBuf, 1500, 0); PlatformMoveMemory(pSimpleConfig->RecieveBuf,BufferPtr, 2); RecieveBufPtrt = (pu1Byte)pSimpleConfig->RecieveBuf+2; RfdBufferPtr =pRfd->Buffer.VirtualAddress+4; //skip Version DATA TYPE fream control PlatformMoveMemory(RecieveBufPtrt,RfdBufferPtr, ETHERNET_ADDRESS_LENGTH*2); RecieveBufPtrt += (ETHERNET_ADDRESS_LENGTH*2); RfdBufferPtr += (ETHERNET_ADDRESS_LENGTH*2); RfdBufferPtr += 14;//Skip LLC Until 888E if(pRfd->Buffer.VirtualAddress[0] & 0x80) {//Skip QoS RfdBufferPtr += 2; RT_TRACE(COMP_WPS, DBG_LOUD, ("The Data is %x and QoS is Set\n",RfdBufferPtr[0])); pRfd->PacketLength -= 2;//18 is the length we don't want PlatformMoveMemory(pSimpleConfig->RecieveBuf,BufferPtr, 2); } PlatformMoveMemory(RecieveBufPtrt,RfdBufferPtr,(pRfd->PacketLength -(ETHERNET_ADDRESS_LENGTH*2)) ); pSimpleConfig->bRecievePacket = TRUE; pSimpleConfig->RecieveLength = (pRfd->PacketLength+2);// 2 is the packet length we reserved for report to lib RT_PRINT_DATA(COMP_WPS, DBG_LOUD, "EAP Packet Content:", pSimpleConfig->RecieveBuf, pRfd->PacketLength); }
void rtl8822be_tx_fill_special_desc(struct ieee80211_hw *hw, u8 *pdesc, u8 *pbd_desc, struct sk_buff *skb, u8 hw_queue) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); u8 fw_queue; u8 txdesc_len = 48; dma_addr_t mapping = pci_map_single(rtlpci->pdev, skb->data, skb->len, PCI_DMA_TODEVICE); if (pci_dma_mapping_error(rtlpci->pdev, mapping)) { RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "DMA mapping error"); return; } rtl8822be_pre_fill_tx_bd_desc(hw, pbd_desc, pdesc, hw_queue, skb, mapping); /* it should be BEACON_QUEUE or H2C_QUEUE, * so skb=NULL is safe to assert */ fw_queue = _rtl8822be_map_hwqueue_to_fwqueue(NULL, hw_queue); CLEAR_PCI_TX_DESC_CONTENT(pdesc, txdesc_len); /* common part for BEACON and H2C */ SET_TX_DESC_TXPKTSIZE((u8 *)pdesc, (u16)(skb->len)); SET_TX_DESC_QSEL(pdesc, fw_queue); if (hw_queue == H2C_QUEUE) { /* fill H2C */ SET_TX_DESC_OFFSET(pdesc, 0); } else { /* fill beacon */ SET_TX_DESC_OFFSET(pdesc, txdesc_len); SET_TX_DESC_DATARATE(pdesc, DESC_RATE1M); SET_TX_DESC_SW_SEQ(pdesc, 0); SET_TX_DESC_RATE_ID(pdesc, 7); SET_TX_DESC_MACID(pdesc, 0); SET_TX_DESC_LS(pdesc, 1); SET_TX_DESC_OFFSET(pdesc, 48); SET_TX_DESC_USE_RATE(pdesc, 1); } RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, "H2C Tx Cmd Content\n", pdesc, txdesc_len); }
// // Description: // Allocate memory for driver log mechansim. // // Assumption: // Target address had been initalized to NULL pointer. // BOOLEAN AllocDrvLogMemory( IN PADAPTER pAdapter ) { u4Byte i; RT_STATUS status; PVOID pTmp; u4Byte Size; // // Allocate memory block to store pointers to DRV_LOG_POOL_T objects. // Size = LTYPE_TOTAL_COUNT * sizeof(PVOID); status = PlatformAllocateMemory(pAdapter, &pTmp, Size); if( RT_STATUS_SUCCESS != status ) { RT_TRACE(COMP_INIT, DBG_SERIOUS, ("AllocDrvLogMemory(): failed to allocate DRV_LOG_POOLS_HANDLE!!!\n")); return FALSE; } else { RT_TRACE(COMP_INIT, DBG_LOUD, ("AllocDrvLogMemory(): %p is allocated for DRV_LOG_POOLS_HANDLE\n", pTmp)); PlatformZeroMemory(pTmp, Size); SET_DRV_LOG_POOLS_HANDLE(pAdapter, (DRV_LOG_POOL_T**)pTmp); } // // Allocate DRV_LOG_POOL_T objects. // for(i = 0; i < (u4Byte)LTYPE_TOTAL_COUNT; i++) { Size = sizeof(DRV_LOG_POOL_T) + ( sizeof(DRV_LOG_DATA_IMP_T) << g_LogTypes[i].MaxLogCountPwr); status = PlatformAllocateMemory(pAdapter, &pTmp, Size); if( RT_STATUS_SUCCESS != status ) { RT_TRACE(COMP_INIT, DBG_SERIOUS, ("AllocDrvLogMemory(): failed driver log pool %d!!!\n", i)); return FALSE; } else { RT_TRACE(COMP_INIT, DBG_LOUD, ("AllocDrvLogMemory(): %p is allocated for driver log pool %d\n", pTmp, i)); PlatformZeroMemory(pTmp, Size); SET_DRV_LOG_POOL(pAdapter, i, pTmp); GET_DRV_LOG_POOL(pAdapter, i)->pLogDataRing = (PDRV_LOG_DATA_IMP_T)((pu1Byte)pTmp + sizeof(DRV_LOG_POOL_T)); RT_PRINT_DATA(COMP_INIT, DBG_TRACE, "driver log pool: ", (pu1Byte)pTmp, sizeof(DRV_LOG_POOL_T)); } } return TRUE; }
VOID FrameBuf_Dump( IN const FRAME_BUF *pBuf, IN u8Byte dbgComp, IN u4Byte dbgLevel, IN const char * strTitle ) { RT_TRACE(dbgComp, dbgLevel, ("%s()\n", strTitle)); RT_PRINT_DATA(dbgComp, dbgLevel, "", FrameBuf_Head(pBuf), FrameBuf_Length(pBuf)); return; }
RT_STATUS WPS_QueryRxEAPPacket( IN PADAPTER Adapter, IN pu1Byte InformationBuffer, IN u4Byte InformationBufferLength, OUT pu4Byte BytesWritten, OUT pu4Byte BytesNeeded ) { PSIMPLE_CONFIG_T pSimpleConfig = GET_SIMPLE_CONFIG(&(Adapter->MgntInfo)); RT_STATUS status = RT_STATUS_SUCCESS; RT_TRACE(COMP_WPS, DBG_LOUD, ("WPS Check Recieve Buffer:\n")); if( InformationBufferLength < pSimpleConfig->RecieveLength) { *BytesNeeded = pSimpleConfig->RecieveLength; *BytesWritten = 0; return RT_STATUS_INVALID_CONTEXT; } if(!pSimpleConfig->bRecievePacket) { *BytesNeeded =0; //*BytesWritten = 0; } else { RT_PRINT_DATA(COMP_WPS, DBG_LOUD, "Driver report Info Buffer before copy:", InformationBuffer, 16); InformationBufferLength = pSimpleConfig->RecieveLength;//Set For packet length PlatformMoveMemory( InformationBuffer, pSimpleConfig->RecieveBuf, pSimpleConfig->RecieveLength); RT_PRINT_DATA(COMP_WPS, DBG_LOUD, "Driver report Info Buffer After copy:", InformationBuffer, 16); *BytesWritten = pSimpleConfig->RecieveLength; pSimpleConfig->bRecievePacket = FALSE; RT_PRINT_DATA(COMP_WPS, DBG_LOUD, "Driver report EAP Packet Content:", pSimpleConfig->RecieveBuf, pSimpleConfig->RecieveLength); } return status; }
// // Description: In normal chip, we should send some packet to Hw which will be used by Fw // in FW LPS mode. The function is to fill the Tx descriptor of this packets, then // Fw can tell Hw to send these packet derectly. // Added by tynli. 2009.10.15. // static VOID FillFakeTxDescriptor92D( IN PADAPTER Adapter, IN u8* pDesc, IN u32 BufferLen, IN BOOLEAN IsPsPoll ) { HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); struct tx_desc *ptxdesc = (struct tx_desc *)pDesc; // Clear all status _rtw_memset(pDesc, 0, 32); //offset 0 ptxdesc->txdw0 |= cpu_to_le32( OWN | FSG | LSG); //own, bFirstSeg, bLastSeg; ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE+OFFSET_SZ)<<OFFSET_SHT)&0x00ff0000); //32 bytes for TX Desc ptxdesc->txdw0 |= cpu_to_le32(BufferLen&0x0000ffff); // Buffer size + command header //offset 4 ptxdesc->txdw1 |= cpu_to_le32((QSLT_MGNT<<QSEL_SHT)&0x00001f00); // Fixed queue of Mgnt queue //Set NAVUSEHDR to prevent Ps-poll AId filed to be changed to error vlaue by Hw. if(IsPsPoll) { ptxdesc->txdw1 |= cpu_to_le32(NAVUSEHDR); } else { ptxdesc->txdw4 |= cpu_to_le32(BIT(7)); // Hw set sequence number ptxdesc->txdw3 |= cpu_to_le32((8 <<28)); //set bit3 to 1. Suugested by TimChen. 2009.12.29. } //offset 16 ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate if(pHalData->CurrentBandType92D == BAND_ON_5G) ptxdesc->txdw5 |= cpu_to_le32(BIT(2));// use OFDM 6Mbps #ifdef CONFIG_USB_HCI // USB interface drop packet if the checksum of descriptor isn't correct. // Using this checksum can let hardware recovery from packet bulk out error (e.g. Cancel URC, Bulk out error.). rtl8192du_cal_txdesc_chksum(ptxdesc); #endif RT_PRINT_DATA(_module_rtl8712_cmd_c_, _drv_info_, "FillFakeTxDescriptor92D(): H2C Tx Desc Content ----->\n", pDesc, TXDESC_SIZE); }
// // Description: // Validate all params specified by the objcts in the obj list. // RT_STATUS P2PSvc_ValidateParamContent( IN PP2PSVC_OBJ_LIST pObjList ) { RT_STATUS rtStatus = RT_STATUS_SUCCESS; PRT_OBJECT_HEADER pCurObj = NULL; u4Byte objIter = 0; u4Byte paramSpecIdx = 0; PP2PSVC_PARAM_SPEC_ENTRY pParamSpec = NULL; do { u4Byte valLen = 0; for(objIter = 0, pParamSpec = NULL; NULL != (pCurObj = P2PSVC_OBJ_LIST_GET_OBJ(pObjList, objIter)); objIter++) { valLen = pCurObj->Length; if(NULL == (pParamSpec = P2PSvc_GetParamSpec(pCurObj->Id))) { //RT_TRACE(COMP_P2P, DBG_LOUD, ("%s(): param id (0x%08X) can't be found in the param spec tab\n", __FUNCTION__, pCurObj->Id)); //rtStatus = RT_STATUS_INVALID_PARAMETER; //break; continue; } if(!(pParamSpec->minLen <= valLen && valLen <= pParamSpec->maxLen)) { RT_TRACE(COMP_P2P, DBG_LOUD, ("%s(): param id (0x%08X) with invalid len: %u, shall between %u and %u\n", __FUNCTION__, pCurObj->Id, valLen, pParamSpec->minLen, pParamSpec->maxLen)); rtStatus = RT_STATUS_INVALID_LENGTH; break; } } if(RT_STATUS_SUCCESS != rtStatus) { break; } }while(FALSE); if(RT_STATUS_SUCCESS != rtStatus) { RT_PRINT_DATA(COMP_P2P, DBG_WARNING, "ObjList:\n", pObjList, P2PSVC_OBJ_LIST_LEN(pObjList)); } return rtStatus; }
VOID FrameBuf_DumpFrom( IN const FRAME_BUF *pBuf, IN const u1Byte *pHead, IN u8Byte dbgComp, IN u4Byte dbgLevel, IN const char * strTitle ) { const u1Byte *pos, *end; pos = pHead; end = FrameBuf_Head(pBuf) + FrameBuf_Length(pBuf); RT_ASSERT(pHead < end, ("%s(): invalid pHead: %p\n", __FUNCTION__, pHead)); RT_TRACE(dbgComp, dbgLevel, ("%s()\n", strTitle)); RT_PRINT_DATA(dbgComp, dbgLevel, "", pos, (end - pos)); return; }
void SetFwRsvdPagePkt(PADAPTER Adapter, BOOLEAN bDLFinished) { HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); struct xmit_frame *pmgntframe; struct pkt_attrib *pattrib; struct xmit_priv *pxmitpriv = &(Adapter->xmitpriv); struct mlme_ext_priv *pmlmeext = &(Adapter->mlmeextpriv); struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); u32 BeaconLength, ProbeRspLength, PSPollLength, NullFunctionDataLength; u8 *ReservedPagePacket; u8 PageNum=0, U1bTmp, TxDescLen=0, TxDescOffset=0; u16 BufIndex=0; u32 TotalPacketLen; u8 u1RsvdPageLoc[3]={0}; BOOLEAN bDLOK = _FALSE; DBG_871X("%s\n", __FUNCTION__); ReservedPagePacket = (u8*)rtw_malloc(1000); if(ReservedPagePacket == NULL){ DBG_871X("%s(): alloc ReservedPagePacket fail !!!\n", __FUNCTION__); return; } _rtw_memset(ReservedPagePacket, 0, 1000); TxDescLen = 32;//TX_DESC_SIZE; #ifdef CONFIG_USB_HCI BufIndex = TXDESC_OFFSET; TxDescOffset = TxDescLen + PACKET_OFFSET_SZ;; #else BufIndex = 0; TxDescOffset = 0; #endif //(1) beacon ConstructBeacon(Adapter,&ReservedPagePacket[BufIndex],&BeaconLength); RT_PRINT_DATA(_module_rtl8712_cmd_c_, _drv_info_, "SetFwRsvdPagePkt(): HW_VAR_SET_TX_CMD: BCN\n", &ReservedPagePacket[BufIndex], (BeaconLength+BufIndex)); //-------------------------------------------------------------------- // When we count the first page size, we need to reserve description size for the RSVD // packet, it will be filled in front of the packet in TXPKTBUF. U1bTmp = (u8)PageNum_128(BeaconLength+TxDescLen); PageNum += U1bTmp; // To reserved 2 pages for beacon buffer. 2010.06.24. if(PageNum == 1) PageNum+=1; pHalData->FwRsvdPageStartOffset = PageNum; BufIndex = (PageNum*128) + TxDescOffset; //(2) ps-poll ConstructPSPoll(Adapter, &ReservedPagePacket[BufIndex],&PSPollLength); FillFakeTxDescriptor92D(Adapter, &ReservedPagePacket[BufIndex-TxDescLen], PSPollLength, _TRUE); RT_PRINT_DATA(_module_rtl8712_cmd_c_, _drv_info_, "SetFwRsvdPagePkt(): HW_VAR_SET_TX_CMD: PS-POLL\n", &ReservedPagePacket[BufIndex-TxDescLen], (PSPollLength+TxDescLen)); SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1RsvdPageLoc, PageNum ); //------------------------------------------------------------------ U1bTmp = (u8)PageNum_128(PSPollLength+TxDescLen); PageNum += U1bTmp; BufIndex = (PageNum*128) + TxDescOffset; //(3) null data ConstructNullFunctionData( Adapter, &ReservedPagePacket[BufIndex], &NullFunctionDataLength, get_my_bssid(&(pmlmeinfo->network)), _FALSE); FillFakeTxDescriptor92D(Adapter, &ReservedPagePacket[BufIndex-TxDescLen], NullFunctionDataLength, _FALSE); SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1RsvdPageLoc, PageNum); RT_PRINT_DATA(_module_rtl8712_cmd_c_, _drv_info_, "SetFwRsvdPagePkt(): HW_VAR_SET_TX_CMD: NULL DATA \n", &ReservedPagePacket[BufIndex-TxDescLen], (NullFunctionDataLength+TxDescLen)); //------------------------------------------------------------------ U1bTmp = (u8)PageNum_128(NullFunctionDataLength+TxDescLen); PageNum += U1bTmp; BufIndex = (PageNum*128) + TxDescOffset; //(4) probe response ConstructProbeRsp( Adapter, &ReservedPagePacket[BufIndex], &ProbeRspLength, get_my_bssid(&(pmlmeinfo->network)), _FALSE); FillFakeTxDescriptor92D(Adapter, &ReservedPagePacket[BufIndex-TxDescLen], ProbeRspLength, _FALSE); SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1RsvdPageLoc, PageNum); RT_PRINT_DATA(_module_rtl8712_cmd_c_, _drv_info_, "SetFwRsvdPagePkt(): HW_VAR_SET_TX_CMD: PROBE RSP \n", &ReservedPagePacket[BufIndex-TxDescLen], (ProbeRspLength-TxDescLen)); //------------------------------------------------------------------ U1bTmp = (u8)PageNum_128(ProbeRspLength+TxDescLen); PageNum += U1bTmp; TotalPacketLen = (PageNum*128); if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) { return; } //update attribute pattrib = &pmgntframe->attrib; update_mgntframe_attrib(Adapter, pattrib); pattrib->qsel = 0x10; pattrib->pktlen = pattrib->last_txcmdsz = TotalPacketLen - TxDescLen; _rtw_memcpy(pmgntframe->buf_addr, ReservedPagePacket, TotalPacketLen); rtw_hal_mgnt_xmit(Adapter, pmgntframe); bDLOK = _TRUE; if(bDLOK) { DBG_871X("Set RSVD page location to Fw.\n"); FillH2CCmd92D(Adapter, H2C_RSVDPAGE, sizeof(u1RsvdPageLoc), u1RsvdPageLoc); //FillH2CCmd92D(Adapter, H2C_RSVDPAGE, sizeof(RsvdPageLoc), (u8 *)&RsvdPageLoc); } rtw_mfree(ReservedPagePacket,1000); }
static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no, u8 *mac_addr, u8 *key_cont_128, u16 us_config) { struct rtl_priv *rtlpriv = rtl_priv(hw); u32 target_command; u32 target_content = 0; u8 entry_i; RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_DMESG, "Key content:", key_cont_128, 16); for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) { target_command = entry_i + CAM_CONTENT_COUNT * entry_no; target_command = target_command | BIT(31) | BIT(16); if (entry_i == 0) { target_content = (u32) (*(mac_addr + 0)) << 16 | (u32) (*(mac_addr + 1)) << 24 | (u32) us_config; rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI], target_content); rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], target_command); RT_TRACE(COMP_SEC, DBG_LOUD, ("WRITE %x: %x\n", rtlpriv->cfg->maps[WCAMI], target_content)); RT_TRACE(COMP_SEC, DBG_LOUD, ("The Key ID is %d\n", entry_no)); RT_TRACE(COMP_SEC, DBG_LOUD, ("WRITE %x: %x\n", rtlpriv->cfg->maps[RWCAM], target_command)); } else if (entry_i == 1) { target_content = (u32) (*(mac_addr + 5)) << 24 | (u32) (*(mac_addr + 4)) << 16 | (u32) (*(mac_addr + 3)) << 8 | (u32) (*(mac_addr + 2)); rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI], target_content); rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], target_command); RT_TRACE(COMP_SEC, DBG_LOUD, ("WRITE A4: %x\n", target_content)); RT_TRACE(COMP_SEC, DBG_LOUD, ("WRITE A0: %x\n", target_command)); } else { target_content = (u32) (*(key_cont_128 + (entry_i * 4 - 8) + 3)) << 24 | (u32) (*(key_cont_128 + (entry_i * 4 - 8) + 2)) << 16 | (u32) (*(key_cont_128 + (entry_i * 4 - 8) + 1)) << 8 | (u32) (*(key_cont_128 + (entry_i * 4 - 8) + 0)); rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI], target_content); rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], target_command); udelay(100); RT_TRACE(COMP_SEC, DBG_LOUD, ("WRITE A4: %x\n", target_content)); RT_TRACE(COMP_SEC, DBG_LOUD, ("WRITE A0: %x\n", target_command)); } } RT_TRACE(COMP_SEC, DBG_LOUD, ("after set key, usconfig:%x\n", us_config)); }
// // Description: // Validate the object list contains all the required parameters of the id. // E.g., for P2PSVC_OBJ_HDR_ID_ACT_SEEK, the obj list shall contain list of // [svc-name, svc-hash, svc-info-req]. // Each required obj shall appear just once. // Order is not important. // RT_STATUS P2PSvc_ValidateActionParam( IN u4Byte id, IN PP2PSVC_OBJ_LIST pObjList ) { RT_STATUS rtStatus = RT_STATUS_SUCCESS; int actSpecIdx = 0; int nParams = 0; int paramIdx = 0; PP2PSVC_ACTION_SPEC_ENTRY pActSpec = NULL; do { // Search table for(actSpecIdx = 0; P2PSVC_OBJ_HDR_ID_ACT_UNKNOWN != lP2PSvcActionSpecTab[actSpecIdx].actId; actSpecIdx++) { if(id == lP2PSvcActionSpecTab[actSpecIdx].actId) { pActSpec = &(lP2PSvcActionSpecTab[actSpecIdx]); break; } } RT_ASSERT(pActSpec, ("p2psvc_AddSeekInfo(): Spec of P2PSVC_OBJ_HDR_ID_ACT_SEEK not specified in the action spec table\n")); // Count # of parameters if (pActSpec != NULL) { for (nParams = 0; P2PSVC_OBJ_HDR_ID_DATA_UNKNOWN != pActSpec->paramList[nParams]; nParams++) {} } // Shall have exactly 1 set of parameters for(paramIdx = 0; paramIdx < nParams; paramIdx++) {// foreach required parameter u4Byte objIter = 0; PRT_OBJECT_HEADER pCurObj = NULL; u4Byte nOccurrence = 0; for(objIter = 0; objIter < pObjList->nObjs; objIter++) { pCurObj = P2PSVC_OBJ_LIST_GET_OBJ(pObjList, objIter); if(pCurObj->Id == pActSpec->paramList[paramIdx]) nOccurrence++; } if(0 == nOccurrence) { RT_TRACE_F(COMP_P2P, DBG_WARNING, ("param (0x%08X) not found\n", pActSpec->paramList[paramIdx])); rtStatus = RT_STATUS_INVALID_PARAMETER; break; } else if(1 < nOccurrence && P2PSVC_OBJ_HDR_ID_DATA_UNKNOWN != pActSpec->paramList[paramIdx] ) { RT_TRACE_F(COMP_P2P, DBG_WARNING, ("id of cur obj (%u) occur more than once: %u\n", pCurObj->Id, nOccurrence)); rtStatus = RT_STATUS_INVALID_PARAMETER; break; } } if(RT_STATUS_SUCCESS != rtStatus) { break; } }while(FALSE); // Dump raw data if invalid if(RT_STATUS_SUCCESS != rtStatus) { RT_TRACE_F(COMP_P2P, DBG_WARNING, ("[WARNING] info action param\n")); RT_PRINT_DATA(COMP_P2P, DBG_WARNING, "ObjList:\n", pObjList, P2PSVC_OBJ_LIST_LEN(pObjList)); } return rtStatus; }
// // Description: // Checks whether a packet contains any invalid IE. // Implemented based on PacketGetElement(). // // 2008.12.32, haich // BOOLEAN PacketCheckIEValidity( IN OCTET_STRING packet, IN PRT_RFD pRfd ) { u2Byte PacketSubType; u2Byte offset = 0; // current offset to the packet BOOLEAN bRet = TRUE; // used for return u1Byte u1EID; // EID of current IE u1Byte u1ELength; // Length of current IE u2Byte ValidPacketLength=0; do { if(sMacHdrLng > packet.Length) {// not able to get packet type RT_TRACE(COMP_SCAN, DBG_LOUD, ("PacketCheckIEValidity(): sMacHdrLng(%u) > packet.Length (%u)\n", sMacHdrLng, packet.Length)); bRet = FALSE; break; } if(!IsMgntFrame(packet.Octet)) {// not a mangaement frame RT_TRACE(COMP_SCAN, DBG_LOUD, ("PacketCheckIEValidity(): frame type: %u\n", Frame_Type(packet))); bRet = FALSE; break; } PacketSubType = Frame_Subtype(packet); if(PacketSubType > 12) {// beyond deauth RT_TRACE(COMP_SCAN, DBG_LOUD, ("PacketCheckIEValidity(): wrong subtype: %u\n", PacketSubType)); bRet = FALSE; break; } if(!(offset = sPacketIEOffsetTable[PacketSubType])) {// not a sub type of frame that could have IEs RT_TRACE(COMP_SCAN, DBG_LOUD, ("PacketCheckIEValidity(): not a sub type of frame that could have IEs, subtype: %u\n", PacketSubType)); bRet = FALSE; break; } do // for all IEs { if(offset + 2 >= packet.Length) {// [malicious attack] not ok to read EID and Element Length RT_TRACE(COMP_SCAN, DBG_LOUD, ("PacketCheckIEValidity(): [malicious attack] not ok to read EID and Element Length\n")); bRet = TRUE; break; } u1EID = packet.Octet[offset]; // Get current Element ID. u1ELength = packet.Octet[offset+1]; // Get current length of the IE. if(!IsIELengthValid(u1EID, u1ELength)) { bRet = FALSE; break; } if(offset + 2 + u1ELength < packet.Length) {// Jump to the position of length of next IE. (2 byte is for the ID and length field.) offset = offset + 2 + u1ELength; // incr at least 2 for every loop ValidPacketLength = offset; } else if(offset + 2 + u1ELength == packet.Length) {// the IEs in the packet are all valid. bRet = TRUE; ValidPacketLength = offset + 2 + u1ELength; break; } else {// [malicious attack] length of IE exceeds packet length RT_TRACE(COMP_SCAN, DBG_LOUD, ("PacketCheckIEValidity(): [malicious attack] length of IE exceeds packet length\n")); bRet = TRUE; break; } }while(TRUE); }while(FALSE); if(!bRet) { RT_PRINT_DATA(COMP_SCAN, DBG_TRACE, "Packet with wrong IE:", packet.Octet, packet.Length); } pRfd->ValidPacketLength = ValidPacketLength; return bRet; }
// Description: Initialize the global key data in Authenticator. // Output: void // Modify: Annie, 2005-07-02 // I check the data struct again, and discard using pMgntInfo->globalKeyInfo.groupKeyInfo. // Now Global/group key data (PMK, GTK, ANonce): all kept in pMgntInfo->globalKeyInfo. // global key state: recorded in pEntry->perSTAKeyInfo.GrState. (I think it should be kept in per station.) // void Authenticator_GlobalReset( IN PADAPTER Adapter ) { PMGNT_INFO pMgntInfo = &Adapter->MgntInfo; PRT_SECURITY_T pSecInfo = &(pMgntInfo->SecurityInfo); PAUTH_GLOBAL_KEY_TAG pGlInfo = &(pMgntInfo->globalKeyInfo); PRT_WLAN_STA pEntry; int i; u1Byte RdmBuf[20], NonceBuf[KEY_NONCE_LEN]; static u1Byte CAM_CONST_BROAD[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; AESCCMP_BLOCK blockKey; //--- [AnnieWorkaround] See 11i D3.0 page91, GTK should be generated by PRF-X. u1Byte TmpGTK[] = "12345678123456781234567812345678"; //--- RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("===> Authenticator_GlobalReset()\n") ); if( !ACTING_AS_AP(Adapter) ) { RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("[Warning] current: STA mode, return.")); return; } pGlInfo->currentId = 0; if(pSecInfo->SecLvl == RT_SEC_LVL_WPA) pGlInfo->DescriptorType = desc_type_RSN; else pGlInfo->DescriptorType = desc_type_WPA2; GetRandomBuffer( RdmBuf ); for( i=0; i<16; i++ ) { NonceBuf[i] = RdmBuf[i]; NonceBuf[16+i] = RdmBuf[19-i]; } NonceBuf[KEY_NONCE_LEN-1] = 0; //[AnnieWorkaround] Remove it if ANonce addition is ready. 2005-11-25. RT_PRINT_DATA( COMP_AUTHENTICATOR, DBG_LOUD, "Authenticator_GlobalReset(): NonceBuf", NonceBuf, KEY_NONCE_LEN ); // 1. Install PMK if( pGlInfo->PassphraseLen < 64 ){ PasswordHash(pGlInfo->Passphrase, pGlInfo->PassphraseLen, pMgntInfo->Ssid.Octet, pMgntInfo->Ssid.Length, pGlInfo->PMK ); } else { // Add for direct to set PMK 64-Hex mode... if( pGlInfo->PassphraseLen == 64 ) PlatformMoveMemory(pGlInfo->PMK, pGlInfo->Passphrase , 32 ); } // 2. Install GTK // // 2010/12/15 Neo Jou check in // When in Linux AP mode, hostapd will set down GTK before Authenticator_GlobalReset() // Thus for Linux AP mode case, we don't reset GTK here // PlatformZeroMemory( pGlInfo->GTK, GTK_LEN ); PlatformMoveMemory( pGlInfo->GTK, TmpGTK, GTK_LEN ); pGlInfo->TxMICKey = pGlInfo->GTK + GTK_MIC_TX_POS; pGlInfo->RxMICKey = pGlInfo->GTK + GTK_MIC_RX_POS; //AP WPA AES,CCW PlatformMoveMemory( blockKey.x , pGlInfo->GTK , 16); AES_SetKey(blockKey.x, AESCCMP_BLK_SIZE*8, (pu4Byte)pGlInfo->AESGTK); // pSecInfo->GroupTransmitKeyIdx = 1; // 3. Install ANonce // CopyMem( pGlInfo->ANonce, NonceBuf, KEY_NONCE_LEN ); PlatformMoveMemory(pGlInfo->ANonce, NonceBuf, KEY_NONCE_LEN ); // 4. Install GNonce // CopyMem( pGlInfo->GNonce, NonceBuf, KEY_NONCE_LEN ); PlatformMoveMemory(pGlInfo->GNonce, NonceBuf, KEY_NONCE_LEN ); // 5. Reset KeyRSC pGlInfo->KeyRSC = 0; // 6. Reset time slot. pGlInfo->CurrentTimeSlot = 0; #if 1 //Addedby Jay 0713 pGlInfo->TimeSlot_IntegrityFail2 = 0; #endif // 7. IV #if 1 //Added by Jay 0712 for security IV pSecInfo->TxIV = DEFAULT_INIT_TX_IV; #endif pMgntInfo->bAPGlobRest = TRUE; // Reset key information of each station. for(i = 0; i < ASSOCIATE_ENTRY_NUM; i++) { pEntry = &(pMgntInfo->AsocEntry[i]); Authenticator_StateINITIALIZE(Adapter, pEntry); } pMgntInfo->bAPGlobRest = FALSE; //reset SWCamTabe and HWCamtable ,add by CCW AP_ClearAllKey(Adapter); if( (MgntActQuery_ApType(Adapter) == RT_AP_TYPE_NORMAL || MgntActQuery_ApType(Adapter) == RT_AP_TYPE_IBSS_EMULATED || MgntActQuery_ApType(Adapter) == RT_AP_TYPE_LINUX) && ( pMgntInfo->NdisVersion < RT_NDIS_VERSION_6_20 )) { switch( pSecInfo->PairwiseEncAlgorithm ) { case RT_ENC_ALG_TKIP: AP_Setkey( Adapter , CAM_CONST_BROAD, 1, // Index entry CAM_TKIP, 1, // Set Group Key pGlInfo->GTK); break; case RT_ENC_ALG_AESCCMP: AP_Setkey( Adapter , CAM_CONST_BROAD, 1, // Index entry CAM_AES, 1, // Set Group Key pGlInfo->GTK); break; case RT_ENC_ALG_WEP40: case RT_ENC_ALG_WEP104: { static u1Byte CAM_CONST_ADDR[4][6] = { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, {0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}}; u1Byte EncAlgo = ((pSecInfo->PairwiseEncAlgorithm == RT_ENC_ALG_WEP40) ? CAM_WEP40 : CAM_WEP104); for(i = 0; i < 4; i++) { if(pSecInfo->KeyLen[i] > 0) { AP_Setkey( Adapter , CAM_CONST_ADDR[i], i, // Index entry EncAlgo, 1, pSecInfo->KeyBuf[i]); } } } break; default: break; } } RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("<=== Authenticator_GlobalReset()\n") ); }
// // Description: // Indiacate the fake provision discovery response to the upper layer. // Arguments: // [in] pDev - // The device entry which is considered as the respondor for the provision discovery. // [in] pP2PInfo - // P2P information context. // Return: // Return RT_STATUS_SUCCESS if the indication of fake reponse succeeds. // By Bruce, 2015-02-17. // RT_STATUS p2p_IndicateFakePdRspReceived( IN P2P_DEV_LIST_ENTRY *pDev, IN P2P_INFO *pP2PInfo ) { PADAPTER pAdapter = pP2PInfo->pAdapter; RT_STATUS rtStatus = RT_STATUS_SUCCESS; pu1Byte pRxFrame = NULL; FRAME_BUF fbuf; PRT_GEN_TEMP_BUFFER pGenBuf = NULL; FunctionIn(COMP_P2P); do { if(NULL == (pGenBuf = GetGenTempBuffer(pAdapter, GEN_TEMP_BUFFER_SIZE))) { RT_TRACE_F(COMP_P2P, DBG_SERIOUS, ("[ERROR] Memory allocation failed!\n")); rtStatus = RT_STATUS_RESOURCE; break; } FrameBuf_Init(pAdapter->MAX_TRANSMIT_BUFFER_SIZE, 0, (pu1Byte)(pGenBuf->Buffer.Ptr), &fbuf); FrameBuf_SetDbgLevel(&fbuf, DBG_LOUD); if(RT_STATUS_SUCCESS != (rtStatus = p2p_Construct_FakePDRsp( pP2PInfo, pDev, pP2PInfo->DeviceAddress, &fbuf ))) { RT_TRACE_F(COMP_P2P, DBG_WARNING, ("Failed (0x%08X) from p2p_Construct_FakePDRsp()\n", rtStatus)); break; } RT_PRINT_DATA(COMP_P2P, DBG_WARNING, "Fake provision response frame:\n", fbuf.os.Octet, fbuf.os.Length); // Handle PD req dialog token // Note that if status is not success, frame and frameLen could be 0 if(P2P_ADAPTER_OS_SUPPORT_P2P(pP2PInfo->pAdapter)) { // Change dialog token to make sure the token is the same as the previous query. p2p_IndicateActionFrameReceivedWithToken(pP2PInfo, P2P_EVENT_RECEIVED_PROVISION_DISCOVERY_RESPONSE, rtStatus, fbuf.os.Octet, fbuf.os.Length, pP2PInfo->oidDialogToken); } else { p2p_IndicateActionFrameReceived(pP2PInfo, P2P_EVENT_RECEIVED_PROVISION_DISCOVERY_RESPONSE, rtStatus, fbuf.os.Octet, fbuf.os.Length); } }while(FALSE); if(pGenBuf) { ReturnGenTempBuffer (pAdapter, pGenBuf); pGenBuf = NULL; } FunctionOut(COMP_P2P); return rtStatus; }
// // Description: // Validate if the input buffer contains an object with obj list as its payload // RT_STATUS P2PSvc_ValidateReqInfo( IN PVOID infoBuf, IN u4Byte inBufLen, OUT pu4Byte pBytesNeeded ) { RT_STATUS rtStatus = RT_STATUS_SUCCESS; u4Byte bytesNeeded = 0; P2PSVC_FUNC_IN(DBG_LOUD); do { PRT_OBJECT_HEADER pObjHdr = NULL; PP2PSVC_OBJ_LIST pObjList = NULL; u4Byte objIter = 0; // Check if we can read the obj hdr bytesNeeded = RT_OBJECT_HEADER_SIZE; if(inBufLen < bytesNeeded) { RT_TRACE_F(COMP_P2P, DBG_WARNING, ("[WARNING] Buffer (%d) too short for required (%d)!\n", inBufLen, bytesNeeded)); rtStatus = RT_STATUS_INVALID_LENGTH; break; } // Check if the in buf is large enough to hold the data whose length is declared in the obj header pObjHdr = (PRT_OBJECT_HEADER)(infoBuf); if(inBufLen < bytesNeeded + pObjHdr->Length) { RT_TRACE_F(COMP_P2P, DBG_WARNING, ("[WARNING] in buf is not large enough to hold the value, value len: %u, inbuf len: %u!\n", pObjHdr->Length, inBufLen)); rtStatus = RT_STATUS_INVALID_DATA; break; } // Check if the payload is a valid obj list pObjList = (PP2PSVC_OBJ_LIST)(pObjHdr->Value); bytesNeeded += FIELD_OFFSET(P2PSVC_OBJ_LIST, varStart); if(inBufLen < bytesNeeded) { RT_TRACE_F(COMP_P2P, DBG_WARNING, ("[WARNING] in buf is not large enough to hold an obj list, inbuf len: %u!\n", inBufLen)); rtStatus = RT_STATUS_INVALID_DATA; break; } // Validate the obj hdr of the info list if(P2PSVC_OBJ_HDR_ID_DATA_OBJ_LIST != pObjList->hdr.Id) { RT_TRACE_F(COMP_P2P, DBG_WARNING, ("[WARNING] payload is not an obj list, its id is: %u\n", pObjList->hdr.Id)); rtStatus = RT_STATUS_INVALID_DATA; break; } // Check if the objs in the obj list has valid length for(objIter = 0; objIter < pObjList->nObjs; objIter++) { PRT_OBJECT_HEADER pCurObj = NULL; // Check we can read the obj hdr of the current obj if(inBufLen < bytesNeeded + pObjList->ObjTab[objIter] + RT_OBJECT_HEADER_SIZE) { bytesNeeded = bytesNeeded + pObjList->ObjTab[objIter] + RT_OBJECT_HEADER_SIZE; RT_TRACE_F(COMP_P2P, DBG_WARNING, ("[WARNING] obj with index %u is not valid\n", objIter)); rtStatus = RT_STATUS_INVALID_DATA; break; } // Get the obj pCurObj = P2PSVC_OBJ_LIST_GET_OBJ(pObjList, objIter); // Check the hdr of the cur obj if(inBufLen < bytesNeeded + pObjList->ObjTab[objIter] + RT_OBJECT_HEADER_SIZE + pCurObj->Length) { bytesNeeded = bytesNeeded + pObjList->ObjTab[objIter] + RT_OBJECT_HEADER_SIZE + pCurObj->Length; RT_TRACE_F(COMP_P2P, DBG_WARNING, ("[WARNING] inbuf (len: %u) is not large enough to hold the obj (index: %u, len: %u)\n", inBufLen, objIter, pCurObj->Length)); rtStatus = RT_STATUS_INVALID_DATA; break; } } if(RT_STATUS_SUCCESS != rtStatus) { break; } }while(FALSE); *pBytesNeeded = bytesNeeded; // Dump raw data if invalid if(RT_STATUS_SUCCESS != rtStatus) { RT_TRACE_F(COMP_P2P, DBG_WARNING, ("[WARNING] info req invalid, bytesNeeded: %u\n", *pBytesNeeded)); RT_PRINT_DATA(COMP_P2P, DBG_WARNING, "InBuf:\n", infoBuf, inBufLen); } P2PSVC_FUNC_OUT(DBG_LOUD, rtStatus); return rtStatus; }
void rtl92c_set_key(struct ieee80211_hw *hw, u32 key_index, u8 *p_macaddr, bool is_group, u8 enc_algo, bool is_wepkey, bool clear_all) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); u8 *macaddr = p_macaddr; u32 entry_id = 0; bool is_pairwise = false; static u8 cam_const_addr[4][6] = { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, {0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, {0x00, 0x00, 0x00, 0x00, 0x00, 0x03} }; static u8 cam_const_broad[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; if (clear_all) { u8 idx = 0; u8 cam_offset = 0; u8 clear_number = 5; RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n"); for (idx = 0; idx < clear_number; idx++) { rtl_cam_mark_invalid(hw, cam_offset + idx); rtl_cam_empty_entry(hw, cam_offset + idx); if (idx < 5) { memset(rtlpriv->sec.key_buf[idx], 0, MAX_KEY_LEN); rtlpriv->sec.key_len[idx] = 0; } } } else { switch (enc_algo) { case WEP40_ENCRYPTION: enc_algo = CAM_WEP40; break; case WEP104_ENCRYPTION: enc_algo = CAM_WEP104; break; case TKIP_ENCRYPTION: enc_algo = CAM_TKIP; break; case AESCCMP_ENCRYPTION: enc_algo = CAM_AES; break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "illegal switch case\n"); enc_algo = CAM_TKIP; break; } if (is_wepkey || rtlpriv->sec.use_defaultkey) { macaddr = cam_const_addr[key_index]; entry_id = key_index; } else { if (is_group) { macaddr = cam_const_broad; entry_id = key_index; } else { if (mac->opmode == NL80211_IFTYPE_AP || mac->opmode == NL80211_IFTYPE_MESH_POINT) { entry_id = rtl_cam_get_free_entry(hw, p_macaddr); if (entry_id >= TOTAL_CAM_ENTRY) { RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG, "Can not find free hw security cam entry\n"); return; } } else { entry_id = CAM_PAIRWISE_KEY_POSITION; } key_index = PAIRWISE_KEYIDX; is_pairwise = true; } } if (rtlpriv->sec.key_len[key_index] == 0) { RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "delete one entry\n"); if (mac->opmode == NL80211_IFTYPE_AP || mac->opmode == NL80211_IFTYPE_MESH_POINT) rtl_cam_del_entry(hw, p_macaddr); rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); } else { RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "The insert KEY length is %d\n", rtlpriv->sec.key_len[PAIRWISE_KEYIDX]); RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "The insert KEY is %x %x\n", rtlpriv->sec.key_buf[0][0], rtlpriv->sec.key_buf[0][1]); RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "add one entry\n"); if (is_pairwise) { RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD, "Pairwise Key content", rtlpriv->sec.pairwise_key, rtlpriv->sec. key_len[PAIRWISE_KEYIDX]); RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "set Pairwise key\n"); rtl_cam_add_one_entry(hw, macaddr, key_index, entry_id, enc_algo, CAM_CONFIG_NO_USEDK, rtlpriv->sec. key_buf[key_index]); } else { RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "set group key\n"); if (mac->opmode == NL80211_IFTYPE_ADHOC) { rtl_cam_add_one_entry(hw, rtlefuse->dev_addr, PAIRWISE_KEYIDX, CAM_PAIRWISE_KEY_POSITION, enc_algo, CAM_CONFIG_NO_USEDK, rtlpriv->sec.key_buf [entry_id]); } rtl_cam_add_one_entry(hw, macaddr, key_index, entry_id, enc_algo, CAM_CONFIG_NO_USEDK, rtlpriv->sec.key_buf[entry_id]); } } } }
void rtl92su_read_eeprom_info(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv); struct rtl_phy *rtlphy = &(rtlpriv->phy); struct r92su_eeprom eeprom; u16 i, eeprom_id; u8 tempval; u8 rf_path, index; rtl92s_read_eeprom_info(hw); switch (rtlefuse->epromtype) { case EEPROM_BOOT_EFUSE: rtl_efuse_shadow_map_update(hw); break; case EEPROM_93C46: pr_err("RTL819X Not boot from eeprom, check it !!\n"); return; default: pr_warn("rtl92su: no efuse data\n\n"); return; } memcpy(&eeprom, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0], HWSET_MAX_SIZE_92S); RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, "MAP", &eeprom, sizeof(eeprom)); eeprom_id = le16_to_cpu(eeprom.id); if (eeprom_id != RTL8190_EEPROM_ID) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, "EEPROM ID(%#x) is invalid!!\n", eeprom_id); rtlefuse->autoload_failflag = true; return; } RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); rtlefuse->autoload_failflag = false; rtl92s_get_IC_Inferiority(hw); /* Read IC Version && Channel Plan */ /* VID, DID SE 0xA-D */ rtlefuse->eeprom_vid = le16_to_cpu(eeprom.vid); rtlefuse->eeprom_did = le16_to_cpu(eeprom.did); rtlefuse->eeprom_svid = 0; rtlefuse->eeprom_smid = 0; rtlefuse->eeprom_version = eeprom.version; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROMId = 0x%4x\n", eeprom_id); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid); ether_addr_copy(rtlefuse->dev_addr, eeprom.mac_addr); for (i = 0; i < 6; i++) rtl_write_byte(rtlpriv, MACIDR0 + i, rtlefuse->dev_addr[i]); RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "%pM\n", rtlefuse->dev_addr); /* Get Tx Power Level by Channel */ /* Read Tx power of Channel 1 ~ 14 from EEPROM. */ /* 92S suupport RF A & B */ for (rf_path = 0; rf_path < RF_PATH; rf_path++) { for (i = 0; i < CHAN_SET; i++) { /* Read CCK RF A & B Tx power */ rtlefuse->eeprom_chnlarea_txpwr_cck[rf_path][i] = eeprom.tx_pwr_cck[rf_path][i]; /* Read OFDM RF A & B Tx power for 1T */ rtlefuse->eeprom_chnlarea_txpwr_ht40_1s[rf_path][i] = eeprom.tx_pwr_ht40_1t[rf_path][i]; /* Read OFDM RF A & B Tx power for 2T */ rtlefuse->eprom_chnl_txpwr_ht40_2sdf[rf_path][i] = eeprom.tx_pwr_ht40_2t[rf_path][i]; } } for (rf_path = 0; rf_path < RF_PATH; rf_path++) { for (i = 0; i < CHAN_SET; i++) { /* Read Power diff limit. */ rtlefuse->eeprom_pwrgroup[rf_path][i] = eeprom.tx_pwr_edge[rf_path][i]; } } for (rf_path = 0; rf_path < RF_PATH; rf_path++) for (i = 0; i < CHAN_SET; i++) RTPRINT(rtlpriv, FINIT, INIT_EEPROM, "RF(%d) EEPROM CCK Area(%d) = 0x%x\n", rf_path, i, rtlefuse->eeprom_chnlarea_txpwr_cck [rf_path][i]); for (rf_path = 0; rf_path < RF_PATH; rf_path++) for (i = 0; i < CHAN_SET; i++) RTPRINT(rtlpriv, FINIT, INIT_EEPROM, "RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n", rf_path, i, rtlefuse->eeprom_chnlarea_txpwr_ht40_1s [rf_path][i]); for (rf_path = 0; rf_path < RF_PATH; rf_path++) for (i = 0; i < CHAN_SET; i++) RTPRINT(rtlpriv, FINIT, INIT_EEPROM, "RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n", rf_path, i, rtlefuse->eprom_chnl_txpwr_ht40_2sdf [rf_path][i]); for (rf_path = 0; rf_path < RF_PATH; rf_path++) { /* Assign dedicated channel tx power */ for (i = 0; i < 14; i++) { /* channel 1~3 use the same Tx Power Level. */ if (i < 3) index = 0; /* Channel 4-8 */ else if (i < 8) index = 1; /* Channel 9-14 */ else index = 2; /* Record A & B CCK /OFDM - 1T/2T Channel area * tx power */ rtlefuse->txpwrlevel_cck[rf_path][i] = rtlefuse->eeprom_chnlarea_txpwr_cck [rf_path][index]; rtlefuse->txpwrlevel_ht40_1s[rf_path][i] = rtlefuse->eeprom_chnlarea_txpwr_ht40_1s [rf_path][index]; rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = rtlefuse->eprom_chnl_txpwr_ht40_2sdf [rf_path][index]; } for (i = 0; i < 14; i++) { RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, "RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = [0x%x / 0x%x / 0x%x]\n", rf_path, i, rtlefuse->txpwrlevel_cck[rf_path][i], rtlefuse->txpwrlevel_ht40_1s[rf_path][i], rtlefuse->txpwrlevel_ht40_2s[rf_path][i]); } } for (rf_path = 0; rf_path < 2; rf_path++) { /* Fill Pwr group */ for (i = 0; i < 14; i++) { /* Chanel 1-3 */ if (i < 3) index = 0; /* Channel 4-8 */ else if (i < 8) index = 1; /* Channel 9-13 */ else index = 2; rtlefuse->pwrgroup_ht20[rf_path][i] = (rtlefuse->eeprom_pwrgroup[rf_path][index] & 0xf); rtlefuse->pwrgroup_ht40[rf_path][i] = ((rtlefuse->eeprom_pwrgroup[rf_path][index] & 0xf0) >> 4); RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, "RF-%d pwrgroup_ht20[%d] = 0x%x\n", rf_path, i, rtlefuse->pwrgroup_ht20[rf_path][i]); RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, "RF-%d pwrgroup_ht40[%d] = 0x%x\n", rf_path, i, rtlefuse->pwrgroup_ht40[rf_path][i]); } } for (i = 0; i < 14; i++) { /* Read tx power difference between HT OFDM 20/40 MHZ */ /* channel 1-3 */ if (i < 3) index = 0; /* Channel 4-8 */ else if (i < 8) index = 1; /* Channel 9-14 */ else index = 2; tempval = eeprom.tx_pwr_ht20_diff[index] & 0xff; rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] = (tempval & 0xF); rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] = ((tempval >> 4) & 0xF); /* Read OFDM<->HT tx power diff */ /* Channel 1-3 */ if (i < 3) tempval = eeprom.tx_pwr_ofdm_diff[0]; /* Channel 4-8 */ else if (i < 8) tempval = eeprom.tx_pwr_ofdm_diff_cont; /* Channel 9-14 */ else tempval = eeprom.tx_pwr_ofdm_diff[1]; rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i] = (tempval & 0xF); rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i] = ((tempval >> 4) & 0xF); tempval = eeprom.tx_pwr_edge_chk; rtlefuse->txpwr_safetyflag = (tempval & 0x01); } rtlefuse->eeprom_regulatory = 0; if (rtlefuse->eeprom_version >= 2) { /* BIT(0)~2 */ if (rtlefuse->eeprom_version >= 4) rtlefuse->eeprom_regulatory = (eeprom.regulatory & 0x7); else /* BIT(0) */ rtlefuse->eeprom_regulatory = (eeprom.regulatory & 0x1); } RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory); for (i = 0; i < 14; i++) RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, "RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", i, rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]); for (i = 0; i < 14; i++) RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, "RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]); for (i = 0; i < 14; i++) RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, "RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", i, rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]); for (i = 0; i < 14; i++) RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, "RF-B Legacy to HT40 Diff[%d] = 0x%x\n", i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]); RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, "TxPwrSafetyFlag = %d\n", rtlefuse->txpwr_safetyflag); /* Read RF-indication and Tx Power gain * index diff of legacy to HT OFDM rate. */ tempval = eeprom.rf_ind_power_diff & 0xff; rtlefuse->eeprom_txpowerdiff = tempval; rtlefuse->legacy_httxpowerdiff = rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][0]; RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, "TxPowerDiff = %#x\n", rtlefuse->eeprom_txpowerdiff); /* Get TSSI value for each path. */ rtlefuse->eeprom_tssi[RF90_PATH_A] = eeprom.tssi[RF90_PATH_A]; rtlefuse->eeprom_tssi[RF90_PATH_B] = eeprom.tssi[RF90_PATH_B]; RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, "TSSI_A = 0x%x, TSSI_B = 0x%x\n", rtlefuse->eeprom_tssi[RF90_PATH_A], rtlefuse->eeprom_tssi[RF90_PATH_B]); /* Read antenna tx power offset of B/C/D to A from EEPROM */ /* and read ThermalMeter from EEPROM */ tempval = eeprom.thermal_meter; rtlefuse->eeprom_thermalmeter = tempval; RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter); /* ThermalMeter, BIT(0)~3 for RFIC1, BIT(4)~7 for RFIC2 */ rtlefuse->thermalmeter[0] = (rtlefuse->eeprom_thermalmeter & 0x1f); rtlefuse->tssi_13dbm = rtlefuse->eeprom_thermalmeter * 100; /* Read CrystalCap from EEPROM */ rtlefuse->eeprom_crystalcap = eeprom.crystal_cap >> 4; /* CrystalCap, BIT(12)~15 */ rtlefuse->crystalcap = rtlefuse->eeprom_crystalcap; /* Read IC Version && Channel Plan */ /* Version ID, Channel plan */ rtlefuse->eeprom_channelplan = eeprom.channel_plan; rtlefuse->txpwr_fromeprom = true; RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, "EEPROM ChannelPlan = 0x%4x\n", rtlefuse->eeprom_channelplan); /* Read Customer ID or Board Type!!! */ tempval = eeprom.board_type; /* Change RF type definition */ if (tempval == 0) rtlphy->rf_type = RF_1T1R; else if (tempval == 1) rtlphy->rf_type = RF_1T2R; else if (tempval == 2) rtlphy->rf_type = RF_2T2R; else if (tempval == 3) rtlphy->rf_type = RF_1T1R; /* 1T2R but 1SS (1x1 receive combining) */ rtlefuse->b1x1_recvcombine = false; if (rtlphy->rf_type == RF_1T2R) { tempval = rtl_read_byte(rtlpriv, 0x07); if (!(tempval & BIT(0))) { rtlefuse->b1x1_recvcombine = true; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "RF_TYPE=1T2R but only 1SS\n"); } } rtlefuse->b1ss_support = rtlefuse->b1x1_recvcombine; rtlefuse->eeprom_oemid = eeprom.custom_id; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid); /* set channel plan to world wide 13 */ rtlefuse->channel_plan = COUNTRY_CODE_WORLD_WIDE_13; }