Merge remote-tracking branch 'staging/staging-next'
[deliverable/linux.git] / drivers / staging / ks7010 / ks_hostif.c
CommitLineData
13a9930d
WS
1/*
2 * Driver for KeyStream wireless LAN cards.
3 *
13a9930d
WS
4 * Copyright (C) 2005-2008 KeyStream Corp.
5 * Copyright (C) 2009 Renesas Technology Corp.
6 *
7 * This program is free software; you can redistribute it and/or modify
c5d9a030
WS
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
13a9930d
WS
10 */
11
12#include "ks_wlan.h"
13a9930d
WS
13#include "ks_hostif.h"
14#include "eap_packet.h"
15#include "michael_mic.h"
16
17#include <linux/if_ether.h>
18#include <linux/if_arp.h>
19
20/* Include Wireless Extension definition and check version */
13a9930d 21#include <net/iw_handler.h> /* New driver API */
13a9930d 22
20c4f9c5
WS
23extern int ks_wlan_hw_tx(struct ks_wlan_private *priv, void *p,
24 unsigned long size,
25 void (*complete_handler) (void *arg1, void *arg2),
26 void *arg1, void *arg2);
13a9930d
WS
27extern void send_packet_complete(void *, void *);
28
feedcf1a
WS
29extern void ks_wlan_hw_wakeup_request(struct ks_wlan_private *priv);
30extern int ks_wlan_hw_power_save(struct ks_wlan_private *priv);
13a9930d
WS
31
32/* macro */
33#define inc_smeqhead(priv) \
34 ( priv->sme_i.qhead = (priv->sme_i.qhead + 1) % SME_EVENT_BUFF_SIZE )
35#define inc_smeqtail(priv) \
36 ( priv->sme_i.qtail = (priv->sme_i.qtail + 1) % SME_EVENT_BUFF_SIZE )
37#define cnt_smeqbody(priv) \
38 (((priv->sme_i.qtail + SME_EVENT_BUFF_SIZE) - (priv->sme_i.qhead)) % SME_EVENT_BUFF_SIZE )
39
40#define KS_WLAN_MEM_FLAG (GFP_ATOMIC)
41
42static
feedcf1a 43inline u8 get_BYTE(struct ks_wlan_private *priv)
13a9930d
WS
44{
45 u8 data;
46 data = *(priv->rxp)++;
47 /* length check in advance ! */
48 --(priv->rx_size);
49 return data;
50}
51
52static
feedcf1a 53inline u16 get_WORD(struct ks_wlan_private *priv)
13a9930d
WS
54{
55 u16 data;
20c4f9c5 56 data = (get_BYTE(priv) & 0xff);
13a9930d
WS
57 data |= ((get_BYTE(priv) << 8) & 0xff00);
58 return data;
59}
60
61static
feedcf1a 62inline u32 get_DWORD(struct ks_wlan_private *priv)
13a9930d
WS
63{
64 u32 data;
20c4f9c5 65 data = (get_BYTE(priv) & 0xff);
13a9930d
WS
66 data |= ((get_BYTE(priv) << 8) & 0x0000ff00);
67 data |= ((get_BYTE(priv) << 16) & 0x00ff0000);
68 data |= ((get_BYTE(priv) << 24) & 0xff000000);
69 return data;
70}
71
9afe11e9 72static void ks_wlan_hw_wakeup_task(struct work_struct *work)
13a9930d 73{
20c4f9c5
WS
74 struct ks_wlan_private *priv =
75 container_of(work, struct ks_wlan_private, ks_wlan_wakeup_task);
13a9930d 76 int ps_status = atomic_read(&priv->psstatus.status);
9d29f14d 77 long time_left;
13a9930d 78
20c4f9c5 79 if (ps_status == PS_SNOOZE) {
13a9930d 80 ks_wlan_hw_wakeup_request(priv);
9d29f14d
NMG
81 time_left = wait_for_completion_interruptible_timeout(
82 &priv->psstatus.wakeup_wait,
83 msecs_to_jiffies(20));
84 if (time_left <= 0) {
85 DPRINTK(1, "wake up timeout or interrupted !!!\n");
13a9930d
WS
86 schedule_work(&priv->ks_wlan_wakeup_task);
87 return;
88 }
20c4f9c5
WS
89 } else {
90 DPRINTK(1, "ps_status=%d\n", ps_status);
13a9930d
WS
91 }
92
93 /* power save */
20c4f9c5
WS
94 if (atomic_read(&priv->sme_task.count) > 0) {
95 DPRINTK(4, "sme task enable.\n");
13a9930d
WS
96 tasklet_enable(&priv->sme_task);
97 }
98}
99
100static
feedcf1a 101int ks_wlan_do_power_save(struct ks_wlan_private *priv)
13a9930d 102{
20c4f9c5 103 int rc = 0;
13a9930d 104
20c4f9c5 105 DPRINTK(4, "psstatus.status=%d\n", atomic_read(&priv->psstatus.status));
13a9930d 106
20c4f9c5 107 if ((priv->connect_status & CONNECT_STATUS_MASK) == CONNECT_STATUS) {
13a9930d 108 hostif_sme_enqueue(priv, SME_POW_MNGMT_REQUEST);
20c4f9c5 109 } else {
13a9930d
WS
110 priv->dev_state = DEVICE_STATE_READY;
111 }
13a9930d
WS
112 return rc;
113}
114
115static
feedcf1a 116int get_current_ap(struct ks_wlan_private *priv, struct link_ap_info_t *ap_info)
13a9930d
WS
117{
118 struct local_ap_t *ap;
13a9930d 119 union iwreq_data wrqu;
20c4f9c5
WS
120 struct net_device *netdev = priv->net_dev;
121 int rc = 0;
13a9930d 122
20c4f9c5 123 DPRINTK(3, "\n");
13a9930d
WS
124 ap = &(priv->current_ap);
125
20c4f9c5
WS
126 if ((priv->connect_status & CONNECT_STATUS_MASK) == DISCONNECT_STATUS) {
127 memset(ap, 0, sizeof(struct local_ap_t));
13a9930d
WS
128 return 1;
129 }
130
131 /* bssid */
20c4f9c5 132 memcpy(&(ap->bssid[0]), &(ap_info->bssid[0]), ETH_ALEN);
13a9930d 133 /* essid */
20c4f9c5
WS
134 memcpy(&(ap->ssid.body[0]), &(priv->reg.ssid.body[0]),
135 priv->reg.ssid.size);
13a9930d
WS
136 ap->ssid.size = priv->reg.ssid.size;
137 /* rate_set */
20c4f9c5
WS
138 memcpy(&(ap->rate_set.body[0]), &(ap_info->rate_set.body[0]),
139 ap_info->rate_set.size);
13a9930d 140 ap->rate_set.size = ap_info->rate_set.size;
20c4f9c5 141 if (ap_info->ext_rate_set.size) {
13a9930d
WS
142 /* rate_set */
143 memcpy(&(ap->rate_set.body[ap->rate_set.size]),
144 &(ap_info->ext_rate_set.body[0]),
145 ap_info->ext_rate_set.size);
146 ap->rate_set.size += ap_info->ext_rate_set.size;
147 }
148 /* channel */
149 ap->channel = ap_info->ds_parameter.channel;
150 /* rssi */
151 ap->rssi = ap_info->rssi;
152 /* sq */
153 ap->sq = ap_info->sq;
154 /* noise */
155 ap->noise = ap_info->noise;
156 /* capability */
157 ap->capability = ap_info->capability;
158 /* rsn */
20c4f9c5
WS
159 if ((ap_info->rsn_mode & RSN_MODE_WPA2)
160 && (priv->wpa.version == IW_AUTH_WPA_VERSION_WPA2)) {
13a9930d 161 ap->rsn_ie.id = 0x30;
20c4f9c5 162 if (ap_info->rsn.size <= RSN_IE_BODY_MAX) {
13a9930d 163 ap->rsn_ie.size = ap_info->rsn.size;
20c4f9c5
WS
164 memcpy(&(ap->rsn_ie.body[0]), &(ap_info->rsn.body[0]),
165 ap_info->rsn.size);
166 } else {
13a9930d 167 ap->rsn_ie.size = RSN_IE_BODY_MAX;
20c4f9c5
WS
168 memcpy(&(ap->rsn_ie.body[0]), &(ap_info->rsn.body[0]),
169 RSN_IE_BODY_MAX);
13a9930d 170 }
20c4f9c5
WS
171 } else if ((ap_info->rsn_mode & RSN_MODE_WPA)
172 && (priv->wpa.version == IW_AUTH_WPA_VERSION_WPA)) {
13a9930d 173 ap->wpa_ie.id = 0xdd;
20c4f9c5 174 if (ap_info->rsn.size <= RSN_IE_BODY_MAX) {
13a9930d 175 ap->wpa_ie.size = ap_info->rsn.size;
20c4f9c5
WS
176 memcpy(&(ap->wpa_ie.body[0]), &(ap_info->rsn.body[0]),
177 ap_info->rsn.size);
178 } else {
13a9930d 179 ap->wpa_ie.size = RSN_IE_BODY_MAX;
20c4f9c5
WS
180 memcpy(&(ap->wpa_ie.body[0]), &(ap_info->rsn.body[0]),
181 RSN_IE_BODY_MAX);
13a9930d 182 }
20c4f9c5 183 } else {
13a9930d
WS
184 ap->rsn_ie.id = 0;
185 ap->rsn_ie.size = 0;
186 ap->wpa_ie.id = 0;
187 ap->wpa_ie.size = 0;
188 }
189
13a9930d
WS
190 wrqu.data.length = 0;
191 wrqu.data.flags = 0;
192 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
20c4f9c5 193 if ((priv->connect_status & CONNECT_STATUS_MASK) == CONNECT_STATUS) {
13a9930d
WS
194 memcpy(wrqu.ap_addr.sa_data,
195 &(priv->current_ap.bssid[0]), ETH_ALEN);
20c4f9c5
WS
196 DPRINTK(3,
197 "IWEVENT: connect bssid=%02x:%02x:%02x:%02x:%02x:%02x\n",
198 (unsigned char)wrqu.ap_addr.sa_data[0],
199 (unsigned char)wrqu.ap_addr.sa_data[1],
200 (unsigned char)wrqu.ap_addr.sa_data[2],
201 (unsigned char)wrqu.ap_addr.sa_data[3],
202 (unsigned char)wrqu.ap_addr.sa_data[4],
203 (unsigned char)wrqu.ap_addr.sa_data[5]);
13a9930d
WS
204 wireless_send_event(netdev, SIOCGIWAP, &wrqu, NULL);
205 }
20c4f9c5
WS
206 DPRINTK(4, "\n Link AP\n");
207 DPRINTK(4, " bssid=%02X:%02X:%02X:%02X:%02X:%02X\n \
13a9930d 208 essid=%s\n rate_set=%02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X\n channel=%d\n \
20c4f9c5
WS
209 rssi=%d\n sq=%d\n capability=%04X\n", ap->bssid[0], ap->bssid[1], ap->bssid[2], ap->bssid[3], ap->bssid[4], ap->bssid[5], &(ap->ssid.body[0]), ap->rate_set.body[0], ap->rate_set.body[1], ap->rate_set.body[2], ap->rate_set.body[3], ap->rate_set.body[4], ap->rate_set.body[5], ap->rate_set.body[6], ap->rate_set.body[7], ap->channel, ap->rssi, ap->sq, ap->capability);
210 DPRINTK(4, "\n Link AP\n rsn.mode=%d\n rsn.size=%d\n",
211 ap_info->rsn_mode, ap_info->rsn.size);
212 DPRINTK(4, "\n ext_rate_set_size=%d\n rate_set_size=%d\n",
213 ap_info->ext_rate_set.size, ap_info->rate_set.size);
13a9930d
WS
214
215 return rc;
216}
217
218static
20c4f9c5
WS
219int get_ap_information(struct ks_wlan_private *priv, struct ap_info_t *ap_info,
220 struct local_ap_t *ap)
13a9930d
WS
221{
222 unsigned char *bp;
20c4f9c5
WS
223 int bsize, offset;
224 int rc = 0;
13a9930d 225
20c4f9c5
WS
226 DPRINTK(3, "\n");
227 memset(ap, 0, sizeof(struct local_ap_t));
13a9930d
WS
228
229 /* bssid */
20c4f9c5 230 memcpy(&(ap->bssid[0]), &(ap_info->bssid[0]), ETH_ALEN);
13a9930d
WS
231 /* rssi */
232 ap->rssi = ap_info->rssi;
233 /* sq */
234 ap->sq = ap_info->sq;
235 /* noise */
236 ap->noise = ap_info->noise;
237 /* capability */
238 ap->capability = ap_info->capability;
239 /* channel */
240 ap->channel = ap_info->ch_info;
241
242 bp = &(ap_info->body[0]);
243 bsize = ap_info->body_size;
244 offset = 0;
245
20c4f9c5 246 while (bsize > offset) {
13a9930d 247 /* DPRINTK(4, "Element ID=%d \n",*bp); */
20c4f9c5
WS
248 switch (*bp) {
249 case 0: /* ssid */
250 if (*(bp + 1) <= SSID_MAX_SIZE) {
251 ap->ssid.size = *(bp + 1);
252 } else {
253 DPRINTK(1, "size over :: ssid size=%d \n",
254 *(bp + 1));
13a9930d
WS
255 ap->ssid.size = SSID_MAX_SIZE;
256 }
20c4f9c5 257 memcpy(&(ap->ssid.body[0]), bp + 2, ap->ssid.size);
13a9930d 258 break;
20c4f9c5
WS
259 case 1: /* rate */
260 case 50: /* ext rate */
261 if ((*(bp + 1) + ap->rate_set.size) <=
262 RATE_SET_MAX_SIZE) {
263 memcpy(&(ap->rate_set.body[ap->rate_set.size]),
264 bp + 2, *(bp + 1));
265 ap->rate_set.size += *(bp + 1);
266 } else {
13a9930d 267 DPRINTK(1, "size over :: rate size=%d \n",
20c4f9c5
WS
268 (*(bp + 1) + ap->rate_set.size));
269 memcpy(&(ap->rate_set.body[ap->rate_set.size]),
270 bp + 2,
13a9930d 271 RATE_SET_MAX_SIZE - ap->rate_set.size);
20c4f9c5
WS
272 ap->rate_set.size +=
273 (RATE_SET_MAX_SIZE - ap->rate_set.size);
13a9930d
WS
274 }
275 break;
20c4f9c5 276 case 3: /* DS parameter */
13a9930d 277 break;
20c4f9c5 278 case 48: /* RSN(WPA2) */
13a9930d 279 ap->rsn_ie.id = *bp;
20c4f9c5
WS
280 if (*(bp + 1) <= RSN_IE_BODY_MAX) {
281 ap->rsn_ie.size = *(bp + 1);
282 } else {
283 DPRINTK(1, "size over :: rsn size=%d \n",
284 *(bp + 1));
13a9930d
WS
285 ap->rsn_ie.size = RSN_IE_BODY_MAX;
286 }
20c4f9c5 287 memcpy(&(ap->rsn_ie.body[0]), bp + 2, ap->rsn_ie.size);
13a9930d 288 break;
20c4f9c5
WS
289 case 221: /* WPA */
290 if (!memcmp(bp + 2, "\x00\x50\xf2\x01", 4)) { /* WPA OUI check */
13a9930d 291 ap->wpa_ie.id = *bp;
20c4f9c5
WS
292 if (*(bp + 1) <= RSN_IE_BODY_MAX) {
293 ap->wpa_ie.size = *(bp + 1);
294 } else {
295 DPRINTK(1,
296 "size over :: wpa size=%d \n",
297 *(bp + 1));
13a9930d
WS
298 ap->wpa_ie.size = RSN_IE_BODY_MAX;
299 }
20c4f9c5
WS
300 memcpy(&(ap->wpa_ie.body[0]), bp + 2,
301 ap->wpa_ie.size);
13a9930d
WS
302 }
303 break;
304
20c4f9c5
WS
305 case 2: /* FH parameter */
306 case 4: /* CF parameter */
307 case 5: /* TIM */
308 case 6: /* IBSS parameter */
309 case 7: /* Country */
310 case 42: /* ERP information */
311 case 47: /* Reserve ID 47 Broadcom AP */
13a9930d
WS
312 break;
313 default:
20c4f9c5 314 DPRINTK(4, "unknown Element ID=%d \n", *bp);
13a9930d
WS
315 break;
316 }
20c4f9c5
WS
317 offset += 2; /* id & size field */
318 offset += *(bp + 1); /* +size offset */
319 bp += (*(bp + 1) + 2); /* pointer update */
13a9930d
WS
320 }
321
322 return rc;
323}
324
325static
feedcf1a 326void hostif_data_indication(struct ks_wlan_private *priv)
13a9930d 327{
20c4f9c5 328 unsigned int rx_ind_size; /* indicate data size */
13a9930d 329 struct sk_buff *skb;
20c4f9c5
WS
330 unsigned short auth_type;
331 unsigned char temp[256];
13a9930d 332
20c4f9c5 333 unsigned char RecvMIC[8];
13a9930d
WS
334 char buf[128];
335 struct ether_hdr *eth_hdr;
336 unsigned short eth_proto;
337 unsigned long now;
338 struct mic_failure_t *mic_failure;
339 struct ieee802_1x_hdr *aa1x_hdr;
340 struct wpa_eapol_key *eap_key;
341 struct michel_mic_t michel_mic;
13a9930d 342 union iwreq_data wrqu;
13a9930d 343
20c4f9c5 344 DPRINTK(3, "\n");
13a9930d
WS
345
346 /* min length check */
347 if (priv->rx_size <= ETH_HLEN) {
20c4f9c5 348 DPRINTK(3, "rx_size = %d\n", priv->rx_size);
13a9930d
WS
349 priv->nstats.rx_errors++;
350 return;
351 }
352
20c4f9c5
WS
353 auth_type = get_WORD(priv); /* AuthType */
354 get_WORD(priv); /* Reserve Area */
13a9930d
WS
355
356 eth_hdr = (struct ether_hdr *)(priv->rxp);
357 eth_proto = ntohs(eth_hdr->h_proto);
20c4f9c5 358 DPRINTK(3, "ether protocol = %04X\n", eth_proto);
13a9930d
WS
359
360 /* source address check */
20c4f9c5 361 if (!memcmp(&priv->eth_addr[0], eth_hdr->h_source, ETH_ALEN)) {
13a9930d 362 DPRINTK(1, "invalid : source is own mac address !!\n");
20c4f9c5
WS
363 DPRINTK(1,
364 "eth_hdrernet->h_dest=%02X:%02X:%02X:%02X:%02X:%02X\n",
365 eth_hdr->h_source[0], eth_hdr->h_source[1],
366 eth_hdr->h_source[2], eth_hdr->h_source[3],
367 eth_hdr->h_source[4], eth_hdr->h_source[5]);
13a9930d
WS
368 priv->nstats.rx_errors++;
369 return;
370 }
371
372 /* for WPA */
20c4f9c5
WS
373 if (auth_type != TYPE_DATA && priv->wpa.rsn_enabled) {
374 if (memcmp(&eth_hdr->h_source[0], &priv->eth_addr[0], ETH_ALEN)) { /* source address check */
375 if (eth_hdr->h_dest_snap != eth_hdr->h_source_snap) {
376 DPRINTK(1, "invalid data format\n");
13a9930d
WS
377 priv->nstats.rx_errors++;
378 return;
379 }
20c4f9c5
WS
380 if (((auth_type == TYPE_PMK1
381 && priv->wpa.pairwise_suite ==
382 IW_AUTH_CIPHER_TKIP) || (auth_type == TYPE_GMK1
383 && priv->wpa.
384 group_suite ==
385 IW_AUTH_CIPHER_TKIP)
386 || (auth_type == TYPE_GMK2
387 && priv->wpa.group_suite ==
388 IW_AUTH_CIPHER_TKIP))
389 && priv->wpa.key[auth_type - 1].key_len) {
390 DPRINTK(4, "TKIP: protocol=%04X: size=%u\n",
391 eth_proto, priv->rx_size);
13a9930d 392 /* MIC save */
20c4f9c5
WS
393 memcpy(&RecvMIC[0],
394 (priv->rxp) + ((priv->rx_size) - 8), 8);
13a9930d 395 priv->rx_size = priv->rx_size - 8;
20c4f9c5
WS
396 if (auth_type > 0 && auth_type < 4) { /* auth_type check */
397 MichaelMICFunction(&michel_mic, (uint8_t *) priv->wpa.key[auth_type - 1].rx_mic_key, (uint8_t *) priv->rxp, (int)priv->rx_size, (uint8_t) 0, /* priority */
398 (uint8_t *)
399 michel_mic.Result);
13a9930d 400 }
20c4f9c5 401 if (memcmp(michel_mic.Result, RecvMIC, 8)) {
13a9930d
WS
402 now = jiffies;
403 mic_failure = &priv->wpa.mic_failure;
404 /* MIC FAILURE */
20c4f9c5
WS
405 if (mic_failure->last_failure_time &&
406 (now -
407 mic_failure->last_failure_time) /
408 HZ >= 60) {
409 mic_failure->failure = 0;
13a9930d 410 }
20c4f9c5
WS
411 DPRINTK(4, "MIC FAILURE \n");
412 if (mic_failure->failure == 0) {
413 mic_failure->failure = 1;
414 mic_failure->counter = 0;
415 } else if (mic_failure->failure == 1) {
416 mic_failure->failure = 2;
13a9930d 417 mic_failure->counter =
20c4f9c5
WS
418 (uint16_t) ((now -
419 mic_failure->
420 last_failure_time)
421 / HZ);
422 if (!mic_failure->counter) /* mic_failure counter value range 1-60 */
423 mic_failure->counter =
424 1;
13a9930d 425 }
20c4f9c5
WS
426 priv->wpa.mic_failure.
427 last_failure_time = now;
13a9930d 428 /* needed parameters: count, keyid, key type, TSC */
20c4f9c5
WS
429 sprintf(buf,
430 "MLME-MICHAELMICFAILURE.indication(keyid=%d %scast addr="
13a9930d 431 "%02x:%02x:%02x:%02x:%02x:%02x)",
20c4f9c5
WS
432 auth_type - 1,
433 eth_hdr->
434 h_dest[0] & 0x01 ? "broad" :
435 "uni", eth_hdr->h_source[0],
436 eth_hdr->h_source[1],
437 eth_hdr->h_source[2],
438 eth_hdr->h_source[3],
439 eth_hdr->h_source[4],
440 eth_hdr->h_source[5]);
13a9930d
WS
441 memset(&wrqu, 0, sizeof(wrqu));
442 wrqu.data.length = strlen(buf);
20c4f9c5
WS
443 DPRINTK(4,
444 "IWEVENT:MICHAELMICFAILURE\n");
445 wireless_send_event(priv->net_dev,
446 IWEVCUSTOM, &wrqu,
447 buf);
13a9930d
WS
448 return;
449 }
450 }
451 }
452 }
453
20c4f9c5
WS
454 if ((priv->connect_status & FORCE_DISCONNECT) ||
455 priv->wpa.mic_failure.failure == 2) {
13a9930d
WS
456 return;
457 }
458
459 /* check 13th byte at rx data */
20c4f9c5
WS
460 switch (*(priv->rxp + 12)) {
461 case 0xAA: /* SNAP */
13a9930d 462 rx_ind_size = priv->rx_size - 6;
20c4f9c5
WS
463 skb = dev_alloc_skb(rx_ind_size);
464 DPRINTK(4, "SNAP, rx_ind_size = %d\n", rx_ind_size);
465
466 if (skb) {
467 memcpy(skb_put(skb, 12), priv->rxp, 12); /* 8802/FDDI MAC copy */
468 /* (SNAP+UI..) skip */
469 memcpy(skb_put(skb, rx_ind_size - 12), priv->rxp + 18, rx_ind_size - 12); /* copy after Type */
470
471 aa1x_hdr = (struct ieee802_1x_hdr *)(priv->rxp + 20);
472 if (aa1x_hdr->type == IEEE802_1X_TYPE_EAPOL_KEY
473 && priv->wpa.rsn_enabled) {
474 eap_key =
475 (struct wpa_eapol_key *)(aa1x_hdr + 1);
13a9930d
WS
476 atomic_set(&priv->psstatus.snooze_guard, 1);
477 }
478
479 /* rx indication */
480 skb->dev = priv->net_dev;
20c4f9c5 481 skb->protocol = eth_type_trans(skb, skb->dev);
13a9930d
WS
482 priv->nstats.rx_packets++;
483 priv->nstats.rx_bytes += rx_ind_size;
484 skb->dev->last_rx = jiffies;
20c4f9c5 485 netif_rx(skb);
13a9930d 486 } else {
20c4f9c5 487 printk(KERN_WARNING
95d2a324 488 "ks_wlan: Memory squeeze, dropping packet.\n");
13a9930d
WS
489 priv->nstats.rx_dropped++;
490 }
491 break;
20c4f9c5 492 case 0xF0: /* NETBEUI/NetBIOS */
13a9930d 493 rx_ind_size = (priv->rx_size + 2);
20c4f9c5
WS
494 skb = dev_alloc_skb(rx_ind_size);
495 DPRINTK(3, "NETBEUI/NetBIOS rx_ind_size=%d\n", rx_ind_size);
13a9930d 496
20c4f9c5
WS
497 if (skb) {
498 memcpy(skb_put(skb, 12), priv->rxp, 12); /* 8802/FDDI MAC copy */
13a9930d 499
20c4f9c5
WS
500 temp[0] = (((rx_ind_size - 12) >> 8) & 0xff); /* NETBEUI size add */
501 temp[1] = ((rx_ind_size - 12) & 0xff);
502 memcpy(skb_put(skb, 2), temp, 2);
13a9930d 503
20c4f9c5 504 memcpy(skb_put(skb, rx_ind_size - 14), priv->rxp + 12, rx_ind_size - 14); /* copy after Type */
13a9930d 505
20c4f9c5
WS
506 aa1x_hdr = (struct ieee802_1x_hdr *)(priv->rxp + 14);
507 if (aa1x_hdr->type == IEEE802_1X_TYPE_EAPOL_KEY
508 && priv->wpa.rsn_enabled) {
509 eap_key =
510 (struct wpa_eapol_key *)(aa1x_hdr + 1);
13a9930d
WS
511 atomic_set(&priv->psstatus.snooze_guard, 1);
512 }
513
514 /* rx indication */
515 skb->dev = priv->net_dev;
20c4f9c5 516 skb->protocol = eth_type_trans(skb, skb->dev);
13a9930d
WS
517 priv->nstats.rx_packets++;
518 priv->nstats.rx_bytes += rx_ind_size;
519 skb->dev->last_rx = jiffies;
20c4f9c5 520 netif_rx(skb);
13a9930d 521 } else {
20c4f9c5 522 printk(KERN_WARNING
95d2a324 523 "ks_wlan: Memory squeeze, dropping packet.\n");
13a9930d
WS
524 priv->nstats.rx_dropped++;
525 }
526 break;
20c4f9c5
WS
527 default: /* other rx data */
528 DPRINTK(2, "invalid data format\n");
13a9930d
WS
529 priv->nstats.rx_errors++;
530 }
531}
532
533static
feedcf1a 534void hostif_mib_get_confirm(struct ks_wlan_private *priv)
13a9930d 535{
20c4f9c5
WS
536 struct net_device *dev = priv->net_dev;
537 uint32_t mib_status;
538 uint32_t mib_attribute;
539 uint16_t mib_val_size;
540 uint16_t mib_val_type;
13a9930d
WS
541
542 DPRINTK(3, "\n");
543
20c4f9c5
WS
544 mib_status = get_DWORD(priv); /* MIB status */
545 mib_attribute = get_DWORD(priv); /* MIB atttibute */
546 mib_val_size = get_WORD(priv); /* MIB value size */
547 mib_val_type = get_WORD(priv); /* MIB value type */
13a9930d
WS
548
549 if (mib_status != 0) {
550 /* in case of error */
20c4f9c5
WS
551 DPRINTK(1, "attribute=%08X, status=%08X\n", mib_attribute,
552 mib_status);
13a9930d
WS
553 return;
554 }
555
556 switch (mib_attribute) {
557 case DOT11_MAC_ADDRESS:
558 /* MAC address */
20c4f9c5 559 DPRINTK(3, " mib_attribute=DOT11_MAC_ADDRESS\n");
13a9930d
WS
560 hostif_sme_enqueue(priv, SME_GET_MAC_ADDRESS);
561 memcpy(priv->eth_addr, priv->rxp, ETH_ALEN);
562 priv->mac_address_valid = 1;
563 dev->dev_addr[0] = priv->eth_addr[0];
564 dev->dev_addr[1] = priv->eth_addr[1];
565 dev->dev_addr[2] = priv->eth_addr[2];
566 dev->dev_addr[3] = priv->eth_addr[3];
567 dev->dev_addr[4] = priv->eth_addr[4];
568 dev->dev_addr[5] = priv->eth_addr[5];
569 dev->dev_addr[6] = 0x00;
570 dev->dev_addr[7] = 0x00;
20c4f9c5
WS
571 printk(KERN_INFO
572 "ks_wlan: MAC ADDRESS = %02x:%02x:%02x:%02x:%02x:%02x\n",
573 priv->eth_addr[0], priv->eth_addr[1], priv->eth_addr[2],
574 priv->eth_addr[3], priv->eth_addr[4], priv->eth_addr[5]);
13a9930d
WS
575 break;
576 case DOT11_PRODUCT_VERSION:
577 /* firmware version */
20c4f9c5 578 DPRINTK(3, " mib_attribute=DOT11_PRODUCT_VERSION\n");
13a9930d
WS
579 priv->version_size = priv->rx_size;
580 memcpy(priv->firmware_version, priv->rxp, priv->rx_size);
581 priv->firmware_version[priv->rx_size] = '\0';
20c4f9c5
WS
582 printk(KERN_INFO "ks_wlan: firmware ver. = %s\n",
583 priv->firmware_version);
13a9930d
WS
584 hostif_sme_enqueue(priv, SME_GET_PRODUCT_VERSION);
585 /* wake_up_interruptible_all(&priv->confirm_wait); */
586 complete(&priv->confirm_wait);
587 break;
588 case LOCAL_GAIN:
589 memcpy(&priv->gain, priv->rxp, sizeof(priv->gain));
20c4f9c5
WS
590 DPRINTK(3, "TxMode=%d, RxMode=%d, TxGain=%d, RxGain=%d\n",
591 priv->gain.TxMode, priv->gain.RxMode, priv->gain.TxGain,
592 priv->gain.RxGain);
13a9930d
WS
593 break;
594 case LOCAL_EEPROM_SUM:
595 memcpy(&priv->eeprom_sum, priv->rxp, sizeof(priv->eeprom_sum));
20c4f9c5
WS
596 DPRINTK(1, "eeprom_sum.type=%x, eeprom_sum.result=%x\n",
597 priv->eeprom_sum.type, priv->eeprom_sum.result);
598 if (priv->eeprom_sum.type == 0) {
13a9930d 599 priv->eeprom_checksum = EEPROM_CHECKSUM_NONE;
20c4f9c5
WS
600 } else if (priv->eeprom_sum.type == 1) {
601 if (priv->eeprom_sum.result == 0) {
13a9930d
WS
602 priv->eeprom_checksum = EEPROM_NG;
603 printk("LOCAL_EEPROM_SUM NG\n");
20c4f9c5 604 } else if (priv->eeprom_sum.result == 1) {
13a9930d
WS
605 priv->eeprom_checksum = EEPROM_OK;
606 }
20c4f9c5 607 } else {
13a9930d
WS
608 printk("LOCAL_EEPROM_SUM error!\n");
609 }
610 break;
611 default:
20c4f9c5 612 DPRINTK(1, "mib_attribute=%08x\n", (unsigned int)mib_attribute);
13a9930d
WS
613 break;
614 }
615}
616
617static
feedcf1a 618void hostif_mib_set_confirm(struct ks_wlan_private *priv)
13a9930d 619{
20c4f9c5
WS
620 uint32_t mib_status; /* +04 MIB Status */
621 uint32_t mib_attribute; /* +08 MIB attribute */
13a9930d 622
20c4f9c5 623 DPRINTK(3, "\n");
13a9930d 624
20c4f9c5
WS
625 mib_status = get_DWORD(priv); /* MIB Status */
626 mib_attribute = get_DWORD(priv); /* MIB attribute */
13a9930d
WS
627
628 if (mib_status != 0) {
629 /* in case of error */
20c4f9c5
WS
630 DPRINTK(1, "error :: attribute=%08X, status=%08X\n",
631 mib_attribute, mib_status);
13a9930d
WS
632 }
633
634 switch (mib_attribute) {
635 case DOT11_RTS_THRESHOLD:
636 hostif_sme_enqueue(priv, SME_RTS_THRESHOLD_CONFIRM);
637 break;
638 case DOT11_FRAGMENTATION_THRESHOLD:
639 hostif_sme_enqueue(priv, SME_FRAGMENTATION_THRESHOLD_CONFIRM);
640 break;
641 case DOT11_WEP_DEFAULT_KEY_ID:
20c4f9c5 642 if (!priv->wpa.wpa_enabled)
13a9930d
WS
643 hostif_sme_enqueue(priv, SME_WEP_INDEX_CONFIRM);
644 break;
645 case DOT11_WEP_DEFAULT_KEY_VALUE1:
20c4f9c5
WS
646 DPRINTK(2, "DOT11_WEP_DEFAULT_KEY_VALUE1:mib_status=%d\n",
647 (int)mib_status);
648 if (priv->wpa.rsn_enabled)
13a9930d
WS
649 hostif_sme_enqueue(priv, SME_SET_PMK_TSC);
650 else
651 hostif_sme_enqueue(priv, SME_WEP_KEY1_CONFIRM);
652 break;
653 case DOT11_WEP_DEFAULT_KEY_VALUE2:
20c4f9c5
WS
654 DPRINTK(2, "DOT11_WEP_DEFAULT_KEY_VALUE2:mib_status=%d\n",
655 (int)mib_status);
656 if (priv->wpa.rsn_enabled)
13a9930d
WS
657 hostif_sme_enqueue(priv, SME_SET_GMK1_TSC);
658 else
659 hostif_sme_enqueue(priv, SME_WEP_KEY2_CONFIRM);
660 break;
661 case DOT11_WEP_DEFAULT_KEY_VALUE3:
20c4f9c5
WS
662 DPRINTK(2, "DOT11_WEP_DEFAULT_KEY_VALUE3:mib_status=%d\n",
663 (int)mib_status);
664 if (priv->wpa.rsn_enabled)
13a9930d
WS
665 hostif_sme_enqueue(priv, SME_SET_GMK2_TSC);
666 else
667 hostif_sme_enqueue(priv, SME_WEP_KEY3_CONFIRM);
668 break;
669 case DOT11_WEP_DEFAULT_KEY_VALUE4:
20c4f9c5
WS
670 DPRINTK(2, "DOT11_WEP_DEFAULT_KEY_VALUE4:mib_status=%d\n",
671 (int)mib_status);
672 if (!priv->wpa.rsn_enabled)
13a9930d
WS
673 hostif_sme_enqueue(priv, SME_WEP_KEY4_CONFIRM);
674 break;
675 case DOT11_PRIVACY_INVOKED:
20c4f9c5 676 if (!priv->wpa.rsn_enabled)
13a9930d
WS
677 hostif_sme_enqueue(priv, SME_WEP_FLAG_CONFIRM);
678 break;
679 case DOT11_RSN_ENABLED:
20c4f9c5
WS
680 DPRINTK(2, "DOT11_RSN_ENABLED:mib_status=%d\n",
681 (int)mib_status);
13a9930d
WS
682 hostif_sme_enqueue(priv, SME_RSN_ENABLED_CONFIRM);
683 break;
684 case LOCAL_RSN_MODE:
685 hostif_sme_enqueue(priv, SME_RSN_MODE_CONFIRM);
686 break;
687 case LOCAL_MULTICAST_ADDRESS:
688 hostif_sme_enqueue(priv, SME_MULTICAST_REQUEST);
689 break;
690 case LOCAL_MULTICAST_FILTER:
691 hostif_sme_enqueue(priv, SME_MULTICAST_CONFIRM);
692 break;
693 case LOCAL_CURRENTADDRESS:
694 priv->mac_address_valid = 1;
695 break;
696 case DOT11_RSN_CONFIG_MULTICAST_CIPHER:
20c4f9c5
WS
697 DPRINTK(2, "DOT11_RSN_CONFIG_MULTICAST_CIPHER:mib_status=%d\n",
698 (int)mib_status);
13a9930d
WS
699 hostif_sme_enqueue(priv, SME_RSN_MCAST_CONFIRM);
700 break;
701 case DOT11_RSN_CONFIG_UNICAST_CIPHER:
20c4f9c5
WS
702 DPRINTK(2, "DOT11_RSN_CONFIG_UNICAST_CIPHER:mib_status=%d\n",
703 (int)mib_status);
13a9930d
WS
704 hostif_sme_enqueue(priv, SME_RSN_UCAST_CONFIRM);
705 break;
706 case DOT11_RSN_CONFIG_AUTH_SUITE:
20c4f9c5
WS
707 DPRINTK(2, "DOT11_RSN_CONFIG_AUTH_SUITE:mib_status=%d\n",
708 (int)mib_status);
13a9930d
WS
709 hostif_sme_enqueue(priv, SME_RSN_AUTH_CONFIRM);
710 break;
711 case DOT11_PMK_TSC:
20c4f9c5 712 DPRINTK(2, "DOT11_PMK_TSC:mib_status=%d\n", (int)mib_status);
13a9930d
WS
713 break;
714 case DOT11_GMK1_TSC:
20c4f9c5
WS
715 DPRINTK(2, "DOT11_GMK1_TSC:mib_status=%d\n", (int)mib_status);
716 if (atomic_read(&priv->psstatus.snooze_guard)) {
13a9930d
WS
717 atomic_set(&priv->psstatus.snooze_guard, 0);
718 }
719 break;
720 case DOT11_GMK2_TSC:
20c4f9c5
WS
721 DPRINTK(2, "DOT11_GMK2_TSC:mib_status=%d\n", (int)mib_status);
722 if (atomic_read(&priv->psstatus.snooze_guard)) {
13a9930d
WS
723 atomic_set(&priv->psstatus.snooze_guard, 0);
724 }
725 break;
726 case LOCAL_PMK:
20c4f9c5 727 DPRINTK(2, "LOCAL_PMK:mib_status=%d\n", (int)mib_status);
13a9930d
WS
728 break;
729 case LOCAL_GAIN:
20c4f9c5 730 DPRINTK(2, "LOCAL_GAIN:mib_status=%d\n", (int)mib_status);
13a9930d
WS
731 break;
732#ifdef WPS
733 case LOCAL_WPS_ENABLE:
20c4f9c5 734 DPRINTK(2, "LOCAL_WPS_ENABLE:mib_status=%d\n", (int)mib_status);
13a9930d
WS
735 break;
736 case LOCAL_WPS_PROBE_REQ:
20c4f9c5
WS
737 DPRINTK(2, "LOCAL_WPS_PROBE_REQ:mib_status=%d\n",
738 (int)mib_status);
13a9930d
WS
739 break;
740#endif /* WPS */
741 case LOCAL_REGION:
20c4f9c5
WS
742 DPRINTK(2, "LOCAL_REGION:mib_status=%d\n", (int)mib_status);
743 default:
13a9930d
WS
744 break;
745 }
746}
747
748static
feedcf1a 749void hostif_power_mngmt_confirm(struct ks_wlan_private *priv)
13a9930d 750{
20c4f9c5 751 DPRINTK(3, "\n");
13a9930d 752
20c4f9c5
WS
753 if (priv->reg.powermgt > POWMGT_ACTIVE_MODE &&
754 priv->reg.operation_mode == MODE_INFRASTRUCTURE) {
13a9930d
WS
755 atomic_set(&priv->psstatus.confirm_wait, 0);
756 priv->dev_state = DEVICE_STATE_SLEEP;
757 ks_wlan_hw_power_save(priv);
20c4f9c5 758 } else {
13a9930d 759 priv->dev_state = DEVICE_STATE_READY;
13a9930d
WS
760 }
761
762}
763
764static
feedcf1a 765void hostif_sleep_confirm(struct ks_wlan_private *priv)
13a9930d 766{
20c4f9c5 767 DPRINTK(3, "\n");
13a9930d 768
20c4f9c5
WS
769 atomic_set(&priv->sleepstatus.doze_request, 1);
770 queue_delayed_work(priv->ks_wlan_hw.ks7010sdio_wq,
771 &priv->ks_wlan_hw.rw_wq, 1);
13a9930d
WS
772}
773
774static
feedcf1a 775void hostif_start_confirm(struct ks_wlan_private *priv)
13a9930d
WS
776{
777#ifdef WPS
20c4f9c5
WS
778 union iwreq_data wrqu;
779 wrqu.data.length = 0;
780 wrqu.data.flags = 0;
781 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
782 if ((priv->connect_status & CONNECT_STATUS_MASK) == CONNECT_STATUS) {
783 memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
784 DPRINTK(3, "IWEVENT: disconnect\n");
785 wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL);
786 }
13a9930d 787#endif
20c4f9c5 788 DPRINTK(3, " scan_ind_count=%d\n", priv->scan_ind_count);
13a9930d
WS
789 hostif_sme_enqueue(priv, SME_START_CONFIRM);
790}
791
792static
feedcf1a 793void hostif_connect_indication(struct ks_wlan_private *priv)
13a9930d
WS
794{
795 unsigned short connect_code;
20c4f9c5
WS
796 unsigned int tmp = 0;
797 unsigned int old_status = priv->connect_status;
798 struct net_device *netdev = priv->net_dev;
13a9930d 799 union iwreq_data wrqu0;
13a9930d
WS
800 connect_code = get_WORD(priv);
801
20c4f9c5
WS
802 switch (connect_code) {
803 case RESULT_CONNECT: /* connect */
804 DPRINTK(3, "connect :: scan_ind_count=%d\n",
805 priv->scan_ind_count);
806 if (!(priv->connect_status & FORCE_DISCONNECT))
13a9930d
WS
807 netif_carrier_on(netdev);
808 tmp = FORCE_DISCONNECT & priv->connect_status;
809 priv->connect_status = tmp + CONNECT_STATUS;
810 break;
20c4f9c5
WS
811 case RESULT_DISCONNECT: /* disconnect */
812 DPRINTK(3, "disconnect :: scan_ind_count=%d\n",
813 priv->scan_ind_count);
13a9930d
WS
814 netif_carrier_off(netdev);
815 tmp = FORCE_DISCONNECT & priv->connect_status;
816 priv->connect_status = tmp + DISCONNECT_STATUS;
817 break;
818 default:
20c4f9c5
WS
819 DPRINTK(1, "unknown connect_code=%d :: scan_ind_count=%d\n",
820 connect_code, priv->scan_ind_count);
13a9930d
WS
821 netif_carrier_off(netdev);
822 tmp = FORCE_DISCONNECT & priv->connect_status;
823 priv->connect_status = tmp + DISCONNECT_STATUS;
824 break;
825 }
826
827 get_current_ap(priv, (struct link_ap_info_t *)priv->rxp);
20c4f9c5
WS
828 if ((priv->connect_status & CONNECT_STATUS_MASK) == CONNECT_STATUS &&
829 (old_status & CONNECT_STATUS_MASK) == DISCONNECT_STATUS) {
13a9930d
WS
830 /* for power save */
831 atomic_set(&priv->psstatus.snooze_guard, 0);
20c4f9c5 832 atomic_set(&priv->psstatus.confirm_wait, 0);
13a9930d
WS
833 }
834 ks_wlan_do_power_save(priv);
835
13a9930d
WS
836 wrqu0.data.length = 0;
837 wrqu0.data.flags = 0;
838 wrqu0.ap_addr.sa_family = ARPHRD_ETHER;
20c4f9c5
WS
839 if ((priv->connect_status & CONNECT_STATUS_MASK) == DISCONNECT_STATUS &&
840 (old_status & CONNECT_STATUS_MASK) == CONNECT_STATUS) {
13a9930d 841 memset(wrqu0.ap_addr.sa_data, '\0', ETH_ALEN);
20c4f9c5
WS
842 DPRINTK(3, "IWEVENT: disconnect\n");
843 DPRINTK(3, "disconnect :: scan_ind_count=%d\n",
844 priv->scan_ind_count);
13a9930d
WS
845 wireless_send_event(netdev, SIOCGIWAP, &wrqu0, NULL);
846 }
20c4f9c5 847 priv->scan_ind_count = 0;
13a9930d
WS
848}
849
850static
feedcf1a 851void hostif_scan_indication(struct ks_wlan_private *priv)
13a9930d
WS
852{
853 int i;
854 struct ap_info_t *ap_info;
855
20c4f9c5 856 DPRINTK(3, "scan_ind_count = %d\n", priv->scan_ind_count);
13a9930d
WS
857 ap_info = (struct ap_info_t *)(priv->rxp);
858
20c4f9c5
WS
859 if (priv->scan_ind_count != 0) {
860 for (i = 0; i < priv->aplist.size; i++) { /* bssid check */
861 if (!memcmp
862 (&(ap_info->bssid[0]),
863 &(priv->aplist.ap[i].bssid[0]), ETH_ALEN)) {
864 if (ap_info->frame_type ==
865 FRAME_TYPE_PROBE_RESP)
866 get_ap_information(priv, ap_info,
867 &(priv->aplist.
868 ap[i]));
13a9930d
WS
869 return;
870 }
871 }
872 }
873 priv->scan_ind_count++;
20c4f9c5
WS
874 if (priv->scan_ind_count < LOCAL_APLIST_MAX + 1) {
875 DPRINTK(4, " scan_ind_count=%d :: aplist.size=%d\n",
876 priv->scan_ind_count, priv->aplist.size);
877 get_ap_information(priv, (struct ap_info_t *)(priv->rxp),
878 &(priv->aplist.
879 ap[priv->scan_ind_count - 1]));
13a9930d 880 priv->aplist.size = priv->scan_ind_count;
20c4f9c5
WS
881 } else {
882 DPRINTK(4, " count over :: scan_ind_count=%d\n",
883 priv->scan_ind_count);
13a9930d 884 }
13a9930d
WS
885
886}
887
888static
feedcf1a 889void hostif_stop_confirm(struct ks_wlan_private *priv)
13a9930d 890{
20c4f9c5
WS
891 unsigned int tmp = 0;
892 unsigned int old_status = priv->connect_status;
893 struct net_device *netdev = priv->net_dev;
13a9930d
WS
894 union iwreq_data wrqu0;
895
20c4f9c5
WS
896 DPRINTK(3, "\n");
897 if (priv->dev_state == DEVICE_STATE_SLEEP)
13a9930d 898 priv->dev_state = DEVICE_STATE_READY;
13a9930d
WS
899
900 /* disconnect indication */
20c4f9c5 901 if ((priv->connect_status & CONNECT_STATUS_MASK) == CONNECT_STATUS) {
13a9930d
WS
902 netif_carrier_off(netdev);
903 tmp = FORCE_DISCONNECT & priv->connect_status;
904 priv->connect_status = tmp | DISCONNECT_STATUS;
905 printk("IWEVENT: disconnect\n");
906
907 wrqu0.data.length = 0;
908 wrqu0.data.flags = 0;
909 wrqu0.ap_addr.sa_family = ARPHRD_ETHER;
20c4f9c5
WS
910 if ((priv->connect_status & CONNECT_STATUS_MASK) ==
911 DISCONNECT_STATUS
912 && (old_status & CONNECT_STATUS_MASK) == CONNECT_STATUS) {
13a9930d 913 memset(wrqu0.ap_addr.sa_data, '\0', ETH_ALEN);
20c4f9c5 914 DPRINTK(3, "IWEVENT: disconnect\n");
13a9930d 915 printk("IWEVENT: disconnect\n");
20c4f9c5
WS
916 DPRINTK(3, "disconnect :: scan_ind_count=%d\n",
917 priv->scan_ind_count);
13a9930d
WS
918 wireless_send_event(netdev, SIOCGIWAP, &wrqu0, NULL);
919 }
20c4f9c5 920 priv->scan_ind_count = 0;
13a9930d
WS
921 }
922
923 hostif_sme_enqueue(priv, SME_STOP_CONFIRM);
924}
925
926static
feedcf1a 927void hostif_ps_adhoc_set_confirm(struct ks_wlan_private *priv)
13a9930d 928{
20c4f9c5
WS
929 DPRINTK(3, "\n");
930 priv->infra_status = 0; /* infrastructure mode cancel */
13a9930d
WS
931 hostif_sme_enqueue(priv, SME_MODE_SET_CONFIRM);
932
933}
934
935static
feedcf1a 936void hostif_infrastructure_set_confirm(struct ks_wlan_private *priv)
13a9930d
WS
937{
938 uint16_t result_code;
20c4f9c5 939 DPRINTK(3, "\n");
13a9930d 940 result_code = get_WORD(priv);
20c4f9c5
WS
941 DPRINTK(3, "result code = %d\n", result_code);
942 priv->infra_status = 1; /* infrastructure mode set */
13a9930d
WS
943 hostif_sme_enqueue(priv, SME_MODE_SET_CONFIRM);
944}
945
946static
feedcf1a 947void hostif_adhoc_set_confirm(struct ks_wlan_private *priv)
13a9930d 948{
20c4f9c5
WS
949 DPRINTK(3, "\n");
950 priv->infra_status = 1; /* infrastructure mode set */
13a9930d
WS
951 hostif_sme_enqueue(priv, SME_MODE_SET_CONFIRM);
952}
953
954static
feedcf1a 955void hostif_associate_indication(struct ks_wlan_private *priv)
13a9930d 956{
13a9930d
WS
957 struct association_request_t *assoc_req;
958 struct association_response_t *assoc_resp;
959 unsigned char *pb;
960 union iwreq_data wrqu;
961 char buf[IW_CUSTOM_MAX];
962 char *pbuf = &buf[0];
963 int i;
964
965 static const char associnfo_leader0[] = "ASSOCINFO(ReqIEs=";
966 static const char associnfo_leader1[] = " RespIEs=";
967
20c4f9c5 968 DPRINTK(3, "\n");
13a9930d 969 assoc_req = (struct association_request_t *)(priv->rxp);
20c4f9c5
WS
970 assoc_resp = (struct association_response_t *)(assoc_req + 1);
971 pb = (unsigned char *)(assoc_resp + 1);
13a9930d
WS
972
973 memset(&wrqu, 0, sizeof(wrqu));
20c4f9c5
WS
974 memcpy(pbuf, associnfo_leader0, sizeof(associnfo_leader0) - 1);
975 wrqu.data.length += sizeof(associnfo_leader0) - 1;
976 pbuf += sizeof(associnfo_leader0) - 1;
13a9930d
WS
977
978 for (i = 0; i < assoc_req->reqIEs_size; i++)
20c4f9c5
WS
979 pbuf += sprintf(pbuf, "%02x", *(pb + i));
980 wrqu.data.length += (assoc_req->reqIEs_size) * 2;
13a9930d 981
20c4f9c5
WS
982 memcpy(pbuf, associnfo_leader1, sizeof(associnfo_leader1) - 1);
983 wrqu.data.length += sizeof(associnfo_leader1) - 1;
984 pbuf += sizeof(associnfo_leader1) - 1;
13a9930d
WS
985
986 pb += assoc_req->reqIEs_size;
987 for (i = 0; i < assoc_resp->respIEs_size; i++)
20c4f9c5
WS
988 pbuf += sprintf(pbuf, "%02x", *(pb + i));
989 wrqu.data.length += (assoc_resp->respIEs_size) * 2;
13a9930d
WS
990
991 pbuf += sprintf(pbuf, ")");
992 wrqu.data.length += 1;
993
20c4f9c5 994 DPRINTK(3, "IWEVENT:ASSOCINFO\n");
13a9930d 995 wireless_send_event(priv->net_dev, IWEVCUSTOM, &wrqu, buf);
13a9930d
WS
996}
997
998static
feedcf1a 999void hostif_bss_scan_confirm(struct ks_wlan_private *priv)
13a9930d
WS
1000{
1001 unsigned int result_code;
13a9930d
WS
1002 struct net_device *dev = priv->net_dev;
1003 union iwreq_data wrqu;
13a9930d 1004 result_code = get_DWORD(priv);
20c4f9c5
WS
1005 DPRINTK(2, "result=%d :: scan_ind_count=%d\n", result_code,
1006 priv->scan_ind_count);
13a9930d
WS
1007
1008 priv->sme_i.sme_flag &= ~SME_AP_SCAN;
1009 hostif_sme_enqueue(priv, SME_BSS_SCAN_CONFIRM);
1010
13a9930d
WS
1011 wrqu.data.length = 0;
1012 wrqu.data.flags = 0;
20c4f9c5 1013 DPRINTK(3, "IWEVENT: SCAN CONFIRM\n");
13a9930d 1014 wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
20c4f9c5 1015 priv->scan_ind_count = 0;
13a9930d
WS
1016}
1017
1018static
feedcf1a 1019void hostif_phy_information_confirm(struct ks_wlan_private *priv)
13a9930d
WS
1020{
1021 struct iw_statistics *wstats = &priv->wstats;
20c4f9c5 1022 unsigned char rssi, signal, noise;
13a9930d
WS
1023 unsigned char LinkSpeed;
1024 unsigned int TransmittedFrameCount, ReceivedFragmentCount;
1025 unsigned int FailedCount, FCSErrorCount;
1026
20c4f9c5 1027 DPRINTK(3, "\n");
13a9930d
WS
1028 rssi = get_BYTE(priv);
1029 signal = get_BYTE(priv);
1030 noise = get_BYTE(priv);
1031 LinkSpeed = get_BYTE(priv);
1032 TransmittedFrameCount = get_DWORD(priv);
1033 ReceivedFragmentCount = get_DWORD(priv);
1034 FailedCount = get_DWORD(priv);
1035 FCSErrorCount = get_DWORD(priv);
1036
1037 DPRINTK(4, "phyinfo confirm rssi=%d signal=%d\n", rssi, signal);
1038 priv->current_rate = (LinkSpeed & RATE_MASK);
1039 wstats->qual.qual = signal;
1040 wstats->qual.level = 256 - rssi;
20c4f9c5 1041 wstats->qual.noise = 0; /* invalid noise value */
13a9930d
WS
1042 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1043
20c4f9c5 1044 DPRINTK(3, "\n rssi=%u\n signal=%u\n LinkSpeed=%ux500Kbps\n \
13a9930d 1045 TransmittedFrameCount=%u\n ReceivedFragmentCount=%u\n FailedCount=%u\n \
20c4f9c5 1046 FCSErrorCount=%u\n", rssi, signal, LinkSpeed, TransmittedFrameCount, ReceivedFragmentCount, FailedCount, FCSErrorCount);
13a9930d
WS
1047
1048 /* wake_up_interruptible_all(&priv->confirm_wait); */
1049 complete(&priv->confirm_wait);
1050}
1051
1052static
feedcf1a 1053void hostif_mic_failure_confirm(struct ks_wlan_private *priv)
13a9930d 1054{
20c4f9c5 1055 DPRINTK(3, "mic_failure=%u\n", priv->wpa.mic_failure.failure);
13a9930d
WS
1056 hostif_sme_enqueue(priv, SME_MIC_FAILURE_CONFIRM);
1057}
1058
13a9930d 1059static
feedcf1a 1060void hostif_event_check(struct ks_wlan_private *priv)
13a9930d
WS
1061{
1062 unsigned short event;
1063
1064 DPRINTK(4, "\n");
20c4f9c5 1065 event = get_WORD(priv); /* get event */
13a9930d
WS
1066 switch (event) {
1067 case HIF_DATA_IND:
1068 hostif_data_indication(priv);
1069 break;
1070 case HIF_MIB_GET_CONF:
1071 hostif_mib_get_confirm(priv);
1072 break;
1073 case HIF_MIB_SET_CONF:
1074 hostif_mib_set_confirm(priv);
1075 break;
1076 case HIF_POWERMGT_CONF:
1077 hostif_power_mngmt_confirm(priv);
1078 break;
1079 case HIF_SLEEP_CONF:
1080 hostif_sleep_confirm(priv);
1081 break;
1082 case HIF_START_CONF:
1083 hostif_start_confirm(priv);
1084 break;
1085 case HIF_CONNECT_IND:
1086 hostif_connect_indication(priv);
1087 break;
1088 case HIF_STOP_CONF:
1089 hostif_stop_confirm(priv);
1090 break;
1091 case HIF_PS_ADH_SET_CONF:
1092 hostif_ps_adhoc_set_confirm(priv);
1093 break;
1094 case HIF_INFRA_SET_CONF:
1095 case HIF_INFRA_SET2_CONF:
1096 hostif_infrastructure_set_confirm(priv);
1097 break;
1098 case HIF_ADH_SET_CONF:
1099 case HIF_ADH_SET2_CONF:
1100 hostif_adhoc_set_confirm(priv);
1101 break;
1102 case HIF_ASSOC_INFO_IND:
1103 hostif_associate_indication(priv);
1104 break;
1105 case HIF_MIC_FAILURE_CONF:
1106 hostif_mic_failure_confirm(priv);
1107 break;
1108 case HIF_SCAN_CONF:
1109 hostif_bss_scan_confirm(priv);
1110 break;
1111 case HIF_PHY_INFO_CONF:
1112 case HIF_PHY_INFO_IND:
1113 hostif_phy_information_confirm(priv);
1114 break;
1115 case HIF_SCAN_IND:
1116 hostif_scan_indication(priv);
1117 break;
1118 case HIF_AP_SET_CONF:
1119 default:
1120 //DPRINTK(1, "undefined event[%04X]\n", event);
1121 printk("undefined event[%04X]\n", event);
1122 /* wake_up_all(&priv->confirm_wait); */
1123 complete(&priv->confirm_wait);
1124 break;
1125 }
1126
1127 /* add event to hostt buffer */
1128 priv->hostt.buff[priv->hostt.qtail] = event;
20c4f9c5 1129 priv->hostt.qtail = (priv->hostt.qtail + 1) % SME_EVENT_BUFF_SIZE;
13a9930d
WS
1130}
1131
1132#define CHECK_ALINE(size) (size%4 ? (size+(4-(size%4))):size)
1133
feedcf1a 1134int hostif_data_request(struct ks_wlan_private *priv, struct sk_buff *packet)
13a9930d 1135{
20c4f9c5 1136 unsigned int packet_len = 0;
13a9930d 1137
20c4f9c5
WS
1138 unsigned char *buffer = NULL;
1139 unsigned int length = 0;
13a9930d 1140 struct hostif_data_request_t *pp;
20c4f9c5
WS
1141 unsigned char *p;
1142 int result = 0;
13a9930d
WS
1143 unsigned short eth_proto;
1144 struct ether_hdr *eth_hdr;
1145 struct michel_mic_t michel_mic;
20c4f9c5 1146 unsigned short keyinfo = 0;
13a9930d
WS
1147 struct ieee802_1x_hdr *aa1x_hdr;
1148 struct wpa_eapol_key *eap_key;
1149 struct ethhdr *eth;
1150
1151 packet_len = packet->len;
1152 if (packet_len > ETH_FRAME_LEN) {
20c4f9c5 1153 DPRINTK(1, "bad length packet_len=%d \n", packet_len);
13a9930d
WS
1154 dev_kfree_skb(packet);
1155 return -1;
1156 }
1157
20c4f9c5
WS
1158 if (((priv->connect_status & CONNECT_STATUS_MASK) == DISCONNECT_STATUS)
1159 || (priv->connect_status & FORCE_DISCONNECT)
1160 || priv->wpa.mic_failure.stop) {
1161 DPRINTK(3, " DISCONNECT\n");
1162 if (netif_queue_stopped(priv->net_dev))
13a9930d 1163 netif_wake_queue(priv->net_dev);
20c4f9c5 1164 if (packet)
13a9930d
WS
1165 dev_kfree_skb(packet);
1166
1167 return 0;
1168 }
1169
1170 /* for PowerSave */
20c4f9c5
WS
1171 if (atomic_read(&priv->psstatus.status) == PS_SNOOZE) { /* power save wakeup */
1172 if (!netif_queue_stopped(priv->net_dev))
13a9930d 1173 netif_stop_queue(priv->net_dev);
13a9930d
WS
1174 }
1175
1176 DPRINTK(4, "skb_buff length=%d\n", packet_len);
20c4f9c5
WS
1177 pp = (struct hostif_data_request_t *)
1178 kmalloc(hif_align_size(sizeof(*pp) + 6 + packet_len + 8),
1179 KS_WLAN_MEM_FLAG);
13a9930d 1180
20c4f9c5 1181 if (pp == NULL) {
13a9930d
WS
1182 DPRINTK(3, "allocate memory failed..\n");
1183 dev_kfree_skb(packet);
1184 return -2;
1185 }
1186
1187 p = (unsigned char *)pp->data;
1188
1189 buffer = packet->data;
1190 length = packet->len;
1191
1192 /* packet check */
1193 eth = (struct ethhdr *)packet->data;
20c4f9c5 1194 if (memcmp(&priv->eth_addr[0], eth->h_source, ETH_ALEN)) {
13a9930d
WS
1195 DPRINTK(1, "invalid mac address !!\n");
1196 DPRINTK(1, "ethernet->h_source=%02X:%02X:%02X:%02X:%02X:%02X\n",
20c4f9c5
WS
1197 eth->h_source[0], eth->h_source[1], eth->h_source[2],
1198 eth->h_source[3], eth->h_source[4], eth->h_source[5]);
aeaf5d86
CIK
1199 dev_kfree_skb(packet);
1200 kfree(pp);
13a9930d
WS
1201 return -3;
1202 }
1203
1204 /* MAC address copy */
20c4f9c5 1205 memcpy(p, buffer, 12); /* DST/SRC MAC address */
13a9930d
WS
1206 p += 12;
1207 buffer += 12;
1208 length -= 12;
1209 /* EtherType/Length check */
20c4f9c5 1210 if (*(buffer + 1) + (*buffer << 8) > 1500) {
13a9930d 1211 /* ProtocolEAP = *(buffer+1) + (*buffer << 8); */
20c4f9c5 1212 /* DPRINTK(2, "Send [SNAP]Type %x\n",ProtocolEAP); */
13a9930d 1213 /* SAP/CTL/OUI(6 byte) add */
20c4f9c5
WS
1214 *p++ = 0xAA; /* DSAP */
1215 *p++ = 0xAA; /* SSAP */
1216 *p++ = 0x03; /* CTL */
1217 *p++ = 0x00; /* OUI ("000000") */
1218 *p++ = 0x00; /* OUI ("000000") */
1219 *p++ = 0x00; /* OUI ("000000") */
13a9930d
WS
1220 packet_len += 6;
1221 } else {
20c4f9c5
WS
1222 DPRINTK(4, "DIX\n");
1223 /* Length(2 byte) delete */
13a9930d
WS
1224 buffer += 2;
1225 length -= 2;
1226 packet_len -= 2;
1227 }
1228
1229 /* pp->data copy */
1230 memcpy(p, buffer, length);
1231
1232 p += length;
1233
1234 /* for WPA */
1235 eth_hdr = (struct ether_hdr *)&pp->data[0];
1236 eth_proto = ntohs(eth_hdr->h_proto);
1237
1238 /* for MIC FAILUER REPORT check */
20c4f9c5
WS
1239 if (eth_proto == ETHER_PROTOCOL_TYPE_EAP
1240 && priv->wpa.mic_failure.failure > 0) {
1241 aa1x_hdr = (struct ieee802_1x_hdr *)(eth_hdr + 1);
1242 if (aa1x_hdr->type == IEEE802_1X_TYPE_EAPOL_KEY) {
1243 eap_key = (struct wpa_eapol_key *)(aa1x_hdr + 1);
1244 keyinfo = ntohs(eap_key->key_info);
13a9930d
WS
1245 }
1246 }
1247
20c4f9c5
WS
1248 if (priv->wpa.rsn_enabled && priv->wpa.key[0].key_len) {
1249 if (eth_proto == ETHER_PROTOCOL_TYPE_EAP
1250 && !(priv->wpa.key[1].key_len)
1251 && !(priv->wpa.key[2].key_len)
1252 && !(priv->wpa.key[3].key_len)) {
1253 pp->auth_type = cpu_to_le16((uint16_t) TYPE_AUTH); /* no encryption */
1254 } else {
1255 if (priv->wpa.pairwise_suite == IW_AUTH_CIPHER_TKIP) {
1256 MichaelMICFunction(&michel_mic, (uint8_t *) priv->wpa.key[0].tx_mic_key, (uint8_t *) & pp->data[0], (int)packet_len, (uint8_t) 0, /* priority */
1257 (uint8_t *) michel_mic.
1258 Result);
13a9930d
WS
1259 memcpy(p, michel_mic.Result, 8);
1260 length += 8;
1261 packet_len += 8;
1262 p += 8;
20c4f9c5
WS
1263 pp->auth_type =
1264 cpu_to_le16((uint16_t) TYPE_DATA);
13a9930d 1265
20c4f9c5
WS
1266 } else if (priv->wpa.pairwise_suite ==
1267 IW_AUTH_CIPHER_CCMP) {
1268 pp->auth_type =
1269 cpu_to_le16((uint16_t) TYPE_DATA);
13a9930d
WS
1270 }
1271 }
20c4f9c5
WS
1272 } else {
1273 if (eth_proto == ETHER_PROTOCOL_TYPE_EAP)
1274 pp->auth_type = cpu_to_le16((uint16_t) TYPE_AUTH);
13a9930d 1275 else
20c4f9c5 1276 pp->auth_type = cpu_to_le16((uint16_t) TYPE_DATA);
13a9930d
WS
1277 }
1278
1279 /* header value set */
20c4f9c5
WS
1280 pp->header.size =
1281 cpu_to_le16((uint16_t)
1282 (sizeof(*pp) - sizeof(pp->header.size) + packet_len));
1283 pp->header.event = cpu_to_le16((uint16_t) HIF_DATA_REQ);
13a9930d
WS
1284
1285 /* tx request */
20c4f9c5
WS
1286 result =
1287 ks_wlan_hw_tx(priv, pp, hif_align_size(sizeof(*pp) + packet_len),
1288 (void *)send_packet_complete, (void *)priv,
1289 (void *)packet);
13a9930d
WS
1290
1291 /* MIC FAILUER REPORT check */
20c4f9c5
WS
1292 if (eth_proto == ETHER_PROTOCOL_TYPE_EAP
1293 && priv->wpa.mic_failure.failure > 0) {
1294 if (keyinfo & WPA_KEY_INFO_ERROR
1295 && keyinfo & WPA_KEY_INFO_REQUEST) {
1296 DPRINTK(3, " MIC ERROR Report SET : %04X\n", keyinfo);
13a9930d
WS
1297 hostif_sme_enqueue(priv, SME_MIC_FAILURE_REQUEST);
1298 }
20c4f9c5
WS
1299 if (priv->wpa.mic_failure.failure == 2)
1300 priv->wpa.mic_failure.stop = 1;
13a9930d
WS
1301 }
1302
1303 return result;
1304}
1305
13a9930d
WS
1306#define ps_confirm_wait_inc(priv) do{if(atomic_read(&priv->psstatus.status) > PS_ACTIVE_SET){ \
1307 atomic_inc(&priv->psstatus.confirm_wait); \
1308 /* atomic_set(&priv->psstatus.status, PS_CONF_WAIT);*/ \
1309 } }while(0)
13a9930d
WS
1310
1311static
20c4f9c5
WS
1312void hostif_mib_get_request(struct ks_wlan_private *priv,
1313 unsigned long mib_attribute)
13a9930d
WS
1314{
1315 struct hostif_mib_get_request_t *pp;
1316
1317 DPRINTK(3, "\n");
1318
1319 /* make primitive */
20c4f9c5
WS
1320 pp = (struct hostif_mib_get_request_t *)
1321 kmalloc(hif_align_size(sizeof(*pp)), KS_WLAN_MEM_FLAG);
1322 if (pp == NULL) {
1323 DPRINTK(3, "allocate memory failed..\n");
13a9930d
WS
1324 return;
1325 }
20c4f9c5
WS
1326 pp->header.size =
1327 cpu_to_le16((uint16_t) (sizeof(*pp) - sizeof(pp->header.size)));
1328 pp->header.event = cpu_to_le16((uint16_t) HIF_MIB_GET_REQ);
1329 pp->mib_attribute = cpu_to_le32((uint32_t) mib_attribute);
13a9930d
WS
1330
1331 /* send to device request */
1332 ps_confirm_wait_inc(priv);
20c4f9c5 1333 ks_wlan_hw_tx(priv, pp, hif_align_size(sizeof(*pp)), NULL, NULL, NULL);
13a9930d
WS
1334}
1335
1336static
20c4f9c5
WS
1337void hostif_mib_set_request(struct ks_wlan_private *priv,
1338 unsigned long mib_attribute, unsigned short size,
1339 unsigned short type, void *vp)
13a9930d
WS
1340{
1341 struct hostif_mib_set_request_t *pp;
1342
20c4f9c5 1343 DPRINTK(3, "\n");
13a9930d
WS
1344
1345 if (priv->dev_state < DEVICE_STATE_BOOT) {
20c4f9c5 1346 DPRINTK(3, "DeviceRemove\n");
13a9930d
WS
1347 return;
1348 }
1349
1350 /* make primitive */
20c4f9c5
WS
1351 pp = (struct hostif_mib_set_request_t *)
1352 kmalloc(hif_align_size(sizeof(*pp) + size), KS_WLAN_MEM_FLAG);
1353 if (pp == NULL) {
13a9930d
WS
1354 DPRINTK(3, "allocate memory failed..\n");
1355 return;
1356 }
1357
20c4f9c5
WS
1358 pp->header.size =
1359 cpu_to_le16((uint16_t)
1360 (sizeof(*pp) - sizeof(pp->header.size) + size));
1361 pp->header.event = cpu_to_le16((uint16_t) HIF_MIB_SET_REQ);
1362 pp->mib_attribute = cpu_to_le32((uint32_t) mib_attribute);
1363 pp->mib_value.size = cpu_to_le16((uint16_t) size);
1364 pp->mib_value.type = cpu_to_le16((uint16_t) type);
13a9930d
WS
1365 memcpy(&pp->mib_value.body, vp, size);
1366
1367 /* send to device request */
1368 ps_confirm_wait_inc(priv);
20c4f9c5
WS
1369 ks_wlan_hw_tx(priv, pp, hif_align_size(sizeof(*pp) + size), NULL, NULL,
1370 NULL);
13a9930d
WS
1371}
1372
1373static
20c4f9c5 1374void hostif_start_request(struct ks_wlan_private *priv, unsigned char mode)
13a9930d
WS
1375{
1376 struct hostif_start_request_t *pp;
1377
20c4f9c5 1378 DPRINTK(3, "\n");
13a9930d
WS
1379
1380 /* make primitive */
20c4f9c5
WS
1381 pp = (struct hostif_start_request_t *)
1382 kmalloc(hif_align_size(sizeof(*pp)), KS_WLAN_MEM_FLAG);
1383 if (pp == NULL) {
13a9930d
WS
1384 DPRINTK(3, "allocate memory failed..\n");
1385 return;
1386 }
20c4f9c5
WS
1387 pp->header.size =
1388 cpu_to_le16((uint16_t) (sizeof(*pp) - sizeof(pp->header.size)));
1389 pp->header.event = cpu_to_le16((uint16_t) HIF_START_REQ);
1390 pp->mode = cpu_to_le16((uint16_t) mode);
13a9930d
WS
1391
1392 /* send to device request */
1393 ps_confirm_wait_inc(priv);
1394 ks_wlan_hw_tx(priv, pp, hif_align_size(sizeof(*pp)), NULL, NULL, NULL);
1395
1396 priv->aplist.size = 0;
20c4f9c5 1397 priv->scan_ind_count = 0;
13a9930d
WS
1398}
1399
1400static
feedcf1a 1401void hostif_ps_adhoc_set_request(struct ks_wlan_private *priv)
13a9930d
WS
1402{
1403 struct hostif_ps_adhoc_set_request_t *pp;
1404 uint16_t capability;
1405
20c4f9c5 1406 DPRINTK(3, "\n");
13a9930d
WS
1407
1408 /* make primitive */
20c4f9c5
WS
1409 pp = (struct hostif_ps_adhoc_set_request_t *)
1410 kmalloc(hif_align_size(sizeof(*pp)), KS_WLAN_MEM_FLAG);
1411 if (pp == NULL) {
13a9930d
WS
1412 DPRINTK(3, "allocate memory failed..\n");
1413 return;
1414 }
1415 memset(pp, 0, sizeof(*pp));
20c4f9c5
WS
1416 pp->header.size =
1417 cpu_to_le16((uint16_t) (sizeof(*pp) - sizeof(pp->header.size)));
1418 pp->header.event = cpu_to_le16((uint16_t) HIF_PS_ADH_SET_REQ);
1419 pp->phy_type = cpu_to_le16((uint16_t) (priv->reg.phy_type));
1420 pp->cts_mode = cpu_to_le16((uint16_t) (priv->reg.cts_mode));
1421 pp->scan_type = cpu_to_le16((uint16_t) (priv->reg.scan_type));
1422 pp->channel = cpu_to_le16((uint16_t) (priv->reg.channel));
13a9930d 1423 pp->rate_set.size = priv->reg.rate_set.size;
20c4f9c5
WS
1424 memcpy(&pp->rate_set.body[0], &priv->reg.rate_set.body[0],
1425 priv->reg.rate_set.size);
13a9930d
WS
1426
1427 capability = 0x0000;
20c4f9c5 1428 if (priv->reg.preamble == SHORT_PREAMBLE) {
13a9930d
WS
1429 /* short preamble */
1430 capability |= BSS_CAP_SHORT_PREAMBLE;
1431 }
20c4f9c5
WS
1432 capability &= ~(BSS_CAP_PBCC); /* pbcc not support */
1433 if (priv->reg.phy_type != D_11B_ONLY_MODE) {
1434 capability |= BSS_CAP_SHORT_SLOT_TIME; /* ShortSlotTime support */
1435 capability &= ~(BSS_CAP_DSSS_OFDM); /* DSSS OFDM */
13a9930d 1436 }
20c4f9c5 1437 pp->capability = cpu_to_le16((uint16_t) capability);
13a9930d
WS
1438
1439 /* send to device request */
1440 ps_confirm_wait_inc(priv);
1441 ks_wlan_hw_tx(priv, pp, hif_align_size(sizeof(*pp)), NULL, NULL, NULL);
1442}
1443
1444static
feedcf1a 1445void hostif_infrastructure_set_request(struct ks_wlan_private *priv)
13a9930d
WS
1446{
1447 struct hostif_infrastructure_set_request_t *pp;
1448 uint16_t capability;
1449
20c4f9c5 1450 DPRINTK(3, "ssid.size=%d \n", priv->reg.ssid.size);
13a9930d
WS
1451
1452 /* make primitive */
20c4f9c5
WS
1453 pp = (struct hostif_infrastructure_set_request_t *)
1454 kmalloc(hif_align_size(sizeof(*pp)), KS_WLAN_MEM_FLAG);
1455 if (pp == NULL) {
13a9930d
WS
1456 DPRINTK(3, "allocate memory failed..\n");
1457 return;
1458 }
20c4f9c5
WS
1459 pp->header.size =
1460 cpu_to_le16((uint16_t) (sizeof(*pp) - sizeof(pp->header.size)));
1461 pp->header.event = cpu_to_le16((uint16_t) HIF_INFRA_SET_REQ);
1462 pp->phy_type = cpu_to_le16((uint16_t) (priv->reg.phy_type));
1463 pp->cts_mode = cpu_to_le16((uint16_t) (priv->reg.cts_mode));
1464 pp->scan_type = cpu_to_le16((uint16_t) (priv->reg.scan_type));
13a9930d
WS
1465
1466 pp->rate_set.size = priv->reg.rate_set.size;
20c4f9c5
WS
1467 memcpy(&pp->rate_set.body[0], &priv->reg.rate_set.body[0],
1468 priv->reg.rate_set.size);
13a9930d
WS
1469 pp->ssid.size = priv->reg.ssid.size;
1470 memcpy(&pp->ssid.body[0], &priv->reg.ssid.body[0], priv->reg.ssid.size);
1471
1472 capability = 0x0000;
20c4f9c5 1473 if (priv->reg.preamble == SHORT_PREAMBLE) {
13a9930d
WS
1474 /* short preamble */
1475 capability |= BSS_CAP_SHORT_PREAMBLE;
1476 }
20c4f9c5
WS
1477 capability &= ~(BSS_CAP_PBCC); /* pbcc not support */
1478 if (priv->reg.phy_type != D_11B_ONLY_MODE) {
1479 capability |= BSS_CAP_SHORT_SLOT_TIME; /* ShortSlotTime support */
1480 capability &= ~(BSS_CAP_DSSS_OFDM); /* DSSS OFDM not support */
13a9930d 1481 }
20c4f9c5
WS
1482 pp->capability = cpu_to_le16((uint16_t) capability);
1483 pp->beacon_lost_count =
1484 cpu_to_le16((uint16_t) (priv->reg.beacon_lost_count));
1485 pp->auth_type = cpu_to_le16((uint16_t) (priv->reg.authenticate_type));
13a9930d
WS
1486
1487 pp->channel_list.body[0] = 1;
1488 pp->channel_list.body[1] = 8;
1489 pp->channel_list.body[2] = 2;
1490 pp->channel_list.body[3] = 9;
1491 pp->channel_list.body[4] = 3;
1492 pp->channel_list.body[5] = 10;
1493 pp->channel_list.body[6] = 4;
1494 pp->channel_list.body[7] = 11;
1495 pp->channel_list.body[8] = 5;
1496 pp->channel_list.body[9] = 12;
1497 pp->channel_list.body[10] = 6;
1498 pp->channel_list.body[11] = 13;
1499 pp->channel_list.body[12] = 7;
20c4f9c5 1500 if (priv->reg.phy_type == D_11G_ONLY_MODE) {
13a9930d 1501 pp->channel_list.size = 13;
20c4f9c5 1502 } else {
13a9930d
WS
1503 pp->channel_list.body[13] = 14;
1504 pp->channel_list.size = 14;
1505 }
1506
1507 /* send to device request */
1508 ps_confirm_wait_inc(priv);
20c4f9c5 1509 ks_wlan_hw_tx(priv, pp, hif_align_size(sizeof(*pp)), NULL, NULL, NULL);
13a9930d
WS
1510}
1511
9afe11e9 1512static void hostif_infrastructure_set2_request(struct ks_wlan_private *priv)
13a9930d
WS
1513{
1514 struct hostif_infrastructure_set2_request_t *pp;
1515 uint16_t capability;
1516
20c4f9c5 1517 DPRINTK(2, "ssid.size=%d \n", priv->reg.ssid.size);
13a9930d
WS
1518
1519 /* make primitive */
20c4f9c5
WS
1520 pp = (struct hostif_infrastructure_set2_request_t *)
1521 kmalloc(hif_align_size(sizeof(*pp)), KS_WLAN_MEM_FLAG);
1522 if (pp == NULL) {
13a9930d
WS
1523 DPRINTK(3, "allocate memory failed..\n");
1524 return;
1525 }
20c4f9c5
WS
1526 pp->header.size =
1527 cpu_to_le16((uint16_t) (sizeof(*pp) - sizeof(pp->header.size)));
1528 pp->header.event = cpu_to_le16((uint16_t) HIF_INFRA_SET2_REQ);
1529 pp->phy_type = cpu_to_le16((uint16_t) (priv->reg.phy_type));
1530 pp->cts_mode = cpu_to_le16((uint16_t) (priv->reg.cts_mode));
1531 pp->scan_type = cpu_to_le16((uint16_t) (priv->reg.scan_type));
13a9930d
WS
1532
1533 pp->rate_set.size = priv->reg.rate_set.size;
20c4f9c5
WS
1534 memcpy(&pp->rate_set.body[0], &priv->reg.rate_set.body[0],
1535 priv->reg.rate_set.size);
13a9930d
WS
1536 pp->ssid.size = priv->reg.ssid.size;
1537 memcpy(&pp->ssid.body[0], &priv->reg.ssid.body[0], priv->reg.ssid.size);
1538
1539 capability = 0x0000;
20c4f9c5 1540 if (priv->reg.preamble == SHORT_PREAMBLE) {
13a9930d
WS
1541 /* short preamble */
1542 capability |= BSS_CAP_SHORT_PREAMBLE;
1543 }
20c4f9c5
WS
1544 capability &= ~(BSS_CAP_PBCC); /* pbcc not support */
1545 if (priv->reg.phy_type != D_11B_ONLY_MODE) {
1546 capability |= BSS_CAP_SHORT_SLOT_TIME; /* ShortSlotTime support */
1547 capability &= ~(BSS_CAP_DSSS_OFDM); /* DSSS OFDM not support */
13a9930d 1548 }
20c4f9c5
WS
1549 pp->capability = cpu_to_le16((uint16_t) capability);
1550 pp->beacon_lost_count =
1551 cpu_to_le16((uint16_t) (priv->reg.beacon_lost_count));
1552 pp->auth_type = cpu_to_le16((uint16_t) (priv->reg.authenticate_type));
13a9930d
WS
1553
1554 pp->channel_list.body[0] = 1;
1555 pp->channel_list.body[1] = 8;
1556 pp->channel_list.body[2] = 2;
1557 pp->channel_list.body[3] = 9;
1558 pp->channel_list.body[4] = 3;
1559 pp->channel_list.body[5] = 10;
1560 pp->channel_list.body[6] = 4;
1561 pp->channel_list.body[7] = 11;
1562 pp->channel_list.body[8] = 5;
1563 pp->channel_list.body[9] = 12;
1564 pp->channel_list.body[10] = 6;
1565 pp->channel_list.body[11] = 13;
1566 pp->channel_list.body[12] = 7;
20c4f9c5 1567 if (priv->reg.phy_type == D_11G_ONLY_MODE) {
13a9930d 1568 pp->channel_list.size = 13;
20c4f9c5 1569 } else {
13a9930d
WS
1570 pp->channel_list.body[13] = 14;
1571 pp->channel_list.size = 14;
1572 }
1573
1574 memcpy(pp->bssid, priv->reg.bssid, ETH_ALEN);
1575
1576 /* send to device request */
1577 ps_confirm_wait_inc(priv);
20c4f9c5 1578 ks_wlan_hw_tx(priv, pp, hif_align_size(sizeof(*pp)), NULL, NULL, NULL);
13a9930d
WS
1579}
1580
1581static
feedcf1a 1582void hostif_adhoc_set_request(struct ks_wlan_private *priv)
13a9930d
WS
1583{
1584 struct hostif_adhoc_set_request_t *pp;
1585 uint16_t capability;
1586
1587 DPRINTK(3, "\n");
1588
1589 /* make primitive */
20c4f9c5
WS
1590 pp = (struct hostif_adhoc_set_request_t *)
1591 kmalloc(hif_align_size(sizeof(*pp)), KS_WLAN_MEM_FLAG);
1592 if (pp == NULL) {
13a9930d
WS
1593 DPRINTK(3, "allocate memory failed..\n");
1594 return;
1595 }
1596 memset(pp, 0, sizeof(*pp));
20c4f9c5
WS
1597 pp->header.size =
1598 cpu_to_le16((uint16_t) (sizeof(*pp) - sizeof(pp->header.size)));
1599 pp->header.event = cpu_to_le16((uint16_t) HIF_ADH_SET_REQ);
1600 pp->phy_type = cpu_to_le16((uint16_t) (priv->reg.phy_type));
1601 pp->cts_mode = cpu_to_le16((uint16_t) (priv->reg.cts_mode));
1602 pp->scan_type = cpu_to_le16((uint16_t) (priv->reg.scan_type));
1603 pp->channel = cpu_to_le16((uint16_t) (priv->reg.channel));
13a9930d 1604 pp->rate_set.size = priv->reg.rate_set.size;
20c4f9c5
WS
1605 memcpy(&pp->rate_set.body[0], &priv->reg.rate_set.body[0],
1606 priv->reg.rate_set.size);
13a9930d
WS
1607 pp->ssid.size = priv->reg.ssid.size;
1608 memcpy(&pp->ssid.body[0], &priv->reg.ssid.body[0], priv->reg.ssid.size);
1609
1610 capability = 0x0000;
20c4f9c5 1611 if (priv->reg.preamble == SHORT_PREAMBLE) {
13a9930d
WS
1612 /* short preamble */
1613 capability |= BSS_CAP_SHORT_PREAMBLE;
1614 }
20c4f9c5
WS
1615 capability &= ~(BSS_CAP_PBCC); /* pbcc not support */
1616 if (priv->reg.phy_type != D_11B_ONLY_MODE) {
1617 capability |= BSS_CAP_SHORT_SLOT_TIME; /* ShortSlotTime support */
1618 capability &= ~(BSS_CAP_DSSS_OFDM); /* DSSS OFDM not support */
13a9930d 1619 }
20c4f9c5 1620 pp->capability = cpu_to_le16((uint16_t) capability);
13a9930d
WS
1621
1622 /* send to device request */
1623 ps_confirm_wait_inc(priv);
20c4f9c5 1624 ks_wlan_hw_tx(priv, pp, hif_align_size(sizeof(*pp)), NULL, NULL, NULL);
13a9930d
WS
1625}
1626
1627static
feedcf1a 1628void hostif_adhoc_set2_request(struct ks_wlan_private *priv)
13a9930d
WS
1629{
1630 struct hostif_adhoc_set2_request_t *pp;
1631 uint16_t capability;
1632
1633 DPRINTK(3, "\n");
1634
1635 /* make primitive */
20c4f9c5
WS
1636 pp = (struct hostif_adhoc_set2_request_t *)
1637 kmalloc(hif_align_size(sizeof(*pp)), KS_WLAN_MEM_FLAG);
1638 if (pp == NULL) {
13a9930d
WS
1639 DPRINTK(3, "allocate memory failed..\n");
1640 return;
1641 }
1642 memset(pp, 0, sizeof(*pp));
20c4f9c5
WS
1643 pp->header.size =
1644 cpu_to_le16((uint16_t) (sizeof(*pp) - sizeof(pp->header.size)));
1645 pp->header.event = cpu_to_le16((uint16_t) HIF_ADH_SET_REQ);
1646 pp->phy_type = cpu_to_le16((uint16_t) (priv->reg.phy_type));
1647 pp->cts_mode = cpu_to_le16((uint16_t) (priv->reg.cts_mode));
1648 pp->scan_type = cpu_to_le16((uint16_t) (priv->reg.scan_type));
13a9930d 1649 pp->rate_set.size = priv->reg.rate_set.size;
20c4f9c5
WS
1650 memcpy(&pp->rate_set.body[0], &priv->reg.rate_set.body[0],
1651 priv->reg.rate_set.size);
13a9930d
WS
1652 pp->ssid.size = priv->reg.ssid.size;
1653 memcpy(&pp->ssid.body[0], &priv->reg.ssid.body[0], priv->reg.ssid.size);
1654
1655 capability = 0x0000;
20c4f9c5 1656 if (priv->reg.preamble == SHORT_PREAMBLE) {
13a9930d
WS
1657 /* short preamble */
1658 capability |= BSS_CAP_SHORT_PREAMBLE;
1659 }
20c4f9c5
WS
1660 capability &= ~(BSS_CAP_PBCC); /* pbcc not support */
1661 if (priv->reg.phy_type != D_11B_ONLY_MODE) {
1662 capability |= BSS_CAP_SHORT_SLOT_TIME; /* ShortSlotTime support */
1663 capability &= ~(BSS_CAP_DSSS_OFDM); /* DSSS OFDM not support */
13a9930d 1664 }
20c4f9c5 1665 pp->capability = cpu_to_le16((uint16_t) capability);
13a9930d
WS
1666
1667 pp->channel_list.body[0] = priv->reg.channel;
1668 pp->channel_list.size = 1;
1669 memcpy(pp->bssid, priv->reg.bssid, ETH_ALEN);
1670
1671 /* send to device request */
1672 ps_confirm_wait_inc(priv);
20c4f9c5 1673 ks_wlan_hw_tx(priv, pp, hif_align_size(sizeof(*pp)), NULL, NULL, NULL);
13a9930d
WS
1674}
1675
1676static
20c4f9c5 1677void hostif_stop_request(struct ks_wlan_private *priv)
13a9930d
WS
1678{
1679 struct hostif_stop_request_t *pp;
1680
20c4f9c5 1681 DPRINTK(3, "\n");
13a9930d
WS
1682
1683 /* make primitive */
20c4f9c5
WS
1684 pp = (struct hostif_stop_request_t *)
1685 kmalloc(hif_align_size(sizeof(*pp)), KS_WLAN_MEM_FLAG);
1686 if (pp == NULL) {
1687 DPRINTK(3, "allocate memory failed..\n");
13a9930d
WS
1688 return;
1689 }
20c4f9c5
WS
1690 pp->header.size =
1691 cpu_to_le16((uint16_t) (sizeof(*pp) - sizeof(pp->header.size)));
1692 pp->header.event = cpu_to_le16((uint16_t) HIF_STOP_REQ);
13a9930d
WS
1693
1694 /* send to device request */
1695 ps_confirm_wait_inc(priv);
20c4f9c5 1696 ks_wlan_hw_tx(priv, pp, hif_align_size(sizeof(*pp)), NULL, NULL, NULL);
13a9930d
WS
1697}
1698
1699static
20c4f9c5 1700void hostif_phy_information_request(struct ks_wlan_private *priv)
13a9930d
WS
1701{
1702 struct hostif_phy_information_request_t *pp;
1703
20c4f9c5 1704 DPRINTK(3, "\n");
13a9930d
WS
1705
1706 /* make primitive */
20c4f9c5
WS
1707 pp = (struct hostif_phy_information_request_t *)
1708 kmalloc(hif_align_size(sizeof(*pp)), KS_WLAN_MEM_FLAG);
1709 if (pp == NULL) {
13a9930d
WS
1710 DPRINTK(3, "allocate memory failed..\n");
1711 return;
1712 }
20c4f9c5
WS
1713 pp->header.size =
1714 cpu_to_le16((uint16_t) (sizeof(*pp) - sizeof(pp->header.size)));
1715 pp->header.event = cpu_to_le16((uint16_t) HIF_PHY_INFO_REQ);
1716 if (priv->reg.phy_info_timer) {
1717 pp->type = cpu_to_le16((uint16_t) TIME_TYPE);
1718 pp->time = cpu_to_le16((uint16_t) (priv->reg.phy_info_timer));
1719 } else {
1720 pp->type = cpu_to_le16((uint16_t) NORMAL_TYPE);
1721 pp->time = cpu_to_le16((uint16_t) 0);
13a9930d
WS
1722 }
1723
1724 /* send to device request */
1725 ps_confirm_wait_inc(priv);
20c4f9c5 1726 ks_wlan_hw_tx(priv, pp, hif_align_size(sizeof(*pp)), NULL, NULL, NULL);
13a9930d
WS
1727}
1728
1729static
20c4f9c5
WS
1730void hostif_power_mngmt_request(struct ks_wlan_private *priv,
1731 unsigned long mode, unsigned long wake_up,
1732 unsigned long receiveDTIMs)
13a9930d
WS
1733{
1734 struct hostif_power_mngmt_request_t *pp;
1735
20c4f9c5
WS
1736 DPRINTK(3, "mode=%lu wake_up=%lu receiveDTIMs=%lu\n", mode, wake_up,
1737 receiveDTIMs);
13a9930d 1738 /* make primitive */
20c4f9c5
WS
1739 pp = (struct hostif_power_mngmt_request_t *)
1740 kmalloc(hif_align_size(sizeof(*pp)), KS_WLAN_MEM_FLAG);
1741 if (pp == NULL) {
1742 DPRINTK(3, "allocate memory failed..\n");
13a9930d
WS
1743 return;
1744 }
20c4f9c5
WS
1745 pp->header.size =
1746 cpu_to_le16((uint16_t) (sizeof(*pp) - sizeof(pp->header.size)));
1747 pp->header.event = cpu_to_le16((uint16_t) HIF_POWERMGT_REQ);
1748 pp->mode = cpu_to_le32((uint32_t) mode);
1749 pp->wake_up = cpu_to_le32((uint32_t) wake_up);
1750 pp->receiveDTIMs = cpu_to_le32((uint32_t) receiveDTIMs);
13a9930d
WS
1751
1752 /* send to device request */
1753 ps_confirm_wait_inc(priv);
20c4f9c5 1754 ks_wlan_hw_tx(priv, pp, hif_align_size(sizeof(*pp)), NULL, NULL, NULL);
13a9930d
WS
1755}
1756
1757static
20c4f9c5 1758void hostif_sleep_request(struct ks_wlan_private *priv, unsigned long mode)
13a9930d
WS
1759{
1760 struct hostif_sleep_request_t *pp;
1761
20c4f9c5 1762 DPRINTK(3, "mode=%lu \n", mode);
13a9930d 1763
20c4f9c5 1764 if (mode == SLP_SLEEP) {
13a9930d 1765 /* make primitive */
20c4f9c5
WS
1766 pp = (struct hostif_sleep_request_t *)
1767 kmalloc(hif_align_size(sizeof(*pp)), KS_WLAN_MEM_FLAG);
1768 if (pp == NULL) {
1769 DPRINTK(3, "allocate memory failed..\n");
13a9930d
WS
1770 return;
1771 }
20c4f9c5
WS
1772 pp->header.size =
1773 cpu_to_le16((uint16_t)
1774 (sizeof(*pp) - sizeof(pp->header.size)));
1775 pp->header.event = cpu_to_le16((uint16_t) HIF_SLEEP_REQ);
13a9930d
WS
1776
1777 /* send to device request */
1778 ps_confirm_wait_inc(priv);
20c4f9c5
WS
1779 ks_wlan_hw_tx(priv, pp, hif_align_size(sizeof(*pp)), NULL, NULL,
1780 NULL);
1781 } else if (mode == SLP_ACTIVE) {
1782 atomic_set(&priv->sleepstatus.wakeup_request, 1);
1783 queue_delayed_work(priv->ks_wlan_hw.ks7010sdio_wq,
1784 &priv->ks_wlan_hw.rw_wq, 1);
1785 } else {
1786 DPRINTK(3, "invalid mode %ld \n", mode);
13a9930d
WS
1787 return;
1788 }
1789}
1790
13a9930d 1791static
20c4f9c5
WS
1792void hostif_bss_scan_request(struct ks_wlan_private *priv,
1793 unsigned long scan_type, uint8_t * scan_ssid,
1794 uint8_t scan_ssid_len)
13a9930d
WS
1795{
1796 struct hostif_bss_scan_request_t *pp;
1797
20c4f9c5 1798 DPRINTK(2, "\n");
13a9930d 1799 /* make primitive */
20c4f9c5
WS
1800 pp = (struct hostif_bss_scan_request_t *)
1801 kmalloc(hif_align_size(sizeof(*pp)), KS_WLAN_MEM_FLAG);
1802 if (pp == NULL) {
1803 DPRINTK(3, "allocate memory failed..\n");
13a9930d
WS
1804 return;
1805 }
20c4f9c5
WS
1806 pp->header.size =
1807 cpu_to_le16((uint16_t) (sizeof(*pp) - sizeof(pp->header.size)));
1808 pp->header.event = cpu_to_le16((uint16_t) HIF_SCAN_REQ);
13a9930d
WS
1809 pp->scan_type = scan_type;
1810
20c4f9c5
WS
1811 pp->ch_time_min = cpu_to_le32((uint32_t) 110); /* default value */
1812 pp->ch_time_max = cpu_to_le32((uint32_t) 130); /* default value */
13a9930d
WS
1813 pp->channel_list.body[0] = 1;
1814 pp->channel_list.body[1] = 8;
1815 pp->channel_list.body[2] = 2;
1816 pp->channel_list.body[3] = 9;
1817 pp->channel_list.body[4] = 3;
1818 pp->channel_list.body[5] = 10;
1819 pp->channel_list.body[6] = 4;
1820 pp->channel_list.body[7] = 11;
1821 pp->channel_list.body[8] = 5;
1822 pp->channel_list.body[9] = 12;
1823 pp->channel_list.body[10] = 6;
1824 pp->channel_list.body[11] = 13;
1825 pp->channel_list.body[12] = 7;
20c4f9c5 1826 if (priv->reg.phy_type == D_11G_ONLY_MODE) {
13a9930d 1827 pp->channel_list.size = 13;
20c4f9c5 1828 } else {
13a9930d
WS
1829 pp->channel_list.body[13] = 14;
1830 pp->channel_list.size = 14;
1831 }
1832 pp->ssid.size = 0;
1833
1834 /* specified SSID SCAN */
20c4f9c5 1835 if (scan_ssid_len > 0 && scan_ssid_len <= 32) {
13a9930d
WS
1836 pp->ssid.size = scan_ssid_len;
1837 memcpy(&pp->ssid.body[0], scan_ssid, scan_ssid_len);
1838 }
1839
13a9930d
WS
1840 /* send to device request */
1841 ps_confirm_wait_inc(priv);
20c4f9c5 1842 ks_wlan_hw_tx(priv, pp, hif_align_size(sizeof(*pp)), NULL, NULL, NULL);
13a9930d
WS
1843
1844 priv->aplist.size = 0;
20c4f9c5 1845 priv->scan_ind_count = 0;
13a9930d
WS
1846}
1847
1848static
20c4f9c5
WS
1849void hostif_mic_failure_request(struct ks_wlan_private *priv,
1850 unsigned short failure_count,
1851 unsigned short timer)
13a9930d
WS
1852{
1853 struct hostif_mic_failure_request_t *pp;
1854
20c4f9c5 1855 DPRINTK(3, "count=%d :: timer=%d\n", failure_count, timer);
13a9930d 1856 /* make primitive */
20c4f9c5
WS
1857 pp = (struct hostif_mic_failure_request_t *)
1858 kmalloc(hif_align_size(sizeof(*pp)), KS_WLAN_MEM_FLAG);
1859 if (pp == NULL) {
1860 DPRINTK(3, "allocate memory failed..\n");
13a9930d
WS
1861 return;
1862 }
20c4f9c5
WS
1863 pp->header.size =
1864 cpu_to_le16((uint16_t) (sizeof(*pp) - sizeof(pp->header.size)));
1865 pp->header.event = cpu_to_le16((uint16_t) HIF_MIC_FAILURE_REQ);
1866 pp->failure_count = cpu_to_le16((uint16_t) failure_count);
1867 pp->timer = cpu_to_le16((uint16_t) timer);
13a9930d
WS
1868
1869 /* send to device request */
1870 ps_confirm_wait_inc(priv);
20c4f9c5 1871 ks_wlan_hw_tx(priv, pp, hif_align_size(sizeof(*pp)), NULL, NULL, NULL);
13a9930d
WS
1872}
1873
1874/* Device I/O Recieve indicate */
20c4f9c5
WS
1875static void devio_rec_ind(struct ks_wlan_private *priv, unsigned char *p,
1876 unsigned int size)
13a9930d
WS
1877{
1878 if (priv->device_open_status) {
20c4f9c5 1879 spin_lock(&priv->dev_read_lock); /* request spin lock */
13a9930d
WS
1880 priv->dev_data[atomic_read(&priv->rec_count)] = p;
1881 priv->dev_size[atomic_read(&priv->rec_count)] = size;
1882
1883 if (atomic_read(&priv->event_count) != DEVICE_STOCK_COUNT) {
1884 /* rx event count inc */
1885 atomic_inc(&priv->event_count);
1886 }
1887 atomic_inc(&priv->rec_count);
20c4f9c5 1888 if (atomic_read(&priv->rec_count) == DEVICE_STOCK_COUNT)
13a9930d
WS
1889 atomic_set(&priv->rec_count, 0);
1890
20c4f9c5 1891 wake_up_interruptible_all(&priv->devread_wait);
13a9930d
WS
1892
1893 /* release spin lock */
1894 spin_unlock(&priv->dev_read_lock);
1895 }
1896}
1897
20c4f9c5
WS
1898void hostif_receive(struct ks_wlan_private *priv, unsigned char *p,
1899 unsigned int size)
13a9930d 1900{
20c4f9c5 1901 DPRINTK(4, "\n");
13a9930d
WS
1902
1903 devio_rec_ind(priv, p, size);
1904
1905 priv->rxp = p;
1906 priv->rx_size = size;
1907
20c4f9c5
WS
1908 if (get_WORD(priv) == priv->rx_size) { /* length check !! */
1909 hostif_event_check(priv); /* event check */
13a9930d
WS
1910 }
1911}
1912
13a9930d 1913static
feedcf1a 1914void hostif_sme_set_wep(struct ks_wlan_private *priv, int type)
13a9930d
WS
1915{
1916 uint32_t val;
20c4f9c5 1917 switch (type) {
13a9930d 1918 case SME_WEP_INDEX_REQUEST:
20c4f9c5 1919 val = cpu_to_le32((uint32_t) (priv->reg.wep_index));
13a9930d 1920 hostif_mib_set_request(priv, DOT11_WEP_DEFAULT_KEY_ID,
20c4f9c5 1921 sizeof(val), MIB_VALUE_TYPE_INT, &val);
13a9930d
WS
1922 break;
1923 case SME_WEP_KEY1_REQUEST:
20c4f9c5
WS
1924 if (!priv->wpa.wpa_enabled)
1925 hostif_mib_set_request(priv,
1926 DOT11_WEP_DEFAULT_KEY_VALUE1,
1927 priv->reg.wep_key[0].size,
1928 MIB_VALUE_TYPE_OSTRING,
1929 &priv->reg.wep_key[0].val[0]);
13a9930d
WS
1930 break;
1931 case SME_WEP_KEY2_REQUEST:
20c4f9c5
WS
1932 if (!priv->wpa.wpa_enabled)
1933 hostif_mib_set_request(priv,
1934 DOT11_WEP_DEFAULT_KEY_VALUE2,
1935 priv->reg.wep_key[1].size,
1936 MIB_VALUE_TYPE_OSTRING,
13a9930d
WS
1937 &priv->reg.wep_key[1].val[0]);
1938 break;
1939 case SME_WEP_KEY3_REQUEST:
20c4f9c5
WS
1940 if (!priv->wpa.wpa_enabled)
1941 hostif_mib_set_request(priv,
1942 DOT11_WEP_DEFAULT_KEY_VALUE3,
1943 priv->reg.wep_key[2].size,
1944 MIB_VALUE_TYPE_OSTRING,
1945 &priv->reg.wep_key[2].val[0]);
13a9930d
WS
1946 break;
1947 case SME_WEP_KEY4_REQUEST:
20c4f9c5
WS
1948 if (!priv->wpa.wpa_enabled)
1949 hostif_mib_set_request(priv,
1950 DOT11_WEP_DEFAULT_KEY_VALUE4,
1951 priv->reg.wep_key[3].size,
1952 MIB_VALUE_TYPE_OSTRING,
13a9930d
WS
1953 &priv->reg.wep_key[3].val[0]);
1954 break;
1955 case SME_WEP_FLAG_REQUEST:
20c4f9c5 1956 val = cpu_to_le32((uint32_t) (priv->reg.privacy_invoked));
13a9930d 1957 hostif_mib_set_request(priv, DOT11_PRIVACY_INVOKED,
20c4f9c5 1958 sizeof(val), MIB_VALUE_TYPE_BOOL, &val);
13a9930d
WS
1959 break;
1960 }
1961
20c4f9c5 1962 return;
13a9930d
WS
1963}
1964
1965struct wpa_suite_t {
1966 unsigned short size;
1967 unsigned char suite[4][CIPHER_ID_LEN];
20c4f9c5 1968} __attribute__ ((packed));
13a9930d
WS
1969
1970struct rsn_mode_t {
1971 uint32_t rsn_mode;
1972 uint16_t rsn_capability;
20c4f9c5 1973} __attribute__ ((packed));
13a9930d
WS
1974
1975static
feedcf1a 1976void hostif_sme_set_rsn(struct ks_wlan_private *priv, int type)
13a9930d
WS
1977{
1978 struct wpa_suite_t wpa_suite;
1979 struct rsn_mode_t rsn_mode;
1980 uint32_t val;
1981
20c4f9c5 1982 memset(&wpa_suite, 0, sizeof(wpa_suite));
13a9930d 1983
20c4f9c5 1984 switch (type) {
13a9930d 1985 case SME_RSN_UCAST_REQUEST:
20c4f9c5
WS
1986 wpa_suite.size = cpu_to_le16((uint16_t) 1);
1987 switch (priv->wpa.pairwise_suite) {
13a9930d 1988 case IW_AUTH_CIPHER_NONE:
20c4f9c5
WS
1989 if (priv->wpa.version == IW_AUTH_WPA_VERSION_WPA2)
1990 memcpy(&wpa_suite.suite[0][0],
1991 CIPHER_ID_WPA2_NONE, CIPHER_ID_LEN);
13a9930d 1992 else
20c4f9c5
WS
1993 memcpy(&wpa_suite.suite[0][0],
1994 CIPHER_ID_WPA_NONE, CIPHER_ID_LEN);
13a9930d
WS
1995 break;
1996 case IW_AUTH_CIPHER_WEP40:
20c4f9c5
WS
1997 if (priv->wpa.version == IW_AUTH_WPA_VERSION_WPA2)
1998 memcpy(&wpa_suite.suite[0][0],
1999 CIPHER_ID_WPA2_WEP40, CIPHER_ID_LEN);
13a9930d 2000 else
20c4f9c5
WS
2001 memcpy(&wpa_suite.suite[0][0],
2002 CIPHER_ID_WPA_WEP40, CIPHER_ID_LEN);
13a9930d
WS
2003 break;
2004 case IW_AUTH_CIPHER_TKIP:
20c4f9c5
WS
2005 if (priv->wpa.version == IW_AUTH_WPA_VERSION_WPA2)
2006 memcpy(&wpa_suite.suite[0][0],
2007 CIPHER_ID_WPA2_TKIP, CIPHER_ID_LEN);
13a9930d 2008 else
20c4f9c5
WS
2009 memcpy(&wpa_suite.suite[0][0],
2010 CIPHER_ID_WPA_TKIP, CIPHER_ID_LEN);
13a9930d
WS
2011 break;
2012 case IW_AUTH_CIPHER_CCMP:
20c4f9c5
WS
2013 if (priv->wpa.version == IW_AUTH_WPA_VERSION_WPA2)
2014 memcpy(&wpa_suite.suite[0][0],
2015 CIPHER_ID_WPA2_CCMP, CIPHER_ID_LEN);
13a9930d 2016 else
20c4f9c5
WS
2017 memcpy(&wpa_suite.suite[0][0],
2018 CIPHER_ID_WPA_CCMP, CIPHER_ID_LEN);
13a9930d
WS
2019 break;
2020 case IW_AUTH_CIPHER_WEP104:
20c4f9c5
WS
2021 if (priv->wpa.version == IW_AUTH_WPA_VERSION_WPA2)
2022 memcpy(&wpa_suite.suite[0][0],
2023 CIPHER_ID_WPA2_WEP104, CIPHER_ID_LEN);
13a9930d 2024 else
20c4f9c5
WS
2025 memcpy(&wpa_suite.suite[0][0],
2026 CIPHER_ID_WPA_WEP104, CIPHER_ID_LEN);
13a9930d
WS
2027 break;
2028 }
2029
2030 hostif_mib_set_request(priv, DOT11_RSN_CONFIG_UNICAST_CIPHER,
20c4f9c5
WS
2031 sizeof(wpa_suite.size) +
2032 CIPHER_ID_LEN * wpa_suite.size,
13a9930d
WS
2033 MIB_VALUE_TYPE_OSTRING, &wpa_suite);
2034 break;
2035 case SME_RSN_MCAST_REQUEST:
20c4f9c5 2036 switch (priv->wpa.group_suite) {
13a9930d 2037 case IW_AUTH_CIPHER_NONE:
20c4f9c5
WS
2038 if (priv->wpa.version == IW_AUTH_WPA_VERSION_WPA2)
2039 memcpy(&wpa_suite.suite[0][0],
2040 CIPHER_ID_WPA2_NONE, CIPHER_ID_LEN);
13a9930d 2041 else
20c4f9c5
WS
2042 memcpy(&wpa_suite.suite[0][0],
2043 CIPHER_ID_WPA_NONE, CIPHER_ID_LEN);
13a9930d
WS
2044 break;
2045 case IW_AUTH_CIPHER_WEP40:
20c4f9c5
WS
2046 if (priv->wpa.version == IW_AUTH_WPA_VERSION_WPA2)
2047 memcpy(&wpa_suite.suite[0][0],
2048 CIPHER_ID_WPA2_WEP40, CIPHER_ID_LEN);
13a9930d 2049 else
20c4f9c5
WS
2050 memcpy(&wpa_suite.suite[0][0],
2051 CIPHER_ID_WPA_WEP40, CIPHER_ID_LEN);
13a9930d
WS
2052 break;
2053 case IW_AUTH_CIPHER_TKIP:
20c4f9c5
WS
2054 if (priv->wpa.version == IW_AUTH_WPA_VERSION_WPA2)
2055 memcpy(&wpa_suite.suite[0][0],
2056 CIPHER_ID_WPA2_TKIP, CIPHER_ID_LEN);
13a9930d 2057 else
20c4f9c5
WS
2058 memcpy(&wpa_suite.suite[0][0],
2059 CIPHER_ID_WPA_TKIP, CIPHER_ID_LEN);
13a9930d
WS
2060 break;
2061 case IW_AUTH_CIPHER_CCMP:
20c4f9c5
WS
2062 if (priv->wpa.version == IW_AUTH_WPA_VERSION_WPA2)
2063 memcpy(&wpa_suite.suite[0][0],
2064 CIPHER_ID_WPA2_CCMP, CIPHER_ID_LEN);
13a9930d 2065 else
20c4f9c5
WS
2066 memcpy(&wpa_suite.suite[0][0],
2067 CIPHER_ID_WPA_CCMP, CIPHER_ID_LEN);
13a9930d
WS
2068 break;
2069 case IW_AUTH_CIPHER_WEP104:
20c4f9c5
WS
2070 if (priv->wpa.version == IW_AUTH_WPA_VERSION_WPA2)
2071 memcpy(&wpa_suite.suite[0][0],
2072 CIPHER_ID_WPA2_WEP104, CIPHER_ID_LEN);
13a9930d 2073 else
20c4f9c5
WS
2074 memcpy(&wpa_suite.suite[0][0],
2075 CIPHER_ID_WPA_WEP104, CIPHER_ID_LEN);
13a9930d
WS
2076 break;
2077 }
2078
2079 hostif_mib_set_request(priv, DOT11_RSN_CONFIG_MULTICAST_CIPHER,
2080 CIPHER_ID_LEN, MIB_VALUE_TYPE_OSTRING,
20c4f9c5 2081 &wpa_suite.suite[0][0]);
13a9930d
WS
2082 break;
2083 case SME_RSN_AUTH_REQUEST:
20c4f9c5
WS
2084 wpa_suite.size = cpu_to_le16((uint16_t) 1);
2085 switch (priv->wpa.key_mgmt_suite) {
13a9930d 2086 case IW_AUTH_KEY_MGMT_802_1X:
20c4f9c5
WS
2087 if (priv->wpa.version == IW_AUTH_WPA_VERSION_WPA2)
2088 memcpy(&wpa_suite.suite[0][0],
2089 KEY_MGMT_ID_WPA2_1X, KEY_MGMT_ID_LEN);
13a9930d 2090 else
20c4f9c5
WS
2091 memcpy(&wpa_suite.suite[0][0],
2092 KEY_MGMT_ID_WPA_1X, KEY_MGMT_ID_LEN);
13a9930d
WS
2093 break;
2094 case IW_AUTH_KEY_MGMT_PSK:
20c4f9c5
WS
2095 if (priv->wpa.version == IW_AUTH_WPA_VERSION_WPA2)
2096 memcpy(&wpa_suite.suite[0][0],
2097 KEY_MGMT_ID_WPA2_PSK, KEY_MGMT_ID_LEN);
13a9930d 2098 else
20c4f9c5
WS
2099 memcpy(&wpa_suite.suite[0][0],
2100 KEY_MGMT_ID_WPA_PSK, KEY_MGMT_ID_LEN);
13a9930d
WS
2101 break;
2102 case 0:
20c4f9c5
WS
2103 if (priv->wpa.version == IW_AUTH_WPA_VERSION_WPA2)
2104 memcpy(&wpa_suite.suite[0][0],
2105 KEY_MGMT_ID_WPA2_NONE, KEY_MGMT_ID_LEN);
13a9930d 2106 else
20c4f9c5
WS
2107 memcpy(&wpa_suite.suite[0][0],
2108 KEY_MGMT_ID_WPA_NONE, KEY_MGMT_ID_LEN);
13a9930d
WS
2109 break;
2110 case 4:
20c4f9c5
WS
2111 if (priv->wpa.version == IW_AUTH_WPA_VERSION_WPA2)
2112 memcpy(&wpa_suite.suite[0][0],
2113 KEY_MGMT_ID_WPA2_WPANONE,
2114 KEY_MGMT_ID_LEN);
13a9930d 2115 else
20c4f9c5
WS
2116 memcpy(&wpa_suite.suite[0][0],
2117 KEY_MGMT_ID_WPA_WPANONE,
2118 KEY_MGMT_ID_LEN);
13a9930d
WS
2119 break;
2120 }
2121
2122 hostif_mib_set_request(priv, DOT11_RSN_CONFIG_AUTH_SUITE,
20c4f9c5
WS
2123 sizeof(wpa_suite.size) +
2124 KEY_MGMT_ID_LEN * wpa_suite.size,
13a9930d
WS
2125 MIB_VALUE_TYPE_OSTRING, &wpa_suite);
2126 break;
2127 case SME_RSN_ENABLED_REQUEST:
20c4f9c5 2128 val = cpu_to_le32((uint32_t) (priv->wpa.rsn_enabled));
13a9930d 2129 hostif_mib_set_request(priv, DOT11_RSN_ENABLED,
20c4f9c5 2130 sizeof(val), MIB_VALUE_TYPE_BOOL, &val);
13a9930d
WS
2131 break;
2132 case SME_RSN_MODE_REQUEST:
20c4f9c5
WS
2133 if (priv->wpa.version == IW_AUTH_WPA_VERSION_WPA2) {
2134 rsn_mode.rsn_mode =
2135 cpu_to_le32((uint32_t) RSN_MODE_WPA2);
2136 rsn_mode.rsn_capability = cpu_to_le16((uint16_t) 0);
2137 } else if (priv->wpa.version == IW_AUTH_WPA_VERSION_WPA) {
2138 rsn_mode.rsn_mode =
2139 cpu_to_le32((uint32_t) RSN_MODE_WPA);
2140 rsn_mode.rsn_capability = cpu_to_le16((uint16_t) 0);
2141 } else {
2142 rsn_mode.rsn_mode =
2143 cpu_to_le32((uint32_t) RSN_MODE_NONE);
2144 rsn_mode.rsn_capability = cpu_to_le16((uint16_t) 0);
13a9930d 2145 }
20c4f9c5
WS
2146 hostif_mib_set_request(priv, LOCAL_RSN_MODE, sizeof(rsn_mode),
2147 MIB_VALUE_TYPE_OSTRING, &rsn_mode);
13a9930d
WS
2148 break;
2149
2150 }
2151 return;
2152}
2153
2154static
feedcf1a 2155void hostif_sme_mode_setup(struct ks_wlan_private *priv)
13a9930d
WS
2156{
2157 unsigned char rate_size;
2158 unsigned char rate_octet[RATE_SET_MAX_SIZE];
20c4f9c5 2159 int i = 0;
13a9930d 2160
20c4f9c5
WS
2161 /* rate setting if rate segging is auto for changing phy_type (#94) */
2162 if (priv->reg.tx_rate == TX_RATE_FULL_AUTO) {
2163 if (priv->reg.phy_type == D_11B_ONLY_MODE) {
13a9930d
WS
2164 priv->reg.rate_set.body[3] = TX_RATE_11M;
2165 priv->reg.rate_set.body[2] = TX_RATE_5M;
20c4f9c5
WS
2166 priv->reg.rate_set.body[1] = TX_RATE_2M | BASIC_RATE;
2167 priv->reg.rate_set.body[0] = TX_RATE_1M | BASIC_RATE;
13a9930d 2168 priv->reg.rate_set.size = 4;
20c4f9c5 2169 } else { /* D_11G_ONLY_MODE or D_11BG_COMPATIBLE_MODE */
13a9930d
WS
2170 priv->reg.rate_set.body[11] = TX_RATE_54M;
2171 priv->reg.rate_set.body[10] = TX_RATE_48M;
2172 priv->reg.rate_set.body[9] = TX_RATE_36M;
2173 priv->reg.rate_set.body[8] = TX_RATE_18M;
2174 priv->reg.rate_set.body[7] = TX_RATE_9M;
20c4f9c5
WS
2175 priv->reg.rate_set.body[6] = TX_RATE_24M | BASIC_RATE;
2176 priv->reg.rate_set.body[5] = TX_RATE_12M | BASIC_RATE;
2177 priv->reg.rate_set.body[4] = TX_RATE_6M | BASIC_RATE;
2178 priv->reg.rate_set.body[3] = TX_RATE_11M | BASIC_RATE;
2179 priv->reg.rate_set.body[2] = TX_RATE_5M | BASIC_RATE;
2180 priv->reg.rate_set.body[1] = TX_RATE_2M | BASIC_RATE;
2181 priv->reg.rate_set.body[0] = TX_RATE_1M | BASIC_RATE;
13a9930d
WS
2182 priv->reg.rate_set.size = 12;
2183 }
2184 }
2185
2186 /* rate mask by phy setting */
20c4f9c5
WS
2187 if (priv->reg.phy_type == D_11B_ONLY_MODE) {
2188 for (i = 0; i < priv->reg.rate_set.size; i++) {
2189 if (IS_11B_RATE(priv->reg.rate_set.body[i])) {
2190 if ((priv->reg.rate_set.body[i] & RATE_MASK) >=
2191 TX_RATE_5M)
2192 rate_octet[i] =
2193 priv->reg.rate_set.
2194 body[i] & RATE_MASK;
13a9930d 2195 else
20c4f9c5
WS
2196 rate_octet[i] =
2197 priv->reg.rate_set.body[i];
2198 } else
13a9930d
WS
2199 break;
2200 }
2201
20c4f9c5
WS
2202 } else { /* D_11G_ONLY_MODE or D_11BG_COMPATIBLE_MODE */
2203 for (i = 0; i < priv->reg.rate_set.size; i++) {
2204 if (IS_11BG_RATE(priv->reg.rate_set.body[i])) {
2205 if (IS_OFDM_EXT_RATE
2206 (priv->reg.rate_set.body[i]))
2207 rate_octet[i] =
2208 priv->reg.rate_set.
2209 body[i] & RATE_MASK;
13a9930d 2210 else
20c4f9c5
WS
2211 rate_octet[i] =
2212 priv->reg.rate_set.body[i];
2213 } else
13a9930d
WS
2214 break;
2215 }
2216 }
2217 rate_size = i;
20c4f9c5
WS
2218 if (rate_size == 0) {
2219 if (priv->reg.phy_type == D_11G_ONLY_MODE)
2220 rate_octet[0] = TX_RATE_6M | BASIC_RATE;
13a9930d 2221 else
20c4f9c5 2222 rate_octet[0] = TX_RATE_2M | BASIC_RATE;
13a9930d
WS
2223 rate_size = 1;
2224 }
2225
2226 /* rate set update */
2227 priv->reg.rate_set.size = rate_size;
2228 memcpy(&priv->reg.rate_set.body[0], &rate_octet[0], rate_size);
2229
20c4f9c5 2230 switch (priv->reg.operation_mode) {
13a9930d
WS
2231 case MODE_PSEUDO_ADHOC:
2232 /* Pseudo Ad-Hoc mode */
2233 hostif_ps_adhoc_set_request(priv);
2234 break;
2235 case MODE_INFRASTRUCTURE:
2236 /* Infrastructure mode */
20c4f9c5 2237 if (!is_valid_ether_addr((u8 *) priv->reg.bssid)) {
13a9930d 2238 hostif_infrastructure_set_request(priv);
20c4f9c5 2239 } else {
13a9930d 2240 hostif_infrastructure_set2_request(priv);
20c4f9c5
WS
2241 DPRINTK(2,
2242 "Infra bssid = %02x:%02x:%02x:%02x:%02x:%02x\n",
2243 priv->reg.bssid[0], priv->reg.bssid[1],
2244 priv->reg.bssid[2], priv->reg.bssid[3],
2245 priv->reg.bssid[4], priv->reg.bssid[5]);
13a9930d
WS
2246 }
2247 break;
2248 case MODE_ADHOC:
2249 /* IEEE802.11 Ad-Hoc mode */
20c4f9c5 2250 if (!is_valid_ether_addr((u8 *) priv->reg.bssid)) {
13a9930d 2251 hostif_adhoc_set_request(priv);
20c4f9c5 2252 } else {
13a9930d 2253 hostif_adhoc_set2_request(priv);
20c4f9c5
WS
2254 DPRINTK(2,
2255 "Adhoc bssid = %02x:%02x:%02x:%02x:%02x:%02x\n",
2256 priv->reg.bssid[0], priv->reg.bssid[1],
2257 priv->reg.bssid[2], priv->reg.bssid[3],
2258 priv->reg.bssid[4], priv->reg.bssid[5]);
13a9930d
WS
2259 }
2260 break;
2261 default:
2262 break;
2263 }
2264
20c4f9c5 2265 return;
13a9930d
WS
2266}
2267
2268static
feedcf1a 2269void hostif_sme_multicast_set(struct ks_wlan_private *priv)
13a9930d
WS
2270{
2271
20c4f9c5 2272 struct net_device *dev = priv->net_dev;
13a9930d 2273 int mc_count;
13a9930d 2274 struct netdev_hw_addr *ha;
20c4f9c5 2275 char set_address[NIC_MAX_MCAST_LIST * ETH_ALEN];
13a9930d 2276 unsigned long filter_type;
f88e6d33 2277 int i = 0;
13a9930d 2278
20c4f9c5 2279 DPRINTK(3, "\n");
13a9930d
WS
2280
2281 spin_lock(&priv->multicast_spin);
2282
20c4f9c5
WS
2283 memset(set_address, 0, NIC_MAX_MCAST_LIST * ETH_ALEN);
2284
2285 if (dev->flags & IFF_PROMISC) {
2286 filter_type = cpu_to_le32((uint32_t) MCAST_FILTER_PROMISC);
2287 hostif_mib_set_request(priv, LOCAL_MULTICAST_FILTER,
2288 sizeof(filter_type), MIB_VALUE_TYPE_BOOL,
2289 &filter_type);
2290 } else if ((netdev_mc_count(dev) > NIC_MAX_MCAST_LIST)
2291 || (dev->flags & IFF_ALLMULTI)) {
2292 filter_type = cpu_to_le32((uint32_t) MCAST_FILTER_MCASTALL);
2293 hostif_mib_set_request(priv, LOCAL_MULTICAST_FILTER,
2294 sizeof(filter_type), MIB_VALUE_TYPE_BOOL,
2295 &filter_type);
2296 } else {
2297 if (priv->sme_i.sme_flag & SME_MULTICAST) {
13a9930d 2298 mc_count = netdev_mc_count(dev);
13a9930d 2299 netdev_for_each_mc_addr(ha, dev) {
20c4f9c5
WS
2300 memcpy(&set_address[i * ETH_ALEN], ha->addr,
2301 ETH_ALEN);
f88e6d33 2302 i++;
13a9930d 2303 }
13a9930d
WS
2304 priv->sme_i.sme_flag &= ~SME_MULTICAST;
2305 hostif_mib_set_request(priv, LOCAL_MULTICAST_ADDRESS,
20c4f9c5
WS
2306 (ETH_ALEN * mc_count),
2307 MIB_VALUE_TYPE_OSTRING,
2308 &set_address[0]);
2309 } else {
2310 filter_type =
2311 cpu_to_le32((uint32_t) MCAST_FILTER_MCAST);
13a9930d 2312 priv->sme_i.sme_flag |= SME_MULTICAST;
20c4f9c5
WS
2313 hostif_mib_set_request(priv, LOCAL_MULTICAST_FILTER,
2314 sizeof(filter_type),
2315 MIB_VALUE_TYPE_BOOL,
2316 &filter_type);
13a9930d
WS
2317 }
2318 }
2319
2320 spin_unlock(&priv->multicast_spin);
2321
2322}
2323
2324static
feedcf1a 2325void hostif_sme_powermgt_set(struct ks_wlan_private *priv)
13a9930d 2326{
20c4f9c5 2327 unsigned long mode, wake_up, receiveDTIMs;
13a9930d 2328
20c4f9c5
WS
2329 DPRINTK(3, "\n");
2330 switch (priv->reg.powermgt) {
13a9930d
WS
2331 case POWMGT_ACTIVE_MODE:
2332 mode = POWER_ACTIVE;
2333 wake_up = 0;
2334 receiveDTIMs = 0;
2335 break;
2336 case POWMGT_SAVE1_MODE:
20c4f9c5 2337 if (priv->reg.operation_mode == MODE_INFRASTRUCTURE) {
13a9930d
WS
2338 mode = POWER_SAVE;
2339 wake_up = 0;
2340 receiveDTIMs = 0;
2341 } else {
2342 mode = POWER_ACTIVE;
2343 wake_up = 0;
2344 receiveDTIMs = 0;
2345 }
2346 break;
2347 case POWMGT_SAVE2_MODE:
20c4f9c5 2348 if (priv->reg.operation_mode == MODE_INFRASTRUCTURE) {
13a9930d
WS
2349 mode = POWER_SAVE;
2350 wake_up = 0;
2351 receiveDTIMs = 1;
2352 } else {
2353 mode = POWER_ACTIVE;
2354 wake_up = 0;
2355 receiveDTIMs = 0;
2356 }
2357 break;
2358 default:
2359 mode = POWER_ACTIVE;
2360 wake_up = 0;
2361 receiveDTIMs = 0;
2362 break;
2363 }
2364 hostif_power_mngmt_request(priv, mode, wake_up, receiveDTIMs);
2365
2366 return;
2367}
2368
2369static
feedcf1a 2370void hostif_sme_sleep_set(struct ks_wlan_private *priv)
13a9930d 2371{
20c4f9c5
WS
2372 DPRINTK(3, "\n");
2373 switch (priv->sleep_mode) {
13a9930d
WS
2374 case SLP_SLEEP:
2375 hostif_sleep_request(priv, priv->sleep_mode);
2376 break;
2377 case SLP_ACTIVE:
2378 hostif_sleep_request(priv, priv->sleep_mode);
2379 break;
2380 default:
2381 break;
2382 }
2383
2384 return;
2385}
2386
2387static
feedcf1a 2388void hostif_sme_set_key(struct ks_wlan_private *priv, int type)
13a9930d
WS
2389{
2390 uint32_t val;
20c4f9c5 2391 switch (type) {
13a9930d 2392 case SME_SET_FLAG:
20c4f9c5 2393 val = cpu_to_le32((uint32_t) (priv->reg.privacy_invoked));
13a9930d 2394 hostif_mib_set_request(priv, DOT11_PRIVACY_INVOKED,
20c4f9c5 2395 sizeof(val), MIB_VALUE_TYPE_BOOL, &val);
13a9930d
WS
2396 break;
2397 case SME_SET_TXKEY:
20c4f9c5 2398 val = cpu_to_le32((uint32_t) (priv->wpa.txkey));
13a9930d 2399 hostif_mib_set_request(priv, DOT11_WEP_DEFAULT_KEY_ID,
20c4f9c5 2400 sizeof(val), MIB_VALUE_TYPE_INT, &val);
13a9930d
WS
2401 break;
2402 case SME_SET_KEY1:
2403 hostif_mib_set_request(priv, DOT11_WEP_DEFAULT_KEY_VALUE1,
20c4f9c5
WS
2404 priv->wpa.key[0].key_len,
2405 MIB_VALUE_TYPE_OSTRING,
2406 &priv->wpa.key[0].key_val[0]);
13a9930d
WS
2407 break;
2408 case SME_SET_KEY2:
2409 hostif_mib_set_request(priv, DOT11_WEP_DEFAULT_KEY_VALUE2,
20c4f9c5
WS
2410 priv->wpa.key[1].key_len,
2411 MIB_VALUE_TYPE_OSTRING,
2412 &priv->wpa.key[1].key_val[0]);
13a9930d
WS
2413 break;
2414 case SME_SET_KEY3:
2415 hostif_mib_set_request(priv, DOT11_WEP_DEFAULT_KEY_VALUE3,
20c4f9c5
WS
2416 priv->wpa.key[2].key_len,
2417 MIB_VALUE_TYPE_OSTRING,
2418 &priv->wpa.key[2].key_val[0]);
13a9930d
WS
2419 break;
2420 case SME_SET_KEY4:
2421 hostif_mib_set_request(priv, DOT11_WEP_DEFAULT_KEY_VALUE4,
20c4f9c5
WS
2422 priv->wpa.key[3].key_len,
2423 MIB_VALUE_TYPE_OSTRING,
2424 &priv->wpa.key[3].key_val[0]);
13a9930d
WS
2425 break;
2426 case SME_SET_PMK_TSC:
2427 hostif_mib_set_request(priv, DOT11_PMK_TSC,
2428 WPA_RX_SEQ_LEN, MIB_VALUE_TYPE_OSTRING,
20c4f9c5 2429 &priv->wpa.key[0].rx_seq[0]);
13a9930d
WS
2430 break;
2431 case SME_SET_GMK1_TSC:
2432 hostif_mib_set_request(priv, DOT11_GMK1_TSC,
2433 WPA_RX_SEQ_LEN, MIB_VALUE_TYPE_OSTRING,
20c4f9c5 2434 &priv->wpa.key[1].rx_seq[0]);
13a9930d
WS
2435 break;
2436 case SME_SET_GMK2_TSC:
2437 hostif_mib_set_request(priv, DOT11_GMK2_TSC,
2438 WPA_RX_SEQ_LEN, MIB_VALUE_TYPE_OSTRING,
20c4f9c5 2439 &priv->wpa.key[2].rx_seq[0]);
13a9930d
WS
2440 break;
2441 }
2442 return;
2443}
2444
2445static
feedcf1a 2446void hostif_sme_set_pmksa(struct ks_wlan_private *priv)
13a9930d
WS
2447{
2448 struct pmk_cache_t {
2449 uint16_t size;
2450 struct {
20c4f9c5
WS
2451 uint8_t bssid[ETH_ALEN];
2452 uint8_t pmkid[IW_PMKID_LEN];
2453 } __attribute__ ((packed)) list[PMK_LIST_MAX];
2454 } __attribute__ ((packed)) pmkcache;
13a9930d
WS
2455 struct pmk_t *pmk;
2456 struct list_head *ptr;
2457 int i;
2458
20c4f9c5
WS
2459 DPRINTK(4, "pmklist.size=%d\n", priv->pmklist.size);
2460 i = 0;
2461 list_for_each(ptr, &priv->pmklist.head) {
13a9930d 2462 pmk = list_entry(ptr, struct pmk_t, list);
20c4f9c5 2463 if (i < PMK_LIST_MAX) {
13a9930d 2464 memcpy(pmkcache.list[i].bssid, pmk->bssid, ETH_ALEN);
20c4f9c5
WS
2465 memcpy(pmkcache.list[i].pmkid, pmk->pmkid,
2466 IW_PMKID_LEN);
13a9930d
WS
2467 i++;
2468 }
2469 }
20c4f9c5 2470 pmkcache.size = cpu_to_le16((uint16_t) (priv->pmklist.size));
13a9930d 2471 hostif_mib_set_request(priv, LOCAL_PMK,
20c4f9c5
WS
2472 sizeof(priv->pmklist.size) + (ETH_ALEN +
2473 IW_PMKID_LEN) *
2474 (priv->pmklist.size), MIB_VALUE_TYPE_OSTRING,
2475 &pmkcache);
13a9930d
WS
2476}
2477
2478/* execute sme */
2479static
feedcf1a 2480void hostif_sme_execute(struct ks_wlan_private *priv, int event)
13a9930d
WS
2481{
2482 uint32_t val;
2483
20c4f9c5 2484 DPRINTK(3, "event=%d\n", event);
13a9930d
WS
2485 switch (event) {
2486 case SME_START:
20c4f9c5 2487 if (priv->dev_state == DEVICE_STATE_BOOT) {
13a9930d
WS
2488 hostif_mib_get_request(priv, DOT11_MAC_ADDRESS);
2489 }
2490 break;
2491 case SME_MULTICAST_REQUEST:
2492 hostif_sme_multicast_set(priv);
2493 break;
2494 case SME_MACADDRESS_SET_REQUEST:
2495 hostif_mib_set_request(priv, LOCAL_CURRENTADDRESS, ETH_ALEN,
20c4f9c5
WS
2496 MIB_VALUE_TYPE_OSTRING,
2497 &priv->eth_addr[0]);
13a9930d
WS
2498 break;
2499 case SME_BSS_SCAN_REQUEST:
20c4f9c5
WS
2500 hostif_bss_scan_request(priv, priv->reg.scan_type,
2501 priv->scan_ssid, priv->scan_ssid_len);
13a9930d
WS
2502 break;
2503 case SME_POW_MNGMT_REQUEST:
2504 hostif_sme_powermgt_set(priv);
2505 break;
2506 case SME_PHY_INFO_REQUEST:
2507 hostif_phy_information_request(priv);
2508 break;
2509 case SME_MIC_FAILURE_REQUEST:
20c4f9c5
WS
2510 if (priv->wpa.mic_failure.failure == 1) {
2511 hostif_mic_failure_request(priv,
2512 priv->wpa.mic_failure.
2513 failure - 1, 0);
2514 } else if (priv->wpa.mic_failure.failure == 2) {
2515 hostif_mic_failure_request(priv,
2516 priv->wpa.mic_failure.
2517 failure - 1,
2518 priv->wpa.mic_failure.
2519 counter);
2520 } else
2521 DPRINTK(4,
2522 "SME_MIC_FAILURE_REQUEST: failure count=%u error?\n",
13a9930d
WS
2523 priv->wpa.mic_failure.failure);
2524 break;
2525 case SME_MIC_FAILURE_CONFIRM:
20c4f9c5
WS
2526 if (priv->wpa.mic_failure.failure == 2) {
2527 if (priv->wpa.mic_failure.stop)
13a9930d
WS
2528 priv->wpa.mic_failure.stop = 0;
2529 priv->wpa.mic_failure.failure = 0;
20c4f9c5 2530 hostif_start_request(priv, priv->reg.operation_mode);
13a9930d
WS
2531 }
2532 break;
2533 case SME_GET_MAC_ADDRESS:
20c4f9c5 2534 if (priv->dev_state == DEVICE_STATE_BOOT) {
13a9930d
WS
2535 hostif_mib_get_request(priv, DOT11_PRODUCT_VERSION);
2536 }
2537 break;
2538 case SME_GET_PRODUCT_VERSION:
20c4f9c5 2539 if (priv->dev_state == DEVICE_STATE_BOOT) {
13a9930d
WS
2540 priv->dev_state = DEVICE_STATE_PREINIT;
2541 }
2542 break;
2543 case SME_STOP_REQUEST:
2544 hostif_stop_request(priv);
2545 break;
2546 case SME_RTS_THRESHOLD_REQUEST:
20c4f9c5 2547 val = cpu_to_le32((uint32_t) (priv->reg.rts));
13a9930d 2548 hostif_mib_set_request(priv, DOT11_RTS_THRESHOLD,
20c4f9c5 2549 sizeof(val), MIB_VALUE_TYPE_INT, &val);
13a9930d
WS
2550 break;
2551 case SME_FRAGMENTATION_THRESHOLD_REQUEST:
20c4f9c5 2552 val = cpu_to_le32((uint32_t) (priv->reg.fragment));
13a9930d 2553 hostif_mib_set_request(priv, DOT11_FRAGMENTATION_THRESHOLD,
20c4f9c5 2554 sizeof(val), MIB_VALUE_TYPE_INT, &val);
13a9930d 2555 break;
20c4f9c5
WS
2556 case SME_WEP_INDEX_REQUEST:
2557 case SME_WEP_KEY1_REQUEST:
2558 case SME_WEP_KEY2_REQUEST:
2559 case SME_WEP_KEY3_REQUEST:
2560 case SME_WEP_KEY4_REQUEST:
2561 case SME_WEP_FLAG_REQUEST:
2562 hostif_sme_set_wep(priv, event);
13a9930d 2563 break;
20c4f9c5
WS
2564 case SME_RSN_UCAST_REQUEST:
2565 case SME_RSN_MCAST_REQUEST:
2566 case SME_RSN_AUTH_REQUEST:
2567 case SME_RSN_ENABLED_REQUEST:
13a9930d 2568 case SME_RSN_MODE_REQUEST:
20c4f9c5 2569 hostif_sme_set_rsn(priv, event);
13a9930d 2570 break;
20c4f9c5
WS
2571 case SME_SET_FLAG:
2572 case SME_SET_TXKEY:
2573 case SME_SET_KEY1:
2574 case SME_SET_KEY2:
2575 case SME_SET_KEY3:
2576 case SME_SET_KEY4:
2577 case SME_SET_PMK_TSC:
2578 case SME_SET_GMK1_TSC:
13a9930d 2579 case SME_SET_GMK2_TSC:
20c4f9c5 2580 hostif_sme_set_key(priv, event);
13a9930d
WS
2581 break;
2582 case SME_SET_PMKSA:
2583 hostif_sme_set_pmksa(priv);
2584 break;
2585#ifdef WPS
2586 case SME_WPS_ENABLE_REQUEST:
2587 hostif_mib_set_request(priv, LOCAL_WPS_ENABLE,
2588 sizeof(priv->wps.wps_enabled),
20c4f9c5
WS
2589 MIB_VALUE_TYPE_INT,
2590 &priv->wps.wps_enabled);
13a9930d
WS
2591 break;
2592 case SME_WPS_PROBE_REQUEST:
2593 hostif_mib_set_request(priv, LOCAL_WPS_PROBE_REQ,
2594 priv->wps.ielen,
2595 MIB_VALUE_TYPE_OSTRING, priv->wps.ie);
2596 break;
2597#endif /* WPS */
2598 case SME_MODE_SET_REQUEST:
2599 hostif_sme_mode_setup(priv);
2600 break;
2601 case SME_SET_GAIN:
2602 hostif_mib_set_request(priv, LOCAL_GAIN,
20c4f9c5
WS
2603 sizeof(priv->gain),
2604 MIB_VALUE_TYPE_OSTRING, &priv->gain);
13a9930d
WS
2605 break;
2606 case SME_GET_GAIN:
2607 hostif_mib_get_request(priv, LOCAL_GAIN);
2608 break;
2609 case SME_GET_EEPROM_CKSUM:
2610 priv->eeprom_checksum = EEPROM_FW_NOT_SUPPORT; /* initialize */
2611 hostif_mib_get_request(priv, LOCAL_EEPROM_SUM);
2612 break;
2613 case SME_START_REQUEST:
20c4f9c5 2614 hostif_start_request(priv, priv->reg.operation_mode);
13a9930d
WS
2615 break;
2616 case SME_START_CONFIRM:
2617 /* for power save */
2618 atomic_set(&priv->psstatus.snooze_guard, 0);
20c4f9c5
WS
2619 atomic_set(&priv->psstatus.confirm_wait, 0);
2620 if (priv->dev_state == DEVICE_STATE_PREINIT) {
13a9930d
WS
2621 priv->dev_state = DEVICE_STATE_INIT;
2622 }
2623 /* wake_up_interruptible_all(&priv->confirm_wait); */
2624 complete(&priv->confirm_wait);
2625 break;
2626 case SME_SLEEP_REQUEST:
2627 hostif_sme_sleep_set(priv);
2628 break;
2629 case SME_SET_REGION:
20c4f9c5 2630 val = cpu_to_le32((uint32_t) (priv->region));
13a9930d 2631 hostif_mib_set_request(priv, LOCAL_REGION,
20c4f9c5 2632 sizeof(val), MIB_VALUE_TYPE_INT, &val);
13a9930d
WS
2633 break;
2634 case SME_MULTICAST_CONFIRM:
2635 case SME_BSS_SCAN_CONFIRM:
2636 case SME_POW_MNGMT_CONFIRM:
2637 case SME_PHY_INFO_CONFIRM:
2638 case SME_STOP_CONFIRM:
2639 case SME_RTS_THRESHOLD_CONFIRM:
2640 case SME_FRAGMENTATION_THRESHOLD_CONFIRM:
20c4f9c5
WS
2641 case SME_WEP_INDEX_CONFIRM:
2642 case SME_WEP_KEY1_CONFIRM:
2643 case SME_WEP_KEY2_CONFIRM:
2644 case SME_WEP_KEY3_CONFIRM:
2645 case SME_WEP_KEY4_CONFIRM:
2646 case SME_WEP_FLAG_CONFIRM:
2647 case SME_RSN_UCAST_CONFIRM:
2648 case SME_RSN_MCAST_CONFIRM:
2649 case SME_RSN_AUTH_CONFIRM:
2650 case SME_RSN_ENABLED_CONFIRM:
13a9930d
WS
2651 case SME_RSN_MODE_CONFIRM:
2652 case SME_MODE_SET_CONFIRM:
2653 break;
2654 case SME_TERMINATE:
2655 default:
2656 break;
2657 }
2658}
2659
2660static
20c4f9c5 2661void hostif_sme_task(unsigned long dev)
13a9930d 2662{
feedcf1a 2663 struct ks_wlan_private *priv = (struct ks_wlan_private *)dev;
13a9930d 2664
20c4f9c5 2665 DPRINTK(3, "\n");
13a9930d 2666
20c4f9c5
WS
2667 if (priv->dev_state >= DEVICE_STATE_BOOT) {
2668 if (0 < cnt_smeqbody(priv)
2669 && priv->dev_state >= DEVICE_STATE_BOOT) {
2670 hostif_sme_execute(priv,
2671 priv->sme_i.event_buff[priv->sme_i.
2672 qhead]);
13a9930d
WS
2673 inc_smeqhead(priv);
2674 if (0 < cnt_smeqbody(priv))
20c4f9c5 2675 tasklet_schedule(&priv->sme_task);
13a9930d
WS
2676 }
2677 }
2678 return;
2679}
2680
2681/* send to Station Management Entity module */
feedcf1a 2682void hostif_sme_enqueue(struct ks_wlan_private *priv, unsigned short event)
13a9930d 2683{
20c4f9c5 2684 DPRINTK(3, "\n");
13a9930d
WS
2685
2686 /* enqueue sme event */
2687 if (cnt_smeqbody(priv) < (SME_EVENT_BUFF_SIZE - 1)) {
2688 priv->sme_i.event_buff[priv->sme_i.qtail] = event;
2689 inc_smeqtail(priv);
2690 //DPRINTK(3,"inc_smeqtail \n");
2691#ifdef KS_WLAN_DEBUG
2692 if (priv->sme_i.max_event_count < cnt_smeqbody(priv))
2693 priv->sme_i.max_event_count = cnt_smeqbody(priv);
2694#endif /* KS_WLAN_DEBUG */
2695 } else {
2696 /* in case of buffer overflow */
2697 //DPRINTK(2,"sme queue buffer overflow\n");
2698 printk("sme queue buffer overflow\n");
2699 }
2700
2701 tasklet_schedule(&priv->sme_task);
2702
2703}
2704
20c4f9c5 2705int hostif_init(struct ks_wlan_private *priv)
13a9930d 2706{
20c4f9c5 2707 int rc = 0;
13a9930d
WS
2708 int i;
2709
20c4f9c5 2710 DPRINTK(3, "\n");
13a9930d 2711
20c4f9c5
WS
2712 priv->aplist.size = 0;
2713 for (i = 0; i < LOCAL_APLIST_MAX; i++)
2714 memset(&(priv->aplist.ap[i]), 0, sizeof(struct local_ap_t));
13a9930d
WS
2715 priv->infra_status = 0;
2716 priv->current_rate = 4;
2717 priv->connect_status = DISCONNECT_STATUS;
2718
2719 spin_lock_init(&priv->multicast_spin);
2720
2721 spin_lock_init(&priv->dev_read_lock);
20c4f9c5 2722 init_waitqueue_head(&priv->devread_wait);
13a9930d
WS
2723 priv->dev_count = 0;
2724 atomic_set(&priv->event_count, 0);
2725 atomic_set(&priv->rec_count, 0);
2726
2727 /* for power save */
2728 atomic_set(&priv->psstatus.status, PS_NONE);
2729 atomic_set(&priv->psstatus.confirm_wait, 0);
2730 atomic_set(&priv->psstatus.snooze_guard, 0);
2731 /* init_waitqueue_head(&priv->psstatus.wakeup_wait); */
2732 init_completion(&priv->psstatus.wakeup_wait);
2733 //INIT_WORK(&priv->ks_wlan_wakeup_task, ks_wlan_hw_wakeup_task, (void *)priv);
2734 INIT_WORK(&priv->ks_wlan_wakeup_task, ks_wlan_hw_wakeup_task);
2735
2736 /* WPA */
2737 memset(&(priv->wpa), 0, sizeof(priv->wpa));
2738 priv->wpa.rsn_enabled = 0;
2739 priv->wpa.mic_failure.failure = 0;
2740 priv->wpa.mic_failure.last_failure_time = 0;
2741 priv->wpa.mic_failure.stop = 0;
2742 memset(&(priv->pmklist), 0, sizeof(priv->pmklist));
2743 INIT_LIST_HEAD(&priv->pmklist.head);
20c4f9c5 2744 for (i = 0; i < PMK_LIST_MAX; i++)
13a9930d
WS
2745 INIT_LIST_HEAD(&priv->pmklist.pmk[i].list);
2746
2747 priv->sme_i.sme_status = SME_IDLE;
2748 priv->sme_i.qhead = priv->sme_i.qtail = 0;
2749#ifdef KS_WLAN_DEBUG
2750 priv->sme_i.max_event_count = 0;
2751#endif
20c4f9c5 2752 spin_lock_init(&priv->sme_i.sme_spin);
13a9930d
WS
2753 priv->sme_i.sme_flag = 0;
2754
2755 tasklet_init(&priv->sme_task, hostif_sme_task, (unsigned long)priv);
2756
2757 return rc;
2758}
2759
20c4f9c5 2760void hostif_exit(struct ks_wlan_private *priv)
13a9930d
WS
2761{
2762 tasklet_kill(&priv->sme_task);
2763 return;
2764}
This page took 0.183716 seconds and 5 git commands to generate.