Commit ed291e80 authored by Adam McDaniel's avatar Adam McDaniel Committed by Greg Kroah-Hartman
Browse files

Staging: rt2860: Ported v1.7.1.1 changes into v1.8.0.0, becoming v1.8.1.1



Staging: rt2860: Ported v1.7.1.1 changes into v1.8.0.0, becoming v1.8.1.1

When RaLink released rt2860 v1.7.0.0, it lacked proper support for both WEP
and WPA/WPA2 encryption. Either was possible, but the module had to be
compiled to support only one or the other, never both.

Since the EeePC was the most common device with this hardware (and these
users were complaining to RaLink that WPA/WPA2 encryption didn't work)
RaLink released a fix as an "eeepc-specific" version of this driver, v1.7.1.1

Unfortunately, when v1.8.0.0 was released, this WPA/WPA2 fix was never
included.

What complicates things further is that RaLink has no interest in
continuing work on this Linux driver for their hardware.

This commit ports the changes introduced in v1.7.1.1 into the v1.8.0.0
release, upgrading the kernel's module to v1.8.1.1

Signed-off-by: default avatarAdam McDaniel <adam@array.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent f4b44e76
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -746,6 +746,7 @@ rt2860_interrupt(int irq, void *dev_instance)
	PRTMP_ADAPTER pAd = net_dev->ml_priv;
	INT_SOURCE_CSR_STRUC	IntSource;
	POS_COOKIE pObj;
	BOOLEAN	bOldValue;

	pObj = (POS_COOKIE) pAd->OS_Cookie;

@@ -778,10 +779,13 @@ rt2860_interrupt(int irq, void *dev_instance)
	// RT2661 => when ASIC is sleeping, MAC register cannot be read and written.
	// RT2860 => when ASIC is sleeping, MAC register can be read and written.

	bOldValue = pAd->bPCIclkOff;
	pAd->bPCIclkOff = FALSE;
	{
		RTMP_IO_READ32(pAd, INT_SOURCE_CSR, &IntSource.word);
		RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, IntSource.word); // write 1 to clear
	}
	pAd->bPCIclkOff = bOldValue;

	// Do nothing if Reset in progress
	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
@@ -796,8 +800,6 @@ rt2860_interrupt(int irq, void *dev_instance)
	// The priority can be adjust by altering processing if statement
	//

    pAd->bPCIclkOff = FALSE;

	// If required spinlock, each interrupt service routine has to acquire
	// and release itself.
	//
@@ -806,6 +808,7 @@ rt2860_interrupt(int irq, void *dev_instance)
	if (IntSource.word == 0xffffffff)
	{
		RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS);
		printk("snowpin - IntSource.word == 0xffffffff\n");
		return IRQ_HANDLED;
	}

+2 −2
Original line number Diff line number Diff line
@@ -366,7 +366,7 @@ NDIS_STATUS MlmeHardTransmitTxRing(
	{
		// outgoing frame always wakeup PHY to prevent frame lost
		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
			AsicForceWakeup(pAd, TRUE);
			AsicForceWakeup(pAd, FROM_TX);
	}
#endif // CONFIG_STA_SUPPORT //
	pFirstTxWI	=(PTXWI_STRUC)pSrcBufVA;
@@ -541,7 +541,7 @@ NDIS_STATUS MlmeHardTransmitMgmtRing(
	{
		// outgoing frame always wakeup PHY to prevent frame lost
		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
			AsicForceWakeup(pAd, TRUE);
			AsicForceWakeup(pAd, FROM_TX);
	}
#endif // CONFIG_STA_SUPPORT //

+99 −45
Original line number Diff line number Diff line
@@ -634,7 +634,7 @@ VOID RT28xxPciAsicRadioOff(
	}

    // Once go into this function, disable tx because don't want too many packets in queue to prevent HW stops.
	pAd->bPCIclkOffDisableTx = TRUE;
	RTMP_SET_PSFLAG(pAd, fRTMP_PS_DISABLE_TX);

	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
	{
@@ -651,7 +651,7 @@ VOID RT28xxPciAsicRadioOff(
			{
				DBGPRINT(RT_DEBUG_TRACE, ("TbTTTime = 0x%x , give up this sleep. \n", TbTTTime));
	            OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
	            pAd->bPCIclkOffDisableTx = FALSE;
				RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_DISABLE_TX);
				return;
			}
			else
@@ -688,18 +688,25 @@ VOID RT28xxPciAsicRadioOff(
	if (i >= 50)
	{
		DBGPRINT(RT_DEBUG_TRACE, ("DMA keeps busy.  return on RT28xxPciAsicRadioOff ()\n"));
		pAd->bPCIclkOffDisableTx = FALSE;
		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word);
		DmaCfg.field.EnableTxDMA = 1;
		RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, DmaCfg.word);
		pAd->CheckDmaBusyCount++;
		return;
	}
	else
	{
		pAd->CheckDmaBusyCount = 0;
	}

    RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF);

    // Set to 1R.
	if (pAd->Antenna.field.RxPath > 1)
	{
		tempBBP_R3 = (pAd->StaCfg.BBPR3 & 0xE7);
		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, tempBBP_R3);
	}

	// In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again.
	if (INFRA_ON(pAd) && (pAd->CommonCfg.CentralChannel != pAd->CommonCfg.Channel)
@@ -714,8 +721,15 @@ VOID RT28xxPciAsicRadioOff(
		AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel);
	}

    // When PCI clock is off, don't want to service interrupt.
	if (Level != RTMP_HALT)
	{
		// Change Interrupt bitmask.
		RTMP_IO_WRITE32(pAd, INT_MASK_CSR, AutoWakeupInt);
	}
	else
	{
		NICDisableInterrupt(pAd);
	}

    RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx);
	// Disable MAC Rx
