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