add rga2 drivers for 64bit platform
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / esp8089 / esp_driver / esp_mac80211.c
1 /*
2  * Copyright (c) 2011-2014 Espressif System.
3  *
4  *     MAC80211 support module
5  */
6
7 #include <linux/etherdevice.h>
8 #include <linux/workqueue.h>
9 #include <linux/nl80211.h>
10 #include <linux/ieee80211.h>
11 #include <linux/slab.h>
12 #include <net/cfg80211.h>
13 #include <net/mac80211.h>
14 #include <linux/version.h>
15 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31))
16 #include <net/regulatory.h>
17 #endif
18 /* for support scan in p2p concurrent */
19 #include <../net/mac80211/ieee80211_i.h>
20 #include "esp_pub.h"
21 #include "esp_sip.h"
22 #include "esp_ctrl.h"
23 #include "esp_sif.h"
24 #include "esp_debug.h"
25 #include "esp_wl.h"
26 #include "esp_utils.h"
27 #include <linux/rfkill-wlan.h>
28
29 #define ESP_IEEE80211_DBG esp_dbg
30
31 #define GET_NEXT_SEQ(seq) (((seq) +1) & 0x0fff)
32
33 #ifdef P2P_CONCURRENT
34 static u8 esp_mac_addr[ETH_ALEN * 2];
35 #endif
36 static u8 getaddr_index(u8 * addr, struct esp_pub *epub);
37
38 static
39 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
40 void
41 esp_op_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, struct sk_buff *skb)
42 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39))
43 void
44 esp_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
45 #else
46 int
47 esp_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
48 #endif /* NEW_KERNEL */
49 {
50         struct esp_pub *epub = (struct esp_pub *)hw->priv;
51
52         ESP_IEEE80211_DBG(ESP_DBG_LOG, "%s enter\n", __func__);
53         if (!mod_support_no_txampdu() &&
54 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
55                         cfg80211_get_chandef_type(&epub->hw->conf.chandef) != NL80211_CHAN_NO_HT
56 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29))
57                         hw->conf.channel_type != NL80211_CHAN_NO_HT
58 #else
59                         !(hw->conf.flags&IEEE80211_CONF_SUPPORT_HT_MODE)
60 #endif                
61            ) {
62                 struct ieee80211_tx_info * tx_info = IEEE80211_SKB_CB(skb);
63                 struct ieee80211_hdr * wh = (struct ieee80211_hdr *)skb->data;
64                 if(ieee80211_is_data_qos(wh->frame_control)) {
65                         if(!(tx_info->flags & IEEE80211_TX_CTL_AMPDU)) {
66                                 u8 tidno = ieee80211_get_qos_ctl(wh)[0] & IEEE80211_QOS_CTL_TID_MASK;
67 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
68                                 struct esp_node * node = esp_get_node_by_addr(epub, wh->addr1);
69 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))
70                                 struct ieee80211_sta *sta = tx_info->control.sta;
71                                 struct esp_node * node = (struct esp_node *)sta->drv_priv;
72                                 if(sta->ht_cap.ht_supported)
73 #else
74                                 struct esp_node * node = esp_get_node_by_addr(epub, wh->addr1);
75                                 if(node->ht_info.ht_supported)
76 #endif
77                                 {
78                                         struct esp_tx_tid *tid = &node->tid[tidno];
79                                         //record ssn
80                                         spin_lock_bh(&epub->tx_ampdu_lock);
81                                         tid->ssn = GET_NEXT_SEQ(le16_to_cpu(wh->seq_ctrl)>>4);
82                                         ESP_IEEE80211_DBG(ESP_DBG_TRACE, "tidno:%u,ssn:%u\n", tidno, tid->ssn);
83                                         spin_unlock_bh(&epub->tx_ampdu_lock);
84                                 }
85                         } else {
86                                 ESP_IEEE80211_DBG(ESP_DBG_TRACE, "tx ampdu pkt, sn:%u, %u\n", le16_to_cpu(wh->seq_ctrl)>>4, skb->len);
87                         }
88                 }
89         }
90
91 #ifdef GEN_ERR_CHECKSUM
92         esp_gen_err_checksum(skb);
93 #endif
94
95         sip_tx_data_pkt_enqueue(epub, skb);
96         if (epub)
97 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32))
98                 ieee80211_queue_work(hw, &epub->tx_work);
99 #else
100                 queue_work(hw->workqueue,&epub->tx_work);    
101 #endif
102 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39))
103         return NETDEV_TX_OK;
104 #endif /*2.6.39*/
105 }
106
107 static int esp_op_start(struct ieee80211_hw *hw)
108 {
109         struct esp_pub *epub;
110
111         ESP_IEEE80211_DBG(ESP_DBG_OP, "%s\n", __func__);
112
113         if (!hw) {
114                 ESP_IEEE80211_DBG(ESP_DBG_ERROR, "%s no hw!\n", __func__);
115                 return -EINVAL;
116         }
117
118         epub = (struct esp_pub *)hw->priv;
119
120         if (!epub) {
121                 ESP_IEEE80211_DBG(ESP_DBG_ERROR, "%s no epub!\n", __func__);
122                 return EINVAL;
123         }
124         /*add rfkill poll function*/
125
126         atomic_set(&epub->wl.off, 0);
127 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31))
128         wiphy_rfkill_start_polling(hw->wiphy);
129 #endif
130         return 0;
131 }
132
133 static void esp_op_stop(struct ieee80211_hw *hw)
134 {
135         struct esp_pub *epub;
136
137         ESP_IEEE80211_DBG(ESP_DBG_OP, "%s\n", __func__);
138
139         if (!hw) {
140                 ESP_IEEE80211_DBG(ESP_DBG_ERROR, "%s no hw!\n", __func__);
141                 return;
142         }
143
144         epub = (struct esp_pub *)hw->priv;
145
146         if (!epub) {
147                 ESP_IEEE80211_DBG(ESP_DBG_ERROR, "%s no epub!\n", __func__);
148                 return;
149         }
150
151         atomic_set(&epub->wl.off, 1);
152
153 #ifdef HOST_RESET_BUG
154         mdelay(200);
155 #endif
156
157         if (epub->wl.scan_req) {
158                 hw_scan_done(epub, true);
159                 epub->wl.scan_req=NULL;
160                 //msleep(2);
161         }
162 }
163
164 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39))        
165 #ifdef CONFIG_PM
166 static int esp_op_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
167 {
168         esp_dbg(ESP_DBG_OP, "%s\n", __func__);
169
170         return 0;
171 }
172
173 static int esp_op_resume(struct ieee80211_hw *hw)
174 {
175         esp_dbg(ESP_DBG_OP, "%s\n", __func__);
176
177         return 0;
178 }
179 #endif //CONFIG_PM
180 #endif
181
182 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 34))
183 static int esp_op_add_interface(struct ieee80211_hw *hw,
184                 struct ieee80211_if_init_conf *conf)
185 #else
186 static int esp_op_add_interface(struct ieee80211_hw *hw,
187                 struct ieee80211_vif *vif)
188 #endif
189 {
190         struct esp_pub *epub = (struct esp_pub *)hw->priv;
191 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 34))
192         struct ieee80211_vif *vif = conf->vif;
193 #endif
194         struct esp_vif *evif = (struct esp_vif *)vif->drv_priv;
195         struct sip_cmd_setvif svif;
196
197 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 34))
198         ESP_IEEE80211_DBG(ESP_DBG_OP, "%s enter: type %d, addr %pM\n", __func__, vif->type, conf->mac_addr);
199 #else
200         ESP_IEEE80211_DBG(ESP_DBG_OP, "%s enter: type %d, addr %pM\n", __func__, vif->type, vif->addr);
201 #endif
202
203         memset(&svif, 0, sizeof(struct sip_cmd_setvif));
204 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 34))
205         memcpy(svif.mac, conf->mac_addr, ETH_ALEN);
206         evif->index = svif.index = getaddr_index(conf->mac_addr, epub);
207 #else
208         memcpy(svif.mac, vif->addr, ETH_ALEN);
209         evif->index = svif.index = getaddr_index(vif->addr, epub);
210 #endif
211         evif->epub = epub;
212         epub->vif = vif;
213         svif.set = 1;
214         if((1 << svif.index) & epub->vif_slot){
215                 ESP_IEEE80211_DBG(ESP_DBG_ERROR, "%s interface %d already used\n", __func__, svif.index);
216                 return -EOPNOTSUPP;
217         }
218         epub->vif_slot |= 1 << svif.index;
219
220         if (svif.index == ESP_PUB_MAX_VIF) {
221                 ESP_IEEE80211_DBG(ESP_DBG_ERROR, "%s only support MAX %d interface\n", __func__, ESP_PUB_MAX_VIF);
222                 return -EOPNOTSUPP;
223         }
224
225         switch (vif->type) {
226                 case NL80211_IFTYPE_STATION:
227                         //if (svif.index == 1)
228                         //      vif->type = NL80211_IFTYPE_UNSPECIFIED;
229                         ESP_IEEE80211_DBG(ESP_SHOW, "%s STA \n", __func__);
230                         svif.op_mode = 0;
231                         svif.is_p2p = 0;
232                         break;
233                 case NL80211_IFTYPE_AP:
234                         ESP_IEEE80211_DBG(ESP_SHOW, "%s AP \n", __func__);
235                         svif.op_mode = 1;
236                         svif.is_p2p = 0;
237                         break;
238 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
239                 case NL80211_IFTYPE_P2P_CLIENT:
240                         ESP_IEEE80211_DBG(ESP_SHOW, "%s P2P_CLIENT \n", __func__);
241                         svif.op_mode = 0;
242                         svif.is_p2p = 1;
243                         break;
244                 case NL80211_IFTYPE_P2P_GO:
245                         ESP_IEEE80211_DBG(ESP_SHOW, "%s P2P_GO \n", __func__);
246                         svif.op_mode = 1;
247                         svif.is_p2p = 1;
248                         break;
249 #endif
250                 case NL80211_IFTYPE_UNSPECIFIED:
251                 case NL80211_IFTYPE_ADHOC:
252                 case NL80211_IFTYPE_AP_VLAN:
253                 case NL80211_IFTYPE_WDS:
254                 case NL80211_IFTYPE_MONITOR:
255                 default:
256                         ESP_IEEE80211_DBG(ESP_DBG_ERROR, "%s does NOT support type %d\n", __func__, vif->type);
257                         return -EOPNOTSUPP;
258         }
259
260         sip_cmd(epub, SIP_CMD_SETVIF, (u8 *)&svif, sizeof(struct sip_cmd_setvif));
261         return 0;
262 }
263
264 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
265 static int esp_op_change_interface(struct ieee80211_hw *hw,
266                                    struct ieee80211_vif *vif,
267                                    enum nl80211_iftype new_type, bool p2p)
268 {
269         struct esp_pub *epub = (struct esp_pub *)hw->priv;
270         struct esp_vif *evif = (struct esp_vif *)vif->drv_priv;
271         struct sip_cmd_setvif svif;
272         ESP_IEEE80211_DBG(ESP_DBG_OP, "%s enter,change to if:%d \n", __func__, new_type);
273         
274         if (new_type == NL80211_IFTYPE_AP) {
275                 ESP_IEEE80211_DBG(ESP_SHOW, "%s enter,change to AP \n", __func__);
276         }
277
278         if (vif->type != new_type) {
279                 ESP_IEEE80211_DBG(ESP_SHOW, "%s type from %d to %d\n", __func__, vif->type, new_type);
280         }
281         
282         memset(&svif, 0, sizeof(struct sip_cmd_setvif));
283         memcpy(svif.mac, vif->addr, ETH_ALEN);
284         svif.index = evif->index;
285         svif.set = 2;
286         
287         switch (new_type) {
288         case NL80211_IFTYPE_STATION:
289                 svif.op_mode = 0;
290                 svif.is_p2p = p2p;
291                 break;
292         case NL80211_IFTYPE_AP:
293                 svif.op_mode = 1;
294                 svif.is_p2p = p2p;
295                 break;
296         case NL80211_IFTYPE_P2P_CLIENT:
297                 svif.op_mode = 0;
298                 svif.is_p2p = 1;
299                 break;
300         case NL80211_IFTYPE_P2P_GO:
301                 svif.op_mode = 1;
302                 svif.is_p2p = 1;
303                 break;
304         case NL80211_IFTYPE_UNSPECIFIED:
305         case NL80211_IFTYPE_ADHOC:
306         case NL80211_IFTYPE_AP_VLAN:
307         case NL80211_IFTYPE_WDS:
308         case NL80211_IFTYPE_MONITOR:
309         default:
310                 ESP_IEEE80211_DBG(ESP_DBG_ERROR, "%s does NOT support type %d\n", __func__, vif->type);
311                 return -EOPNOTSUPP;
312         }
313         sip_cmd(epub, SIP_CMD_SETVIF, (u8 *)&svif, sizeof(struct sip_cmd_setvif));
314         return 0;
315 }
316 #endif
317
318 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 34))
319 static void esp_op_remove_interface(struct ieee80211_hw *hw,
320                                     struct ieee80211_if_init_conf *conf)
321 #else
322 static void esp_op_remove_interface(struct ieee80211_hw *hw,
323                                     struct ieee80211_vif *vif)
324 #endif
325 {
326         struct esp_pub *epub = (struct esp_pub *)hw->priv;
327 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 34))
328         struct ieee80211_vif *vif = conf->vif;
329 #endif
330         struct esp_vif *evif = (struct esp_vif *)vif->drv_priv;
331         struct sip_cmd_setvif svif;
332
333 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 30))
334         ESP_IEEE80211_DBG(ESP_DBG_OP, "%s enter, vif addr %pM\n", __func__, conf->mac_addr);
335 #elif (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 34))
336         ESP_IEEE80211_DBG(ESP_DBG_OP, "%s enter, vif addr %pM, beacon enable %x\n", __func__, conf->mac_addr, vif->bss_conf.enable_beacon);
337 #else
338         ESP_IEEE80211_DBG(ESP_DBG_OP, "%s enter, vif addr %pM, beacon enable %x\n", __func__, vif->addr, vif->bss_conf.enable_beacon);
339 #endif
340
341         memset(&svif, 0, sizeof(struct sip_cmd_setvif));
342         svif.index = evif->index;
343         epub->vif_slot &= ~(1 << svif.index);
344
345         if(evif->ap_up){
346                 evif->beacon_interval = 0;
347                 del_timer_sync(&evif->beacon_timer);
348                 evif->ap_up = false;
349         }
350         epub->vif = NULL;
351         evif->epub = NULL;
352
353         sip_cmd(epub, SIP_CMD_SETVIF, (u8 *)&svif, sizeof(struct sip_cmd_setvif));
354
355         /* clean up tx/rx queue */
356
357 }
358
359 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29))
360 #define BEACON_TIM_SAVE_MAX 20
361 u8 beacon_tim_saved[BEACON_TIM_SAVE_MAX];
362 int beacon_tim_count;
363 static void beacon_tim_init(void)
364 {
365         memset(beacon_tim_saved, BEACON_TIM_SAVE_MAX, 0);
366         beacon_tim_count = 0;
367 }
368
369 static u8 beacon_tim_save(u8 this_tim)
370 {
371         u8 all_tim = 0;
372         int i;
373         beacon_tim_saved[beacon_tim_count] = this_tim;
374         if(++beacon_tim_count >= BEACON_TIM_SAVE_MAX)
375                 beacon_tim_count = 0;
376         for(i = 0; i < BEACON_TIM_SAVE_MAX; i++)
377                 all_tim |= beacon_tim_saved[i];
378         return all_tim;
379 }
380
381 static bool beacon_tim_alter(struct sk_buff *beacon)
382 {
383         u8 *p, *tim_end;
384         u8 tim_count;
385         int len;
386         int remain_len;
387         struct ieee80211_mgmt * mgmt;
388
389         if (beacon == NULL)
390                 return false;
391
392         mgmt = (struct ieee80211_mgmt *)((u8 *)beacon->data);
393
394         remain_len = beacon->len - ((u8 *)mgmt->u.beacon.variable - (u8 *)mgmt + 12);
395         p = mgmt->u.beacon.variable;
396
397         while (remain_len > 0) {
398                 len = *(++p);
399                 if (*p == WLAN_EID_TIM) {       // tim field
400                         tim_end = p + len;
401                         tim_count = *(++p);
402                         p += 2;
403                         //multicast
404                         if(tim_count == 0)
405                             *p |= 0x1;
406                         if((*p & 0xfe) == 0 && tim_end >= p+1){// we only support 8 sta in this case
407                                 p++;
408                                 *p = beacon_tim_save(*p);
409                         }
410                         return tim_count == 0;
411                 }
412                 p += (len + 1);
413                 remain_len -= (2 + len);
414         }
415
416         return false;
417 }
418
419 unsigned long init_jiffies;
420 unsigned long cycle_beacon_count;
421 static void drv_handle_beacon(unsigned long data)
422 {
423         struct ieee80211_vif *vif = (struct ieee80211_vif *) data;
424         struct esp_vif *evif = (struct esp_vif *)vif->drv_priv;
425         struct sk_buff *beacon;
426         struct sk_buff *skb;
427         static int dbgcnt = 0;
428         bool tim_reach = false;
429
430         if(evif->epub == NULL)
431                 return;
432
433         mdelay(2400 * (cycle_beacon_count % 25) % 10000 /1000);
434         
435         beacon = ieee80211_beacon_get(evif->epub->hw, vif);
436
437         tim_reach = beacon_tim_alter(beacon);
438
439         if (beacon && !(dbgcnt++ % 600)) {
440                 ESP_IEEE80211_DBG(ESP_SHOW, " beacon length:%d,fc:0x%x\n", beacon->len,
441                         ((struct ieee80211_mgmt *)(beacon->data))->frame_control);
442
443         }
444
445         if(beacon)
446                 sip_tx_data_pkt_enqueue(evif->epub, beacon);
447
448         if(cycle_beacon_count++ == 100){
449                 init_jiffies = jiffies;
450                 cycle_beacon_count -= 100;
451         }
452 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))    
453         mod_timer(&evif->beacon_timer, init_jiffies + msecs_to_jiffies(cycle_beacon_count * vif->bss_conf.beacon_int*1024/1000));
454 #else
455         mod_timer(&evif->beacon_timer, init_jiffies +msecs_to_jiffies(cycle_beacon_count * evif->beacon_interval*1024/1000));
456 #endif
457         //FIXME:the packets must be sent at home channel
458         //send buffer mcast frames
459         if(tim_reach){
460                 skb = ieee80211_get_buffered_bc(evif->epub->hw, vif);
461                 while (skb) {
462                         sip_tx_data_pkt_enqueue(evif->epub, skb);
463                         skb = ieee80211_get_buffered_bc(evif->epub->hw, vif);
464                 }
465         }
466 }
467
468 static void init_beacon_timer(struct ieee80211_vif *vif)
469 {
470         struct esp_vif *evif = (struct esp_vif *)vif->drv_priv;
471
472         ESP_IEEE80211_DBG(ESP_DBG_OP, " %s enter: beacon interval %x\n", __func__, evif->beacon_interval);
473
474         beacon_tim_init();
475         init_timer(&evif->beacon_timer);  //TBD, not init here...
476         cycle_beacon_count = 1;
477         init_jiffies = jiffies;
478 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))
479         evif->beacon_timer.expires = init_jiffies + msecs_to_jiffies(cycle_beacon_count * vif->bss_conf.beacon_int*1024/1000);
480 #else
481         evif->beacon_timer.expires = init_jiffies + msecs_to_jiffies(cycle_beacon_count * evif->beacon_interval*1024/1000);
482 #endif
483         evif->beacon_timer.data = (unsigned long) vif;
484         evif->beacon_timer.function = drv_handle_beacon;
485         add_timer(&evif->beacon_timer);
486 }
487 #endif
488
489 /*
490 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))
491     static void init_beacon_timer(struct ieee80211_vif *vif)
492 #else
493     static void init_beacon_timer(struct ieee80211_conf *conf)
494 #endif
495 {
496         struct esp_vif *evif = (struct esp_vif *)vif->drv_priv;
497 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))
498         ESP_IEEE80211_DBG(ESP_DBG_OP, " %s enter: beacon interval %x\n", __func__, vif->bss_conf.beacon_int);
499 #else
500         ESP_IEEE80211_DBG(ESP_DBG_OP, " %s enter: beacon interval %x\n", __func__, conf->beacon_int);
501 #endif
502         init_timer(&evif->beacon_timer);  //TBD, not init here...
503 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))
504         evif->beacon_timer.expires=jiffies+msecs_to_jiffies(vif->bss_conf.beacon_int*102/100);
505         evif->beacon_timer.data = (unsigned long) vif;
506 #else
507         evif->beacon_timer.expires=jiffies+msecs_to_jiffies(conf->beacon_int*102/100);
508         evif->beacon_timer.data = (unsigned long) conf;
509 #endif
510         //evif->beacon_timer.data = (unsigned long) vif;
511         evif->beacon_timer.function = drv_handle_beacon;
512         add_timer(&evif->beacon_timer);
513 }
514 */
515
516 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29))
517 static int esp_op_config(struct ieee80211_hw *hw, u32 changed)
518 #else
519 static int esp_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
520 #endif
521 {
522         //struct ieee80211_conf *conf = &hw->conf;
523
524         struct esp_pub *epub = (struct esp_pub *)hw->priv;
525 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29))
526         //struct esp_vif *evif = (struct esp_vif *)epub->vif->drv_priv;
527 #endif
528
529 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29))
530         ESP_IEEE80211_DBG(ESP_DBG_TRACE, "%s enter 0x%08x\n", __func__, changed);
531
532         if (changed & (IEEE80211_CONF_CHANGE_CHANNEL | IEEE80211_CONF_CHANGE_IDLE)) {
533                 sip_send_config(epub, &hw->conf);
534         }
535 #else
536         ESP_IEEE80211_DBG(ESP_DBG_TRACE, "%s enter 0x%08x\n", __func__, conf->flags);
537         sip_send_config(epub, &hw->conf);
538 #endif
539
540 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29))
541         //evif->beacon_interval = conf->beacon_int;
542         //init_beacon_timer(epub->vif);
543 #endif
544
545
546 #if 0
547         if (changed & IEEE80211_CONF_CHANGE_PS) {
548                 struct esp_ps *ps = &epub->ps;
549
550                 ps->dtim_period = conf->ps_dtim_period;
551                 ps->max_sleep_period = conf->max_sleep_period;
552                 esp_ps_config(epub, ps, (conf->flags & IEEE80211_CONF_PS));
553         }
554 #endif
555     return 0;
556 }
557
558 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28))
559 static int esp_op_config_interface (struct ieee80211_hw *hw, 
560                                     struct ieee80211_vif *vif,
561                                     struct ieee80211_if_conf *conf)
562 {
563         // assoc = 2 means AP
564         struct esp_pub *epub = (struct esp_pub *)hw->priv;
565         struct esp_vif *evif = (struct esp_vif *)vif->drv_priv;
566         //struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
567         ESP_IEEE80211_DBG(ESP_DBG_OP, " %s enter: changed %x, bssid %pM,vif->type = %d\n", __func__, conf->changed, conf->bssid,vif->type);
568
569         if(conf->bssid)
570                 memcpy(epub->wl.bssid, conf->bssid, ETH_ALEN);
571         else
572                 memset(epub->wl.bssid, 0, ETH_ALEN);
573
574         if(vif->type == NL80211_IFTYPE_AP){
575                 if((conf->changed & IEEE80211_IFCC_BEACON)){
576                         sip_send_bss_info_update(epub, evif, (u8*)conf->bssid, 2);
577                         //evif->beacon_interval = conf->beacon_int;
578                 }
579                 else{
580                         ESP_IEEE80211_DBG(ESP_DBG_ERROR, "%s op----1-- mode unspecified\n", __func__);
581                 }
582         }
583         else{
584                 ESP_IEEE80211_DBG(ESP_DBG_ERROR, "%s op----2-- mode unspecified\n", __func__);
585         }
586         return 0;
587 }
588 #endif
589
590 static void esp_op_bss_info_changed(struct ieee80211_hw *hw,
591                                     struct ieee80211_vif *vif,
592                                     struct ieee80211_bss_conf *info,
593                                     u32 changed)
594 {
595         struct esp_pub *epub = (struct esp_pub *)hw->priv;
596         struct esp_vif *evif = (struct esp_vif *)vif->drv_priv;
597 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28))
598
599     struct sta_info *sta;
600     struct esp_node *node;
601     struct ieee80211_ht_info *ht_info;   
602
603     u8 addr_0[ETH_ALEN];
604     memset(addr_0,0,ETH_ALEN);
605
606     ESP_IEEE80211_DBG(ESP_DBG_OP,"%s enter, changed %x\n",__func__,changed);
607
608     if((changed & BSS_CHANGED_ASSOC) && (memcmp(epub->wl.bssid,addr_0, ETH_ALEN)))
609     {
610
611         rcu_read_lock();
612         node = esp_get_node_by_addr(epub, epub->wl.bssid );
613         sta = sta_info_get(container_of(hw,struct ieee80211_local,hw), epub->wl.bssid);
614
615         ht_info = &sta->ht_info;
616         memcpy(node->supp_rates, sta->supp_rates, sizeof(node->supp_rates));
617         memcpy(&node->ht_info.cap, &ht_info->cap, sizeof(node->ht_info.cap));
618         memcpy(&node->ht_info.ht_supported, &ht_info->ht_supported, sizeof(node->ht_info.ht_supported));
619         memcpy(&node->ht_info.ampdu_density, &ht_info->ampdu_density, sizeof(node->ht_info.ampdu_density));
620         memcpy(&node->ht_info.ampdu_factor, &ht_info->ampdu_factor, sizeof(node->ht_info.ampdu_factor));
621         if(sta->aid == 0)
622             memcpy(&node->aid, &info->aid, sizeof(node->aid));
623         else
624             memcpy(&node->aid, &sta->aid, sizeof(node->aid));
625         rcu_read_unlock();
626
627         sip_send_set_sta(epub, evif->index, 1, node, vif, (u8)node->index);
628     }
629 #else
630 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
631         struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
632 #endif
633
634         // ieee80211_bss_conf(include/net/mac80211.h) is included in ieee80211_sub_if_data(net/mac80211/ieee80211_i.h) , does bssid=ieee80211_if_ap's ssid ?
635         // in 2.6.27, ieee80211_sub_if_data has ieee80211_bss_conf while in 2.6.32 ieee80211_sub_if_data don't have ieee80211_bss_conf
636         // in 2.6.27, ieee80211_bss_conf->enable_beacon don't exist, does it mean it support beacon always?
637         // ESP_IEEE80211_DBG(ESP_DBG_OP, " %s enter: vif addr %pM, changed %x, assoc %x, bssid %pM\n", __func__, vif->addr, changed, info->assoc, info->bssid);
638         // sdata->u.sta.bssid
639
640         ESP_IEEE80211_DBG(ESP_DBG_OP, " %s enter: changed %x, assoc %x, bssid %pM\n", __func__, changed, info->assoc, info->bssid);
641
642         if (vif->type == NL80211_IFTYPE_STATION) {
643                 if ((changed & BSS_CHANGED_BSSID) ||
644                                 ((changed & BSS_CHANGED_ASSOC) && (info->assoc)))
645                 {
646                         ESP_IEEE80211_DBG(ESP_DBG_TRACE, " %s STA change bssid or assoc\n", __func__);
647                         evif->beacon_interval = info->aid;
648                         memcpy(epub->wl.bssid, (u8*)info->bssid, ETH_ALEN);
649                         sip_send_bss_info_update(epub, evif, (u8*)info->bssid, info->assoc);
650                 } else if ((changed & BSS_CHANGED_ASSOC) && (!info->assoc)) {
651                         ESP_IEEE80211_DBG(ESP_DBG_TRACE, " %s STA change disassoc\n", __func__);
652                         evif->beacon_interval = 0;
653                         memset(epub->wl.bssid, 0, ETH_ALEN);
654                         sip_send_bss_info_update(epub, evif, (u8*)info->bssid, info->assoc);
655                 } else {
656                         ESP_IEEE80211_DBG(ESP_DBG_TRACE, "%s wrong mode of STA mode\n", __func__);
657                 }
658         } else if (vif->type == NL80211_IFTYPE_AP) {
659                 if ((changed & BSS_CHANGED_BEACON_ENABLED) ||
660                                 (changed & BSS_CHANGED_BEACON_INT)) {
661                         ESP_IEEE80211_DBG(ESP_DBG_TRACE, " %s AP change enable %d, interval is %d, bssid %pM\n", __func__, info->enable_beacon, info->beacon_int, info->bssid);
662                         if (info->enable_beacon && evif->ap_up != true) {
663                                 evif->beacon_interval = info->beacon_int;
664                                 init_beacon_timer(vif);
665                                 sip_send_bss_info_update(epub, evif, (u8*)info->bssid, 2);
666                                 evif->ap_up = true;
667                         } else if (!info->enable_beacon && evif->ap_up &&
668 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
669                     !test_bit(SDATA_STATE_OFFCHANNEL, &sdata->state)
670 #else
671                     true
672 #endif
673                     ) {
674                                 ESP_IEEE80211_DBG(ESP_DBG_TRACE, " %s AP disable beacon, interval is %d\n", __func__, info->beacon_int);
675                                 evif->beacon_interval = 0;
676                                 del_timer_sync(&evif->beacon_timer);
677                                 sip_send_bss_info_update(epub, evif, (u8*)info->bssid, 2);
678                                 evif->ap_up = false;
679                         }
680                 }
681         } else {
682                 ESP_IEEE80211_DBG(ESP_DBG_ERROR, "%s op mode unspecified\n", __func__);
683         }
684 #endif
685 }
686
687
688 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32))
689 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35))
690 static u64 esp_op_prepare_multicast(struct ieee80211_hw *hw,
691                                     int mc_count, struct dev_addr_list *mc_list)
692 {
693         ESP_IEEE80211_DBG(ESP_DBG_TRACE, "%s enter \n", __func__);
694
695         return 0;
696 }
697 #else
698 static u64 esp_op_prepare_multicast(struct ieee80211_hw *hw,
699                                     struct netdev_hw_addr_list *mc_list)
700 {
701         ESP_IEEE80211_DBG(ESP_DBG_TRACE, "%s enter \n", __func__);
702
703         return 0;
704 }
705
706 #endif /* NEW_KERNEL && KERNEL_35 */
707 #endif
708
709 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32))
710 static void esp_op_configure_filter(struct ieee80211_hw *hw,
711                                     unsigned int changed_flags,
712                                     unsigned int *total_flags,
713                                     u64 multicast)
714 #else
715 static void esp_op_configure_filter(struct ieee80211_hw *hw,
716                                     unsigned int changed_flags,
717                                     unsigned int *total_flags,
718                                     int mc_count,
719                                     struct dev_addr_list *mc_list)
720 #endif
721 {
722         struct esp_pub *epub = (struct esp_pub *)hw->priv;
723
724         ESP_IEEE80211_DBG(ESP_DBG_TRACE, "%s enter \n", __func__);
725
726         epub->rx_filter = 0;
727
728         if (*total_flags & FIF_PROMISC_IN_BSS)
729                 epub->rx_filter |= FIF_PROMISC_IN_BSS;
730
731         if (*total_flags & FIF_ALLMULTI)
732                 epub->rx_filter |= FIF_ALLMULTI;
733
734         *total_flags = epub->rx_filter;
735 }
736
737 #if 0
738 static int esp_op_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
739                           bool set)
740 {
741         ESP_IEEE80211_DBG(ESP_DBG_TRACE, "%s enter \n", __func__);
742
743         return 0;
744 }
745 #endif
746
747 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30))
748 static int esp_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
749                           struct ieee80211_vif *vif, struct ieee80211_sta *sta,
750                           struct ieee80211_key_conf *key)
751 #else
752 static int esp_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
753                           const u8 *local_address,const u8 *address,
754                           struct ieee80211_key_conf *key)
755 #endif
756 {
757         u8 i;
758         int  ret;
759         struct esp_pub *epub = (struct esp_pub *)hw->priv;
760 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30))
761         struct esp_vif *evif = (struct esp_vif *)vif->drv_priv;
762         u8 ifidx = evif->index;
763 #else
764         u8 ifidx = getaddr_index((u8 *)(local_address), epub); 
765 #endif
766         u8 *peer_addr,isvalid;
767
768 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
769         ESP_IEEE80211_DBG(ESP_DBG_OP, "%s enter, flags = %x keyindx = %x cmd = %x mac = %pM cipher = %x\n", __func__, key->flags, key->keyidx, cmd, vif->addr, key->cipher);
770 #else
771         ESP_IEEE80211_DBG(ESP_DBG_OP, "%s enter, flags = %x keyindx = %x cmd = %x cipher = %x\n", __func__, key->flags, key->keyidx, cmd, key->alg);
772 #endif
773
774         key->flags= key->flags|IEEE80211_KEY_FLAG_GENERATE_IV;
775
776 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30))
777         if (sta) {
778                 if (memcmp(sta->addr, epub->wl.bssid, ETH_ALEN))
779                         peer_addr = sta->addr;
780                 else
781                         peer_addr = epub->wl.bssid;
782         } else {
783                 peer_addr=epub->wl.bssid;
784         }
785 #else
786         peer_addr = (u8 *)address;
787 #endif
788         isvalid = (cmd==SET_KEY) ? 1 : 0;
789
790 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
791         if ((key->flags&IEEE80211_KEY_FLAG_PAIRWISE) || (key->cipher == WLAN_CIPHER_SUITE_WEP40 || key->cipher == WLAN_CIPHER_SUITE_WEP104))
792 #else
793         if ((key->flags&IEEE80211_KEY_FLAG_PAIRWISE) || (key->alg == ALG_WEP))
794 #endif
795             {
796                 if (isvalid) {
797                         for (i = 0; i < 19; i++) {
798                                 if (epub->hi_map[i].flag == 0) {
799                                         epub->hi_map[i].flag = 1;
800                                         key->hw_key_idx = i + 6;
801                                         memcpy(epub->hi_map[i].mac, peer_addr, ETH_ALEN);
802                                         break;
803                                 }
804                         }
805                 } else {
806                         u8 index = key->hw_key_idx - 6;
807                         epub->hi_map[index].flag = 0;
808                         memset(epub->hi_map[index].mac, 0, ETH_ALEN);
809                 }
810         } else {
811                 if(isvalid){
812                         for(i = 0; i < 2; i++)
813                                 if (epub->low_map[ifidx][i].flag == 0) {
814                                         epub->low_map[ifidx][i].flag = 1;
815                                         key->hw_key_idx = i + ifidx * 2 + 2;
816                                         memcpy(epub->low_map[ifidx][i].mac, peer_addr, ETH_ALEN);
817                                         break;
818                                 }
819                 } else {
820                         u8 index = key->hw_key_idx - 2 - ifidx * 2;
821                                 epub->low_map[ifidx][index].flag = 0;
822                                 memset(epub->low_map[ifidx][index].mac, 0, ETH_ALEN);
823                 }
824                 //key->hw_key_idx = key->keyidx + ifidx * 2 + 1;
825         }
826
827         if (key->hw_key_idx >= 6) {
828                 /*send sub_scan task to target*/
829                 //epub->wl.ptk = (cmd==SET_KEY) ? key : NULL;
830                 if(isvalid)
831                         atomic_inc(&epub->wl.ptk_cnt);
832                 else
833                         atomic_dec(&epub->wl.ptk_cnt);
834 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
835                 if (key->cipher == WLAN_CIPHER_SUITE_WEP40 || key->cipher == WLAN_CIPHER_SUITE_WEP104)
836 #else
837                 if (key->alg == ALG_WEP)
838 #endif
839                 {
840                         if(isvalid)
841                                 atomic_inc(&epub->wl.gtk_cnt);
842                         else
843                                 atomic_dec(&epub->wl.gtk_cnt);
844                 }
845         } else {
846                 /*send sub_scan task to target*/
847                 if(isvalid)
848                         atomic_inc(&epub->wl.gtk_cnt);
849                 else
850                         atomic_dec(&epub->wl.gtk_cnt);
851
852 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
853                 if((key->cipher == WLAN_CIPHER_SUITE_WEP40 || key->cipher == WLAN_CIPHER_SUITE_WEP104))
854 #else
855         if((key->alg == ALG_WEP))
856 #endif
857                 {
858                         if(isvalid)
859                                 atomic_inc(&epub->wl.ptk_cnt);
860                         else
861                                 atomic_dec(&epub->wl.ptk_cnt);
862                         //epub->wl.ptk = (cmd==SET_KEY) ? key : NULL;
863                 }
864         }
865
866         ret = sip_send_setkey(epub, ifidx, peer_addr, key, isvalid);
867
868 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35))
869         if((key->cipher == WLAN_CIPHER_SUITE_TKIP || key->cipher == WLAN_CIPHER_SUITE_TKIP))
870 #else
871         if((key->alg == ALG_TKIP))
872 #endif
873         {
874                 if(ret == 0)
875                         atomic_set(&epub->wl.tkip_key_set, 1);
876         }
877
878         ESP_IEEE80211_DBG(ESP_DBG_OP, "%s exit\n", __func__);
879         return ret;
880 }
881
882 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 34))
883 static void esp_op_update_tkip_key(struct ieee80211_hw *hw,
884                                    struct ieee80211_key_conf *conf, const u8 *address,
885                                    u32 iv32, u16 *phase1key)
886 {
887         ESP_IEEE80211_DBG(ESP_DBG_TRACE, "%s enter \n", __func__);
888
889 }
890 #else
891 static void esp_op_update_tkip_key(struct ieee80211_hw *hw,
892                                    struct ieee80211_vif *vif,
893                                    struct ieee80211_key_conf *conf,
894                                    struct ieee80211_sta *sta,
895                                    u32 iv32, u16 *phase1key)
896 {
897         ESP_IEEE80211_DBG(ESP_DBG_TRACE, "%s enter \n", __func__);
898
899 }
900 #endif /* KERNEL_35 NEW_KERNEL*/
901
902
903 void hw_scan_done(struct esp_pub *epub, bool aborted)
904 {
905         cancel_delayed_work_sync(&epub->scan_timeout_work);
906
907         ESSERT(epub->wl.scan_req != NULL);
908
909 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30))
910         ieee80211_scan_completed(epub->hw, aborted);
911 #else
912         ieee80211_scan_completed(epub->hw);
913 #endif
914         if (test_and_clear_bit(ESP_WL_FLAG_STOP_TXQ, &epub->wl.flags)) {
915                 sip_trigger_txq_process(epub->sip);
916         }
917 }
918
919 static void hw_scan_timeout_report(struct work_struct *work)
920 {
921         struct esp_pub *epub =
922                 container_of(work, struct esp_pub, scan_timeout_work.work);
923         bool aborted;
924
925         ESP_IEEE80211_DBG(ESP_DBG_TRACE, "eagle hw scan done\n");
926
927         if (test_and_clear_bit(ESP_WL_FLAG_STOP_TXQ, &epub->wl.flags)) {
928                 sip_trigger_txq_process(epub->sip);
929         }
930         /*check if normally complete or aborted like timeout/hw error */
931         aborted = (epub->wl.scan_req) ? true : false;
932
933         if (aborted==true) {
934                 epub->wl.scan_req = NULL;
935         }
936
937 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30))
938         ieee80211_scan_completed(epub->hw, aborted);
939 #else
940         ieee80211_scan_completed(epub->hw);
941 #endif  
942 }
943
944 #if 0
945 static void esp_op_sw_scan_start(struct ieee80211_hw *hw)
946 {}
947
948 static void esp_op_sw_scan_complete(struct ieee80211_hw *hw)
949 {
950         ESP_IEEE80211_DBG(ESP_DBG_TRACE, "%s enter \n", __func__);
951 }
952 #endif
953
954 #if 0
955 static int esp_op_get_stats(struct ieee80211_hw *hw,
956                             struct ieee80211_low_level_stats *stats)
957 {
958         ESP_IEEE80211_DBG(ESP_DBG_TRACE, "%s enter \n", __func__);
959
960         return 0;
961 }
962
963 static void esp_op_get_tkip_seq(struct ieee80211_hw *hw, u8 hw_key_idx,
964                                 u32 *iv32, u16 *iv16)
965 {
966         ESP_IEEE80211_DBG(ESP_DBG_TRACE, "%s enter \n", __func__);
967 }
968 #endif
969
970 static int esp_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
971 {
972         ESP_IEEE80211_DBG(ESP_DBG_TRACE, "%s enter \n", __func__);
973
974         return 0;
975 }
976
977 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))
978 static int esp_node_attach(struct ieee80211_hw *hw, u8 ifidx, struct ieee80211_sta *sta)
979 #else
980 static int esp_node_attach(struct ieee80211_hw *hw, u8 ifidx, const u8 *addr)
981 #endif
982 {
983         struct esp_pub *epub = (struct esp_pub *)hw->priv;
984         struct esp_node *node;
985         u8 tidno;
986         struct esp_tx_tid *tid;
987             int i;
988 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28))
989         struct sta_info *info = sta_info_get(container_of(hw,struct ieee80211_local,hw),(u8 *)addr);
990         struct ieee80211_ht_info *ht_info = &info->ht_info;
991 #endif
992
993         spin_lock_bh(&epub->tx_ampdu_lock);
994
995         if(hweight32(epub->enodes_maps[ifidx]) < ESP_PUB_MAX_STA && (i = ffz(epub->enodes_map)) < ESP_PUB_MAX_STA + 1){
996                 epub->enodes_map |= (1 << i);
997                 epub->enodes_maps[ifidx] |= (1 << i);
998 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))
999                 node = (struct esp_node *)sta->drv_priv;
1000                 epub->enodes[i] = node;
1001                 node->sta = sta;
1002 #else
1003                 node = &epub->nodes[i];
1004                 epub->enodes[i] = node;
1005                 memcpy(node->addr, addr, ETH_ALEN);
1006                 memcpy(&node->aid, &info->aid, sizeof(node->aid)); 
1007                 memcpy(node->supp_rates, info->supp_rates, sizeof(node->supp_rates));
1008                 memcpy(&node->ht_info.cap, &ht_info->cap, sizeof(node->ht_info.cap));
1009                 memcpy(&node->ht_info.ht_supported, &ht_info->ht_supported, sizeof(node->ht_info.ht_supported));
1010                 memcpy(&node->ht_info.ampdu_factor, &ht_info->ampdu_factor, sizeof(node->ht_info.ampdu_factor));
1011                 memcpy(&node->ht_info.ampdu_density, &ht_info->ampdu_density, sizeof(node->ht_info.ampdu_density));
1012 #endif
1013                 node->ifidx = ifidx;
1014                 node->index = i;
1015
1016                 for(tidno = 0, tid = &node->tid[tidno]; tidno < WME_NUM_TID; tidno++) {
1017                 tid->ssn = 0;
1018                 tid->cnt = 0;
1019                 tid->state = ESP_TID_STATE_INIT;
1020         }
1021
1022
1023         } else {
1024                 i = -1;
1025         }
1026
1027         spin_unlock_bh(&epub->tx_ampdu_lock);
1028         return i;
1029 }
1030
1031 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))
1032 static int esp_node_detach(struct ieee80211_hw *hw, u8 ifidx, struct ieee80211_sta *sta)
1033 #else
1034 static int esp_node_detach(struct ieee80211_hw *hw, u8 ifidx, const u8 *addr)
1035 #endif
1036 {
1037     struct esp_pub *epub = (struct esp_pub *)hw->priv;
1038         u32 map;
1039         int i;
1040     struct esp_node *node = NULL;
1041
1042         spin_lock_bh(&epub->tx_ampdu_lock);
1043         map = epub->enodes_maps[ifidx];
1044         while(map != 0){
1045                 i = ffs(map) - 1;
1046 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))
1047                 if(epub->enodes[i]->sta == sta){
1048                         epub->enodes[i]->sta = NULL;
1049 #else
1050                 if(memcmp(epub->enodes[i]->addr, addr, ETH_ALEN) == 0){
1051 #endif
1052                         node = epub->enodes[i];
1053                         epub->enodes[i] = NULL;
1054                         epub->enodes_map &= ~(1 << i);
1055                         epub->enodes_maps[ifidx] &= ~(1 << i);
1056                         
1057                         spin_unlock_bh(&epub->tx_ampdu_lock);
1058                         return i;
1059                 }
1060                 map &= ~(1 << i);
1061         }
1062
1063         spin_unlock_bh(&epub->tx_ampdu_lock);
1064         return -1;
1065 }
1066
1067 struct esp_node * esp_get_node_by_addr(struct esp_pub * epub, const u8 *addr)
1068 {
1069         int i;
1070         u32 map;
1071         struct esp_node *node = NULL;
1072         if(addr == NULL)
1073                 return NULL;
1074         spin_lock_bh(&epub->tx_ampdu_lock);
1075         map = epub->enodes_map;
1076         while(map != 0){
1077                 i = ffs(map) - 1;
1078                 if(i < 0){
1079                         spin_unlock_bh(&epub->tx_ampdu_lock);
1080                         return NULL;
1081                 }
1082                 map &= ~(1 << i);
1083 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))
1084                 if(memcmp(epub->enodes[i]->sta->addr, addr, ETH_ALEN) == 0)
1085 #else
1086                 if(memcmp(epub->enodes[i]->addr, addr, ETH_ALEN) == 0)
1087 #endif
1088                 {
1089                         node = epub->enodes[i];
1090                         break;
1091                 }
1092         }
1093
1094         spin_unlock_bh(&epub->tx_ampdu_lock);
1095         return node;
1096 }
1097
1098 struct esp_node * esp_get_node_by_index(struct esp_pub * epub, u8 index)
1099 {
1100         u32 map;
1101         struct esp_node *node = NULL;
1102
1103         if (epub == NULL)
1104                 return NULL;
1105
1106         spin_lock_bh(&epub->tx_ampdu_lock);
1107         map = epub->enodes_map;
1108         if (map & BIT(index)) {
1109                 node = epub->enodes[index];
1110         } else {
1111                 spin_unlock_bh(&epub->tx_ampdu_lock);
1112                 return NULL;
1113         }
1114
1115         spin_unlock_bh(&epub->tx_ampdu_lock);
1116         return node;
1117 }
1118
1119 int esp_get_empty_rxampdu(struct esp_pub * epub, const u8 *addr, u8 tid)
1120 {
1121         int index = -1;
1122         if(addr == NULL)
1123                 return index;
1124         spin_lock_bh(&epub->rx_ampdu_lock);
1125         if((index = ffz(epub->rxampdu_map)) < ESP_PUB_MAX_RXAMPDU){
1126                 epub->rxampdu_map |= BIT(index);
1127                 epub->rxampdu_node[index] = esp_get_node_by_addr(epub, addr);
1128                 epub->rxampdu_tid[index] = tid;
1129         } else {
1130                 index = -1;
1131         }
1132         spin_unlock_bh(&epub->rx_ampdu_lock);
1133         return index;
1134 }
1135
1136 int esp_get_exist_rxampdu(struct esp_pub * epub, const u8 *addr, u8 tid)
1137 {       
1138         u8 map;
1139         int index = -1;
1140         int i;
1141         if(addr == NULL)
1142                 return index;
1143         spin_lock_bh(&epub->rx_ampdu_lock);
1144         map = epub->rxampdu_map;
1145         while(map != 0){
1146                 i = ffs(map) - 1;
1147                 if(i < 0){
1148                         spin_unlock_bh(&epub->rx_ampdu_lock);
1149                         return index;
1150                 }
1151                 map &= ~ BIT(i);
1152                 if(epub->rxampdu_tid[i] == tid && 
1153 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))
1154                         memcmp(epub->rxampdu_node[i]->sta->addr, addr, ETH_ALEN) == 0
1155 #else
1156                         memcmp(epub->rxampdu_node[i]->addr, addr, ETH_ALEN) == 0
1157 #endif
1158                 ){
1159                         index = i;
1160                         break;
1161                 }
1162         }
1163
1164         epub->rxampdu_map &= ~ BIT(index);
1165         spin_unlock_bh(&epub->rx_ampdu_lock);
1166         return index;
1167
1168 }
1169
1170 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))
1171 static int esp_op_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta)
1172 #else
1173 static int esp_op_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, const u8 *addr)
1174 #endif
1175 {
1176 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))
1177         struct esp_pub *epub = (struct esp_pub *)hw->priv;
1178 #endif
1179         struct esp_vif *evif = (struct esp_vif *)vif->drv_priv;
1180         int index;
1181 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28))
1182         ESP_IEEE80211_DBG(ESP_DBG_OP, "%s enter, addr %pM\n", __func__, addr);
1183         index = esp_node_attach(hw, evif->index, addr);
1184
1185 #else
1186 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 34))
1187         ESP_IEEE80211_DBG(ESP_DBG_OP, "%s enter, sta addr %pM\n", __func__, sta->addr);
1188 #else 
1189         ESP_IEEE80211_DBG(ESP_DBG_OP, "%s enter, vif addr %pM, sta addr %pM\n", __func__, vif->addr, sta->addr);
1190 #endif
1191         index = esp_node_attach(hw, evif->index, sta);
1192 #endif
1193
1194         if(index < 0)
1195                 return -1;
1196 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))
1197         sip_send_set_sta(epub, evif->index, 1, sta, vif, (u8)index);
1198 #else
1199         //node = esp_get_node_by_addr(epub, addr);
1200         //sip_send_set_sta(epub, evif->index, 1, node, vif, (u8)index);
1201 #endif
1202     return 0;
1203 }
1204
1205 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))
1206 static int esp_op_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta)
1207 #else
1208 static int esp_op_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, const u8 *addr)
1209 #endif
1210 {       
1211         struct esp_pub *epub = (struct esp_pub *)hw->priv;
1212         struct esp_vif *evif = (struct esp_vif *)vif->drv_priv;
1213         int index;
1214
1215 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28))
1216         struct esp_node *node;
1217         ESP_IEEE80211_DBG(ESP_DBG_OP, "%s enter, addr %pM\n", __func__, addr);
1218 #elif (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 34))
1219         ESP_IEEE80211_DBG(ESP_DBG_OP, "%s enter, sta addr %pM\n", __func__, sta->addr);
1220 #else 
1221         ESP_IEEE80211_DBG(ESP_DBG_OP, "%s enter, vif addr %pM, sta addr %pM\n", __func__, vif->addr, sta->addr);
1222 #endif
1223         
1224         //remove a connect in target
1225 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))
1226         index = esp_node_detach(hw, evif->index, sta);
1227         sip_send_set_sta(epub, evif->index, 0, sta, vif, (u8)index);
1228 #else
1229         node = esp_get_node_by_addr(epub, addr);
1230         index = esp_node_detach(hw, evif->index, addr);
1231         sip_send_set_sta(epub, evif->index, 0, node, vif, node->index);
1232 #endif
1233
1234         return 0;
1235 }
1236
1237
1238 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))
1239 static void esp_op_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum sta_notify_cmd cmd, struct ieee80211_sta *sta)
1240 #else
1241 static void esp_op_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum sta_notify_cmd cmd, const u8 *addr)
1242 #endif
1243 {
1244 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28))
1245         struct esp_pub *epub = (struct esp_pub *)hw->priv;
1246 #endif
1247
1248         ESP_IEEE80211_DBG(ESP_DBG_TRACE, "%s enter \n", __func__);
1249
1250         switch (cmd) {
1251 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39))
1252         case STA_NOTIFY_ADD:
1253             ESP_IEEE80211_DBG(ESP_DBG_ERROR, "%s cmd add\n", __func__);
1254 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))
1255             esp_op_sta_add(hw, vif, sta);
1256 #else
1257             memcpy(epub->wl.bssid, addr, ETH_ALEN);
1258             esp_op_sta_add(hw, vif, addr);
1259 #endif
1260             break;
1261
1262         case STA_NOTIFY_REMOVE:
1263 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))
1264             esp_op_sta_remove(hw, vif, sta);
1265 #else
1266             esp_op_sta_remove(hw, vif, addr);
1267             memset(epub->wl.bssid, 0, ETH_ALEN);
1268 #endif
1269             break;
1270 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29))
1271         case STA_NOTIFY_SLEEP:
1272                 break;
1273
1274         case STA_NOTIFY_AWAKE:
1275                 break;
1276 #endif /* NEW_KERNEL */
1277
1278         default:
1279                 break;
1280         }
1281 }
1282
1283
1284 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
1285 static int esp_op_conf_tx(struct ieee80211_hw *hw, 
1286                           struct ieee80211_vif *vif,
1287                           u16 queue,
1288                           const struct ieee80211_tx_queue_params *params)
1289
1290 #else
1291 static int esp_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
1292                           const struct ieee80211_tx_queue_params *params)
1293 #endif
1294 {
1295         struct esp_pub *epub = (struct esp_pub *)hw->priv;
1296         ESP_IEEE80211_DBG(ESP_DBG_TRACE, "%s enter \n", __func__);
1297         return sip_send_wmm_params(epub, queue, params);
1298 }
1299
1300 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35))
1301 static int esp_op_get_tx_stats(struct ieee80211_hw *hw,
1302                                struct ieee80211_tx_queue_stats *stats)
1303 {
1304         ESP_IEEE80211_DBG(ESP_DBG_TRACE, "%s enter \n", __func__);
1305
1306         return 0;
1307 }
1308 #endif /* !NEW_KERNEL && !KERNEL_35*/
1309
1310 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
1311 static u64 esp_op_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
1312 #else
1313 static u64 esp_op_get_tsf(struct ieee80211_hw *hw)
1314 #endif
1315 {
1316         ESP_IEEE80211_DBG(ESP_DBG_TRACE, "%s enter \n", __func__);
1317
1318         return 0;
1319 }
1320
1321 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30))
1322 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
1323 static void esp_op_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u64 tsf)
1324 #else
1325 static void esp_op_set_tsf(struct ieee80211_hw *hw, u64 tsf)
1326 #endif
1327 {
1328         ESP_IEEE80211_DBG(ESP_DBG_TRACE, "%s enter \n", __func__);
1329 }
1330 #endif
1331
1332 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
1333 static void esp_op_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
1334 #else
1335 static void esp_op_reset_tsf(struct ieee80211_hw *hw)
1336 #endif
1337 {
1338         ESP_IEEE80211_DBG(ESP_DBG_TRACE, "%s enter \n", __func__);
1339
1340 }
1341
1342 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31))
1343 static void esp_op_rfkill_poll(struct ieee80211_hw *hw)
1344 {
1345         struct esp_pub *epub = (struct esp_pub *)hw->priv;
1346
1347         ESP_IEEE80211_DBG(ESP_DBG_TRACE, "%s enter \n", __func__);
1348
1349         wiphy_rfkill_set_hw_state(hw->wiphy,
1350                                   test_bit(ESP_WL_FLAG_RFKILL, &epub->wl.flags) ? true : false);
1351 }
1352 #endif
1353
1354 #ifdef HW_SCAN
1355 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35))
1356 static int esp_op_hw_scan(struct ieee80211_hw *hw,
1357                           struct cfg80211_scan_request *req)
1358 #else
1359 static int esp_op_hw_scan(struct ieee80211_hw *hw,
1360                           struct ieee80211_vif *vif,
1361                           struct cfg80211_scan_request *req)
1362 #endif /* NEW_KERNEL && KERNEL_35 */
1363 {
1364         struct esp_pub *epub = (struct esp_pub *)hw->priv;
1365         int i, ret;
1366         bool scan_often = true;
1367
1368         ESP_IEEE80211_DBG(ESP_DBG_OP, "%s\n", __func__);
1369
1370         ESP_IEEE80211_DBG(ESP_DBG_TRACE, "scan, %d\n", req->n_ssids);
1371         ESP_IEEE80211_DBG(ESP_DBG_TRACE, "scan, len 1:%d,ssid 1:%s\n", req->ssids->ssid_len, req->ssids->ssid_len == 0? "":(char *)req->ssids->ssid);
1372         if(req->n_ssids > 1)
1373                 ESP_IEEE80211_DBG(ESP_DBG_TRACE, "scan, len 2:%d,ssid 2:%s\n", (req->ssids+1)->ssid_len, (req->ssids+1)->ssid_len == 0? "":(char *)(req->ssids + 1)->ssid);
1374
1375         /*scan_request is keep allocate untill scan_done,record it
1376           to split request into multi sdio_cmd*/
1377         if (atomic_read(&epub->wl.off)) {
1378                 esp_dbg(ESP_DBG_ERROR, "%s scan but wl off \n", __func__);
1379                 return -EPERM;
1380         }
1381
1382         if(req->n_ssids > 1){
1383                 struct cfg80211_ssid *ssid2 = req->ssids + 1;
1384                 if((req->ssids->ssid_len > 0 && ssid2->ssid_len > 0) || req->n_ssids > 2){
1385                         ESP_IEEE80211_DBG(ESP_DBG_ERROR, "scan ssid num: %d, ssid1:%s, ssid2:%s,not support\n", req->n_ssids, 
1386                                         req->ssids->ssid_len == 0 ? "":(char *)req->ssids->ssid, ssid2->ssid_len == 0? "":(char *)ssid2->ssid);
1387                                 return -EINVAL;
1388                         }
1389         }
1390
1391         epub->wl.scan_req = req;
1392
1393         for (i = 0; i < req->n_channels; i++)
1394                 ESP_IEEE80211_DBG(ESP_DBG_TRACE, "eagle hw_scan freq %d\n",
1395                                   req->channels[i]->center_freq);
1396 #if 0
1397         for (i = 0; i < req->n_ssids; i++) {
1398                 if (req->ssids->ssid_len> 0) {
1399                         req->ssids->ssid[req->ssids->ssid_len]='\0';
1400                         ESP_IEEE80211_DBG(ESP_DBG_TRACE, "scan_ssid %d:%s\n",
1401                                           i, req->ssids->ssid);
1402                 }
1403         }
1404 #endif
1405
1406         /*in connect state, suspend tx data*/
1407         if(epub->sip->support_bgscan &&
1408                 test_bit(ESP_WL_FLAG_CONNECT, &epub->wl.flags) &&
1409                 req->n_channels > 0)
1410         {
1411
1412                 scan_often = epub->scan_permit_valid && time_before(jiffies, epub->scan_permit);
1413                 epub->scan_permit_valid = true;
1414
1415                 if (!scan_often) {
1416 /*                        epub->scan_permit = jiffies + msecs_to_jiffies(900);
1417                         set_bit(ESP_WL_FLAG_STOP_TXQ, &epub->wl.flags);
1418                         if (atomic_read(&epub->txq_stopped) == false) {
1419                                 atomic_set(&epub->txq_stopped, true);
1420                                 ieee80211_stop_queues(hw);
1421                         }
1422 */
1423                 } else {
1424                         ESP_IEEE80211_DBG(ESP_DBG_LOG, "scan too often\n");
1425                         return -EACCES;
1426                 }
1427         } else {
1428                 scan_often = false;
1429         }
1430
1431         /*send sub_scan task to target*/
1432         ret = sip_send_scan(epub);
1433
1434         if (ret) {
1435                 ESP_IEEE80211_DBG(ESP_DBG_ERROR, "fail to send scan_cmd\n");
1436                 return ret;
1437         } else {
1438                 if(!scan_often) {
1439                         epub->scan_permit = jiffies + msecs_to_jiffies(900);
1440                         set_bit(ESP_WL_FLAG_STOP_TXQ, &epub->wl.flags);
1441                         if (atomic_read(&epub->txq_stopped) == false) {
1442                                 atomic_set(&epub->txq_stopped, true);
1443                                 ieee80211_stop_queues(hw);
1444                         }
1445                         /*force scan complete in case target fail to report in time*/
1446                         ieee80211_queue_delayed_work(hw, &epub->scan_timeout_work, req->n_channels * HZ / 4);
1447                 }
1448         }
1449
1450         return 0;
1451 }
1452
1453 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38))
1454 static int esp_op_remain_on_channel(struct ieee80211_hw *hw,
1455                                     struct ieee80211_channel *chan,
1456                                     enum nl80211_channel_type channel_type,
1457                                     int duration)
1458 {
1459       struct esp_pub *epub = (struct esp_pub *)hw->priv;
1460
1461       ESP_IEEE80211_DBG(ESP_DBG_OP, "%s enter, center_freq = %d duration = %d\n", __func__, chan->center_freq, duration);
1462       sip_send_roc(epub, chan->center_freq, duration);
1463       return 0;
1464 }
1465
1466 static int esp_op_cancel_remain_on_channel(struct ieee80211_hw *hw)
1467 {
1468       struct esp_pub *epub = (struct esp_pub *)hw->priv;
1469
1470       ESP_IEEE80211_DBG(ESP_DBG_OP, "%s enter \n", __func__);
1471       epub->roc_flags= 0;  // to disable roc state
1472       sip_send_roc(epub, 0, 0);
1473      return 0;
1474 }
1475 #endif /* > 2.6.38 */
1476 #endif
1477
1478 void esp_rocdone_process(struct ieee80211_hw *hw, struct sip_evt_roc *report)
1479 {    
1480       struct esp_pub *epub = (struct esp_pub *)hw->priv;
1481
1482       ESP_IEEE80211_DBG(ESP_DBG_OP, "%s enter, state = %d is_ok = %d\n", __func__, report->state, report->is_ok);
1483
1484       //roc process begin 
1485       if((report->state==1)&&(report->is_ok==1)) 
1486       {
1487            epub->roc_flags=1;  //flags in roc state, to fix channel, not change
1488 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38))
1489            ieee80211_ready_on_channel(hw);
1490 #endif
1491       }
1492       else if ((report->state==0)&&(report->is_ok==1))    //roc process timeout
1493       {
1494            epub->roc_flags= 0;  // to disable roc state
1495 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38))
1496            ieee80211_remain_on_channel_expired(hw);     
1497 #endif
1498        }
1499 }
1500
1501 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39))        
1502 static int esp_op_set_bitrate_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1503                                 const struct cfg80211_bitrate_mask *mask)
1504 {
1505         ESP_IEEE80211_DBG(ESP_DBG_OP, "%s enter \n", __func__);
1506         ESP_IEEE80211_DBG(ESP_DBG_OP, "%s vif->macaddr[%pM], mask[%d]\n", __func__, vif->addr, mask->control[0].legacy);
1507
1508         return 0;
1509 }
1510 #endif
1511
1512 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))        
1513 void esp_op_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
1514 #else
1515 void esp_op_flush(struct ieee80211_hw *hw, bool drop)
1516 #endif
1517 {
1518         
1519         ESP_IEEE80211_DBG(ESP_DBG_OP, "%s enter \n", __func__);
1520         do{
1521                 
1522                 struct esp_pub *epub = (struct esp_pub *)hw->priv;
1523                 unsigned long time = jiffies + msecs_to_jiffies(15);
1524                 while(atomic_read(&epub->sip->tx_data_pkt_queued)){
1525                         if(!time_before(jiffies, time)){
1526                                 break;
1527                         }
1528 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32)
1529             if(sif_get_ate_config() == 0){
1530                 ieee80211_queue_work(epub->hw, &epub->tx_work);
1531             } else {
1532                 queue_work(epub->esp_wkq, &epub->tx_work);
1533             }
1534 #else
1535             queue_work(epub->esp_wkq, &epub->tx_work);
1536 #endif
1537                         //sip_txq_process(epub);
1538                 }
1539                 mdelay(10);
1540                 
1541         }while(0);
1542 }
1543
1544 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33))
1545 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))
1546 static int esp_op_ampdu_action(struct ieee80211_hw *hw,
1547                 enum ieee80211_ampdu_mlme_action action,
1548                             struct ieee80211_sta *sta, u16 tid, u16 *ssn)
1549 #else
1550 static int esp_op_ampdu_action(struct ieee80211_hw *hw,
1551                 enum ieee80211_ampdu_mlme_action action,
1552                             const u8 *addr, u16 tid, u16 *ssn)
1553 #endif
1554 #else
1555 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39))
1556 static int esp_op_ampdu_action(struct ieee80211_hw *hw,
1557                 struct ieee80211_vif *vif,
1558                                enum ieee80211_ampdu_mlme_action action,
1559                                struct ieee80211_sta *sta, u16 tid, u16 *ssn)
1560 #else
1561 static int esp_op_ampdu_action(struct ieee80211_hw *hw,
1562                                struct ieee80211_vif *vif,
1563                                enum ieee80211_ampdu_mlme_action action,
1564                                struct ieee80211_sta *sta, u16 tid, u16 *ssn,
1565                                u8 buf_size)
1566 #endif
1567 #endif /* NEW_KERNEL && KERNEL_35 */
1568 {
1569         int ret = -EOPNOTSUPP;
1570         struct esp_pub *epub = (struct esp_pub *)hw->priv;
1571 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))
1572         struct esp_node * node = (struct esp_node *)sta->drv_priv;
1573 #else
1574         struct esp_node * node = esp_get_node_by_addr(epub, addr);
1575 #endif
1576         struct esp_tx_tid * tid_info = &node->tid[tid];
1577 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39))
1578         u8 buf_size = 64;
1579 #endif
1580
1581         ESP_IEEE80211_DBG(ESP_DBG_OP, "%s enter \n", __func__);
1582         switch(action) {
1583         case IEEE80211_AMPDU_TX_START:
1584                 if (mod_support_no_txampdu() ||
1585 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
1586                         cfg80211_get_chandef_type(&epub->hw->conf.chandef) == NL80211_CHAN_NO_HT
1587 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29))
1588                         hw->conf.channel_type == NL80211_CHAN_NO_HT
1589 #else
1590                         !(hw->conf.flags&IEEE80211_CONF_SUPPORT_HT_MODE)
1591 #endif
1592                         ||
1593 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))
1594                         !sta->ht_cap.ht_supported
1595 #else
1596                         !node->ht_info.ht_supported
1597 #endif
1598                             )
1599                         return ret;
1600
1601                 //if (vif->p2p || vif->type != NL80211_IFTYPE_STATION)
1602                 //      return ret;
1603
1604 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28))
1605                 ESP_IEEE80211_DBG(ESP_DBG_ERROR, "%s TX START, addr:%pM,tid:%u\n", __func__, addr, tid);
1606 #else
1607                 ESP_IEEE80211_DBG(ESP_DBG_ERROR, "%s TX START, addr:%pM,tid:%u,state:%d\n", __func__, sta->addr, tid, tid_info->state);
1608 #endif
1609                 spin_lock_bh(&epub->tx_ampdu_lock);
1610 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))                
1611                 ESSERT(tid_info->state == ESP_TID_STATE_TRIGGER);
1612                 *ssn = tid_info->ssn;
1613                 tid_info->state = ESP_TID_STATE_PROGRESS;
1614 #endif
1615
1616 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28))
1617                 ieee80211_start_tx_ba_cb_irqsafe(hw, addr, tid);
1618 #elif (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33))
1619                 ieee80211_start_tx_ba_cb_irqsafe(hw, sta->addr, tid);
1620 #else
1621                 ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
1622 #endif
1623                 spin_unlock_bh(&epub->tx_ampdu_lock);
1624 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29))
1625                 ret = 0;
1626 #else
1627                 spin_lock_bh(&epub->tx_ampdu_lock);
1628                 
1629                 if (tid_info->state != ESP_TID_STATE_PROGRESS) {
1630                         if (tid_info->state == ESP_TID_STATE_INIT) {
1631                                                 printk(KERN_ERR "%s WIFI RESET, IGNORE\n", __func__);
1632                                 spin_unlock_bh(&epub->tx_ampdu_lock);
1633                                                 return -ENETRESET;
1634                         } else {
1635                                                 ESSERT(0);
1636                         }
1637                 }
1638                         
1639                 tid_info->state = ESP_TID_STATE_OPERATIONAL;
1640                 spin_unlock_bh(&epub->tx_ampdu_lock);
1641 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))
1642                 ret = sip_send_ampdu_action(epub, SIP_AMPDU_TX_OPERATIONAL, sta->addr, tid, node->ifidx, buf_size);
1643 #else
1644                 ret = sip_send_ampdu_action(epub, SIP_AMPDU_TX_OPERATIONAL, addr, tid, node->ifidx, buf_size);
1645 #endif
1646 #endif
1647                 break;
1648 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
1649         case IEEE80211_AMPDU_TX_STOP_CONT:
1650 #else
1651         case IEEE80211_AMPDU_TX_STOP:
1652 #endif
1653 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28))
1654                 ESP_IEEE80211_DBG(ESP_DBG_ERROR, "%s TX STOP, addr:%pM,tid:%u\n", __func__, addr, tid);
1655 #else
1656                 ESP_IEEE80211_DBG(ESP_DBG_ERROR, "%s TX STOP, addr:%pM,tid:%u,state:%d\n", __func__, sta->addr, tid, tid_info->state);
1657 #endif
1658                 spin_lock_bh(&epub->tx_ampdu_lock);
1659 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))
1660                 if(tid_info->state == ESP_TID_STATE_WAIT_STOP)
1661                         tid_info->state = ESP_TID_STATE_STOP;
1662                 else
1663                         tid_info->state = ESP_TID_STATE_INIT;
1664 #endif
1665 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28))
1666                 ieee80211_stop_tx_ba_cb_irqsafe(hw, addr, tid);
1667 #elif (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33))
1668                 ieee80211_stop_tx_ba_cb_irqsafe(hw, sta->addr, tid);
1669 #else
1670                 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
1671 #endif
1672                 spin_unlock_bh(&epub->tx_ampdu_lock);
1673 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28))
1674                 ret = sip_send_ampdu_action(epub, SIP_AMPDU_TX_STOP, addr, tid, node->ifidx, 0);
1675 #else
1676                 ret = sip_send_ampdu_action(epub, SIP_AMPDU_TX_STOP, sta->addr, tid, node->ifidx, 0);
1677 #endif
1678                 break;
1679 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
1680         case IEEE80211_AMPDU_TX_STOP_FLUSH:
1681         case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
1682 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))
1683                 if(tid_info->state == ESP_TID_STATE_WAIT_STOP)
1684                         tid_info->state = ESP_TID_STATE_STOP;
1685                 else
1686                         tid_info->state = ESP_TID_STATE_INIT;
1687 #endif
1688                 ret = sip_send_ampdu_action(epub, SIP_AMPDU_TX_STOP, sta->addr, tid, node->ifidx, 0);
1689                         break;
1690 #endif
1691 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29))
1692 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30))
1693         case IEEE80211_AMPDU_TX_OPERATIONAL:
1694 #else
1695         case IEEE80211_AMPDU_TX_RESUME:
1696 #endif
1697                 ESP_IEEE80211_DBG(ESP_DBG_ERROR, "%s TX OPERATION, addr:%pM,tid:%u,state:%d\n", __func__, sta->addr, tid, tid_info->state);
1698                 spin_lock_bh(&epub->tx_ampdu_lock);
1699                 
1700                 if (tid_info->state != ESP_TID_STATE_PROGRESS) {
1701                         if (tid_info->state == ESP_TID_STATE_INIT) {
1702                                                 printk(KERN_ERR "%s WIFI RESET, IGNORE\n", __func__);
1703                                 spin_unlock_bh(&epub->tx_ampdu_lock);
1704                                                 return -ENETRESET;
1705                         } else {
1706                                                 ESSERT(0);
1707                         }
1708                 }
1709                         
1710                 tid_info->state = ESP_TID_STATE_OPERATIONAL;
1711                 spin_unlock_bh(&epub->tx_ampdu_lock);
1712                 ret = sip_send_ampdu_action(epub, SIP_AMPDU_TX_OPERATIONAL, sta->addr, tid, node->ifidx, buf_size);
1713                 break;
1714 #endif
1715         case IEEE80211_AMPDU_RX_START:
1716                 if(mod_support_no_rxampdu() ||
1717 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
1718                         cfg80211_get_chandef_type(&epub->hw->conf.chandef) == NL80211_CHAN_NO_HT
1719 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29))
1720                         hw->conf.channel_type == NL80211_CHAN_NO_HT
1721 #else
1722                         !(hw->conf.flags&IEEE80211_CONF_SUPPORT_HT_MODE)
1723 #endif
1724                         ||
1725 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))
1726                         !sta->ht_cap.ht_supported
1727 #else
1728                         !node->ht_info.ht_supported
1729 #endif
1730                         )
1731                         return ret;
1732
1733                 if (
1734 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
1735                 (vif->p2p && false)
1736 #else
1737                 false
1738 #endif
1739 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33))
1740                 || false
1741 #else
1742                 || (vif->type != NL80211_IFTYPE_STATION && false)
1743 #endif
1744            )
1745                         return ret;
1746 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28))
1747                 ESP_IEEE80211_DBG(ESP_DBG_ERROR, "%s RX START %pM tid %u %u\n", __func__, addr, tid, *ssn);
1748                 ret = sip_send_ampdu_action(epub, SIP_AMPDU_RX_START, addr, tid, *ssn, 64);
1749 #else
1750                 ESP_IEEE80211_DBG(ESP_DBG_ERROR, "%s RX START %pM tid %u %u\n", __func__, sta->addr, tid, *ssn);
1751                 ret = sip_send_ampdu_action(epub, SIP_AMPDU_RX_START, sta->addr, tid, *ssn, 64);
1752 #endif
1753                 break;
1754         case IEEE80211_AMPDU_RX_STOP:
1755 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28))
1756                 ESP_IEEE80211_DBG(ESP_DBG_ERROR, "%s RX STOP %pM tid %u\n", __func__, addr, tid);
1757                 ret = sip_send_ampdu_action(epub, SIP_AMPDU_RX_STOP, addr, tid, 0, 0);
1758 #else
1759                 ESP_IEEE80211_DBG(ESP_DBG_ERROR, "%s RX STOP %pM tid %u\n", __func__, sta->addr, tid);
1760                 ret = sip_send_ampdu_action(epub, SIP_AMPDU_RX_STOP, sta->addr, tid, 0, 0);
1761 #endif
1762                 break;
1763         default:
1764                 break;
1765         }
1766         return ret;
1767 }
1768
1769 #if 0
1770 static int esp_op_tx_last_beacon(struct ieee80211_hw *hw)
1771 {
1772
1773         ESP_IEEE80211_DBG(ESP_DBG_TRACE, "%s enter \n", __func__);
1774
1775         return 0;
1776 }
1777
1778 #ifdef CONFIG_NL80211_TESTMODE
1779 static int esp_op_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
1780 {
1781         ESP_IEEE80211_DBG(ESP_DBG_TRACE, "%s enter \n", __func__);
1782
1783         return 0;
1784 }
1785 #endif /* CONFIG_NL80211_TESTMODE */
1786 #endif
1787
1788 static void
1789 esp_tx_work(struct work_struct *work)
1790 {
1791         struct esp_pub *epub = container_of(work, struct esp_pub, tx_work);
1792
1793         mutex_lock(&epub->tx_mtx);
1794         sip_txq_process(epub);
1795         mutex_unlock(&epub->tx_mtx);
1796 }
1797
1798 #ifndef RX_SENDUP_SYNC
1799 //for debug
1800 static int data_pkt_dequeue_cnt = 0;
1801 static void _esp_flush_rxq(struct esp_pub *epub)
1802 {
1803         struct sk_buff *skb = NULL;
1804
1805         while ((skb = skb_dequeue(&epub->rxq))) {
1806                 //do not log when in spin_lock
1807                 //esp_dbg(ESP_DBG_TRACE, "%s call ieee80211_rx \n", __func__);
1808                 ieee80211_rx(epub->hw, skb);
1809         }
1810 }
1811
1812 static void
1813 esp_sendup_work(struct work_struct *work)
1814 {
1815         struct esp_pub *epub = container_of(work, struct esp_pub, sendup_work);
1816         spin_lock_bh(&epub->rx_lock);
1817         _esp_flush_rxq(epub);
1818         spin_unlock_bh(&epub->rx_lock);
1819 }
1820 #endif /* !RX_SENDUP_SYNC */
1821
1822 static const struct ieee80211_ops esp_mac80211_ops = {
1823         .tx = esp_op_tx,
1824         .start = esp_op_start,
1825         .stop = esp_op_stop,
1826 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39))        
1827 #ifdef CONFIG_PM
1828         .suspend = esp_op_suspend,
1829         .resume = esp_op_resume,
1830 #endif
1831 #endif
1832         .add_interface = esp_op_add_interface,
1833         .remove_interface = esp_op_remove_interface,
1834         .config = esp_op_config,
1835
1836         .bss_info_changed = esp_op_bss_info_changed,
1837 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28))
1838         .config_interface = esp_op_config_interface,
1839 #endif
1840 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32))
1841         .prepare_multicast = esp_op_prepare_multicast,
1842 #endif
1843         .configure_filter = esp_op_configure_filter,
1844         .set_key = esp_op_set_key,
1845         .update_tkip_key = esp_op_update_tkip_key,
1846         //.sched_scan_start = esp_op_sched_scan_start,
1847         //.sched_scan_stop = esp_op_sched_scan_stop,
1848         .set_rts_threshold = esp_op_set_rts_threshold,
1849         .sta_notify = esp_op_sta_notify,
1850         .conf_tx = esp_op_conf_tx,
1851 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35))
1852         .get_tx_stats = esp_op_get_tx_stats,
1853 #endif /* KERNEL_VERSION < 2.6.35*/
1854 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
1855         .change_interface = esp_op_change_interface,
1856 #endif
1857         .get_tsf = esp_op_get_tsf,
1858 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30))
1859         .set_tsf = esp_op_set_tsf,
1860 #endif
1861         .reset_tsf = esp_op_reset_tsf,
1862 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31))
1863         .rfkill_poll= esp_op_rfkill_poll,
1864 #endif
1865 #ifdef HW_SCAN
1866         .hw_scan = esp_op_hw_scan,
1867 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38))
1868         .remain_on_channel= esp_op_remain_on_channel,
1869         .cancel_remain_on_channel=esp_op_cancel_remain_on_channel,
1870 #endif /* >=2.6.38 */
1871 #endif
1872         .ampdu_action = esp_op_ampdu_action,
1873         //.get_survey = esp_op_get_survey,
1874 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34))
1875         .sta_add = esp_op_sta_add,
1876         .sta_remove = esp_op_sta_remove,
1877 #endif /* >= 2.6.34 */
1878 #ifdef CONFIG_NL80211_TESTMODE
1879         //CFG80211_TESTMODE_CMD(esp_op_tm_cmd)
1880 #endif
1881 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39))
1882         .set_bitrate_mask = esp_op_set_bitrate_mask,
1883 #endif
1884 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34))
1885         .flush = esp_op_flush,
1886 #endif
1887 };
1888
1889 struct esp_pub * esp_pub_alloc_mac80211(struct device *dev)
1890 {
1891         struct ieee80211_hw *hw;
1892         struct esp_pub *epub;
1893         int ret = 0;
1894
1895         hw = ieee80211_alloc_hw(sizeof(struct esp_pub), &esp_mac80211_ops);
1896
1897         if (hw == NULL) {
1898                 esp_dbg(ESP_DBG_ERROR, "ieee80211 can't alloc hw!\n");
1899                 ret = -ENOMEM;
1900                 return ERR_PTR(ret);
1901         }
1902 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
1903         hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
1904 #endif
1905
1906         epub = hw->priv;
1907         memset(epub, 0, sizeof(*epub));
1908         epub->hw = hw;
1909         SET_IEEE80211_DEV(hw, dev);
1910         epub->dev = dev;
1911
1912         skb_queue_head_init(&epub->txq);
1913         skb_queue_head_init(&epub->txdoneq);
1914         skb_queue_head_init(&epub->rxq);
1915
1916         spin_lock_init(&epub->tx_ampdu_lock);
1917         spin_lock_init(&epub->rx_ampdu_lock);
1918         spin_lock_init(&epub->tx_lock);
1919         mutex_init(&epub->tx_mtx);
1920         spin_lock_init(&epub->rx_lock);
1921
1922         INIT_WORK(&epub->tx_work, esp_tx_work);
1923 #ifndef RX_SENDUP_SYNC
1924         INIT_WORK(&epub->sendup_work, esp_sendup_work);
1925 #endif //!RX_SENDUP_SYNC
1926
1927 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39))
1928         //epub->esp_wkq = create_freezeable_workqueue("esp_wkq"); 
1929         epub->esp_wkq = create_singlethread_workqueue("esp_wkq");
1930 #else
1931         //epub->esp_wkq = create_freezable_workqueue("esp_wkq"); 
1932         epub->esp_wkq = create_singlethread_workqueue("esp_wkq");
1933 #endif /* NEW_KERNEL */
1934
1935         if (epub->esp_wkq == NULL) {
1936                 ret = -ENOMEM;
1937                 return ERR_PTR(ret);
1938         }
1939         epub->scan_permit_valid = false;
1940         INIT_DELAYED_WORK(&epub->scan_timeout_work, hw_scan_timeout_report);
1941
1942         return epub;
1943 }
1944
1945
1946 int esp_pub_dealloc_mac80211(struct esp_pub *epub)
1947 {
1948         set_bit(ESP_WL_FLAG_RFKILL, &epub->wl.flags);
1949
1950         destroy_workqueue(epub->esp_wkq);
1951         mutex_destroy(&epub->tx_mtx);
1952
1953 #ifdef ESP_NO_MAC80211
1954         free_netdev(epub->net_dev);
1955         wiphy_free(epub->wdev->wiphy);
1956         kfree(epub->wdev);
1957 #else
1958         if (epub->hw) {
1959                 ieee80211_free_hw(epub->hw);
1960         }
1961 #endif
1962
1963         return 0;
1964 }
1965
1966 #if 0
1967 static int esp_reg_notifier(struct wiphy *wiphy,
1968                             struct regulatory_request *request)
1969 {
1970         struct ieee80211_supported_band *sband;
1971         struct ieee80211_channel *ch;
1972         int i;
1973
1974         ESP_IEEE80211_DBG(ESP_DBG_TRACE, "%s enter %d\n", __func__, request->initiator
1975                          );
1976
1977         //TBD
1978 }
1979 #endif
1980
1981 /* 2G band channels */
1982 static struct ieee80211_channel esp_channels_2ghz[] = {
1983         { .hw_value = 1, .center_freq = 2412, .max_power = 25 },
1984         { .hw_value = 2, .center_freq = 2417, .max_power = 25 },
1985         { .hw_value = 3, .center_freq = 2422, .max_power = 25 },
1986         { .hw_value = 4, .center_freq = 2427, .max_power = 25 },
1987         { .hw_value = 5, .center_freq = 2432, .max_power = 25 },
1988         { .hw_value = 6, .center_freq = 2437, .max_power = 25 },
1989         { .hw_value = 7, .center_freq = 2442, .max_power = 25 },
1990         { .hw_value = 8, .center_freq = 2447, .max_power = 25 },
1991         { .hw_value = 9, .center_freq = 2452, .max_power = 25 },
1992         { .hw_value = 10, .center_freq = 2457, .max_power = 25 },
1993         { .hw_value = 11, .center_freq = 2462, .max_power = 25 },
1994         { .hw_value = 12, .center_freq = 2467, .max_power = 25 },
1995         { .hw_value = 13, .center_freq = 2472, .max_power = 25 },
1996         //{ .hw_value = 14, .center_freq = 2484, .max_power = 25 },
1997 };
1998
1999 /* 11G rate */
2000 static struct ieee80211_rate esp_rates_2ghz[] = {
2001         {
2002                 .bitrate = 10,
2003                 .hw_value = CONF_HW_BIT_RATE_1MBPS,
2004                 .hw_value_short = CONF_HW_BIT_RATE_1MBPS,
2005         },
2006         {
2007                 .bitrate = 20,
2008                 .hw_value = CONF_HW_BIT_RATE_2MBPS,
2009                 .hw_value_short = CONF_HW_BIT_RATE_2MBPS,
2010                 .flags = IEEE80211_RATE_SHORT_PREAMBLE
2011         },
2012         {
2013                 .bitrate = 55,
2014                 .hw_value = CONF_HW_BIT_RATE_5_5MBPS,
2015                 .hw_value_short = CONF_HW_BIT_RATE_5_5MBPS,
2016                 .flags = IEEE80211_RATE_SHORT_PREAMBLE
2017         },
2018         {
2019                 .bitrate = 110,
2020                 .hw_value = CONF_HW_BIT_RATE_11MBPS,
2021                 .hw_value_short = CONF_HW_BIT_RATE_11MBPS,
2022                 .flags = IEEE80211_RATE_SHORT_PREAMBLE
2023         },
2024         {
2025                 .bitrate = 60,
2026                 .hw_value = CONF_HW_BIT_RATE_6MBPS,
2027                 .hw_value_short = CONF_HW_BIT_RATE_6MBPS,
2028         },
2029         {
2030                 .bitrate = 90,
2031                 .hw_value = CONF_HW_BIT_RATE_9MBPS,
2032                 .hw_value_short = CONF_HW_BIT_RATE_9MBPS,
2033         },
2034         {
2035                 .bitrate = 120,
2036                 .hw_value = CONF_HW_BIT_RATE_12MBPS,
2037                 .hw_value_short = CONF_HW_BIT_RATE_12MBPS,
2038         },
2039         {
2040                 .bitrate = 180,
2041                 .hw_value = CONF_HW_BIT_RATE_18MBPS,
2042                 .hw_value_short = CONF_HW_BIT_RATE_18MBPS,
2043         },
2044         {
2045                 .bitrate = 240,
2046                 .hw_value = CONF_HW_BIT_RATE_24MBPS,
2047                 .hw_value_short = CONF_HW_BIT_RATE_24MBPS,
2048         },
2049         {
2050                 .bitrate = 360,
2051                 .hw_value = CONF_HW_BIT_RATE_36MBPS,
2052                 .hw_value_short = CONF_HW_BIT_RATE_36MBPS,
2053         },
2054         {
2055                 .bitrate = 480,
2056                 .hw_value = CONF_HW_BIT_RATE_48MBPS,
2057                 .hw_value_short = CONF_HW_BIT_RATE_48MBPS,
2058         },
2059         {
2060                 .bitrate = 540,
2061                 .hw_value = CONF_HW_BIT_RATE_54MBPS,
2062                 .hw_value_short = CONF_HW_BIT_RATE_54MBPS,
2063         },
2064 };
2065
2066 static void
2067 esp_pub_init_mac80211(struct esp_pub *epub)
2068 {
2069         struct ieee80211_hw *hw = epub->hw;
2070
2071 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31))
2072         static const u32 cipher_suites[] = {
2073                 WLAN_CIPHER_SUITE_WEP40,
2074                 WLAN_CIPHER_SUITE_WEP104,
2075                 WLAN_CIPHER_SUITE_TKIP,
2076                 WLAN_CIPHER_SUITE_CCMP,
2077         };
2078 #endif
2079
2080         hw->channel_change_time = 420000; /* in us */
2081         hw->max_listen_interval = 10;
2082
2083         hw->flags = IEEE80211_HW_SIGNAL_DBM |
2084 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33))
2085                     IEEE80211_HW_HAS_RATE_CONTROL |
2086 #endif /* >= 2.6.33 */
2087 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30))
2088                     IEEE80211_HW_SUPPORTS_PS |
2089 #endif
2090 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29))
2091                 IEEE80211_HW_AMPDU_AGGREGATION |
2092 #endif
2093                                 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING;
2094    //IEEE80211_HW_PS_NULLFUNC_STACK |   
2095         //IEEE80211_HW_CONNECTION_MONITOR |
2096         //IEEE80211_HW_BEACON_FILTER |
2097         //IEEE80211_HW_AMPDU_AGGREGATION |
2098         //IEEE80211_HW_REPORTS_TX_ACK_STATUS;
2099 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39))
2100         hw->max_rx_aggregation_subframes = 0x40;
2101         hw->max_tx_aggregation_subframes = 0x40;
2102 #endif /* >= 2.6.39 */
2103         
2104 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31))
2105         hw->wiphy->cipher_suites = cipher_suites;
2106         hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
2107         hw->wiphy->max_scan_ie_len = epub->sip->tx_blksz - sizeof(struct sip_hdr) - sizeof(struct sip_cmd_scan);
2108 #endif
2109
2110 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))
2111         /* ONLY station for now, support P2P soon... */
2112         hw->wiphy->interface_modes = 
2113 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
2114             BIT(NL80211_IFTYPE_P2P_GO) |
2115                     BIT(NL80211_IFTYPE_P2P_CLIENT) |
2116 #endif
2117             BIT(NL80211_IFTYPE_STATION) |
2118                     BIT(NL80211_IFTYPE_AP);
2119 #endif
2120
2121 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30))
2122         hw->wiphy->max_scan_ssids = 2;
2123         //hw->wiphy->max_sched_scan_ssids = 16;
2124         //hw->wiphy->max_match_sets = 16;
2125 #endif
2126
2127 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38))
2128                 hw->wiphy->max_remain_on_channel_duration = 5000;
2129 #endif
2130
2131         atomic_set(&epub->wl.off, 1);
2132
2133         epub->wl.sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
2134         epub->wl.sbands[IEEE80211_BAND_2GHZ].channels = esp_channels_2ghz;
2135         epub->wl.sbands[IEEE80211_BAND_2GHZ].bitrates = esp_rates_2ghz;
2136         epub->wl.sbands[IEEE80211_BAND_2GHZ].n_channels = ARRAY_SIZE(esp_channels_2ghz);
2137         epub->wl.sbands[IEEE80211_BAND_2GHZ].n_bitrates = ARRAY_SIZE(esp_rates_2ghz);
2138         /*add to support 11n*/
2139 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29))
2140         epub->wl.sbands[IEEE80211_BAND_2GHZ].ht_cap.ht_supported = true;
2141         epub->wl.sbands[IEEE80211_BAND_2GHZ].ht_cap.cap = 0x116C;//IEEE80211_HT_CAP_RX_STBC; //IEEE80211_HT_CAP_SGI_20;
2142 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32))
2143         epub->wl.sbands[IEEE80211_BAND_2GHZ].ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K;
2144         epub->wl.sbands[IEEE80211_BAND_2GHZ].ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
2145 #else
2146         epub->wl.sbands[IEEE80211_BAND_2GHZ].ht_cap.ampdu_factor = 1;//IEEE80211_HT_MAX_AMPDU_16K;
2147         epub->wl.sbands[IEEE80211_BAND_2GHZ].ht_cap.ampdu_density = 0;//IEEE80211_HT_MPDU_DENSITY_NONE;
2148 #endif
2149         memset(&epub->wl.sbands[IEEE80211_BAND_2GHZ].ht_cap.mcs, 0,
2150                sizeof(epub->wl.sbands[IEEE80211_BAND_2GHZ].ht_cap.mcs));
2151         epub->wl.sbands[IEEE80211_BAND_2GHZ].ht_cap.mcs.rx_mask[0] = 0xff;
2152         //epub->wl.sbands[IEEE80211_BAND_2GHZ].ht_cap.mcs.rx_highest = 7;
2153         //epub->wl.sbands[IEEE80211_BAND_2GHZ].ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
2154 #else
2155         epub->wl.sbands[IEEE80211_BAND_2GHZ].ht_info.ht_supported = true;
2156         epub->wl.sbands[IEEE80211_BAND_2GHZ].ht_info.cap = 0x116C;//IEEE80211_HT_CAP_RX_STBC; //IEEE80211_HT_CAP_SGI_20;
2157         epub->wl.sbands[IEEE80211_BAND_2GHZ].ht_info.ampdu_factor = 1;//IEEE80211_HT_MAX_AMPDU_16K;
2158         epub->wl.sbands[IEEE80211_BAND_2GHZ].ht_info.ampdu_density = 0;//IEEE80211_HT_MPDU_DENSITY_NONE;
2159         memset(&epub->wl.sbands[IEEE80211_BAND_2GHZ].ht_info.supp_mcs_set, 0,
2160                sizeof(epub->wl.sbands[IEEE80211_BAND_2GHZ].ht_info.supp_mcs_set));
2161         epub->wl.sbands[IEEE80211_BAND_2GHZ].ht_info.supp_mcs_set[0] = 0xff;
2162 #endif
2163
2164
2165         /* BAND_5GHZ TBD */
2166
2167         hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
2168                 &epub->wl.sbands[IEEE80211_BAND_2GHZ];
2169         /* BAND_5GHZ TBD */
2170
2171 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31))
2172         /*no fragment*/
2173         hw->wiphy->frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD;
2174 #endif
2175
2176         /* handle AC queue in f/w */
2177         hw->queues = 4;
2178 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))
2179 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30))
2180         hw->max_rates = 4;
2181 #else
2182         hw->max_altrates = 4;
2183 #endif
2184 #endif
2185         //hw->wiphy->reg_notifier = esp_reg_notify;
2186
2187         hw->vif_data_size = sizeof(struct esp_vif);
2188 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))
2189         hw->sta_data_size = sizeof(struct esp_node);
2190 #endif
2191
2192         //hw->max_rx_aggregation_subframes = 8;
2193 }
2194
2195 int
2196 esp_register_mac80211(struct esp_pub *epub)
2197 {
2198         int ret = 0;
2199         u8 mac[ETH_ALEN];
2200 #ifdef P2P_CONCURRENT
2201         u8 *wlan_addr;
2202         u8 *p2p_addr;
2203         int idx;
2204 #endif
2205
2206         esp_pub_init_mac80211(epub);
2207
2208         printk("Wifi Efuse Mac => %02x:%02x:%02x:%02x:%02x:%02x\n", epub->mac_addr[0], epub->mac_addr[1],
2209           epub->mac_addr[2], epub->mac_addr[3], epub->mac_addr[4], epub->mac_addr[5]);
2210         
2211         if (!rockchip_wifi_mac_addr(mac)) 
2212         {
2213                 printk("=========> get mac address from flash=[%02x:%02x:%02x:%02x:%02x:%02x]\n", mac[0], mac[1],
2214                 mac[2], mac[3], mac[4], mac[5]);
2215                 memcpy(epub->mac_addr, mac, ETH_ALEN);
2216         }
2217
2218 #ifdef P2P_CONCURRENT
2219         epub->hw->wiphy->addresses = (struct mac_address *)esp_mac_addr;
2220         memcpy(&epub->hw->wiphy->addresses[0], epub->mac_addr, ETH_ALEN);
2221         memcpy(&epub->hw->wiphy->addresses[1], epub->mac_addr, ETH_ALEN);
2222         wlan_addr = (u8 *)&epub->hw->wiphy->addresses[0];
2223         p2p_addr  = (u8 *)&epub->hw->wiphy->addresses[1];
2224
2225         for (idx = 0; idx < 64; idx++) {
2226                 p2p_addr[0] = wlan_addr[0] | 0x02;
2227                 p2p_addr[0] ^= idx << 2;
2228                 if (strncmp(p2p_addr, wlan_addr, 6) != 0)
2229                         break;
2230         }
2231
2232         epub->hw->wiphy->n_addresses = 2;
2233 #else
2234
2235         SET_IEEE80211_PERM_ADDR(epub->hw, epub->mac_addr);
2236 #endif
2237
2238         ret = ieee80211_register_hw(epub->hw);
2239
2240         if (ret < 0) {
2241                 ESP_IEEE80211_DBG(ESP_DBG_ERROR, "unable to register mac80211 hw: %d\n", ret);
2242                 return ret;
2243         } else {
2244 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
2245 #ifdef MAC80211_NO_CHANGE
2246                 rtnl_lock();
2247                 if (epub->hw->wiphy->interface_modes &
2248                 (BIT(NL80211_IFTYPE_P2P_GO) | BIT(NL80211_IFTYPE_P2P_CLIENT))) {
2249                 ret = ieee80211_if_add(hw_to_local(epub->hw), "p2p%d", NULL,
2250                                           NL80211_IFTYPE_STATION, NULL);
2251                 if (ret)
2252                         wiphy_warn(epub->hw->wiphy,
2253                                    "Failed to add default virtual iface\n");
2254                 }
2255
2256                 rtnl_unlock();
2257 #endif
2258 #endif
2259         }
2260
2261         set_bit(ESP_WL_FLAG_HW_REGISTERED, &epub->wl.flags);
2262
2263         return ret;
2264 }
2265
2266 static u8 getaddr_index(u8 * addr, struct esp_pub *epub)
2267 {
2268 #ifdef P2P_CONCURRENT
2269         int i;
2270         for(i = 0; i < ESP_PUB_MAX_VIF; i++)
2271                 if(memcmp(addr, (u8 *)&epub->hw->wiphy->addresses[i], ETH_ALEN) == 0)
2272                         return i;
2273         return ESP_PUB_MAX_VIF;
2274 #else
2275         return 0;
2276 #endif
2277 }
2278