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;
}
Beispiel #2
0
/*
* 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;
}
Beispiel #3
0
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;
}
Beispiel #6
0
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);
			
}
Beispiel #7
0
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;
}
Beispiel #10
0
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;
}
Beispiel #11
0
//
// 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;
}
Beispiel #14
0
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);
}
Beispiel #15
0
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;
}
Beispiel #21
0
Datei: mac.c Projekt: 7799/linux
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]);
			}
		}
	}
}
Beispiel #22
0
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;
}