@@ -726,7 +740,8 @@ VOID RT28xxPciAsicRadioOff(
	//  2. Send Sleep command
	RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff);
	RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff);
	AsicSendCommandToMcu(pAd, 0x30, PowerSafeCID, 0xff, 0x00);   // send POWER-SAVE command to MCU. Timeout unit:40us.
	// send POWER-SAVE command to MCU. high-byte = 1 save power as much as possible. high byte = 0 save less power
	AsicSendCommandToMcu(pAd, 0x30, PowerSafeCID, 0xff, 0x1);
	//  2-1. Wait command success
	// Status = 1 : success, Status = 2, already sleep, Status = 3, Maybe MAC is busy so can't finish this task.
	brc = AsicCheckCommanOk(pAd, PowerSafeCID);
@@ -734,7 +749,7 @@ VOID RT28xxPciAsicRadioOff(
    if (brc == FALSE)
    {
        // try again
    	AsicSendCommandToMcu(pAd, 0x30, PowerSafeCID, 0xff, 0x00);   // send POWER-SAVE command to MCU. Timeout unit:40us.
    	AsicSendCommandToMcu(pAd, 0x30, PowerSafeCID, 0xff, 0x01);   // send POWER-SAVE command to MCU. Timeout unit:40us.
    	//RTMPusecDelay(200);
    	brc = AsicCheckCommanOk(pAd, PowerSafeCID);
    }
@@ -759,7 +774,7 @@ VOID RT28xxPciAsicRadioOff(
	do
	{
		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word);
		if (DmaCfg.field.RxDMABusy == 0)
		if ((DmaCfg.field.RxDMABusy == 0) && (DmaCfg.field.TxDMABusy == 0))
			break;
		RTMPusecDelay(20);
		i++;
@@ -767,13 +782,12 @@ VOID RT28xxPciAsicRadioOff(

	if (i >= 50)
	{
		pAd->CheckDmaBusyCount++;
		DBGPRINT(RT_DEBUG_TRACE, ("DMA Rx keeps busy.  on RT28xxPciAsicRadioOff ()\n"));
	}
	// disable DMA Rx.
	else
	{
		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word);
		DmaCfg.field.EnableRxDMA = 0;
		RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, DmaCfg.word);
		pAd->CheckDmaBusyCount = 0;
	}

	if (Level == DOT11POWERSAVE)
@@ -799,7 +813,7 @@ VOID RT28xxPciAsicRadioOff(
	if (Level == RTMP_HALT)
	{
		if ((brc == TRUE) && (i < 50))
			RTMPPCIeLinkCtrlSetting(pAd, 1);
			RTMPPCIeLinkCtrlSetting(pAd, 0);
	}
	//  4. Set PCI configuration Space Link Comtrol fields.  Only Radio Off needs to call this function
	else
@@ -808,7 +822,7 @@ VOID RT28xxPciAsicRadioOff(
			RTMPPCIeLinkCtrlSetting(pAd, 3);
	}

    pAd->bPCIclkOffDisableTx = FALSE;
	RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_DISABLE_TX);
}


