rtmp_init.c

来自「Ralink RT61 SoftAP Driver source code. 」· C语言 代码 · 共 1,988 行 · 第 1/5 页

C
1,988
字号
			pRxD = (PRXD_STRUC) pAdapter->RxRing.Cell[index].AllocVa;
			pRxD->BufPhyAddr = pDmaBuf->AllocPa;

			// Rx owner bit assign to NIC immediately
			pRxD->Owner = DESC_OWN_NIC;

#ifdef BIG_ENDIAN
			RTMPDescriptorEndianChange((PUCHAR)pRxD, TYPE_RXD);
#endif			
		}
        DBGPRINT(RT_DEBUG_TRACE, "Rx Ring: total %d entry allocated\n", index);

	}	while (FALSE);

	DBGPRINT(RT_DEBUG_TRACE, "<-- RTMPAllocDMAMemory\n");

    return 0;
}

/*
    ========================================================================

    Routine Description:
        Free all DMA memory.

    Arguments:
        Adapter         Pointer to our adapter

    Return Value:
        None

    Note:

    ========================================================================
*/
VOID    RTMPFreeDMAMemory(
    IN  PRTMP_ADAPTER   pAdapter)
{
	INT		    index, num;

	DBGPRINT(RT_DEBUG_TRACE, "--> RTMPFreeDMAMemory\n");

	//
	// Free RX Ring related space
	//
	for (index = RX_RING_SIZE - 1 ; index >= 0; index--)
	{
		if ((pAdapter->RxRing.Cell[index].DmaBuf.AllocVa) && (pAdapter->RxRing.Cell[index].DmaBuf.pSkb))
		{
			pci_unmap_single(pAdapter->pPci_Dev, pAdapter->RxRing.Cell[index].DmaBuf.AllocPa, pAdapter->RxRing.Cell[index].DmaBuf.AllocSize, PCI_DMA_FROMDEVICE);
			RELEASE_NDIS_PACKET(pAdapter, pAdapter->RxRing.Cell[index].DmaBuf.pSkb);
		}
	}
	NdisZeroMemory(pAdapter->RxRing.Cell, RX_RING_SIZE * sizeof(RTMP_DMACB));

    if (pAdapter->RxDescRing.AllocVa)
    {
    	pci_free_consistent(pAdapter->pPci_Dev, pAdapter->RxDescRing.AllocSize,
			pAdapter->RxDescRing.AllocVa, pAdapter->RxDescRing.AllocPa);
    }
    NdisZeroMemory(&pAdapter->RxDescRing, sizeof(RTMP_DMABUF));

	//
	// Free MGMT Ring related space
	//
	if (pAdapter->MgmtDescRing.AllocVa)
	{
		pci_free_consistent(pAdapter->pPci_Dev, pAdapter->MgmtDescRing.AllocSize,
			pAdapter->MgmtDescRing.AllocVa, pAdapter->MgmtDescRing.AllocPa);
	}
	NdisZeroMemory(&pAdapter->MgmtDescRing, sizeof(RTMP_DMABUF));

	//
	// Free TX Ring buffer
	//
	for (num = 0; num < NUM_OF_TX_RING; num++)
	{
    	if (pAdapter->TxBufSpace[num].AllocVa)
	    {
	    	pci_free_consistent(pAdapter->pPci_Dev, pAdapter->TxBufSpace[num].AllocSize,
				pAdapter->TxBufSpace[num].AllocVa, pAdapter->TxBufSpace[num].AllocPa);
	    }
	    NdisZeroMemory(&pAdapter->TxBufSpace[num], sizeof(RTMP_DMABUF));
	    
    	if (pAdapter->TxDescRing[num].AllocVa)
	    {
	    	pci_free_consistent(pAdapter->pPci_Dev, pAdapter->TxDescRing[num].AllocSize,
				pAdapter->TxDescRing[num].AllocVa, pAdapter->TxDescRing[num].AllocPa);
	    }
	    NdisZeroMemory(&pAdapter->TxDescRing[num], sizeof(RTMP_DMABUF));
	}

	//
	// Free preallocated shared memory
	//
    NdisFreeSpinLock(&pAdapter->TxSwQueueLock);
	NdisFreeSpinLock(&pAdapter->RxRingLock);
	NdisFreeSpinLock(&pAdapter->MgmtRingLock);
	NdisFreeSpinLock(&pAdapter->TxRingLock);

	DBGPRINT(RT_DEBUG_TRACE, "<-- RTMPFreeDMAMemory\n");
}

