/* * 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); }