@@ -835,7 +849,8 @@ BOOLEAN RT28xxPciAsicRadioOn(
	{
	    pAd->Mlme.bPsPollTimerRunning = FALSE;
		RTMPCancelTimer(&pAd->Mlme.PsPollTimer,	&Cancelled);
		if ((Level == GUIRADIO_OFF) || (Level == GUI_IDLE_POWER_SAVE))
		if ((Level == GUIRADIO_OFF) || (Level == GUI_IDLE_POWER_SAVE)
		|| (RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND)))
		{
			DBGPRINT(RT_DEBUG_TRACE, ("RT28xxPciAsicRadioOn ()\n"));
			// 1. Set PCI Link Control in Configuration Space.
@@ -845,15 +860,14 @@ BOOLEAN RT28xxPciAsicRadioOn(
	}

    pAd->bPCIclkOff = FALSE;

	RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0x3a80);
	// 2. Send wake up command.
	AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x00);
	AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x02);

	// 2-1. wait command ok.
	brv = AsicCheckCommanOk(pAd, PowerWakeCID);
    if (brv)
    {
    	//RTMP_IO_WRITE32(pAd, INT_MASK_CSR, (DELAYINTMASK|RxINT));
    	NICEnableInterrupt(pAd);

    	// 3. Enable Tx DMA.
@@ -893,13 +907,10 @@ BOOLEAN RT28xxPciAsicRadioOn(

VOID RT28xxPciStaAsicForceWakeup(
	IN PRTMP_ADAPTER pAd,
	IN BOOLEAN       bFromTx)
	IN UCHAR    	 Level)
{
    AUTO_WAKEUP_STRUC	AutoWakeupCfg;

    if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
        return;

    if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WAKEUP_NOW))
    {
        DBGPRINT(RT_DEBUG_TRACE, ("waking up now!\n"));
@@ -907,21 +918,30 @@ VOID RT28xxPciStaAsicForceWakeup(
    }

    OPSTATUS_SET_FLAG(pAd, fOP_STATUS_WAKEUP_NOW);
	RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);

    if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
    {
        // Support PCIe Advance Power Save
    	if (bFromTx == TRUE)
    	if (((Level == FROM_TX) && (pAd->Mlme.bPsPollTimerRunning == TRUE)) ||
			(Level == RTMP_HALT))
    	{
            pAd->Mlme.bPsPollTimerRunning = FALSE;
    		RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP);
    		RTMPusecDelay(3000);
    		RTMPusecDelay(5000);
            DBGPRINT(RT_DEBUG_TRACE, ("=======AsicForceWakeup===bFromTx\n"));
    	}

		AutoWakeupCfg.word = 0;
		RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);

		// If this is called from Halt. ALWAYS force wakeup!!!
		if (Level == RTMP_HALT)
		{
			RT28xxPciAsicRadioOn(pAd, RTMP_HALT);
		}
		else
		{
			if (RT28xxPciAsicRadioOn(pAd, DOT11POWERSAVE))
			{
				// In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again.
@@ -940,6 +960,7 @@ VOID RT28xxPciStaAsicForceWakeup(
				}
			}
		}
    }
    else
    {
        // PCI, 2860-PCIe
@@ -1122,6 +1143,7 @@ VOID RT28xxPciMlmeRadioOn(
    {
    	NICResetFromError(pAd);

    	/*
    	RTMPRingCleanUp(pAd, QID_AC_BK);
    	RTMPRingCleanUp(pAd, QID_AC_BE);
    	RTMPRingCleanUp(pAd, QID_AC_VI);
@@ -1129,6 +1151,7 @@ VOID RT28xxPciMlmeRadioOn(
    	RTMPRingCleanUp(pAd, QID_HCCA);
    	RTMPRingCleanUp(pAd, QID_MGMT);
    	RTMPRingCleanUp(pAd, QID_RX);
		*/

    	// Enable Tx/Rx
    	RTMPEnableRxTx(pAd);
@@ -1162,6 +1185,12 @@ VOID RT28xxPciMlmeRadioOFF(
    WPDMA_GLO_CFG_STRUC	GloCfg;
	UINT32	i;

	if (pAd->StaCfg.bRadio == TRUE)
	{
		DBGPRINT(RT_DEBUG_TRACE,("-->MlmeRadioOff() return on bRadio == TRUE; \n"));
		return;
	}

    if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
    	return;

@@ -1169,13 +1198,12 @@ VOID RT28xxPciMlmeRadioOFF(

	// Set LED
	RTMPSetLED(pAd, LED_RADIO_OFF);
	// Set Radio off flag
	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);

#ifdef CONFIG_STA_SUPPORT
	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
    {
    	BOOLEAN		Cancelled;

    	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
    	{
			RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled);
@@ -1185,6 +1213,15 @@ VOID RT28xxPciMlmeRadioOFF(
		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
        {
            BOOLEAN Cancelled;

			// Always radio on since the NIC needs to set the MCU command (LED_RADIO_OFF).
			if ((pAd->OpMode == OPMODE_STA) && 
			     (IDLE_ON(pAd)) && 
			     (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)))
			{
				RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE);
			}

            pAd->Mlme.bPsPollTimerRunning = FALSE;
            RTMPCancelTimer(&pAd->Mlme.PsPollTimer,	&Cancelled);
	        RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer,	&Cancelled);
@@ -1197,9 +1234,26 @@ VOID RT28xxPciMlmeRadioOFF(
        //==========================================
        // Clean up old bss table
        BssTableInit(&pAd->ScanTab);

		RTMPRingCleanUp(pAd, QID_AC_BK);
    	RTMPRingCleanUp(pAd, QID_AC_BE);
    	RTMPRingCleanUp(pAd, QID_AC_VI);
    	RTMPRingCleanUp(pAd, QID_AC_VO);
    	RTMPRingCleanUp(pAd, QID_HCCA);
    	RTMPRingCleanUp(pAd, QID_MGMT);
    	RTMPRingCleanUp(pAd, QID_RX);

		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
		{
			RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 500);
			return;
		}
    }
#endif // CONFIG_STA_SUPPORT //

	// Set Radio off flag
	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);

	// Disable Tx/Rx DMA
	RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);	   // disable DMA
	GloCfg.field.EnableTxDMA = 0;
+1 −1
Original line number Diff line number Diff line
@@ -470,7 +470,7 @@ VOID ScanNextChannel(
		{
		// BBP and RF are not accessible in PS mode, we has to wake them up first
		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
			AsicForceWakeup(pAd, TRUE);
				AsicForceWakeup(pAd, FROM_TX);

			// leave PSM during scanning. otherwise we may lost ProbeRsp & BEACON
			if (pAd->StaCfg.Psm == PWR_SAVE)
+39 −1
Original line number Diff line number Diff line
@@ -39,8 +39,10 @@
// WPA OUI
UCHAR		OUI_WPA_NONE_AKM[4]		= {0x00, 0x50, 0xF2, 0x00};
UCHAR       OUI_WPA_VERSION[4]      = {0x00, 0x50, 0xF2, 0x01};
UCHAR       OUI_WPA_WEP40[4]      = {0x00, 0x50, 0xF2, 0x01};
UCHAR       OUI_WPA_TKIP[4]     = {0x00, 0x50, 0xF2, 0x02};
UCHAR       OUI_WPA_CCMP[4]     = {0x00, 0x50, 0xF2, 0x04};
UCHAR       OUI_WPA_WEP104[4]      = {0x00, 0x50, 0xF2, 0x05};
UCHAR       OUI_WPA_8021X_AKM[4]	= {0x00, 0x50, 0xF2, 0x01};
UCHAR       OUI_WPA_PSK_AKM[4]      = {0x00, 0x50, 0xF2, 0x02};
// WPA2 OUI
@@ -49,6 +51,7 @@ UCHAR OUI_WPA2_TKIP[4] = {0x00, 0x0F, 0xAC, 0x02};
UCHAR       OUI_WPA2_CCMP[4]        = {0x00, 0x0F, 0xAC, 0x04};
UCHAR       OUI_WPA2_8021X_AKM[4]   = {0x00, 0x0F, 0xAC, 0x01};
UCHAR       OUI_WPA2_PSK_AKM[4]   	= {0x00, 0x0F, 0xAC, 0x02};
UCHAR       OUI_WPA2_WEP104[4]   = {0x00, 0x0F, 0xAC, 0x05};
// MSA OUI
UCHAR   	OUI_MSA_8021X_AKM[4]    = {0x00, 0x0F, 0xAC, 0x05};		// Not yet final - IEEE 802.11s-D1.06
UCHAR   	OUI_MSA_PSK_AKM[4]   	= {0x00, 0x0F, 0xAC, 0x06};		// Not yet final - IEEE 802.11s-D1.06
@@ -367,6 +370,24 @@ static VOID RTMPInsertRsnIeCipher(
                break;
        }

#ifdef CONFIG_STA_SUPPORT
		if ((pAd->OpMode == OPMODE_STA) &&
			(pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) &&
			(pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled))
		{
			UINT GroupCipher = pAd->StaCfg.GroupCipher;
			switch(GroupCipher)
			{
				case Ndis802_11GroupWEP40Enabled:
					NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_WEP40, 4);
					break;
				case Ndis802_11GroupWEP104Enabled:
					NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_WEP104, 4);
					break;
			}
		}
#endif // CONFIG_STA_SUPPORT //

		// swap for big-endian platform
		pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
	    pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
@@ -427,11 +448,28 @@ static VOID RTMPInsertRsnIeCipher(
                break;
        }

#ifdef CONFIG_STA_SUPPORT
		if ((pAd->OpMode == OPMODE_STA) &&
			(pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) &&
			(pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled))
		{
			UINT GroupCipher = pAd->StaCfg.GroupCipher;
			switch(GroupCipher)
			{
				case Ndis802_11GroupWEP40Enabled:
					NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_WEP40, 4);
					break;
				case Ndis802_11GroupWEP104Enabled:
					NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_WEP104, 4);
					break;
			}
		}
#endif // CONFIG_STA_SUPPORT //

		// swap for big-endian platform
		pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
	    pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
	}

}

/*
Loading