4bd43f507c
Initial dump of the otus USB wireless network driver. It builds properly, but a lot of work needs to be done cleaning it up before it can be merged into the wireless driver tree. Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
260 lines
7.8 KiB
C
260 lines
7.8 KiB
C
/*
|
|
* Copyright (c) 2007-2008 Atheros Communications Inc.
|
|
*
|
|
* Permission to use, copy, modify, and/or distribute this software for any
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
* copyright notice and this permission notice appear in all copies.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
*/
|
|
|
|
#include "cprecomp.h"
|
|
|
|
/* zfAddFreqChangeReq should be called inside the critical section */
|
|
static void zfAddFreqChangeReq(zdev_t* dev, u16_t frequency, u8_t bw40,
|
|
u8_t extOffset, zfpFreqChangeCompleteCb cb)
|
|
{
|
|
zmw_get_wlan_dev(dev);
|
|
|
|
//printk("zfAddFreqChangeReq freqReqQueueTail%d\n", wd->freqCtrl.freqReqQueueTail);
|
|
wd->freqCtrl.freqReqQueue[wd->freqCtrl.freqReqQueueTail] = frequency;
|
|
wd->freqCtrl.freqReqBw40[wd->freqCtrl.freqReqQueueTail] = bw40;
|
|
wd->freqCtrl.freqReqExtOffset[wd->freqCtrl.freqReqQueueTail] = extOffset;
|
|
wd->freqCtrl.freqChangeCompCb[wd->freqCtrl.freqReqQueueTail] = cb;
|
|
wd->freqCtrl.freqReqQueueTail++;
|
|
if ( wd->freqCtrl.freqReqQueueTail >= ZM_MAX_FREQ_REQ_QUEUE )
|
|
{
|
|
wd->freqCtrl.freqReqQueueTail = 0;
|
|
}
|
|
}
|
|
|
|
void zfCoreSetFrequencyV2(zdev_t* dev, u16_t frequency, zfpFreqChangeCompleteCb cb)
|
|
{
|
|
zfCoreSetFrequencyEx(dev, frequency, 0, 0, cb);
|
|
}
|
|
|
|
void zfCoreSetFrequencyExV2(zdev_t* dev, u16_t frequency, u8_t bw40,
|
|
u8_t extOffset, zfpFreqChangeCompleteCb cb, u8_t forceSetFreq)
|
|
{
|
|
u8_t setFreqImmed = 0;
|
|
u8_t initRF = 0;
|
|
zmw_get_wlan_dev(dev);
|
|
zmw_declare_for_critical_section();
|
|
|
|
zm_msg1_scan(ZM_LV_1, "Freq=", frequency);
|
|
|
|
zmw_enter_critical_section(dev);
|
|
if ((wd->sta.currentFrequency == frequency)
|
|
&& (wd->sta.currentBw40 == bw40)
|
|
&& (wd->sta.currentExtOffset == extOffset))
|
|
{
|
|
if ( forceSetFreq == 0 && wd->sta.flagFreqChanging == 0 )
|
|
{
|
|
goto done;
|
|
}
|
|
}
|
|
#ifdef ZM_FB50
|
|
/*if(frequency!=2437) {
|
|
zmw_leave_critical_section(dev);
|
|
return;
|
|
}*/
|
|
#endif
|
|
|
|
zfAddFreqChangeReq(dev, frequency, bw40, extOffset, cb);
|
|
|
|
// zm_assert( wd->sta.flagFreqChanging == 0 );
|
|
//wd->sta.flagFreqChanging = 1;
|
|
if ( wd->sta.flagFreqChanging == 0 )
|
|
{
|
|
if ((wd->sta.currentBw40 != bw40) || (wd->sta.currentExtOffset != extOffset))
|
|
{
|
|
initRF = 1;
|
|
}
|
|
wd->sta.currentFrequency = frequency;
|
|
wd->sta.currentBw40 = bw40;
|
|
wd->sta.currentExtOffset = extOffset;
|
|
setFreqImmed = 1;
|
|
}
|
|
wd->sta.flagFreqChanging++;
|
|
|
|
zmw_leave_critical_section(dev);
|
|
|
|
if ( setFreqImmed )
|
|
{
|
|
//zfHpSetFrequency(dev, frequency, 0);
|
|
if ( forceSetFreq )
|
|
{ // Cold reset to reset the frequency after scanning !
|
|
zm_debug_msg0("#6_1 20070917");
|
|
zm_debug_msg0("It is happen!!! No error message");
|
|
zfHpSetFrequencyEx(dev, frequency, bw40, extOffset, 2);
|
|
}
|
|
else
|
|
{
|
|
zfHpSetFrequencyEx(dev, frequency, bw40, extOffset, initRF);
|
|
}
|
|
|
|
if ( zfStaIsConnected(dev)
|
|
&& (frequency == wd->frequency)) {
|
|
wd->sta.connPowerInHalfDbm = zfHpGetTransmitPower(dev);
|
|
}
|
|
}
|
|
return;
|
|
|
|
done:
|
|
zmw_leave_critical_section(dev);
|
|
|
|
if ( cb != NULL )
|
|
{
|
|
cb(dev);
|
|
}
|
|
zfPushVtxq(dev);
|
|
return;
|
|
}
|
|
|
|
void zfCoreSetFrequencyEx(zdev_t* dev, u16_t frequency, u8_t bw40,
|
|
u8_t extOffset, zfpFreqChangeCompleteCb cb)
|
|
{
|
|
zfCoreSetFrequencyExV2(dev, frequency, bw40, extOffset, cb, 0);
|
|
}
|
|
|
|
void zfCoreSetFrequency(zdev_t* dev, u16_t frequency)
|
|
{
|
|
zfCoreSetFrequencyV2(dev, frequency, NULL);
|
|
}
|
|
|
|
/* zfRemoveFreqChangeReq SHOULD NOT be called inside the critical section */
|
|
static void zfRemoveFreqChangeReq(zdev_t* dev)
|
|
{
|
|
zfpFreqChangeCompleteCb cb = NULL;
|
|
u16_t frequency;
|
|
u8_t bw40;
|
|
u8_t extOffset;
|
|
u16_t compFreq = 0;
|
|
u8_t compBw40 = 0;
|
|
u8_t compExtOffset = 0;
|
|
|
|
zmw_get_wlan_dev(dev);
|
|
zmw_declare_for_critical_section();
|
|
|
|
zmw_enter_critical_section(dev);
|
|
|
|
if (wd->freqCtrl.freqReqQueueHead != wd->freqCtrl.freqReqQueueTail)
|
|
{
|
|
zm_msg1_scan(ZM_LV_1, "Freq=",
|
|
wd->freqCtrl.freqReqQueue[wd->freqCtrl.freqReqQueueHead]);
|
|
compFreq = wd->freqCtrl.freqReqQueue[wd->freqCtrl.freqReqQueueHead];
|
|
compBw40 = wd->freqCtrl.freqReqBw40[wd->freqCtrl.freqReqQueueHead];
|
|
compExtOffset = wd->freqCtrl.freqReqExtOffset[wd->freqCtrl.freqReqQueueHead];
|
|
|
|
wd->freqCtrl.freqReqQueue[wd->freqCtrl.freqReqQueueHead] = 0;
|
|
cb = wd->freqCtrl.freqChangeCompCb[wd->freqCtrl.freqReqQueueHead];
|
|
wd->freqCtrl.freqReqQueueHead++;
|
|
if ( wd->freqCtrl.freqReqQueueHead >= ZM_MAX_FREQ_REQ_QUEUE )
|
|
{
|
|
wd->freqCtrl.freqReqQueueHead = 0;
|
|
}
|
|
}
|
|
zmw_leave_critical_section(dev);
|
|
|
|
if ( cb != NULL )
|
|
{
|
|
cb(dev);
|
|
}
|
|
|
|
zmw_enter_critical_section(dev);
|
|
while (wd->freqCtrl.freqReqQueue[wd->freqCtrl.freqReqQueueHead] != 0)
|
|
{
|
|
frequency = wd->freqCtrl.freqReqQueue[wd->freqCtrl.freqReqQueueHead];
|
|
bw40 = wd->freqCtrl.freqReqBw40[wd->freqCtrl.freqReqQueueHead];
|
|
extOffset=wd->freqCtrl.freqReqExtOffset[wd->freqCtrl.freqReqQueueHead];
|
|
if ((compFreq == frequency)
|
|
&& (compBw40 == bw40)
|
|
&& (compExtOffset == extOffset))
|
|
{
|
|
/* Duplicated frequency command */
|
|
zm_msg1_scan(ZM_LV_1, "Duplicated Freq=", frequency);
|
|
|
|
cb = wd->freqCtrl.freqChangeCompCb[wd->freqCtrl.freqReqQueueHead];
|
|
wd->freqCtrl.freqReqQueue[wd->freqCtrl.freqReqQueueHead] = 0;
|
|
wd->freqCtrl.freqReqQueueHead++;
|
|
|
|
if ( wd->freqCtrl.freqReqQueueHead >= ZM_MAX_FREQ_REQ_QUEUE )
|
|
{
|
|
wd->freqCtrl.freqReqQueueHead = 0;
|
|
}
|
|
|
|
if ( wd->sta.flagFreqChanging != 0 )
|
|
{
|
|
wd->sta.flagFreqChanging--;
|
|
}
|
|
|
|
zmw_leave_critical_section(dev);
|
|
if ( cb != NULL )
|
|
{
|
|
cb(dev);
|
|
}
|
|
zmw_enter_critical_section(dev);
|
|
}
|
|
else
|
|
{
|
|
u8_t initRF = 0;
|
|
if ((wd->sta.currentBw40 != bw40) || (wd->sta.currentExtOffset != extOffset))
|
|
{
|
|
initRF = 1;
|
|
}
|
|
wd->sta.currentFrequency = frequency;
|
|
wd->sta.currentBw40 = bw40;
|
|
wd->sta.currentExtOffset = extOffset;
|
|
zmw_leave_critical_section(dev);
|
|
|
|
zfHpSetFrequencyEx(dev, frequency, bw40, extOffset, initRF);
|
|
if ( zfStaIsConnected(dev)
|
|
&& (frequency == wd->frequency)) {
|
|
wd->sta.connPowerInHalfDbm = zfHpGetTransmitPower(dev);
|
|
}
|
|
|
|
return;
|
|
}
|
|
}
|
|
zmw_leave_critical_section(dev);
|
|
|
|
return;
|
|
}
|
|
|
|
void zfCoreSetFrequencyComplete(zdev_t* dev)
|
|
{
|
|
zmw_get_wlan_dev(dev);
|
|
zmw_declare_for_critical_section();
|
|
|
|
zm_msg1_scan(ZM_LV_1, "flagFreqChanging=", wd->sta.flagFreqChanging);
|
|
|
|
zmw_enter_critical_section(dev);
|
|
//wd->sta.flagFreqChanging = 0;
|
|
if ( wd->sta.flagFreqChanging != 0 )
|
|
{
|
|
wd->sta.flagFreqChanging--;
|
|
}
|
|
|
|
zmw_leave_critical_section(dev);
|
|
|
|
zfRemoveFreqChangeReq(dev);
|
|
|
|
zfPushVtxq(dev);
|
|
return;
|
|
}
|
|
|
|
void zfReSetCurrentFrequency(zdev_t* dev)
|
|
{
|
|
zmw_get_wlan_dev(dev);
|
|
|
|
zm_debug_msg0("It is happen!!! No error message");
|
|
|
|
zfCoreSetFrequencyExV2(dev, wd->frequency, 0, 0, NULL, 1);
|
|
}
|