inline  VOID    NICDisableInterrupt(
    IN  PRTMP_ADAPTER   pAdapter)
{
    RTMP_IO_WRITE32(pAdapter, INT_MASK_CSR, 0xffffff7f);     // 0xffffff7f
    RTMP_IO_WRITE32(pAdapter, MCU_INT_MASK_CSR, 0xffffffff);
    RTMP_CLEAR_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_ACTIVE);
}

inline  VOID    NICEnableInterrupt(
    IN  PRTMP_ADAPTER   pAdapter,
    IN	UINT32			int_mask)
{
#ifdef THREAD_ISR
	/* 
	 * mask out pendding interrupt bit 
     * interrupt aggregation : 0x0000fe90
	 */
    RTMP_IO_WRITE32(pAdapter, INT_MASK_CSR, 0x0000fe90 | int_mask);
#else 
    RTMP_IO_WRITE32(pAdapter, INT_MASK_CSR, 0x0000ff10 | int_mask);     // 0x0000fe90(interrupt aggregation, can be test in embedded platform while bad throughput)
#endif
    RTMP_IO_WRITE32(pAdapter, MCU_INT_MASK_CSR, 0x00000200); // 0x000001ff
    RTMP_SET_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_ACTIVE);
}

/*
	========================================================================
	
	Routine Description:
		Initialize transmit data structures

	Arguments:
		Adapter						Pointer to our adapter

	Return Value:
		None

	Note:
		Initialize all transmit releated private buffer, include those define
		in RTMP_ADAPTER structure and all private data structures.
		
	========================================================================
*/
VOID	NICInitTxRxRingAndBacklogQueue(
	IN	PRTMP_ADAPTER	pAdapter)
{
	DBGPRINT(RT_DEBUG_TRACE, "<--> NICInitTxRxRingAndBacklogQueue\n");

    // Initialize all transmit related software queues
    InitializeQueueHeader(&pAdapter->TxSwQueue[QID_AC_BE]);
    InitializeQueueHeader(&pAdapter->TxSwQueue[QID_AC_BK]);
    InitializeQueueHeader(&pAdapter->TxSwQueue[QID_AC_VI]);
    InitializeQueueHeader(&pAdapter->TxSwQueue[QID_AC_VO]);
    InitializeQueueHeader(&pAdapter->TxSwQueue[QID_HCCA]);
    
	// Init RX Ring index pointer
	pAdapter->RxRing.CurRxIndex           = 0;
	
    // Init TX rings index pointer
    {
        INT i;
        for (i=0; i<NUM_OF_TX_RING; i++)
        {
	        pAdapter->TxRing[i].CurTxIndex         = 0;
            pAdapter->TxRing[i].NextTxDmaDoneIndex = 0;
        }
    }

    // init MGMT ring index pointer
    pAdapter->MgmtRing.CurTxIndex              = 0;
    pAdapter->MgmtRing.NextTxDmaDoneIndex      = 0;
        
	pAdapter->PrivateInfo.TxRingFullCnt       = 0;
}

