1/* 2 * Copyright (c) 2007-2008 Atheros Communications Inc. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17#include "cprecomp.h" 18 19/* zfAddFreqChangeReq should be called inside the critical section */ 20static void zfAddFreqChangeReq(zdev_t* dev, u16_t frequency, u8_t bw40, 21 u8_t extOffset, zfpFreqChangeCompleteCb cb) 22{ 23 zmw_get_wlan_dev(dev); 24 25//printk("zfAddFreqChangeReq freqReqQueueTail%d\n", wd->freqCtrl.freqReqQueueTail); 26 wd->freqCtrl.freqReqQueue[wd->freqCtrl.freqReqQueueTail] = frequency; 27 wd->freqCtrl.freqReqBw40[wd->freqCtrl.freqReqQueueTail] = bw40; 28 wd->freqCtrl.freqReqExtOffset[wd->freqCtrl.freqReqQueueTail] = extOffset; 29 wd->freqCtrl.freqChangeCompCb[wd->freqCtrl.freqReqQueueTail] = cb; 30 wd->freqCtrl.freqReqQueueTail++; 31 if ( wd->freqCtrl.freqReqQueueTail >= ZM_MAX_FREQ_REQ_QUEUE ) 32 { 33 wd->freqCtrl.freqReqQueueTail = 0; 34 } 35} 36 37void zfCoreSetFrequencyV2(zdev_t* dev, u16_t frequency, zfpFreqChangeCompleteCb cb) 38{ 39 zfCoreSetFrequencyEx(dev, frequency, 0, 0, cb); 40} 41 42void zfCoreSetFrequencyExV2(zdev_t* dev, u16_t frequency, u8_t bw40, 43 u8_t extOffset, zfpFreqChangeCompleteCb cb, u8_t forceSetFreq) 44{ 45 u8_t setFreqImmed = 0; 46 u8_t initRF = 0; 47 zmw_get_wlan_dev(dev); 48 zmw_declare_for_critical_section(); 49 50 zm_msg1_scan(ZM_LV_1, "Freq=", frequency); 51 52 zmw_enter_critical_section(dev); 53 if ((wd->sta.currentFrequency == frequency) 54 && (wd->sta.currentBw40 == bw40) 55 && (wd->sta.currentExtOffset == extOffset)) 56 { 57 if ( forceSetFreq == 0 && wd->sta.flagFreqChanging == 0 ) 58 { 59 goto done; 60 } 61 } 62#ifdef ZM_FB50 63 /*if(frequency!=2437) { 64 zmw_leave_critical_section(dev); 65 return; 66 }*/ 67#endif 68 69 zfAddFreqChangeReq(dev, frequency, bw40, extOffset, cb); 70 71// zm_assert( wd->sta.flagFreqChanging == 0 ); 72 //wd->sta.flagFreqChanging = 1; 73 if ( wd->sta.flagFreqChanging == 0 ) 74 { 75 if ((wd->sta.currentBw40 != bw40) || (wd->sta.currentExtOffset != extOffset)) 76 { 77 initRF = 1; 78 } 79 wd->sta.currentFrequency = frequency; 80 wd->sta.currentBw40 = bw40; 81 wd->sta.currentExtOffset = extOffset; 82 setFreqImmed = 1; 83 } 84 wd->sta.flagFreqChanging++; 85 86 zmw_leave_critical_section(dev); 87 88 if ( setFreqImmed ) 89 { 90 //zfHpSetFrequency(dev, frequency, 0); 91 if ( forceSetFreq ) 92 { // Cold reset to reset the frequency after scanning ! 93 zm_debug_msg0("#6_1 20070917"); 94 zm_debug_msg0("It is happen!!! No error message"); 95 zfHpSetFrequencyEx(dev, frequency, bw40, extOffset, 2); 96 } 97 else 98 { 99 zfHpSetFrequencyEx(dev, frequency, bw40, extOffset, initRF); 100 } 101 102 if ( zfStaIsConnected(dev) 103 && (frequency == wd->frequency)) { 104 wd->sta.connPowerInHalfDbm = zfHpGetTransmitPower(dev); 105 } 106 } 107 return; 108 109done: 110 zmw_leave_critical_section(dev); 111 112 if ( cb != NULL ) 113 { 114 cb(dev); 115 } 116 zfPushVtxq(dev); 117 return; 118} 119 120void zfCoreSetFrequencyEx(zdev_t* dev, u16_t frequency, u8_t bw40, 121 u8_t extOffset, zfpFreqChangeCompleteCb cb) 122{ 123 zfCoreSetFrequencyExV2(dev, frequency, bw40, extOffset, cb, 0); 124} 125 126void zfCoreSetFrequency(zdev_t* dev, u16_t frequency) 127{ 128 zfCoreSetFrequencyV2(dev, frequency, NULL); 129} 130 131/* zfRemoveFreqChangeReq SHOULD NOT be called inside the critical section */ 132static void zfRemoveFreqChangeReq(zdev_t* dev) 133{ 134 zfpFreqChangeCompleteCb cb = NULL; 135 u16_t frequency; 136 u8_t bw40; 137 u8_t extOffset; 138 u16_t compFreq = 0; 139 u8_t compBw40 = 0; 140 u8_t compExtOffset = 0; 141 142 zmw_get_wlan_dev(dev); 143 zmw_declare_for_critical_section(); 144 145 zmw_enter_critical_section(dev); 146 147 if (wd->freqCtrl.freqReqQueueHead != wd->freqCtrl.freqReqQueueTail) 148 { 149 zm_msg1_scan(ZM_LV_1, "Freq=", 150 wd->freqCtrl.freqReqQueue[wd->freqCtrl.freqReqQueueHead]); 151 compFreq = wd->freqCtrl.freqReqQueue[wd->freqCtrl.freqReqQueueHead]; 152 compBw40 = wd->freqCtrl.freqReqBw40[wd->freqCtrl.freqReqQueueHead]; 153 compExtOffset = wd->freqCtrl.freqReqExtOffset[wd->freqCtrl.freqReqQueueHead]; 154 155 wd->freqCtrl.freqReqQueue[wd->freqCtrl.freqReqQueueHead] = 0; 156 cb = wd->freqCtrl.freqChangeCompCb[wd->freqCtrl.freqReqQueueHead]; 157 wd->freqCtrl.freqReqQueueHead++; 158 if ( wd->freqCtrl.freqReqQueueHead >= ZM_MAX_FREQ_REQ_QUEUE ) 159 { 160 wd->freqCtrl.freqReqQueueHead = 0; 161 } 162 } 163 zmw_leave_critical_section(dev); 164 165 if ( cb != NULL ) 166 { 167 cb(dev); 168 } 169 170 zmw_enter_critical_section(dev); 171 while (wd->freqCtrl.freqReqQueue[wd->freqCtrl.freqReqQueueHead] != 0) 172 { 173 frequency = wd->freqCtrl.freqReqQueue[wd->freqCtrl.freqReqQueueHead]; 174 bw40 = wd->freqCtrl.freqReqBw40[wd->freqCtrl.freqReqQueueHead]; 175 extOffset=wd->freqCtrl.freqReqExtOffset[wd->freqCtrl.freqReqQueueHead]; 176 if ((compFreq == frequency) 177 && (compBw40 == bw40) 178 && (compExtOffset == extOffset)) 179 { 180 /* Duplicated frequency command */ 181 zm_msg1_scan(ZM_LV_1, "Duplicated Freq=", frequency); 182 183 cb = wd->freqCtrl.freqChangeCompCb[wd->freqCtrl.freqReqQueueHead]; 184 wd->freqCtrl.freqReqQueue[wd->freqCtrl.freqReqQueueHead] = 0; 185 wd->freqCtrl.freqReqQueueHead++; 186 187 if ( wd->freqCtrl.freqReqQueueHead >= ZM_MAX_FREQ_REQ_QUEUE ) 188 { 189 wd->freqCtrl.freqReqQueueHead = 0; 190 } 191 192 if ( wd->sta.flagFreqChanging != 0 ) 193 { 194 wd->sta.flagFreqChanging--; 195 } 196 197 zmw_leave_critical_section(dev); 198 if ( cb != NULL ) 199 { 200 cb(dev); 201 } 202 zmw_enter_critical_section(dev); 203 } 204 else 205 { 206 u8_t initRF = 0; 207 if ((wd->sta.currentBw40 != bw40) || (wd->sta.currentExtOffset != extOffset)) 208 { 209 initRF = 1; 210 } 211 wd->sta.currentFrequency = frequency; 212 wd->sta.currentBw40 = bw40; 213 wd->sta.currentExtOffset = extOffset; 214 zmw_leave_critical_section(dev); 215 216 zfHpSetFrequencyEx(dev, frequency, bw40, extOffset, initRF); 217 if ( zfStaIsConnected(dev) 218 && (frequency == wd->frequency)) { 219 wd->sta.connPowerInHalfDbm = zfHpGetTransmitPower(dev); 220 } 221 222 return; 223 } 224 } 225 zmw_leave_critical_section(dev); 226 227 return; 228} 229 230void zfCoreSetFrequencyComplete(zdev_t* dev) 231{ 232 zmw_get_wlan_dev(dev); 233 zmw_declare_for_critical_section(); 234 235 zm_msg1_scan(ZM_LV_1, "flagFreqChanging=", wd->sta.flagFreqChanging); 236 237 zmw_enter_critical_section(dev); 238 //wd->sta.flagFreqChanging = 0; 239 if ( wd->sta.flagFreqChanging != 0 ) 240 { 241 wd->sta.flagFreqChanging--; 242 } 243 244 zmw_leave_critical_section(dev); 245 246 zfRemoveFreqChangeReq(dev); 247 248 zfPushVtxq(dev); 249 return; 250} 251 252void zfReSetCurrentFrequency(zdev_t* dev) 253{ 254 zmw_get_wlan_dev(dev); 255 256 zm_debug_msg0("It is happen!!! No error message"); 257 258 zfCoreSetFrequencyExV2(dev, wd->frequency, 0, 0, NULL, 1); 259} 260