2 * Copyright (c) 2009 - 2014 Espressif System.
4 * SIP ctrl packet parse and pack
7 #include <net/mac80211.h>
8 #include <net/cfg80211.h>
9 #include <linux/skbuff.h>
10 #include <linux/bitops.h>
11 #include <linux/firmware.h>
17 #include "esp_debug.h"
19 #include "esp_utils.h"
25 #endif /* TEST_MODE */
26 #include "esp_version.h"
28 extern struct completion *gl_bootup_cplx;
30 static void esp_tx_ba_session_op(struct esp_sip *sip, struct esp_node *node, trc_ampdu_state_t state, u8 tid )
32 struct esp_tx_tid *txtid;
34 txtid = &node->tid[tid];
35 if (state == TRC_TX_AMPDU_STOPPED) {
36 if (txtid->state == ESP_TID_STATE_OPERATIONAL) {
37 esp_dbg(ESP_DBG_TXAMPDU, "%s tid %d TXAMPDU GOT STOP EVT\n", __func__, tid);
39 spin_lock_bh(&sip->epub->tx_ampdu_lock);
40 txtid->state = ESP_TID_STATE_WAIT_STOP;
41 spin_unlock_bh(&sip->epub->tx_ampdu_lock);
42 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28))
43 ieee80211_stop_tx_ba_session(sip->epub->hw, node->addr, (u16)tid, WLAN_BACK_INITIATOR);
44 #elif (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 32))
45 ieee80211_stop_tx_ba_session(sip->epub->hw, node->sta->addr, (u16)tid, WLAN_BACK_INITIATOR);
46 #elif (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))
47 ieee80211_stop_tx_ba_session(node->sta, (u16)tid, WLAN_BACK_INITIATOR);
49 ieee80211_stop_tx_ba_session(node->sta, (u16)tid);
50 #endif /* KERNEL_VERSION 2.6.39 */
52 esp_dbg(ESP_DBG_TXAMPDU, "%s tid %d TXAMPDU GOT STOP EVT IN WRONG STATE %d\n", __func__, tid, txtid->state);
54 } else if (state == TRC_TX_AMPDU_OPERATIONAL) {
55 if (txtid->state == ESP_TID_STATE_STOP) {
56 esp_dbg(ESP_DBG_TXAMPDU, "%s tid %d TXAMPDU GOT OPERATIONAL\n", __func__, tid);
58 spin_lock_bh(&sip->epub->tx_ampdu_lock);
59 txtid->state = ESP_TID_STATE_TRIGGER;
60 spin_unlock_bh(&sip->epub->tx_ampdu_lock);
61 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28))
62 ieee80211_start_tx_ba_session(sip->epub->hw, node->addr, tid);
63 #elif (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 32))
64 ieee80211_start_tx_ba_session(sip->epub->hw, node->sta->addr, tid);
65 #elif (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 37))
66 ieee80211_start_tx_ba_session(node->sta, (u16)tid);
68 ieee80211_start_tx_ba_session(node->sta, (u16)tid, 0);
69 #endif /* KERNEL_VERSION 2.6.39 */
71 } else if(txtid->state == ESP_TID_STATE_OPERATIONAL) {
72 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28))
73 sip_send_ampdu_action(sip->epub, SIP_AMPDU_TX_OPERATIONAL, node->addr, tid, node->ifidx, 0);
75 sip_send_ampdu_action(sip->epub, SIP_AMPDU_TX_OPERATIONAL, node->sta->addr, tid, node->ifidx, 0);
78 esp_dbg(ESP_DBG_TXAMPDU, "%s tid %d TXAMPDU GOT OPERATIONAL EVT IN WRONG STATE %d\n", __func__, tid, txtid->state);
83 int sip_parse_event_debug(struct esp_pub *epub, const u8 *src, u8 *dst)
85 struct sip_evt_debug* debug_evt = (struct sip_evt_debug *)(src + SIP_CTRL_HDR_LEN);
87 switch (debug_evt->results[0]) {
89 u32 mask = debug_evt->results[1];
90 u8 *p = (u8 *)&debug_evt->results[2];
92 struct esp_node *enode;
95 index = ffs(mask) - 1;
96 if (index >= ESP_PUB_MAX_STA)
98 enode = esp_get_node_by_index(epub, index);
100 esp_dbg(ESP_DBG_ERROR, "trc mask dismatch");
102 dst += sprintf(dst, "%02x:%02x:%02x:%02x:%02x:%02x 0x%x 0x%x\n",
103 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))
104 enode->sta->addr[0], enode->sta->addr[1], enode->sta->addr[2],
105 enode->sta->addr[3], enode->sta->addr[4], enode->sta->addr[5],
107 enode->addr[0], enode->addr[1], enode->addr[2],
108 enode->addr[3], enode->addr[4], enode->addr[5],
115 dst += sprintf(dst, "%c", '\0');
120 for(i = 1; i < debug_evt->len; i++)
121 dst += sprintf(dst, "0x%x%s", debug_evt->results[i], i == debug_evt->len -1 ? "":" " );
129 int sip_parse_events(struct esp_sip *sip, u8 *buf)
131 struct sip_hdr *hdr = (struct sip_hdr *)buf;
133 switch (hdr->c_evtid) {
134 case SIP_EVT_TARGET_ON: {
135 /* use rx work queue to send... */
136 if (atomic_read(&sip->state) == SIP_PREPARE_BOOT || atomic_read(&sip->state) == SIP_BOOT) {
137 atomic_set(&sip->state, SIP_SEND_INIT);
138 queue_work(sip->epub->esp_wkq, &sip->rx_process_work);
140 esp_dbg(ESP_DBG_ERROR, "%s boot during wrong state %d\n", __func__, atomic_read(&sip->state));
145 case SIP_EVT_BOOTUP: {
146 struct sip_evt_bootup2 *bootup_evt = (struct sip_evt_bootup2 *)(buf + SIP_CTRL_HDR_LEN);
150 sip_post_init(sip, bootup_evt);
153 complete(gl_bootup_cplx);
157 case SIP_EVT_RESETTING:{
158 sip->epub->wait_reset = 1;
160 complete(gl_bootup_cplx);
164 //atomic_set(&sip->epub->ps.state, ESP_PM_ON);
167 case SIP_EVT_TXIDLE:{
168 //struct sip_evt_txidle *txidle = (struct sip_evt_txidle *)(buf + SIP_CTRL_HDR_LEN);
169 //sip_txdone_clear(sip, txidle->last_seq);
172 #ifndef FAST_TX_STATUS
173 case SIP_EVT_TX_STATUS: {
174 struct sip_evt_tx_report *report = (struct sip_evt_tx_report *)(buf + SIP_CTRL_HDR_LEN);
175 sip_txdoneq_process(sip, report);
179 #endif /* FAST_TX_STATUS */
181 case SIP_EVT_SCAN_RESULT: {
182 struct sip_evt_scan_report *report = (struct sip_evt_scan_report *)(buf + SIP_CTRL_HDR_LEN);
183 if (atomic_read(&sip->epub->wl.off)) {
184 esp_dbg(ESP_DBG_ERROR, "%s scan result while wlan off\n", __func__);
187 sip_scandone_process(sip, report);
193 struct sip_evt_roc* report = (struct sip_evt_roc *)(buf + SIP_CTRL_HDR_LEN);
194 esp_rocdone_process(sip->epub->hw, report);
199 #ifdef ESP_RX_COPYBACK_TEST
201 case SIP_EVT_COPYBACK: {
202 u32 len = hdr->len - SIP_CTRL_HDR_LEN;
204 esp_dbg(ESP_DBG_TRACE, "%s copyback len %d seq %u\n", __func__, len, hdr->seq);
206 memcpy(copyback_buf + copyback_offset, pkt->buf + SIP_CTRL_HDR_LEN, len);
207 copyback_offset += len;
209 //show_buf(pkt->buf, 256);
211 //how about totlen % 256 == 0??
212 if (hdr->hdr.len < 256) {
217 #endif /* ESP_RX_COPYBACK_TEST */
218 case SIP_EVT_CREDIT_RPT:
222 case SIP_EVT_WAKEUP: {
224 struct sip_evt_wakeup* wakeup_evt= (struct sip_evt_wakeup *)(buf + SIP_CTRL_HDR_LEN);
225 sprintf((char *)&check_str, "%d", wakeup_evt->check_data);
226 esp_test_cmd_event(TEST_CMD_WAKEUP, (char *)&check_str);
230 case SIP_EVT_DEBUG: {
232 sip_parse_event_debug(sip->epub, buf, check_str);
233 esp_dbg(ESP_DBG_TRACE, "%s", check_str);
234 esp_test_cmd_event(TEST_CMD_DEBUG, (char *)&check_str);
238 case SIP_EVT_LOOPBACK: {
240 struct sip_evt_loopback *loopback_evt = (struct sip_evt_loopback *)(buf + SIP_CTRL_HDR_LEN);
241 esp_dbg(ESP_DBG_LOG, "%s loopback len %d seq %u\n", __func__,hdr->len, hdr->seq);
243 if(loopback_evt->pack_id!=get_loopback_id()) {
244 sprintf((char *)&check_str, "seq id error %d, expect %d", loopback_evt->pack_id, get_loopback_id());
245 esp_test_cmd_event(TEST_CMD_LOOPBACK, (char *)&check_str);
248 if((loopback_evt->pack_id+1) <get_loopback_num()) {
250 sip_send_loopback_mblk(sip, loopback_evt->txlen, loopback_evt->rxlen, get_loopback_id());
252 sprintf((char *)&check_str, "test over!");
253 esp_test_cmd_event(TEST_CMD_LOOPBACK, (char *)&check_str);
259 case SIP_EVT_SNPRINTF_TO_HOST: {
260 u8 *p = (buf + sizeof(struct sip_hdr) + sizeof(u16));
261 u16 *len = (u16 *)(buf + sizeof(struct sip_hdr));
262 char test_res_str[560];
263 sprintf(test_res_str, "esp_host:%llx\nesp_target: %.*s", DRIVER_VER, *len, p);
265 esp_dbg(ESP_SHOW, "%s\n", test_res_str);
266 if(*len && sip->epub->sdio_state == ESP_SDIO_STATE_FIRST_INIT){
268 if (mod_eagle_path_get() == NULL)
269 sprintf(filename, "%s/%s", FWPATH, "test_results");
271 sprintf(filename, "%s/%s", mod_eagle_path_get(), "test_results");
272 esp_readwrite_file(filename, NULL, test_res_str, strlen(test_res_str));
276 case SIP_EVT_TRC_AMPDU: {
277 struct sip_evt_trc_ampdu *ep = (struct sip_evt_trc_ampdu*)(buf + SIP_CTRL_HDR_LEN);
278 struct esp_node *node = NULL;
281 if (atomic_read(&sip->epub->wl.off)) {
282 esp_dbg(ESP_DBG_ERROR, "%s scan result while wlan off\n", __func__);
286 node = esp_get_node_by_addr(sip->epub, ep->addr);
289 for (i = 0; i < 8; i++) {
290 if (ep->tid & (1<<i)) {
291 esp_tx_ba_session_op(sip, node, ep->state, i);
298 char *ep = (char *)(buf + SIP_CTRL_HDR_LEN);
299 static int counter = 0;
301 esp_dbg(ESP_ATE, "%s EVT_EP \n\n", __func__);
303 esp_dbg(ESP_ATE, "ATE: %s \n", ep);
306 esp_test_ate_done_cb(ep);
310 case SIP_EVT_INIT_EP: {
311 char *ep = (char *)(buf + SIP_CTRL_HDR_LEN);
312 esp_dbg(ESP_ATE, "Phy Init: %s \n", ep);
316 case SIP_EVT_NOISEFLOOR:{
317 struct sip_evt_noisefloor *ep = (struct sip_evt_noisefloor *)(buf + SIP_CTRL_HDR_LEN);
318 atomic_set(&sip->noise_floor, ep->noise_floor);
329 #include "esp_init_data.h"
331 #define ESP_INIT_NAME "esp_init_data.bin"
332 #endif /* HAS_INIT_DATA */
334 void sip_send_chip_init(struct esp_sip *sip)
337 #ifndef HAS_INIT_DATA
338 const struct firmware *fw_entry;
339 u8 * esp_init_data = NULL;
342 ret = esp_request_firmware(&fw_entry, ESP_INIT_NAME, sip->epub->dev);
345 esp_dbg(ESP_DBG_ERROR, "%s =============ERROR! NO INIT DATA!!=================\n", __func__);
348 esp_init_data = kmemdup(fw_entry->data, fw_entry->size, GFP_KERNEL);
350 size = fw_entry->size;
352 esp_release_firmware(fw_entry);
354 if (esp_init_data == NULL) {
355 esp_dbg(ESP_DBG_ERROR, "%s =============ERROR! NO MEMORY!!=================\n", __func__);
359 size = sizeof(esp_init_data);
361 #endif /* !HAS_INIT_DATA */
363 fix_init_data(esp_init_data, size);
365 atomic_sub(1, &sip->tx_credits);
367 sip_send_cmd(sip, SIP_CMD_INIT, size, (void *)esp_init_data);
369 #ifndef HAS_INIT_DATA
370 kfree(esp_init_data);
371 #endif /* !HAS_INIT_DATA */
374 int sip_send_config(struct esp_pub *epub, struct ieee80211_conf * conf)
376 struct sk_buff *skb = NULL;
377 struct sip_cmd_config *configcmd;
379 skb = sip_alloc_ctrl_skbuf(epub->sip, sizeof(struct sip_cmd_config) + sizeof(struct sip_hdr), SIP_CMD_CONFIG);
382 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
383 esp_dbg(ESP_DBG_TRACE, "%s config center freq %d\n", __func__, conf->chandef.chan->center_freq);
385 esp_dbg(ESP_DBG_TRACE, "%s config center freq %d\n", __func__, conf->channel->center_freq);
387 configcmd = (struct sip_cmd_config *)(skb->data + sizeof(struct sip_hdr));
388 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
389 configcmd->center_freq= conf->chandef.chan->center_freq;
391 configcmd->center_freq= conf->channel->center_freq;
393 configcmd->duration= 0;
394 return sip_cmd_enqueue(epub->sip, skb, ENQUEUE_PRIOR_TAIL);
397 int sip_send_bss_info_update(struct esp_pub *epub, struct esp_vif *evif, u8 *bssid, int assoc)
399 struct sk_buff *skb = NULL;
400 struct sip_cmd_bss_info_update*bsscmd;
402 skb = sip_alloc_ctrl_skbuf(epub->sip, sizeof(struct sip_cmd_bss_info_update) + sizeof(struct sip_hdr), SIP_CMD_BSS_INFO_UPDATE);
406 bsscmd = (struct sip_cmd_bss_info_update *)(skb->data + sizeof(struct sip_hdr));
407 if (assoc == 2) { //hack for softAP mode
408 bsscmd->beacon_int = evif->beacon_interval;
409 } else if (assoc == 1) {
410 set_bit(ESP_WL_FLAG_CONNECT, &epub->wl.flags);
412 clear_bit(ESP_WL_FLAG_CONNECT, &epub->wl.flags);
414 bsscmd->bssid_no = evif->index;
415 bsscmd->isassoc= assoc;
416 bsscmd->beacon_int = evif->beacon_interval;
417 memcpy(bsscmd->bssid, bssid, ETH_ALEN);
418 return sip_cmd_enqueue(epub->sip, skb, ENQUEUE_PRIOR_TAIL);
421 int sip_send_wmm_params(struct esp_pub *epub, u8 aci, const struct ieee80211_tx_queue_params *params)
423 struct sk_buff *skb = NULL;
424 struct sip_cmd_set_wmm_params* bsscmd;
425 skb = sip_alloc_ctrl_skbuf(epub->sip, sizeof(struct sip_cmd_set_wmm_params) + sizeof(struct sip_hdr), SIP_CMD_SET_WMM_PARAM);
429 bsscmd = (struct sip_cmd_set_wmm_params *)(skb->data + sizeof(struct sip_hdr));
431 bsscmd->aifs=params->aifs;
432 bsscmd->txop_us=params->txop*32;
434 bsscmd->ecw_min = 32 - __builtin_clz(params->cw_min);
435 bsscmd->ecw_max= 32 -__builtin_clz(params->cw_max);
437 return sip_cmd_enqueue(epub->sip, skb, ENQUEUE_PRIOR_TAIL);
440 int sip_send_ampdu_action(struct esp_pub *epub, u8 action_num, const u8 * addr, u16 tid, u16 ssn, u8 buf_size)
443 struct sk_buff *skb = NULL;
444 struct sip_cmd_ampdu_action * action;
445 if(action_num == SIP_AMPDU_RX_START){
446 index = esp_get_empty_rxampdu(epub, addr, tid);
447 } else if(action_num == SIP_AMPDU_RX_STOP){
448 index = esp_get_exist_rxampdu(epub, addr, tid);
452 skb = sip_alloc_ctrl_skbuf(epub->sip, sizeof(struct sip_cmd_ampdu_action) + sizeof(struct sip_hdr), SIP_CMD_AMPDU_ACTION);
456 action = (struct sip_cmd_ampdu_action *)(skb->data + sizeof(struct sip_hdr));
457 action->action = action_num;
458 //for TX, it means interface index
462 case SIP_AMPDU_RX_START:
464 case SIP_AMPDU_RX_STOP:
465 action->index = index;
466 case SIP_AMPDU_TX_OPERATIONAL:
467 case SIP_AMPDU_TX_STOP:
468 action->win_size = buf_size;
470 memcpy(action->addr, addr, ETH_ALEN);
474 return sip_cmd_enqueue(epub->sip, skb, ENQUEUE_PRIOR_TAIL);
478 /*send cmd to target, if aborted is true, inform target stop scan, report scan complete imediately
479 return 1: complete over, 0: success, still have next scan, -1: hardware failure
481 int sip_send_scan(struct esp_pub *epub)
483 struct cfg80211_scan_request *scan_req = epub->wl.scan_req;
484 struct sk_buff *skb = NULL;
485 struct sip_cmd_scan *scancmd;
488 u8 append_len, ssid_len;
490 ESSERT(scan_req != NULL);
491 ssid_len = scan_req->n_ssids == 0 ? 0:
492 (scan_req->n_ssids == 1 ? scan_req->ssids->ssid_len: scan_req->ssids->ssid_len + (scan_req->ssids + 1)->ssid_len);
493 append_len = ssid_len + scan_req->n_channels + scan_req->ie_len;
495 skb = sip_alloc_ctrl_skbuf(epub->sip, sizeof(struct sip_cmd_scan) + sizeof(struct sip_hdr) + append_len, SIP_CMD_SCAN);
501 scancmd = (struct sip_cmd_scan *)(ptr + sizeof(struct sip_hdr));
502 ptr += sizeof(struct sip_hdr);
504 scancmd->aborted= false;
506 if (scancmd->aborted==false) {
507 ptr += sizeof(struct sip_cmd_scan);
508 if (scan_req->n_ssids <=0 || (scan_req->n_ssids == 1&& ssid_len == 0)) {
509 scancmd->ssid_len = 0;
511 scancmd->ssid_len = ssid_len;
512 if(scan_req->ssids->ssid_len == ssid_len)
513 memcpy(ptr, scan_req->ssids->ssid, scancmd->ssid_len);
515 memcpy(ptr, (scan_req->ssids + 1)->ssid, scancmd->ssid_len);
518 ptr += scancmd->ssid_len;
519 scancmd->n_channels=scan_req->n_channels;
520 for (i=0; i<scan_req->n_channels; i++)
521 ptr[i] = scan_req->channels[i]->hw_value;
523 ptr += scancmd->n_channels;
524 if (scan_req->ie_len && scan_req->ie != NULL) {
525 scancmd->ie_len=scan_req->ie_len;
526 memcpy(ptr, scan_req->ie, scan_req->ie_len);
530 //add a flag that support two ssids,
531 if(scan_req->n_ssids > 1)
532 scancmd->ssid_len |= 0x80;
536 return sip_cmd_enqueue(epub->sip, skb, ENQUEUE_PRIOR_TAIL);
540 int sip_send_suspend_config(struct esp_pub *epub, u8 suspend)
542 struct sip_cmd_suspend *cmd = NULL;
543 struct sk_buff *skb = NULL;
545 skb = sip_alloc_ctrl_skbuf(epub->sip, sizeof(struct sip_cmd_suspend) + sizeof(struct sip_hdr), SIP_CMD_SUSPEND);
550 cmd = (struct sip_cmd_suspend *)(skb->data + sizeof(struct sip_hdr));
551 cmd->suspend = suspend;
552 return sip_cmd_enqueue(epub->sip, skb, ENQUEUE_PRIOR_TAIL);
555 int sip_send_ps_config(struct esp_pub *epub, struct esp_ps *ps)
557 struct sip_cmd_ps *pscmd = NULL;
558 struct sk_buff *skb = NULL;
559 struct sip_hdr *shdr = NULL;
561 skb = sip_alloc_ctrl_skbuf(epub->sip, sizeof(struct sip_cmd_ps) + sizeof(struct sip_hdr), SIP_CMD_PS);
567 shdr = (struct sip_hdr *)skb->data;
568 pscmd = (struct sip_cmd_ps *)(skb->data + sizeof(struct sip_hdr));
570 pscmd->dtim_period = ps->dtim_period;
571 pscmd->max_sleep_period = ps->max_sleep_period;
573 return sip_cmd_enqueue(epub->sip, skb, ENQUEUE_PRIOR_TAIL);
576 void sip_scandone_process(struct esp_sip *sip, struct sip_evt_scan_report *scan_report)
578 struct esp_pub *epub = sip->epub;
580 esp_dbg(ESP_DBG_TRACE, "eagle hw scan report\n");
582 if (epub->wl.scan_req) {
583 hw_scan_done(epub, scan_report->aborted);
584 epub->wl.scan_req = NULL;
588 int sip_send_setkey(struct esp_pub *epub, u8 bssid_no, u8 *peer_addr, struct ieee80211_key_conf *key, u8 isvalid)
590 struct sip_cmd_setkey *setkeycmd;
591 struct sk_buff *skb = NULL;
593 skb = sip_alloc_ctrl_skbuf(epub->sip, sizeof(struct sip_cmd_setkey) + sizeof(struct sip_hdr), SIP_CMD_SETKEY);
598 setkeycmd = (struct sip_cmd_setkey *)(skb->data + sizeof(struct sip_hdr));
601 memcpy(setkeycmd->addr, peer_addr, ETH_ALEN);
603 memset(setkeycmd->addr, 0, ETH_ALEN);
606 setkeycmd->bssid_no = bssid_no;
607 setkeycmd->hw_key_idx= key->hw_key_idx;
610 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39))
611 setkeycmd->alg= key->alg;
613 setkeycmd->alg= esp_cipher2alg(key->cipher);
614 #endif /* NEW_KERNEL */
615 setkeycmd->keyidx = key->keyidx;
616 setkeycmd->keylen = key->keylen;
617 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39))
618 if (key->alg == ALG_TKIP) {
620 if (key->cipher == WLAN_CIPHER_SUITE_TKIP) {
621 #endif /* NEW_KERNEL */
622 memcpy(setkeycmd->key, key->key, 16);
623 memcpy(setkeycmd->key+16,key->key+24,8);
624 memcpy(setkeycmd->key+24,key->key+16,8);
626 memcpy(setkeycmd->key, key->key, key->keylen);
633 return sip_cmd_enqueue(epub->sip, skb, ENQUEUE_PRIOR_TAIL);
637 #define LOOPBACK_PKT_LEN 200
638 int sip_send_loopback_cmd_mblk(struct esp_sip *sip)
642 for (cnt = 0; cnt < 4; cnt++) {
643 if (0!=(ret=sip_send_loopback_mblk(sip, LOOPBACK_PKT_LEN, LOOPBACK_PKT_LEN, 0)))
648 #endif /* FPGA_LOOPBACK */
650 int sip_send_loopback_mblk(struct esp_sip *sip, int txpacket_len, int rxpacket_len, int packet_id)
652 struct sk_buff *skb = NULL;
653 struct sip_cmd_loopback *cmd;
657 //send 100 loopback pkt
659 skb = sip_alloc_ctrl_skbuf(sip, sizeof(struct sip_cmd_loopback) + sizeof(struct sip_hdr) + txpacket_len, SIP_CMD_LOOPBACK);
661 skb = sip_alloc_ctrl_skbuf(sip, sizeof(struct sip_cmd_loopback) + sizeof(struct sip_hdr), SIP_CMD_LOOPBACK);
667 cmd = (struct sip_cmd_loopback *)(ptr + sizeof(struct sip_hdr));
668 ptr += sizeof(struct sip_hdr);
669 cmd->txlen = txpacket_len;
670 cmd->rxlen = rxpacket_len;
671 cmd->pack_id = packet_id;
674 ptr += sizeof(struct sip_cmd_loopback);
675 /* fill up pkt payload */
676 for (i = 0; i < txpacket_len; i++) {
681 ret = sip_cmd_enqueue(sip, skb, ENQUEUE_PRIOR_TAIL);
689 int sip_send_roc(struct esp_pub *epub, u16 center_freq, u16 duration)
691 struct sk_buff *skb = NULL;
692 struct sip_cmd_config *configcmd;
694 skb = sip_alloc_ctrl_skbuf(epub->sip, sizeof(struct sip_cmd_config) + sizeof(struct sip_hdr), SIP_CMD_CONFIG);
698 configcmd = (struct sip_cmd_config *)(skb->data + sizeof(struct sip_hdr));
699 configcmd->center_freq= center_freq;
700 configcmd->duration= duration;
701 return sip_cmd_enqueue(epub->sip, skb, ENQUEUE_PRIOR_TAIL);
704 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))
705 int sip_send_set_sta(struct esp_pub *epub, u8 ifidx, u8 set, struct ieee80211_sta *sta, struct ieee80211_vif *vif, u8 index)
707 int sip_send_set_sta(struct esp_pub *epub, u8 ifidx, u8 set, struct esp_node *node, struct ieee80211_vif *vif, u8 index)
710 struct sk_buff *skb = NULL;
711 struct sip_cmd_setsta *setstacmd;
712 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28))
713 struct ieee80211_ht_info ht_info = node->ht_info;
715 skb = sip_alloc_ctrl_skbuf(epub->sip, sizeof(struct sip_cmd_setsta) + sizeof(struct sip_hdr), SIP_CMD_SETSTA);
719 setstacmd = (struct sip_cmd_setsta *)(skb->data + sizeof(struct sip_hdr));
720 setstacmd->ifidx = ifidx;
721 setstacmd->index = index;
722 setstacmd->set = set;
723 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))
725 setstacmd->aid = vif->bss_conf.aid;
727 setstacmd->aid = sta->aid;
728 memcpy(setstacmd->mac, sta->addr, ETH_ALEN);
730 if(sta->ht_cap.ht_supported){
731 if(sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20)
732 setstacmd->phymode = ESP_IEEE80211_T_HT20_S;
734 setstacmd->phymode = ESP_IEEE80211_T_HT20_L;
735 setstacmd->ampdu_factor = sta->ht_cap.ampdu_factor;
736 setstacmd->ampdu_density = sta->ht_cap.ampdu_density;
738 if(sta->supp_rates[IEEE80211_BAND_2GHZ] & (~(u32)CONF_HW_BIT_RATE_11B_MASK)){
739 setstacmd->phymode = ESP_IEEE80211_T_OFDM;
741 setstacmd->phymode = ESP_IEEE80211_T_CCK;
746 setstacmd->aid = node->aid;
747 memcpy(setstacmd->mac, node->addr, ETH_ALEN);
749 if(ht_info.ht_supported){
750 if(ht_info.cap & IEEE80211_HT_CAP_SGI_20)
751 setstacmd->phymode = ESP_IEEE80211_T_HT20_S;
753 setstacmd->phymode = ESP_IEEE80211_T_HT20_L;
754 setstacmd->ampdu_factor = ht_info.ampdu_factor;
755 setstacmd->ampdu_density = ht_info.ampdu_density;
757 //note supp_rates is u64[] in 2.6.27
758 if(node->supp_rates[IEEE80211_BAND_2GHZ] & (~(u64)CONF_HW_BIT_RATE_11B_MASK)){
759 setstacmd->phymode = ESP_IEEE80211_T_OFDM;
761 setstacmd->phymode = ESP_IEEE80211_T_CCK;
766 return sip_cmd_enqueue(epub->sip, skb, ENQUEUE_PRIOR_TAIL);
769 int sip_send_recalc_credit(struct esp_pub *epub)
771 struct sk_buff *skb = NULL;
773 skb = sip_alloc_ctrl_skbuf(epub->sip, 0 + sizeof(struct sip_hdr), SIP_CMD_RECALC_CREDIT);
777 return sip_cmd_enqueue(epub->sip, skb, ENQUEUE_PRIOR_HEAD);
780 int sip_cmd(struct esp_pub *epub, enum sip_cmd_id cmd_id, u8 *cmd_buf, u8 cmd_len)
782 struct sk_buff *skb = NULL;
784 skb = sip_alloc_ctrl_skbuf(epub->sip, cmd_len + sizeof(struct sip_hdr), cmd_id);
788 memcpy(skb->data + sizeof(struct sip_hdr), cmd_buf, cmd_len);
790 return sip_cmd_enqueue(epub->sip, skb, ENQUEUE_PRIOR_TAIL);