/*
    ========================================================================

    Routine Description:
        Read initial parameters from EEPROM

    Arguments:
        Adapter                     Pointer to our adapter

    Return Value:
        None

    Note:
        
    ========================================================================
*/
VOID    NICReadEEPROMParameters(
    IN  PRTMP_ADAPTER   pAd)
{
	ULONG			data;
	USHORT			i, value, value2;
	EEPROM_TX_PWR_STRUC	    Power;
    EEPROM_VERSION_STRUC    Version;
	EEPROM_ANTENNA_STRUC	Antenna;
	EEPROM_LED_STRUC		LedSetting;
	UCHAR			AModeGainValue = 0;

	DBGPRINT(RT_DEBUG_TRACE, "--> NICReadEEPROMParameters\n");

	// Init EEPROM Address Number, before access EEPROM; if 93c46, EEPROMAddressNum=6, else if 93c66, EEPROMAddressNum=8
	RTMP_IO_READ32(pAd, E2PROM_CSR, &data);

	if(data & 0x20)
		pAd->EEPROMAddressNum = 6;		// 93C46
	else
		pAd->EEPROMAddressNum = 8;     // 93C66

    // RT2660 MAC no longer auto load MAC address from E2PROM. Driver has to intialize
    // MAC address registers according to E2PROM setting
    {
        USHORT  Addr01,Addr23,Addr45 ;
        MAC_CSR2_STRUC csr2;
        MAC_CSR3_STRUC csr3;

        Addr01=RTMP_EEPROM_READ16(pAd, 0x04);
        Addr23=RTMP_EEPROM_READ16(pAd, 0x06);
        Addr45=RTMP_EEPROM_READ16(pAd, 0x08);

        pAd->CurrentAddress[0] = (UCHAR)(Addr01 & 0xff);
        pAd->CurrentAddress[1] = (UCHAR)(Addr01 >> 8);
        pAd->CurrentAddress[2] = (UCHAR)(Addr23 & 0xff);
        pAd->CurrentAddress[3] = (UCHAR)(Addr23 >> 8);
        pAd->CurrentAddress[4] = (UCHAR)(Addr45 & 0xff);
        pAd->CurrentAddress[5] = (UCHAR)(Addr45 >> 8);

        csr2.field.Byte0 = pAd->CurrentAddress[0];
        csr2.field.Byte1 = pAd->CurrentAddress[1];
        csr2.field.Byte2 = pAd->CurrentAddress[2];
        csr2.field.Byte3 = pAd->CurrentAddress[3];
        RTMP_IO_WRITE32(pAd, MAC_CSR2, csr2.word);
        csr3.word = 0;
        csr3.field.Byte4 = pAd->CurrentAddress[4];
        csr3.field.Byte5 = pAd->CurrentAddress[5];
        csr3.field.U2MeMask = 0xff;
        RTMP_IO_WRITE32(pAd, MAC_CSR3, csr3.word);

        // Prepare MBSSID's mac addr, the mac addr will be the E2PROM's mac addr plus 0,1,2,3 as MBSSID[0],MBSSID[1],MBSSID[2],MBSSID[3]'s mac addr
        for(i = 0; i < MAX_MBSSID_NUM; i++)
        {
        	BOOLEAN bCarry = FALSE;
        	INT		j;
        	
        	for (j = (MAC_ADDR_LEN-1); j >= 0; j--)
        	{
        		if (j == (MAC_ADDR_LEN-1))
        		{
	        		if (((pAd->CurrentAddress[j]+i) & 0xFF) < pAd->CurrentAddress[j])
	        			bCarry = TRUE;
	        		else
	        			bCarry = FALSE;
	        		pAd->PortCfg.MBSSID[i].Bssid[j] = (pAd->CurrentAddress[j]+i) & 0xFF;
        		}
        		else
        		{
        			if (bCarry == TRUE)
        			{
        				if (((pAd->CurrentAddress[j]+1) & 0xFF) < pAd->CurrentAddress[j])
		        			bCarry = TRUE;
		        		else
		        			bCarry = FALSE;
		        		pAd->PortCfg.MBSSID[i].Bssid[j] = (pAd->CurrentAddress[j]+1) & 0xFF;
        			}
        			else
        				pAd->PortCfg.MBSSID[i].Bssid[j] = pAd->CurrentAddress[j];
        		}
        	}

        	DBGPRINT(RT_DEBUG_TRACE,"MBSSID[%d] MAC=%02x:%02x:%02x:%02x:%02x:%02x\n", i,
	            pAd->PortCfg.MBSSID[i].Bssid[0], pAd->PortCfg.MBSSID[i].Bssid[1],
	            pAd->PortCfg.MBSSID[i].Bssid[2], pAd->PortCfg.MBSSID[i].Bssid[3],
	            pAd->PortCfg.MBSSID[i].Bssid[4], pAd->PortCfg.MBSSID[i].Bssid[5]);
        }
    }   

    // Init the channel number for TX channel power
    NdisZeroMemory(pAd->TxPower, sizeof(pAd->TxPower));
    // 0. 11b/g
    for (i = 0; i < 14; i++)
        pAd->TxPower[i].Channel = i + 1;
    // 1. UNI 36 - 64
    for (i = 0; i < 8; i++)
        pAd->TxPower[i + 14].Channel = 36 + i * 4;
    // 2. HipperLAN 2 100 - 140
    for (i = 0; i < 11; i++)
        pAd->TxPower[i + 22].Channel = 100 + i * 4;
    // 3. UNI 140 - 165
    for (i = 0; i < 5; i++)
        pAd->TxPower[i + 33].Channel = 149 + i * 4;        

    // if E2PROM version mismatch with driver's expectation, then skip
    // all subsequent E2RPOM retieval and set a system error bit to notify GUI
    Version.word = RTMP_EEPROM_READ16(pAd, EEPROM_VERSION_OFFSET);
    pAd->EepromVersion = Version.field.Version + Version.field.FaeReleaseNumber * 256;
    DBGPRINT(RT_DEBUG_TRACE, "E2PROM: Version = %d, FAE release #%d\n", Version.field.Version, Version.field.FaeReleaseNumber);
    
    if (Version.field.Version > VALID_EEPROM_VERSION)
    {
        DBGPRINT_ERR("E2PROM: WRONG VERSION %d, should be %d\n",Version.field.Version, VALID_EEPROM_VERSION);

        // hard-code default value when no proper E2PROM installed
        pAd->bAutoTxAgcA = FALSE;
        pAd->bAutoTxAgcG = FALSE;
        
        // Default the channel power
        for (i = 0; i < MAX_NUM_OF_CHANNELS; i++)
            pAd->TxPower[i].Power = DEFAULT_RF_TX_POWER;
    
        pAd->RfIcType = RFIC_5225;
        for(i = 0; i < NUM_EEPROM_BBP_PARMS; i++)
            pAd->EEPROMDefaultValue[i] = 0xffff;
        return;
    }

	// Read BBP default value from EEPROM and store to array(EEPROMDefaultValue) in pAd
	for(i = 0; i < NUM_EEPROM_BBP_PARMS; i++)
	{
		value = RTMP_EEPROM_READ16(pAd, EEPROM_BBP_BASE_OFFSET + i*2);
		
		pAd->EEPROMDefaultValue[i] = value;
	}

	// We have to parse NIC configuration 0 at here.
	// If TSSI did not have preloaded value, it should reset the TxAutoAgc to false
	// Therefore, we have to read TxAutoAgc control beforehand.
	// Read Tx AGC control bit
	Antenna.word = pAd->EEPROMDefaultValue[0];
	if (Antenna.field.DynamicTxAgcControl == 1)
		pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = TRUE;
	else
		pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = FALSE;		
	
	//
	// Reset PhyMode if we don't support 802.11a
	//
	if ((pAd->PortCfg.PhyMode == PHY_11ABG_MIXED) || (pAd->PortCfg.PhyMode == PHY_11A))
	{
		//
		// Only RFIC_5225 & RFIC_5325 support 802.11a
		//
		if ((Antenna.field.RfIcType != RFIC_5225) && (Antenna.field.RfIcType != RFIC_5325))
			pAd->PortCfg.PhyMode = PHY_11BG_MIXED;
	}
	
	// Read Tx power value for all channels
	// Value from 1 - 0x7f. Default value is 24.
	// 0. 11b/g
	// Power value 0xFA (-6) ~ 0x24 (36)
	for (i = 0; i < 7; i++)
	{
		Power.word = RTMP_EEPROM_READ16(pAd, EEPROM_G_TX_PWR_OFFSET + i * 2);
		
		if ((Power.field.Byte0 > 36) || (Power.field.Byte0 < -6))
			pAd->TxPower[i * 2].Power = DEFAULT_RF_TX_POWER;
		else
			pAd->TxPower[i * 2].Power = Power.field.Byte0;

		if ((Power.field.Byte1 > 36) || (Power.field.Byte1 < -6))
			pAd->TxPower[i * 2 + 1].Power = DEFAULT_RF_TX_POWER;
		else
			pAd->TxPower[i * 2 + 1].Power = Power.field.Byte1;
	}
	// 1. UNI 36 - 64, HipperLAN 2 100 - 140, UNI 140 - 165
	for (i = 0; i < 12; i++)
	{
		Power.word = RTMP_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + i * 2);
		
		if ((Power.field.Byte0 > 36) || (Power.field.Byte0 < -6))
			pAd->TxPower[i * 2 + 14].Power = DEFAULT_RF_TX_POWER;
		else
			pAd->TxPower[i * 2 + 14].Power = Power.field.Byte0;

		if ((Power.field.Byte1 > 36) || (Power.field.Byte1 < -6))
			pAd->TxPower[i * 2 + 15].Power = DEFAULT_RF_TX_POWER;
		else
			pAd->TxPower[i * 2 + 15].Power = Power.field.Byte1;
	}

	// Read TSSI reference and TSSI boundary for temperature compensation. This is ugly
	// 0. 11b/g
	{
		Power.word = RTMP_EEPROM_READ16(pAd, 0x54);
		pAd->TssiMinusBoundaryG[4] = Power.field.Byte0;
		pAd->TssiMinusBoundaryG[3] = Power.field.Byte1;
		Power.word = RTMP_EEPROM_READ16(pAd, 0x56);
		pAd->TssiMinusBoundaryG[2] = Power.field.Byte0;
		pAd->TssiMinusBoundaryG[1] = Power.field.Byte1;
		Power.word = RTMP_EEPROM_READ16(pAd, 0x58);
		pAd->TssiPlusBoundaryG[1] = Power.field.Byte0;
		pAd->TssiPlusBoundaryG[2] = Power.field.Byte1;
		Power.word = RTMP_EEPROM_READ16(pAd, 0x5a);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?