1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40#include "ttype.h"
41#include "mac.h"
42#include "device.h"
43#include "wmgr.h"
44#include "power.h"
45#include "wcmd.h"
46#include "rxtx.h"
47#include "card.h"
48
49
50
51
52
53
54static int msglevel = MSG_LEVEL_INFO;
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71void
72PSvEnablePowerSaving(
73 void *hDeviceContext,
74 unsigned short wListenInterval
75)
76{
77 PSDevice pDevice = (PSDevice)hDeviceContext;
78 PSMgmtObject pMgmt = pDevice->pMgmt;
79 unsigned short wAID = pMgmt->wCurrAID | BIT14 | BIT15;
80
81
82 VNSvOutPortW(pDevice->PortOffset + MAC_REG_PWBT, C_PWBT);
83 if (pDevice->eOPMode != OP_MODE_ADHOC) {
84
85 VNSvOutPortW(pDevice->PortOffset + MAC_REG_AIDATIM, wAID);
86 } else {
87
88 MACvWriteATIMW(pDevice->PortOffset, pMgmt->wCurrATIMWindow);
89 }
90
91 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCFG, PSCFG_AUTOSLEEP);
92
93 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_TFTCTL, TFTCTL_HWUTSF);
94
95 if (wListenInterval >= 2) {
96
97 MACvRegBitsOff(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_ALBCN);
98
99
100 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_LNBCN);
101 pMgmt->wCountToWakeUp = wListenInterval;
102 } else {
103
104 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_ALBCN);
105
106 pMgmt->wCountToWakeUp = 0;
107 }
108
109
110 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PSEN);
111 pDevice->bEnablePSMode = true;
112
113 if (pDevice->eOPMode == OP_MODE_ADHOC) {
114
115 }
116
117 else if (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) {
118 PSbSendNullPacket(pDevice);
119 }
120 pDevice->bPWBitOn = true;
121 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "PS:Power Saving Mode Enable... \n");
122 return;
123}
124
125
126
127
128
129
130
131
132
133
134
135void
136PSvDisablePowerSaving(
137 void *hDeviceContext
138)
139{
140 PSDevice pDevice = (PSDevice)hDeviceContext;
141
142
143
144 MACbPSWakeup(pDevice->PortOffset);
145
146 MACvRegBitsOff(pDevice->PortOffset, MAC_REG_PSCFG, PSCFG_AUTOSLEEP);
147
148 MACvRegBitsOff(pDevice->PortOffset, MAC_REG_TFTCTL, TFTCTL_HWUTSF);
149
150 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_ALBCN);
151
152 pDevice->bEnablePSMode = false;
153
154 if (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) {
155 PSbSendNullPacket(pDevice);
156 }
157 pDevice->bPWBitOn = false;
158 return;
159}
160
161
162
163
164
165
166
167
168
169
170
171bool
172PSbConsiderPowerDown(
173 void *hDeviceContext,
174 bool bCheckRxDMA,
175 bool bCheckCountToWakeUp
176)
177{
178 PSDevice pDevice = (PSDevice)hDeviceContext;
179 PSMgmtObject pMgmt = pDevice->pMgmt;
180 unsigned int uIdx;
181
182
183 if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS))
184 return true;
185
186 if (pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) {
187
188 if (pMgmt->bInTIMWake)
189 return false;
190 }
191
192
193 if (pDevice->bCmdRunning)
194 return false;
195
196
197 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PSEN);
198
199
200 for (uIdx = 0; uIdx < TYPE_MAXTD; uIdx++) {
201 if (pDevice->iTDUsed[uIdx] != 0)
202 return false;
203 }
204
205
206 if (bCheckRxDMA &&
207 ((pDevice->dwIsr & ISR_RXDMA0) != 0) &&
208 ((pDevice->dwIsr & ISR_RXDMA1) != 0)) {
209 return false;
210 }
211
212 if (pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) {
213 if (bCheckCountToWakeUp &&
214 (pMgmt->wCountToWakeUp == 0 || pMgmt->wCountToWakeUp == 1)) {
215 return false;
216 }
217 }
218
219
220 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_GO2DOZE);
221 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Go to Doze ZZZZZZZZZZZZZZZ\n");
222 return true;
223}
224
225
226
227
228
229
230
231
232
233
234
235void
236PSvSendPSPOLL(
237 void *hDeviceContext
238)
239{
240 PSDevice pDevice = (PSDevice)hDeviceContext;
241 PSMgmtObject pMgmt = pDevice->pMgmt;
242 PSTxMgmtPacket pTxPacket = NULL;
243
244 memset(pMgmt->pbyPSPacketPool, 0, sizeof(STxMgmtPacket) + WLAN_HDR_ADDR2_LEN);
245 pTxPacket = (PSTxMgmtPacket)pMgmt->pbyPSPacketPool;
246 pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
247 pTxPacket->p80211Header->sA2.wFrameCtl = cpu_to_le16(
248 (
249 WLAN_SET_FC_FTYPE(WLAN_TYPE_CTL) |
250 WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_PSPOLL) |
251 WLAN_SET_FC_PWRMGT(0)
252));
253 pTxPacket->p80211Header->sA2.wDurationID = pMgmt->wCurrAID | BIT14 | BIT15;
254 memcpy(pTxPacket->p80211Header->sA2.abyAddr1, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN);
255 memcpy(pTxPacket->p80211Header->sA2.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
256 pTxPacket->cbMPDULen = WLAN_HDR_ADDR2_LEN;
257 pTxPacket->cbPayloadLen = 0;
258
259 if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) {
260 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send PS-Poll packet failed..\n");
261 } else {
262
263 };
264
265 return;
266}
267
268
269
270
271
272
273
274
275
276
277bool
278PSbSendNullPacket(
279 void *hDeviceContext
280)
281{
282 PSDevice pDevice = (PSDevice)hDeviceContext;
283 PSTxMgmtPacket pTxPacket = NULL;
284 PSMgmtObject pMgmt = pDevice->pMgmt;
285 unsigned int uIdx;
286
287 if (pDevice->bLinkPass == false) {
288 return false;
289 }
290#ifdef TxInSleep
291 if ((pDevice->bEnablePSMode == false) &&
292 (pDevice->fTxDataInSleep == false)) {
293 return false;
294 }
295#else
296 if (pDevice->bEnablePSMode == false) {
297 return false;
298 }
299#endif
300 if (pDevice->bEnablePSMode) {
301 for (uIdx = 0; uIdx < TYPE_MAXTD; uIdx++) {
302 if (pDevice->iTDUsed[uIdx] != 0)
303 return false;
304 }
305 }
306
307 memset(pMgmt->pbyPSPacketPool, 0, sizeof(STxMgmtPacket) + WLAN_NULLDATA_FR_MAXLEN);
308 pTxPacket = (PSTxMgmtPacket)pMgmt->pbyPSPacketPool;
309 pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
310
311 if (pDevice->bEnablePSMode) {
312 pTxPacket->p80211Header->sA3.wFrameCtl = cpu_to_le16(
313 (
314 WLAN_SET_FC_FTYPE(WLAN_TYPE_DATA) |
315 WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_NULL) |
316 WLAN_SET_FC_PWRMGT(1)
317));
318 } else {
319 pTxPacket->p80211Header->sA3.wFrameCtl = cpu_to_le16(
320 (
321 WLAN_SET_FC_FTYPE(WLAN_TYPE_DATA) |
322 WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_NULL) |
323 WLAN_SET_FC_PWRMGT(0)
324));
325 }
326
327 if (pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) {
328 pTxPacket->p80211Header->sA3.wFrameCtl |= cpu_to_le16((unsigned short)WLAN_SET_FC_TODS(1));
329 }
330
331 memcpy(pTxPacket->p80211Header->sA3.abyAddr1, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN);
332 memcpy(pTxPacket->p80211Header->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
333 memcpy(pTxPacket->p80211Header->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
334 pTxPacket->cbMPDULen = WLAN_HDR_ADDR3_LEN;
335 pTxPacket->cbPayloadLen = 0;
336
337 if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) {
338 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send Null Packet failed !\n");
339 return false;
340 } else {
341
342 }
343
344 return true;
345}
346
347
348
349
350
351
352
353
354
355
356
357bool
358PSbIsNextTBTTWakeUp(
359 void *hDeviceContext
360)
361{
362 PSDevice pDevice = (PSDevice)hDeviceContext;
363 PSMgmtObject pMgmt = pDevice->pMgmt;
364 bool bWakeUp = false;
365
366 if (pMgmt->wListenInterval >= 2) {
367 if (pMgmt->wCountToWakeUp == 0) {
368 pMgmt->wCountToWakeUp = pMgmt->wListenInterval;
369 }
370
371 pMgmt->wCountToWakeUp--;
372
373 if (pMgmt->wCountToWakeUp == 1) {
374
375 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_LNBCN);
376 bWakeUp = true;
377 }
378
379 }
380
381 return bWakeUp;
382}
383