summaryrefslogtreecommitdiff
path: root/ANDROID_3.4.5/drivers/net/wireless/eagle/esp_sip.c
diff options
context:
space:
mode:
Diffstat (limited to 'ANDROID_3.4.5/drivers/net/wireless/eagle/esp_sip.c')
-rwxr-xr-xANDROID_3.4.5/drivers/net/wireless/eagle/esp_sip.c2377
1 files changed, 0 insertions, 2377 deletions
diff --git a/ANDROID_3.4.5/drivers/net/wireless/eagle/esp_sip.c b/ANDROID_3.4.5/drivers/net/wireless/eagle/esp_sip.c
deleted file mode 100755
index ef11ff57..00000000
--- a/ANDROID_3.4.5/drivers/net/wireless/eagle/esp_sip.c
+++ /dev/null
@@ -1,2377 +0,0 @@
-/*
- * Copyright (c) 2009 - 2013 Espressif System.
- */
-
-#include <linux/ieee80211.h>
-#include <net/mac80211.h>
-#include <net/cfg80211.h>
-#include <linux/skbuff.h>
-#include <linux/bitops.h>
-#include <linux/version.h>
-#include <linux/mmc/card.h>
-#include <linux/mmc/mmc.h>
-#include <linux/mmc/host.h>
-#include <linux/mmc/sdio_func.h>
-#include <linux/mmc/sdio_ids.h>
-#include <linux/mmc/sdio.h>
-#include <linux/mmc/sd.h>
-#include <linux/completion.h>
-
-#include "esp_pub.h"
-#include "esp_sip.h"
-#include "esp_ctrl.h"
-#include "esp_sif.h"
-#include "esp_debug.h"
-#include "slc_host_register.h"
-#include "esp_wmac.h"
-#include "esp_utils.h"
-#ifdef TEST_MODE
-#include "testmode.h"
-#endif
-
-#ifdef USE_EXT_GPIO
-#include "esp_ext.h"
-#endif /* USE_EXT_GPIO */
-
-extern struct completion *gl_bootup_cplx;
-static u32 bcn_counter = 0;
-static u32 probe_rsp_counter = 0;
-
-static int old_signal = -35;
-static int avg_signal = 0;
-static int signal_loop = 0;
-
-#define SIGNAL_COUNT 300
-
-#define TID_TO_AC(_tid) ((_tid)== 0||((_tid)==3)?WME_AC_BE:((_tid)<3)?WME_AC_BK:((_tid)<6)?WME_AC_VI:WME_AC_VO)
-
-#ifdef SIP_DEBUG
-#define esp_sip_dbg esp_dbg
-struct sip_trace {
- u32 tx_data;
- u32 tx_cmd;
- u32 rx_data;
- u32 rx_evt;
- u32 rx_tx_status;
- u32 tx_out_of_credit;
- u32 tx_one_shot_overflow;
-};
-static struct sip_trace str;
-#define STRACE_TX_DATA_INC() (str.tx_data++)
-#define STRACE_TX_CMD_INC() (str.tx_cmd++)
-#define STRACE_RX_DATA_INC() (str.rx_data++)
-#define STRACE_RX_EVENT_INC() (str.rx_evt++)
-#define STRACE_RX_TXSTATUS_INC() (str.rx_tx_status++)
-#define STRACE_TX_OUT_OF_CREDIT_INC() (str.tx_out_of_credit++)
-#define STRACE_TX_ONE_SHOT_INC() (str.tx_one_shot_overflow++)
-
-#if 0
-static void sip_show_trace(struct esp_sip *sip);
-#endif //0000
-
-#define STRACE_SHOW(sip) sip_show_trace(sip)
-#else
-#define esp_sip_dbg(...)
-#define STRACE_TX_DATA_INC()
-#define STRACE_TX_CMD_INC()
-#define STRACE_RX_DATA_INC()
-#define STRACE_RX_EVENT_INC()
-#define STRACE_RX_TXSTATUS_INC()
-#define STRACE_TX_OUT_OF_CREDIT_INC()
-#define STRACE_TX_ONE_SHOT_INC()
-#define STRACE_SHOW(sip)
-#endif /* SIP_DEBUG */
-
-#define SIP_STOP_QUEUE_THRESHOLD 48
-#define SIP_RESUME_QUEUE_THRESHOLD 12
-#ifndef FAST_TX_STATUS
-#define SIP_PENDING_STOP_TX_THRESHOLD 6
-#define SIP_PENDING_RESUME_TX_THRESHOLD 6
-#endif /* !FAST_TX_STATUS */
-
-#define SIP_MIN_DATA_PKT_LEN (sizeof(struct esp_mac_rx_ctrl) + 24) //24 is min 80211hdr
-#define TARGET_RX_SIZE 524
-
-static struct sip_pkt *sip_get_ctrl_buf(struct esp_sip *sip, SIP_BUF_TYPE bftype);
-
-static void sip_reclaim_ctrl_buf(struct esp_sip *sip, struct sip_pkt *pkt, SIP_BUF_TYPE bftype);
-
-static void sip_free_init_ctrl_buf(struct esp_sip *sip);
-
-static void sip_dec_credit(struct esp_sip *sip);
-
-
-static int sip_pack_pkt(struct esp_sip *sip, struct sk_buff *skb, int *pm_state);
-
-static struct esp_mac_rx_ctrl *sip_parse_normal_mac_ctrl(struct sk_buff *skb, int * pkt_len_enc, int *buf_len, int *pulled_len);
-
-static struct sk_buff * sip_parse_data_rx_info(struct esp_sip *sip, struct sk_buff *skb, int pkt_len_enc, int buf_len, struct esp_mac_rx_ctrl *mac_ctrl, int *pulled_len);
-
-#ifndef RX_SYNC
-static inline void sip_rx_pkt_enqueue(struct esp_sip *sip, struct sk_buff *skb);
-
-static inline struct sk_buff * sip_rx_pkt_dequeue(struct esp_sip *sip);
-#endif /* RX_SYNC */
-#ifndef FAST_TX_STATUS
-static void sip_after_tx_status_update(struct esp_sip *sip);
-#endif /* !FAST_TX_STATUS */
-
-static void sip_after_write_pkts(struct esp_sip *sip);
-
-//static void show_data_seq(u8 *pkt);
-
-static void sip_update_tx_credits(struct esp_sip *sip, u16 recycled_credits);
-
-//static void sip_trigger_txq_process(struct esp_sip *sip);
-
-#ifndef RX_SYNC
-static bool sip_rx_pkt_process(struct esp_sip * sip, struct sk_buff *skb);
-#else
-static void sip_rx_pkt_process_sync(struct esp_sip *sip, struct sk_buff *skb);
-#endif /* RX_SYNC */
-
-#ifdef FAST_TX_STATUS
-static void sip_tx_status_report(struct esp_sip *sip, struct sk_buff *skb, struct ieee80211_tx_info* tx_info, bool success);
-#endif /* FAST_TX_STATUS */
-
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35))
-static void sip_check_skb_alignment(struct sk_buff *skb);
-#endif /* NEW_KERNEL */
-
-#ifdef ESP_RX_COPYBACK_TEST
-/* only for rx test */
-static u8 *copyback_buf;
-static u32 copyback_offset = 0;
-#endif /* ESP_RX_COPYBACK_TEST */
-
-#ifdef FPGA_TXDATA
-int sip_send_tx_data(struct esp_sip *sip);
-#endif/* FPGA_TXDATA */
-
-#ifdef FPGA_LOOPBACK
-int sip_send_loopback_cmd_mblk(struct esp_sip *sip);
-#endif /* FPGA_LOOPBACK */
-
-#ifdef SIP_DEBUG
-#if 0
-static void sip_show_trace(struct esp_sip *sip)
-{
- esp_sip_dbg(ESP_DBG_TRACE, "\n \t tx_data %u \t tx_cmd %u \t rx_data %u \t rx_evt %u \t rx_tx_status %u \n\n", \
- str.tx_data, str.tx_cmd, str.rx_data, str.rx_evt, str.rx_tx_status);
-}
-#endif //0000
-#endif //SIP_DEBUG
-
-#if 0
-static void show_data_seq(u8 *pkt)
-{
- struct ieee80211_hdr * wh = (struct ieee80211_hdr *)pkt;
- u16 seq = 0;
-
- if (ieee80211_is_data(wh->frame_control)) {
- seq = (le16_to_cpu(wh->seq_ctrl) >> 4);
- esp_sip_dbg(ESP_DBG_TRACE, " ieee80211 seq %u addr1 %pM\n", seq, wh->addr1);
- } else if (ieee80211_is_beacon(wh->frame_control) || ieee80211_is_probe_resp(wh->frame_control))
- esp_sip_dbg(ESP_DBG_TRACE, " ieee80211 probe resp or beacon 0x%04x\n", wh->frame_control);
- else
- esp_sip_dbg(ESP_DBG_TRACE, " ieee80211 other mgmt pkt 0x%04x\n", wh->frame_control);
-}
-#endif //0000
-
-//#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
-static bool check_ac_tid(u8 *pkt, u8 ac, u8 tid)
-{
- struct ieee80211_hdr * wh = (struct ieee80211_hdr *)pkt;
-#ifdef TID_DEBUG
- u16 real_tid = 0;
-#endif //TID_DEBUG
-
- if (ieee80211_is_data_qos(wh->frame_control)) {
-#ifdef TID_DEBUG
- real_tid = *ieee80211_get_qos_ctl(wh) & IEEE80211_QOS_CTL_TID_MASK;
-
- esp_sip_dbg(ESP_SHOW, "ac:%u, tid:%u, tid in pkt:%u\n", ac, tid, real_tid);
- if (tid != real_tid) {
- esp_sip_dbg(ESP_DBG_ERROR, "111 ac:%u, tid:%u, tid in pkt:%u\n", ac, tid, real_tid);
- }
- if (TID_TO_AC(tid) != ac) {
- esp_sip_dbg(ESP_DBG_ERROR, "222 ac:%u, tid:%u, tid in pkt:%u\n", ac, tid, real_tid);
- }
-
- //ASSERT(tid == real_tid);
- //ASSERT(TID_TO_AC(tid) == ac);
-#endif /* TID_DEBUG*/
- } else if (ieee80211_is_mgmt(wh->frame_control)) {
-#ifdef TID_DEBUG
- esp_sip_dbg(ESP_SHOW, "ac:%u, tid:%u\n", ac, tid);
- if (tid != 7 || ac != WME_AC_VO) {
- esp_sip_dbg(ESP_DBG_ERROR, "333 ac:%u, tid:%u\n", ac, tid);
- }
- //ASSERT(tid == 7);
- //ASSERT(ac == WME_AC_VO);
-#endif /* TID_DEBUG*/
- } else {
- if (ieee80211_is_ctl(wh->frame_control)) {
-#ifdef TID_DEBUG
- esp_sip_dbg(ESP_SHOW, "%s is ctrl pkt fc 0x%04x ac:%u, tid:%u, tid in pkt:%u\n", __func__, wh->frame_control, ac, tid, real_tid);
-#endif /* TID_DEBUG*/
- } else {
- if (tid != 0 || ac != WME_AC_BE) {
- //show_buf(pkt, 24);
- esp_sip_dbg(ESP_DBG_LOG, "444 ac:%u, tid:%u \n", ac, tid);
- if (tid == 7 && ac == WME_AC_VO)
- return false;
- }
- return true; //hack to modify non-qos null data.
-
- }
- //ASSERT(tid == 0);
- //ASSERT(ac = WME_AC_BE);
- }
-
- return false;
-}
-//#endif /* NEW_KERNEL || KERNEL_35 */
-
-static void sip_update_tx_credits(struct esp_sip *sip, u16 recycled_credits)
-{
- esp_sip_dbg(ESP_DBG_TRACE, "%s:before add, credits is %d\n", __func__, atomic_read(&sip->tx_credits));
- atomic_add(recycled_credits, &sip->tx_credits);
- esp_sip_dbg(ESP_DBG_TRACE, "%s:after add %d, credits is %d\n", __func__, recycled_credits, atomic_read(&sip->tx_credits));
-}
-
-void sip_trigger_txq_process(struct esp_sip *sip)
-{
- if (atomic_read(&sip->tx_credits) <= sip->credit_to_reserve) //no credits, do nothing
- return;
-
- if (sip_queue_may_resume(sip)) {
- /* wakeup upper queue only if we have sufficient credits */
- esp_sip_dbg(ESP_DBG_TRACE, "%s wakeup ieee80211 txq \n", __func__);
- atomic_set(&sip->epub->txq_stopped, false);
- ieee80211_wake_queues(sip->epub->hw);
- } else if (atomic_read(&sip->epub->txq_stopped) ) {
- esp_sip_dbg(ESP_DBG_TRACE, "%s can't wake txq, credits: %d \n", __func__, atomic_read(&sip->tx_credits) );
- }
-
- if (!skb_queue_empty(&sip->epub->txq)) {
- /* try to send out pkt already in sip queue once we have credits */
- esp_sip_dbg(ESP_DBG_TRACE, "%s resume sip txq \n", __func__);
-#if !defined(FPGA_LOOPBACK) && !defined(FPGA_TXDATA) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32))
- ieee80211_queue_work(sip->epub->hw, &sip->epub->tx_work);
-#else
- queue_work(sip->epub->esp_wkq, &sip->epub->tx_work);
-#endif
- }
-}
-
-static bool sip_ampdu_occupy_buf(struct esp_sip *sip, struct esp_rx_ampdu_len * ampdu_len)
-{
- return (ampdu_len->substate == 0 || esp_wmac_rxsec_error(ampdu_len->substate) || (sip->dump_rpbm_err && ampdu_len->substate == RX_RPBM_ERR));
-}
-
-#ifdef RX_SYNC
-static void sip_rx_pkt_process_sync(struct esp_sip *sip, struct sk_buff *skb)
-#else
-static bool sip_rx_pkt_process(struct esp_sip * sip, struct sk_buff *skb)
-#endif /* RX_SYNC */
-{
-#define DO_NOT_COPY false
-#define DO_COPY true
-
- struct sip_hdr * hdr = NULL;
- struct sk_buff * rskb = NULL;
- int remains_len = 0;
- int first_pkt_len = 0;
- u8 *bufptr = NULL;
- int ret = 0;
- bool trigger_rxq = false;
-#ifdef RX_SYNC
- bool trigger_txq = false;
-#endif/* RX_SYNC */
-
- if (skb == NULL) {
- esp_sip_dbg(ESP_DBG_ERROR, "%s NULL SKB!!!!!!!! \n", __func__);
-#ifdef RX_SYNC
- return;
-#else
- return trigger_rxq;
-#endif /* RX_SYNC */
- }
-
- hdr = (struct sip_hdr *)skb->data;
- bufptr = skb->data;
-
-
- esp_sip_dbg(ESP_DBG_TRACE, "%s Hcredits 0x%08x, realCredits %d\n", __func__, hdr->h_credits, hdr->h_credits & SIP_CREDITS_MASK);
- if (hdr->h_credits & SIP_CREDITS_MASK) {
- sip_update_tx_credits(sip, hdr->h_credits & SIP_CREDITS_MASK);
-#ifdef RX_SYNC
- trigger_txq = true;
-#endif/* RX_SYNC */
- }
-
- hdr->h_credits &= ~SIP_CREDITS_MASK; /* clean credits in sip_hdr, prevent over-add */
-
- esp_sip_dbg(ESP_DBG_TRACE, "%s credits %d\n", __func__, hdr->h_credits);
-
- /*
- * first pkt's length is stored in recycled_credits first 20 bits
- * config w3 [31:12]
- * repair hdr->len of first pkt
- */
- remains_len = hdr->len;
- first_pkt_len = hdr->h_credits >> 12;
- hdr->len = first_pkt_len;
-
- esp_dbg(ESP_DBG_TRACE, "%s first_pkt_len %d, whole pkt len %d \n", __func__, first_pkt_len, remains_len);
- if (first_pkt_len > remains_len) {
- printk("first_pkt_len %d, whole pkt len %d\n", first_pkt_len, remains_len);
- show_buf((u8 *)hdr, first_pkt_len);
- ASSERT(0);
- }
-
- /*
- * pkts handling, including the first pkt, should alloc new skb for each data pkt.
- * free the original whole skb after parsing is done.
- */
- while (remains_len) {
- ASSERT(remains_len >= sizeof(struct sip_hdr));
- hdr = (struct sip_hdr *)bufptr;
- ASSERT(hdr->len > 0);
- if((hdr->len & 3) != 0) {
- show_buf((u8 *)hdr, 512);
- }
- ASSERT((hdr->len & 3) == 0);
- if (unlikely(hdr->seq != sip->rxseq++)) {
- esp_dbg(ESP_DBG_ERROR, "%s seq mismatch! got %u, expect %u\n", __func__, hdr->seq, sip->rxseq-1);
- show_buf(bufptr, 32);
- ASSERT(0);
- }
-
- if (SIP_HDR_IS_CTRL(hdr)) {
- STRACE_RX_EVENT_INC();
- esp_sip_dbg(ESP_DBG_TRACE, "seq %u \n", hdr->seq);
-
- ret = sip_parse_events(sip, bufptr);
-
- skb_pull(skb, hdr->len);
-
- } else if (SIP_HDR_IS_DATA(hdr)) {
- struct esp_mac_rx_ctrl * mac_ctrl = NULL;
- int pkt_len_enc = 0, buf_len = 0, pulled_len = 0;
-
- STRACE_RX_DATA_INC();
- esp_sip_dbg(ESP_DBG_TRACE, "seq %u \n", hdr->seq);
- mac_ctrl = sip_parse_normal_mac_ctrl(skb, &pkt_len_enc, &buf_len, &pulled_len);
- rskb = sip_parse_data_rx_info(sip, skb, pkt_len_enc, buf_len, mac_ctrl, &pulled_len);
-
- if(rskb == NULL)
- goto _move_on;
-
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35))
- sip_check_skb_alignment(rskb);
-#endif /* !NEW_KERNEL */
- if (likely(atomic_read(&sip->epub->wl.off) == 0)) {
-#ifndef RX_SENDUP_SYNC
- skb_queue_tail(&sip->epub->rxq, rskb);
- trigger_rxq = true;
-#else
-#ifdef RX_CHECKSUM_TEST
- esp_rx_checksum_test(rskb);
-#endif
- local_bh_disable();
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32))
- ieee80211_rx(sip->epub->hw, rskb);
-#else
- //simulate IEEE80211_SKB_RXCB in 2.6.32
- ieee80211_rx(sip->epub->hw, rskb ,(struct ieee80211_rx_status *)rskb->cb);
-#endif
- local_bh_enable();
-#endif /* RX_SENDUP_SYNC */
- } else {
- /* still need go thro parsing as skb_pull should invoke */
- kfree_skb(rskb);
- }
- } else if (SIP_HDR_IS_AMPDU(hdr)) {
- struct esp_mac_rx_ctrl * mac_ctrl = NULL;
- struct esp_mac_rx_ctrl new_mac_ctrl;
- struct esp_rx_ampdu_len *ampdu_len;
- int pkt_num;
- int pulled_len = 0;
- static int pkt_dropped = 0;
- static int pkt_total = 0;
- bool have_rxabort = false;
- bool have_goodpkt = false;
- static u8 frame_head[16];
- static u8 frame_buf_ttl = 0;
-
- ampdu_len = (struct esp_rx_ampdu_len *)(skb->data + hdr->len/sip->rx_blksz * sip->rx_blksz);
- esp_sip_dbg(ESP_DBG_TRACE, "%s rx ampdu total len %u\n", __func__, hdr->len);
- if(skb->data != (u8 *)hdr) {
- printk("%p %p\n", skb->data, hdr);
- show_buf(skb->data, 512);
- show_buf((u8 *)hdr, 512);
- }
- ASSERT(skb->data == (u8 *)hdr);
- mac_ctrl = sip_parse_normal_mac_ctrl(skb, NULL, NULL, &pulled_len);
- memcpy(&new_mac_ctrl, mac_ctrl, sizeof(struct esp_mac_rx_ctrl));
- mac_ctrl = &new_mac_ctrl;
- pkt_num = mac_ctrl->ampdu_cnt;
- esp_sip_dbg(ESP_DBG_TRACE, "%s %d rx ampdu %u pkts, %d pkts dumped, first len %u\n",
- __func__, __LINE__, (unsigned int)((hdr->len % sip->rx_blksz) / sizeof(struct esp_rx_ampdu_len)), pkt_num, (unsigned int)ampdu_len->sublen);
-
- pkt_total += mac_ctrl->ampdu_cnt;
- //esp_sip_dbg(ESP_DBG_ERROR, "%s ampdu dropped %d/%d\n", __func__, pkt_dropped, pkt_total);
- while (pkt_num > 0) {
- esp_sip_dbg(ESP_DBG_TRACE, "%s %d ampdu sub state %02x,\n", __func__, __LINE__, ampdu_len->substate);
-
- if (sip_ampdu_occupy_buf(sip, ampdu_len)) { //pkt is dumped
-
- rskb = sip_parse_data_rx_info(sip, skb, ampdu_len->sublen - FCS_LEN, 0, mac_ctrl, &pulled_len);
- assert(rskb != NULL);
-
- if (likely(atomic_read(&sip->epub->wl.off) == 0) &&
- (ampdu_len->substate == 0 || ampdu_len->substate == RX_TKIPMIC_ERR ||
- (sip->sendup_rpbm_pkt && ampdu_len->substate == RX_RPBM_ERR)) &&
- (sip->rxabort_fixed || !have_rxabort) )
- {
- if(!have_goodpkt) {
- have_goodpkt = true;
- memcpy(frame_head, rskb->data, 16);
- frame_head[1] &= ~0x80;
- frame_buf_ttl = 3;
- }
-#ifndef RX_SENDUP_SYNC
- skb_queue_tail(&sip->epub->rxq, rskb);
- trigger_rxq = true;
-#else
-#ifdef RX_CHECKSUM_TEST
- esp_rx_checksum_test(rskb);
-#endif
- local_bh_disable();
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32))
- ieee80211_rx(sip->epub->hw, rskb);
-#else
- //simulate IEEE80211_SKB_RXCB in 2.6.32
- ieee80211_rx(sip->epub->hw, rskb ,(struct ieee80211_rx_status *)rskb->cb);
-#endif
- local_bh_enable();
-#endif /* RX_SENDUP_SYNC */
-
- } else {
- kfree_skb(rskb);
- }
- } else {
- if (ampdu_len->substate == RX_ABORT) {
- u8 * a;
- have_rxabort = true;
- esp_sip_dbg(ESP_DBG_TRACE, "rx abort %d %d\n", frame_buf_ttl, pkt_num);
- if(frame_buf_ttl && !sip->rxabort_fixed) {
- struct esp_rx_ampdu_len * next_good_ampdu_len = ampdu_len + 1;
- a = frame_head;
- esp_sip_dbg(ESP_DBG_TRACE, "frame:%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
- a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]);
- while(!sip_ampdu_occupy_buf(sip, next_good_ampdu_len)) {
- if(next_good_ampdu_len > ampdu_len + pkt_num - 1)
- break;
- next_good_ampdu_len++;
-
- }
- if(next_good_ampdu_len <= ampdu_len + pkt_num -1) {
- bool b0, b10, b11;
- a = skb->data;
- esp_sip_dbg(ESP_DBG_TRACE, "buf:%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
- a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]);
- b0 = memcmp(frame_head + 4, skb->data + 4, 12) == 0;
- b10 = memcmp(frame_head + 10, skb->data, 6) == 0;
- b11 = memcpy(frame_head + 11, skb->data, 5) == 0;
- esp_sip_dbg(ESP_DBG_TRACE, "com %d %d %d\n", b0, b10, b11);
- if(b0 && !b10 && !b11) {
- have_rxabort = false;
- esp_sip_dbg(ESP_DBG_TRACE, "repair 0\n");
- } else if(!b0 && b10 && !b11) {
- skb_push(skb, 10);
- memcpy(skb->data, frame_head, 10);
- have_rxabort = false;
- pulled_len -= 10;
- esp_sip_dbg(ESP_DBG_TRACE, "repair 10\n");
- } else if(!b0 && !b10 && b11) {
- skb_push(skb, 11);
- memcpy(skb->data, frame_head, 11);
- have_rxabort = false;
- pulled_len -= 11;
- esp_sip_dbg(ESP_DBG_TRACE, "repair 11\n");
- }
- }
- }
- }
- pkt_dropped++;
- esp_sip_dbg(ESP_DBG_LOG, "%s ampdu dropped %d/%d\n", __func__, pkt_dropped, pkt_total);
- }
- pkt_num--;
- ampdu_len++;
- }
- if(frame_buf_ttl)
- frame_buf_ttl--;
- skb_pull(skb, hdr->len - pulled_len);
- } else {
- esp_sip_dbg(ESP_DBG_ERROR, "%s %d unknown type\n", __func__, __LINE__);
- }
-
-_move_on:
- if (hdr->len < remains_len) {
- remains_len -= hdr->len;
- } else {
- break;
- }
- bufptr += hdr->len;
- }
-
- do {
- ASSERT(skb != rskb);
- kfree_skb(skb);
- } while (0);
-
-#ifdef RX_SYNC
- if (trigger_rxq) {
- queue_work(sip->epub->esp_wkq, &sip->epub->sendup_work);
- }
- if (trigger_txq) {
- sip_trigger_txq_process(sip);
- }
-#else
- return trigger_rxq;
-#endif /* RX_SYNC */
-
-#undef DO_NOT_COPY
-#undef DO_COPY
-}
-
-#ifndef RX_SYNC
-static void _sip_rxq_process(struct esp_sip *sip)
-{
- struct sk_buff *skb = NULL;
- bool sendup = false;
-
- while ((skb = skb_dequeue(&sip->rxq))) {
- if (sip_rx_pkt_process(sip, skb))
- sendup = true;
- }
-#ifndef RX_SENDUP_SYNC
- if (sendup) {
- queue_work(sip->epub->esp_wkq, &sip->epub->sendup_work);
- }
-#endif /* !RX_SENDUP_SYNC */
-
- /* probably tx_credit is updated, try txq */
- sip_trigger_txq_process(sip);
-}
-
-void sip_rxq_process(struct work_struct *work)
-{
- struct esp_sip *sip = container_of(work, struct esp_sip, rx_process_work);
- ASSERT(sip != NULL);
-
- if (unlikely(atomic_read(&sip->state) == SIP_SEND_INIT)) {
- sip_send_chip_init(sip);
- atomic_set(&sip->state, SIP_WAIT_BOOTUP);
- return;
- }
-
- spin_lock(&sip->rx_lock);
- _sip_rxq_process(sip);
- spin_unlock(&sip->rx_lock);
-}
-
-static inline void sip_rx_pkt_enqueue(struct esp_sip *sip, struct sk_buff *skb)
-{
- skb_queue_tail(&sip->rxq, skb);
-}
-
-static inline struct sk_buff * sip_rx_pkt_dequeue(struct esp_sip *sip) {
- return skb_dequeue(&sip->rxq);
-}
-#endif /* RX_SYNC */
-
-static u32 sip_rx_count = 0;
-void sip_debug_show(struct esp_sip *sip)
-{
- esp_sip_dbg(ESP_DBG_ERROR, "txq left %d %d\n", skb_queue_len(&sip->epub->txq), atomic_read(&sip->tx_data_pkt_queued));
- esp_sip_dbg(ESP_DBG_ERROR, "tx queues stop ? %d\n", atomic_read(&sip->epub->txq_stopped));
- esp_sip_dbg(ESP_DBG_ERROR, "txq stop? %d\n", test_bit(ESP_WL_FLAG_STOP_TXQ, &sip->epub->wl.flags));
- esp_sip_dbg(ESP_DBG_ERROR, "tx credit %d\n", atomic_read(&sip->tx_credits));
- esp_sip_dbg(ESP_DBG_ERROR, "rx collect %d\n", sip_rx_count);
- sip_rx_count = 0;
-}
-
-#ifndef LOOKAHEAD
-int sip_rx(struct esp_pub *epub)
-{
- struct sip_hdr *shdr = NULL;
- struct esp_sip *sip = epub->sip;
- int err = 0;
- struct sk_buff *first_skb = NULL;
- struct sk_buff *next_skb = NULL;
- u8 *rx_buf = NULL;
- u32 rx_blksz;
- u32 first_sz = 4;
- struct sk_buff *rx_skb = NULL;
-
- esp_sip_dbg(ESP_DBG_LOG, "%s enter\n", __func__);
-
-
- /* first read one block out, if we luck enough, that's it
- *
- * To make design as simple as possible, we allocate skb(s)
- * separately for each sif read operation to avoid global
- * read_buf_pointe access. It coule be optimized late.
- */
- rx_blksz = sif_get_blksz(epub);
- first_skb = __dev_alloc_skb(first_sz, GFP_KERNEL);
- if (first_skb == NULL) {
- esp_sip_dbg(ESP_DBG_ERROR, "%s first no memory \n", __func__);
- goto _err;
- }
-
- rx_buf = skb_put(first_skb, first_sz);
- esp_sip_dbg(ESP_DBG_LOG, "%s rx_buf ptr %p, first_sz %d\n", __func__, rx_buf, first_sz);
-
- sif_lock_bus(epub);
-
-#ifdef USE_EXT_GPIO
- do{
- int err2;
- u16 value = 0;
- u16 intr_mask = ext_gpio_get_int_mask_reg();
- if(!intr_mask)
- break;
- err2 = sif_get_gpio_intr(epub, intr_mask, &value);
- if(!err2 && value) {
- esp_sip_dbg(ESP_DBG_TRACE, "%s intr_mask[0x%04x] value[0x%04x]\n", __func__, intr_mask, value);
- ext_gpio_int_process(value);
- }
- }while(0);
-#endif
-#ifdef ESP_ACK_INTERRUPT
-#ifdef ESP_ACK_LATER
- err = esp_common_read(epub, rx_buf, first_sz, ESP_SIF_NOSYNC, true);
- sif_platform_ack_interrupt(epub);
-#else
- sif_platform_ack_interrupt(epub);
- err = esp_common_read(epub, rx_buf, first_sz, ESP_SIF_NOSYNC, true);
-#endif /* ESP_ACK_LATER */
-#else
- err = esp_common_read(epub, rx_buf, first_sz, ESP_SIF_NOSYNC, true);
-#endif //ESP_ACK_INTERRUPT
-
- sip_rx_count++;
- if (unlikely(err)) {
- esp_dbg(ESP_DBG_ERROR, " %s first read err %d %d\n", __func__, err, sif_get_regs(epub)->config_w0);
- kfree_skb(first_skb);
- sif_unlock_bus(epub);
- goto _err;
- }
-
- shdr = (struct sip_hdr *)rx_buf;
- if(SIP_HDR_IS_CTRL(shdr) && (shdr->c_evtid == SIP_EVT_SLEEP)) {
- atomic_set(&sip->epub->ps.state, ESP_PM_ON);
- esp_dbg(ESP_DBG_TRACE, "s\n");
- }
-
- ASSERT((shdr->len & 3) == 0);
- //ASSERT(shdr->len >= SIP_HDR_LEN && shdr->len <= SIP_PKT_MAX_LEN);
- if (shdr->len > first_sz) {
- /* larger than one blk, fetch the rest */
- next_skb = __dev_alloc_skb(roundup(shdr->len, rx_blksz) + first_sz, GFP_KERNEL);
- if (unlikely(next_skb == NULL)) {
- sif_unlock_bus(epub);
- esp_sip_dbg(ESP_DBG_ERROR, "%s next no memory \n", __func__);
- kfree_skb(first_skb);
- goto _err;
- }
- rx_buf = skb_put(next_skb, shdr->len);
- rx_buf += first_sz; /* skip the first block */
-
- err = esp_common_read(epub, rx_buf, (shdr->len - first_sz), ESP_SIF_NOSYNC, false);
- sif_unlock_bus(epub);
-
- if (unlikely(err)) {
- esp_sip_dbg(ESP_DBG_ERROR, "%s next read err %d \n", __func__, err);
- kfree(first_skb);
- kfree(next_skb);
- goto _err;
- }
- /* merge two skbs, TBD: could be optimized by skb_linearize*/
- memcpy(next_skb->data, first_skb->data, first_sz);
- esp_dbg(ESP_DBG_TRACE, " %s next skb\n", __func__);
-
- rx_skb = next_skb;
- kfree_skb(first_skb);
- } else {
- sif_unlock_bus(epub);
- skb_trim(first_skb, shdr->len);
- esp_dbg(ESP_DBG_TRACE, " %s first_skb only\n", __func__);
-
- rx_skb = first_skb;
- }
- if (atomic_read(&sip->state) == SIP_STOP) {
- kfree_skb(rx_skb);
- esp_sip_dbg(ESP_DBG_ERROR, "%s when sip stopped\n", __func__);
- return 0;
- }
-#ifndef RX_SYNC
- sip_rx_pkt_enqueue(sip, rx_skb);
- queue_work(sip->epub->esp_wkq, &sip->rx_process_work);
-#else
- sip_rx_pkt_process_sync(sip, rx_skb);
-#endif /* RX_SYNC */
-
-_err:
-
- return err;
-}
-
-#else
-
-int sip_rx(struct esp_pub *epub)
-{
- struct sip_hdr *shdr = NULL;
- struct esp_sip *sip = epub->sip;
- int err = 0;
- struct sk_buff *rx_skb = NULL;
- u8 *rx_buf = NULL;
- u32 lookahead = 0;
- struct slc_host_regs *regs = sif_get_regs(epub);
- bool free_skb = false;
-
- esp_sip_dbg(ESP_DBG_LOG, "%s enter\n", __func__);
-
- lookahead = regs->config_w0;
-
- esp_sip_dbg(ESP_DBG_TRACE, "%s lookahead %u \n", __func__, lookahead);
- rx_skb = __dev_alloc_skb(lookahead, GFP_KERNEL);
- if (rx_skb == NULL) {
- esp_sip_dbg(ESP_DBG_ERROR, "%s no memory \n", __func__);
- goto __out;
- }
- rx_buf = skb_put(rx_skb, lookahead);
- err = sif_lldesc_read_raw(epub, rx_buf, lookahead);
- if (unlikely(err)) {
- esp_dbg(ESP_DBG_ERROR, " %s read err %d \n", __func__, err);
- goto __out;
- }
-
- shdr = (struct sip_hdr *)rx_buf;
- esp_sip_dbg(ESP_DBG_TRACE, "%s len %d totlen %d\n", __func__, shdr->len, (shdr->h_credits >> 12));
- show_buf(rx_buf, 32);
- //ASSERT(shdr->len >= SIP_HDR_LEN && shdr->len <= SIP_PKT_MAX_LEN);
-
- esp_sip_dbg(ESP_DBG_TRACE, "%s credits %d\n", __func__, shdr->h_credits);
- if (shdr->h_credits & SIP_CREDITS_MASK) {
- sip_update_tx_credits(sip, shdr->h_credits & SIP_CREDITS_MASK);
- }
-#if 0
- if (SIP_HDR_IS_CREDIT_RPT(shdr)) {
- esp_sip_dbg(ESP_DBG_TRACE, "%s credit update %d\n", __func__, shdr->h_credits & SIP_CREDITS_MASK);
- if (unlikely(shdr->seq != sip->rxseq++)) {
- esp_sip_dbg(ESP_DBG_ERROR, "%s seq mismatch! got %u, expect %u\n", __func__, shdr->seq, sip->rxseq-1);
- }
-
- free_skb = true;
- goto __out;
- }
-#endif
- shdr->h_credits &= ~SIP_CREDITS_MASK; /* clean credits in sip_hdr, prevent over-add */
-
- /* we need some place to store the total length of the pkt chain, the simple way is make it consistent with
- * non-lookahead case
- */
- shdr->h_credits = (shdr->len << 12);
- shdr->len = lookahead;
-
- sip_rx_pkt_enqueue(sip, rx_skb);
- queue_work(sip->epub->esp_wkq, &sip->rx_process_work);
-
-__out:
- if (free_skb)
- kfree_skb(rx_skb);
-
- sip_trigger_txq_process(sip);
-
- return err;
-}
-#endif /* LOOKAHEAD */
-
-int sip_get_raw_credits(struct esp_sip *sip)
-{
-#if 1
- unsigned long timeout;
- int err = 0;
-
- esp_dbg(ESP_DBG_TRACE, "%s entern \n", __func__);
-
- /* 1s timeout */
- timeout = jiffies + msecs_to_jiffies(1000);
-
- while (time_before(jiffies, timeout) && !sip->boot_credits) {
-
- err = esp_common_read_with_addr(sip->epub, SLC_HOST_TOKEN_RDATA, (u8 *)&sip->boot_credits, 4, ESP_SIF_SYNC);
-
- if (err) {
- esp_dbg(ESP_DBG_ERROR, "Can't read credits\n");
- return err;
- }
- sip->boot_credits &= SLC_HOST_TOKEN0_MASK;
-#ifdef SIP_DEBUG
- if (sip->boot_credits == 0) {
- esp_dbg(ESP_DBG_ERROR, "no credit, try again\n");
- mdelay(50);
- }
-#endif /* SIP_DEBUG */
- }
-
- if (!sip->boot_credits) {
- esp_dbg(ESP_DBG_ERROR, "read credits timeout\n");
- return -ETIMEDOUT;
- }
-
- esp_dbg(ESP_DBG_TRACE, "%s got credits: %d\n", __func__, sip->boot_credits);
-#endif //0000
-
- return 0;
-}
-
-
-/* Only cooperate with get_raw_credits */
-static void
-sip_dec_credit(struct esp_sip *sip)
-{
-#if 0
- u32 reg = 0;
- int err = 0;
-
- reg = SLC_HOST_TOKEN0_WR | SLC_HOST_TOKEN0_DEC;
- memcpy(sip->rawbuf, &reg, sizeof(u32));
- err = sif_io_sync(sip->epub, SLC_HOST_INT_CLR, sip->rawbuf, sizeof(u32), SIF_TO_DEVICE | SIF_SYNC | SIF_BYTE_BASIS | SIF_INC_ADDR);
-
- if (err)
- esp_dbg(ESP_DBG_ERROR, "%s can't clear target token0 \n", __func__);
-
-#endif //0000
- /* SLC 2.0, token reg is read-to-clean, thus no need to access target */
- sip->boot_credits--;
-}
-
-int sip_post_init(struct esp_sip *sip, struct sip_evt_bootup2 *bevt)
-{
- struct esp_pub *epub;
- int po = 0;
-
- ASSERT(sip != NULL);
-
- epub = sip->epub;
-
- po = get_order(SIP_TX_AGGR_BUF_SIZE);
- sip->tx_aggr_buf = (u8 *)__get_free_pages(GFP_ATOMIC, po);
- if (sip->tx_aggr_buf == NULL) {
- esp_dbg(ESP_DBG_ERROR, "no mem for tx_aggr_buf! \n");
- return -ENOMEM;
- }
-#if 0
- po = get_order(SIP_RX_AGGR_BUF_SIZE);
- sip->rx_aggr_buf = (u8 *)__get_free_pages(GFP_ATOMIC, po);
-
- if (sip->rx_aggr_buf == NULL) {
- po = get_order(SIP_TX_AGGR_BUF_SIZE);
- free_pages((unsigned long)sip->tx_aggr_buf, po);
- esp_dbg(ESP_DBG_ERROR, "no mem for rx_aggr_buf! \n");
- return -ENOMEM;
- }
-#endif
-
- sip->tx_aggr_write_ptr = sip->tx_aggr_buf;
-
- sip->tx_blksz = bevt->tx_blksz;
- sip->rx_blksz = bevt->rx_blksz;
- sip->credit_to_reserve = bevt->credit_to_reserve;
-
- sip->dump_rpbm_err = (bevt->options & SIP_DUMP_RPBM_ERR);
- sip->rxabort_fixed = (bevt->options & SIP_RXABORT_FIXED);
- sip->support_bgscan = (bevt->options & SIP_SUPPORT_BGSCAN);
-
- sip->sendup_rpbm_pkt = sip->dump_rpbm_err && false;
-
- /* print out MAC addr... */
- memcpy(epub->mac_addr, bevt->mac_addr, ETH_ALEN);
- atomic_set(&sip->noise_floor, bevt->noise_floor);
-
- esp_sip_dbg(ESP_DBG_TRACE, "%s tx_blksz %d rx_blksz %d mac addr %pM\n", __func__, sip->tx_blksz, sip->rx_blksz, epub->mac_addr);
-
- return 0;
-}
-
-/* write pkts in aggr buf to target memory */
-static void sip_write_pkts(struct esp_sip *sip, int pm_state)
-{
- int tx_aggr_len = 0;
- struct sip_hdr *first_shdr = NULL;
- int err = 0;
-
- tx_aggr_len = sip->tx_aggr_write_ptr - sip->tx_aggr_buf;
- if (tx_aggr_len < sizeof(struct sip_hdr)) {
- printk("%s tx_aggr_len %d \n", __func__, tx_aggr_len);
- ASSERT(0);
- }
- //ASSERT(tx_aggr_len >= sizeof(struct sip_hdr));
- ASSERT((tx_aggr_len & 0x3) == 0);
-
- first_shdr = (struct sip_hdr *)sip->tx_aggr_buf;
-
- if (atomic_read(&sip->tx_credits) <= SIP_CREDITS_LOW_THRESHOLD) {
- first_shdr->fc[1] |= SIP_HDR_F_NEED_CRDT_RPT;
- }
-
- ASSERT(tx_aggr_len == sip->tx_tot_len);
-
- /* still use lock bus instead of sif_lldesc_write_sync since we want to protect several global varibles assignments */
- sif_lock_bus(sip->epub);
-
- /* add a dummy read in power saving mode, although target may not really in
- * sleep
- */
- //if (atomic_read(&sip->epub->ps.state) == ESP_PM_ON) {
- // atomic_set(&sip->epub->ps.state, ESP_PM_OFF);
- sif_raw_dummy_read(sip->epub);
- //}
- //esp_dbg(ESP_DBG_ERROR, "%s write len %u\n", __func__, tx_aggr_len);
-
- err = esp_common_write(sip->epub, sip->tx_aggr_buf, tx_aggr_len, ESP_SIF_NOSYNC);
-
- sip->tx_aggr_write_ptr = sip->tx_aggr_buf;
- sip->tx_tot_len = 0;
-
-#if 0
- if (pm_state == ESP_PM_TURNING_ON) {
- ASSERT(atomic_read(&sip->epub->ps.state) == ESP_PM_TURNING_ON);
- atomic_set(&sip->epub->ps.state, ESP_PM_ON);
- } else if (pm_state == ESP_PM_TURNING_OFF) {
- ASSERT(atomic_read(&sip->epub->ps.state) == ESP_PM_TURNING_OFF);
- atomic_set(&sip->epub->ps.state, ESP_PM_OFF);
- esp_dbg(ESP_DBG_PS, "----beacon %d, probe rsp %d -------\n", bcn_counter, probe_rsp_counter);
- bcn_counter = 0; probe_rsp_counter = 0;
- } else if (pm_state && atomic_read(&sip->epub->ps.state)) {
- esp_dbg(ESP_DBG_ERROR, "%s wrong pm_state %d ps.state %d \n", __func__, pm_state, atomic_read(&sip->epub->ps.state));
- }
-#endif
- sif_unlock_bus(sip->epub);
-
- if (err)
- esp_sip_dbg(ESP_DBG_ERROR, "func %s err!!!!!!!!!: %d\n", __func__, err);
-
-}
-
-/* setup sip header and tx info, copy pkt into aggr buf */
-static int sip_pack_pkt(struct esp_sip *sip, struct sk_buff *skb, int *pm_state)
-{
- struct ieee80211_tx_info *itx_info;
- struct sip_hdr *shdr;
- u32 tx_len = 0, offset = 0;
- bool is_data = true;
-
- itx_info = IEEE80211_SKB_CB(skb);
-
- if (itx_info->flags == 0xffffffff) {
- shdr = (struct sip_hdr *)skb->data;
- is_data = false;
- tx_len = skb->len;
- } else {
- struct ieee80211_hdr * wh = (struct ieee80211_hdr *)skb->data;
- struct esp_vif *evif = (struct esp_vif *)itx_info->control.vif->drv_priv;
- u8 sta_index;
- struct esp_node *node;
- /* update sip header */
- shdr = (struct sip_hdr *)sip->tx_aggr_write_ptr;
-
- shdr->fc[0] = 0;
- shdr->fc[1] = 0;
-
- if ((itx_info->flags & IEEE80211_TX_CTL_AMPDU) && (true || esp_is_ip_pkt(skb)))
- SIP_HDR_SET_TYPE(shdr->fc[0], SIP_DATA_AMPDU);
- else
- SIP_HDR_SET_TYPE(shdr->fc[0], SIP_DATA);
-
- if(evif->epub == NULL){
-#ifndef FAST_TX_STATUS
- /* TBD */
-#else
- sip_tx_status_report(sip, skb, itx_info, false);
- atomic_dec(&sip->tx_data_pkt_queued);
- return -EINVAL;
-#endif /* FAST_TX_STATUS */
- }
-
- /* make room for encrypted pkt */
- if (itx_info->control.hw_key) {
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39))
- shdr->d_enc_flag= itx_info->control.hw_key->alg+1;
-#else
- int alg = esp_cipher2alg(itx_info->control.hw_key->cipher);
- if (unlikely(alg == -1)) {
-#ifndef FAST_TX_STATUS
- /* TBD */
-#else
- sip_tx_status_report(sip, skb, itx_info, false);
- atomic_dec(&sip->tx_data_pkt_queued);
- return -1;
-#endif /* FAST_TX_STATUS */
- } else {
- shdr->d_enc_flag = alg + 1;
- }
-
-#endif /* NEW_KERNEL */
- shdr->d_hw_kid = itx_info->control.hw_key->hw_key_idx | (evif->index<<7);
- } else {
- shdr->d_enc_flag=0;
- shdr->d_hw_kid = (evif->index << 7 | evif->index);
- }
-
- /* update sip tx info */
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))
- if(itx_info->control.sta == NULL){
- node = NULL;
- } else {
- node = esp_get_node_by_addr(sip->epub, itx_info->control.sta->addr);
- }
-#else
-
- node = esp_get_node_by_addr(sip->epub, wh->addr1);
-#endif
- if(node != NULL)
- sta_index = node->index;
- else
- sta_index = ESP_PUB_MAX_STA + 1;
- SIP_HDR_SET_IFIDX(shdr->fc[0], evif->index << 3 | sta_index);
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
- shdr->d_p2p = itx_info->control.vif->p2p;
- if(evif->index == 1)
- shdr->d_p2p = 1;
-#endif
- shdr->d_ac = skb_get_queue_mapping(skb);
- shdr->d_tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
- wh = (struct ieee80211_hdr *)skb->data;
- if (ieee80211_is_mgmt(wh->frame_control)) {
- /* addba/delba/bar may use different tid/ac */
- if (ieee80211_is_beacon(wh->frame_control)||shdr->d_ac == WME_AC_VO) {
- shdr->d_tid = 7;
- }
- }
-//#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
- if (check_ac_tid(skb->data, shdr->d_ac, shdr->d_tid)) {
- shdr->d_ac = WME_AC_BE;
- shdr->d_tid = 0;
- }
-//#endif /* NEW_KERNEL || KERNEL_35 */
-
-
- /* make sure data is start at 4 bytes aligned addr. */
- offset = roundup(sizeof(struct sip_hdr), 4);
-
-#ifdef HOST_RC
- esp_sip_dbg(ESP_DBG_TRACE, "%s offset0 %d \n", __func__, offset);
- memcpy(sip->tx_aggr_write_ptr + offset, (void *)&itx_info->control,
- sizeof(struct sip_tx_rc));
-
- offset += roundup(sizeof(struct sip_tx_rc), 4);
- esp_show_tx_rates(&itx_info->control.rates[0]);
-
-#endif /* HOST_RC */
-
- if (SIP_HDR_IS_AMPDU(shdr)) {
- memset(sip->tx_aggr_write_ptr + offset, 0, sizeof(struct esp_tx_ampdu_entry));
- offset += roundup(sizeof(struct esp_tx_ampdu_entry), 4);
- }
-
- tx_len = offset + skb->len;
- shdr->len = tx_len; /* actual len */
-
- esp_sip_dbg(ESP_DBG_TRACE, "%s offset %d skblen %d txlen %d\n", __func__, offset, skb->len, tx_len);
-
- }
-
- shdr->seq = sip->txseq++;
- //esp_sip_dbg(ESP_DBG_ERROR, "%s seq %u, %u %u\n", __func__, shdr->seq, SIP_HDR_GET_TYPE(shdr->fc[0]),shdr->c_cmdid);
-
- /* copy skb to aggr buf */
- memcpy(sip->tx_aggr_write_ptr + offset, skb->data, skb->len);
-
- if (is_data) {
- spin_lock_bh(&sip->epub->tx_lock);
- sip->txdataseq = shdr->seq;
- spin_unlock_bh(&sip->epub->tx_lock);
-#ifndef FAST_TX_STATUS
- /* store seq in driver data, need seq to pick pkt during tx status report */
- *(u32 *)itx_info->driver_data = shdr->seq;
- atomic_inc(&sip->pending_tx_status);
-#else
- /* fake a tx_status and report to mac80211 stack to speed up tx, may affect
- * 1) rate control (now it's all in target, so should be OK)
- * 2) ps mode, mac80211 want to check ACK of ps/nulldata to see if AP is awake
- * 3) BAR, mac80211 do BAR by checking ACK
- */
- /*
- * XXX: need to adjust for 11n, e.g. report tx_status according to BA received in target
- *
- */
- sip_tx_status_report(sip, skb, itx_info, true);
- atomic_dec(&sip->tx_data_pkt_queued);
-
-#endif /* FAST_TX_STATUS */
- STRACE_TX_DATA_INC();
- } else {
- /* check pm state here */
-#if 0
- if (*pm_state == 0) {
- if (SIP_HDR_IS_PM_TURNING_ON(shdr))
- *pm_state = ESP_PM_TURNING_ON;
- else if (SIP_HDR_IS_PM_TURNING_OFF(shdr))
- *pm_state = ESP_PM_TURNING_OFF;
- } else {
- if (SIP_HDR_IS_PM_TURNING_ON(shdr) || SIP_HDR_IS_PM_TURNING_OFF(shdr)) {
- esp_dbg(ESP_DBG_ERROR, "%s two pm states in one bunch - prev: %d; curr %d\n", __func__,
- *pm_state, SIP_HDR_IS_PM_TURNING_ON(shdr)?ESP_PM_TURNING_ON:ESP_PM_TURNING_OFF);
- if (*pm_state == ESP_PM_TURNING_ON && SIP_HDR_IS_PM_TURNING_OFF(shdr)) {
- *pm_state = 0;
- atomic_set(&sip->epub->ps.state, ESP_PM_OFF);
- } else if (*pm_state == ESP_PM_TURNING_OFF && SIP_HDR_IS_PM_TURNING_ON(shdr)) {
- *pm_state = 0;
- atomic_set(&sip->epub->ps.state, ESP_PM_ON);
- } else {
- ASSERT(0);
- }
- }
- }
-#endif
- /* no need to hold ctrl skb */
- sip_free_ctrl_skbuff(sip, skb);
- STRACE_TX_CMD_INC();
- }
-
- /* TBD: roundup here or whole aggr-buf */
- tx_len = roundup(tx_len, sip->tx_blksz);
-
- sip->tx_aggr_write_ptr += tx_len;
- sip->tx_tot_len += tx_len;
-
- return 0;
-}
-
-#ifndef FAST_TX_STATUS
-static void
-sip_after_tx_status_update(struct esp_sip *sip)
-{
- if (atomic_read(&sip->data_tx_stopped) == true && sip_tx_data_may_resume(sip)) {
- atomic_set(&sip->data_tx_stopped, false);
- if (sip_is_tx_mblk_avail(sip) == false) {
- esp_sip_dbg(ESP_DBG_ERROR, "%s mblk still unavail \n", __func__);
- } else {
- esp_sip_dbg(ESP_DBG_TRACE, "%s trigger txq \n", __func__);
- sip_trigger_txq_process(sip);
- }
- } else if (!sip_tx_data_may_resume(sip)) { //JLU: this is redundant
- STRACE_SHOW(sip);
- }
-}
-#endif /* !FAST_TX_STATUS */
-
-#ifdef HOST_RC
-static void sip_set_tx_rate_status(struct sip_rc_status *rcstatus, struct ieee80211_tx_rate *irates)
-{
- int i;
- u8 shift = 0;
- u32 cnt = 0;
-
- for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
- if (rcstatus->rc_map & BIT(i)) {
- shift = i << 2;
- cnt = (rcstatus->rc_cnt_store >> shift) & RC_CNT_MASK;
- irates[i].idx = i;
- irates[i].count = (u8)cnt;
- } else {
- irates[i].idx = -1;
- irates[i].count = 0;
- }
- }
-
- esp_show_rcstatus(rcstatus);
- esp_show_tx_rates(irates);
-}
-#endif /* HOST_RC */
-
-#ifndef FAST_TX_STATUS
-static void
-sip_txdoneq_process(struct esp_sip *sip, struct sip_evt_tx_report *tx_report)
-{
- struct sk_buff *skb, *tmp;
- struct esp_pub *epub = sip->epub;
- int matchs = 0;
- struct ieee80211_tx_info *tx_info;
- struct sip_tx_status *tx_status;
- int i;
-
- esp_sip_dbg(ESP_DBG_LOG, "%s enter, report->pkts %d, pending tx_status %d\n", __func__, tx_report->pkts, atomic_read(&sip->pending_tx_status));
-
- /* traversal the txdone queue, find out matched skb by seq, hand over
- * to up layer stack
- */
- for (i = 0; i < tx_report->pkts; i++) {
- //esp_sip_dbg(ESP_DBG_TRACE, "%s status %d seq %u\n", __func__, i, tx_report->status[i].sip_seq);
- skb_queue_walk_safe(&epub->txdoneq, skb, tmp) {
- tx_info = IEEE80211_SKB_CB(skb);
-
- //esp_sip_dbg(ESP_DBG_TRACE, "%s skb seq %u\n", __func__, *(u32 *)tx_info->driver_data);
- if (tx_report->status[i].sip_seq == *(u32 *)tx_info->driver_data) {
- tx_status = &tx_report->status[i];
- __skb_unlink(skb, &epub->txdoneq);
-
- //fill up ieee80211_tx_info
- //TBD: lock ??
- if (tx_status->errno == SIP_TX_ST_OK &&
- !(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) {
- tx_info->flags |= IEEE80211_TX_STAT_ACK;
- }
-#ifdef HOST_RC
- sip_set_tx_rate_status(&tx_report->status[i].rcstatus, &tx_info->status.rates[0]);
- esp_sip_dbg(ESP_DBG_TRACE, "%s idx0 %d, cnt0 %d, flags0 0x%02x\n", __func__, tx_info->status.rates[0].idx,tx_info->status.rates[0].count, tx_info->status.rates[0].flags);
-
-#else
- /* manipulate rate status... */
- tx_info->status.rates[0].idx = 0;
- tx_info->status.rates[0].count = 1;
- tx_info->status.rates[0].flags = 0;
- tx_info->status.rates[1].idx = -1;
-#endif /* HOST_RC */
-
- ieee80211_tx_status(epub->hw, skb);
- matchs++;
- atomic_dec(&sip->pending_tx_status);
- STRACE_RX_TXSTATUS_INC();
- }
- }
- }
-
- if (matchs < tx_report->pkts) {
- esp_sip_dbg(ESP_DBG_ERROR, "%s tx report mismatch! \n", __func__);
- } else {
- //esp_sip_dbg(ESP_DBG_TRACE, "%s tx report %d pkts! \n", __func__, matchs);
- }
-
- sip_after_tx_status_update(sip);
-}
-#else
-#ifndef FAST_TX_NOWAIT
-
-static void
-sip_txdoneq_process(struct esp_sip *sip)
-{
- struct esp_pub *epub = sip->epub;
- struct sk_buff *skb;
- while ((skb = skb_dequeue(&epub->txdoneq))) {
- ieee80211_tx_status(epub->hw, skb);
- }
-}
-#endif
-#endif /* !FAST_TX_STATUS */
-
-#ifdef FAST_TX_STATUS
-static void sip_tx_status_report(struct esp_sip *sip, struct sk_buff *skb, struct ieee80211_tx_info *tx_info, bool success)
-{
- if(!(tx_info->flags & IEEE80211_TX_CTL_AMPDU)) {
- if (likely(success))
- tx_info->flags |= IEEE80211_TX_STAT_ACK;
- else
- tx_info->flags &= ~IEEE80211_TX_STAT_ACK;
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29))
- /* manipulate rate status... */
- tx_info->status.rates[0].idx = 11;
- tx_info->status.rates[0].count = 1;
- tx_info->status.rates[0].flags = 0;
- tx_info->status.rates[1].idx = -1;
-#else
- tx_info->status.retry_count = 1;
- tx_info->status.excessive_retries = false;
-#endif
-
- } else {
- tx_info->flags |= IEEE80211_TX_STAT_AMPDU | IEEE80211_TX_STAT_ACK;
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39))
- tx_info->status.ampdu_ack_map = 1;
-#else
- tx_info->status.ampdu_len = 1;
-#endif
- tx_info->status.ampdu_ack_len = 1;
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29))
- /* manipulate rate status... */
- tx_info->status.rates[0].idx = 7;
- tx_info->status.rates[0].count = 1;
- tx_info->status.rates[0].flags = IEEE80211_TX_RC_MCS | IEEE80211_TX_RC_SHORT_GI;
- tx_info->status.rates[1].idx = -1;
-#else
- tx_info->status.retry_count = 1;
- tx_info->status.excessive_retries = false;
-#endif
-
- }
-
- if(tx_info->flags & IEEE80211_TX_STAT_AMPDU)
- esp_sip_dbg(ESP_DBG_TRACE, "%s ampdu status! \n", __func__);
-
- if (!mod_support_no_txampdu() &&
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29))
- sip->epub->hw->conf.channel_type != NL80211_CHAN_NO_HT
-#else
- !(sip->epub->hw->conf.flags&IEEE80211_CONF_SUPPORT_HT_MODE)
-#endif
- ) {
- struct ieee80211_tx_info * tx_info = IEEE80211_SKB_CB(skb);
- struct ieee80211_hdr * wh = (struct ieee80211_hdr *)skb->data;
- if(ieee80211_is_data_qos(wh->frame_control)) {
- if(!(tx_info->flags & IEEE80211_TX_CTL_AMPDU)) {
- u8 tidno = ieee80211_get_qos_ctl(wh)[0] & IEEE80211_QOS_CTL_TID_MASK;
- struct esp_node * node;
- struct esp_tx_tid *tid;
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))
- struct ieee80211_sta *sta;
- sta = tx_info->control.sta;
- if(sta == NULL)
- goto _exit;
- node = (struct esp_node *)sta->drv_priv;
- ASSERT(node != NULL);
- if(node->sta == NULL)
- goto _exit;
-#else
- node = esp_get_node_by_addr(sip->epub, wh->addr1);
- if(node == NULL)
- goto _exit;
-#endif
- tid = &node->tid[tidno];
- spin_lock_bh(&sip->epub->tx_ampdu_lock);
- //start session
- ASSERT(tid != NULL);
- if ((tid->state == ESP_TID_STATE_INIT) &&
- (TID_TO_AC(tidno) != WME_AC_VO) && tid->cnt >= 10) {
- tid->state = ESP_TID_STATE_TRIGGER;
- esp_sip_dbg(ESP_DBG_ERROR, "start tx ba session,addr:%pM,tid:%u\n", wh->addr1, tidno);
- spin_unlock_bh(&sip->epub->tx_ampdu_lock);
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28))
- ieee80211_start_tx_ba_session(sip->epub->hw, wh->addr1, tidno);
-#elif (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 32))
- ieee80211_start_tx_ba_session(sip->epub->hw, sta->addr, tidno);
-#elif (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 37))
- ieee80211_start_tx_ba_session(sta, tidno);
-#else
- ieee80211_start_tx_ba_session(sta, tidno, 0);
-#endif
- } else {
- if(tid->state == ESP_TID_STATE_INIT)
- tid->cnt++;
- else
- tid->cnt = 0;
- spin_unlock_bh(&sip->epub->tx_ampdu_lock);
- }
- }
- }
- }
-_exit:
-#ifndef FAST_TX_NOWAIT
- skb_queue_tail(&sip->epub->txdoneq, skb);
-#else
- ieee80211_tx_status(sip->epub->hw, skb);
-#endif
-}
-#endif /* FAST_TX_STATUS */
-
-/*
- * NB: this routine should be locked when calling
- */
-void
-sip_txq_process(struct esp_pub *epub)
-{
- struct sk_buff *skb;
- struct esp_sip *sip = epub->sip;
- u32 pkt_len = 0, tx_len = 0, blknum = 0;
- bool queued_back = false;
- bool out_of_credits = false;
- struct ieee80211_tx_info *itx_info;
- int pm_state = 0;
-
- while ((skb = skb_dequeue(&epub->txq))) {
-
- /* cmd skb->len does not include sip_hdr too */
- pkt_len = skb->len;
- itx_info = IEEE80211_SKB_CB(skb);
- if (itx_info->flags != 0xffffffff) {
- pkt_len += roundup(sizeof(struct sip_hdr), 4);
- if ((itx_info->flags & IEEE80211_TX_CTL_AMPDU) && (true || esp_is_ip_pkt(skb)))
- pkt_len += roundup(sizeof(struct esp_tx_ampdu_entry), 4);
- }
-
- /* current design simply requires every sip_hdr must be at the begin of mblk, that definitely
- * need to be optimized, e.g. calulate remain length in the previous mblk, if it larger than
- * certain threshold (e.g, whole pkt or > 50% of pkt or 2 x sizeof(struct sip_hdr), append pkt
- * to the previous mblk. This might be done in sip_pack_pkt()
- */
- pkt_len = roundup(pkt_len, sip->tx_blksz);
- blknum = pkt_len / sip->tx_blksz;
- esp_dbg(ESP_DBG_TRACE, "%s skb_len %d pkt_len %d blknum %d\n", __func__, skb->len, pkt_len, blknum);
-
- if (unlikely(blknum > atomic_read(&sip->tx_credits) - sip->credit_to_reserve)) {
- esp_dbg(ESP_DBG_TRACE, "%s out of credits!\n", __func__);
- STRACE_TX_OUT_OF_CREDIT_INC();
- queued_back = true;
- out_of_credits = true;
- /*
- if (epub->hw) {
- ieee80211_stop_queues(epub->hw);
- atomic_set(&epub->txq_stopped, true);
- }
- */
- /* we will be back */
- break;
- }
-
- tx_len += pkt_len;
- if (tx_len >= SIP_TX_AGGR_BUF_SIZE) {
- /* do we need to have limitation likemax 8 pkts in a row? */
- esp_dbg(ESP_DBG_TRACE, "%s too much pkts in one shot!\n", __func__);
- STRACE_TX_ONE_SHOT_INC();
- tx_len -= pkt_len;
- queued_back = true;
- break;
- }
-
- if (sip_pack_pkt(sip, skb, &pm_state) != 0) {
- /* wrong pkt, won't send to target */
- tx_len -= pkt_len;
- continue;
- }
-
- esp_sip_dbg(ESP_DBG_TRACE, "%s:before sub, credits is %d\n", __func__, atomic_read(&sip->tx_credits));
- atomic_sub(blknum, &sip->tx_credits);
- esp_sip_dbg(ESP_DBG_TRACE, "%s:after sub %d,credits remains %d\n", __func__, blknum, atomic_read(&sip->tx_credits));
-
- }
-
- if (queued_back) {
- skb_queue_head(&epub->txq, skb);
- }
-
- if (atomic_read(&sip->state) == SIP_STOP
-#ifdef HOST_RESET_BUG
- || atomic_read(&epub->wl.off) == 1
-#endif
- )
- {
- queued_back = 1;
- tx_len = 0;
- sip_after_write_pkts(sip);
- }
-
- if (tx_len) {
-
- sip_write_pkts(sip, pm_state);
-
- sip_after_write_pkts(sip);
- }
-
- if (queued_back && !out_of_credits) {
-
- /* skb pending, do async process again */
- // if (!skb_queue_empty(&epub->txq))
- sip_trigger_txq_process(sip);
- }
-}
-
-static void sip_after_write_pkts(struct esp_sip *sip)
-{
- //enable txq
-#if 0
- if (atomic_read(&sip->epub->txq_stopped) == true && sip_queue_may_resume(sip)) {
- atomic_set(&sip->epub->txq_stopped, false);
- ieee80211_wake_queues(sip->epub->hw);
- esp_sip_dbg(ESP_DBG_TRACE, "%s resume ieee80211 tx \n", __func__);
- }
-#endif
-
-#ifndef FAST_TX_NOWAIT
- sip_txdoneq_process(sip);
-#endif
- //disable tx_data
-#ifndef FAST_TX_STATUS
- if (atomic_read(&sip->data_tx_stopped) == false && sip_tx_data_need_stop(sip)) {
- esp_sip_dbg(ESP_DBG_TRACE, "%s data_tx_stopped \n", __func__);
- atomic_set(&sip->data_tx_stopped, true);
- }
-#endif /* FAST_TX_STATUS */
-}
-
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35))
-/*
- * old mac80211 (2.6.32.x) needs payload is 4 byte aligned, thus we need this hack.
- * TBD: However, the latest mac80211 stack does not need this. we may
- * need to check kernel version here...
- */
-static void sip_check_skb_alignment(struct sk_buff *skb)
-{
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
- int hdrlen;
-
- hdrlen = ieee80211_hdrlen(hdr->frame_control);
-
-#if 0
-
- /* TBD */
- if (rx->flags & IEEE80211_RX_AMSDU)
- hdrlen += ETH_HLEN;
-
-#endif
-
- if (unlikely(((unsigned long)(skb->data + hdrlen)) & 3)) {
-
- esp_sip_dbg(ESP_DBG_TRACE, "%s adjust skb data postion \n", __func__);
- skb_push(skb, 2);
- memmove(skb->data, skb->data+2, skb->len-2);
- skb_trim(skb, skb->len-2);
- }
-}
-#endif /* !NEW_KERNEL */
-
-int sip_channel_value_inconsistency(u8 *start, size_t len, unsigned channel)
-{
- size_t left = len;
- u8 *pos = start;
- u8 *DS_Param = NULL;
- u8 channel_parsed = 0xff;
- bool found = false;
- u8 ssid[33];
-
- while(left >=2 && !found) {
- u8 id, elen;
- id = *pos++;
- elen = *pos++;
- left -= 2;
-
- if(elen > left)
- break;
-
- switch (id) {
- case WLAN_EID_SSID:
- ASSERT(elen < 33);
- memcpy(ssid, pos, elen);
- ssid[elen] = 0;
- esp_sip_dbg(ESP_DBG_TRACE, "ssid:%s\n", ssid);
- break;
- case WLAN_EID_SUPP_RATES:
- break;
- case WLAN_EID_FH_PARAMS:
- break;
- case WLAN_EID_DS_PARAMS:
- DS_Param = pos;
- found = true;
- break;
- default:
- break;
- }
-
- left -= elen;
- pos += elen;
- }
-
- if (DS_Param) {
- channel_parsed = DS_Param[0];
- } else {
- esp_dbg(ESP_DBG_ERROR, "DS_Param not found\n");
- return -1;
- }
-
- return channel_parsed != channel;
-}
-
-/* parse mac_rx_ctrl and return length */
-static int sip_parse_mac_rx_info(struct esp_sip *sip, struct esp_mac_rx_ctrl * mac_ctrl, struct sk_buff *skb)
-{
- struct ieee80211_rx_status *rx_status = NULL;
- struct ieee80211_hdr *hdr;
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32))
- rx_status = IEEE80211_SKB_RXCB(skb);
-#else
- rx_status = (struct ieee80211_rx_status *)skb->cb;
-#endif
- rx_status->freq = esp_ieee2mhz(mac_ctrl->channel);
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39))
- rx_status->signal = mac_ctrl->rssi + atomic_read(&sip->noise_floor); /* snr actually, need to offset noise floor e.g. -85 */
-#else
- rx_status->signal = mac_ctrl->rssi; /* snr actually, need to offset noise floor e.g. -85 */
-#endif /* NEW_KERNEL */
-
- hdr = (struct ieee80211_hdr *)skb->data;
- if (mac_ctrl->damatch0 == 1 && mac_ctrl->bssidmatch0 == 1 /*match bssid and da, but beacon package contain other bssid*/
- && strncmp(hdr->addr2, sip->epub->wl.bssid, ETH_ALEN) == 0) { /* force match addr2 */
- if (++signal_loop >= SIGNAL_COUNT) {
- avg_signal += rx_status->signal;
- avg_signal /= SIGNAL_COUNT;
- old_signal = rx_status->signal = (avg_signal + 5);
- signal_loop = 0;
- avg_signal = 0;
- } else {
- avg_signal += rx_status->signal;
- rx_status->signal = old_signal;
- }
- }
-
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35))
-#define ESP_RSSI_MIN_RSSI (-90)
-#define ESP_RSSI_MAX_RSSI (-45)
- rx_status->noise = 0; /* TBD */
- rx_status->qual = (mac_ctrl->rssi - ESP_RSSI_MIN_RSSI)* 100/(ESP_RSSI_MAX_RSSI - ESP_RSSI_MIN_RSSI);
- rx_status->qual = min(rx_status->qual, 100);
- rx_status->qual = max(rx_status->qual, 0);
-#undef ESP_RSSI_MAX_RSSI
-#undef ESP_RSSI_MIN_RSSI
-#endif /* !NEW_KERNEL && KERNEL_35*/
- rx_status->antenna = 0; /* one antenna for now */
- rx_status->band = IEEE80211_BAND_2GHZ;
- rx_status->flag = RX_FLAG_DECRYPTED | RX_FLAG_MMIC_STRIPPED;
- if (mac_ctrl->sig_mode) {
- // 2.6.27 has RX_FLAG_RADIOTAP in enum mac80211_rx_flags in include/net/mac80211.h
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29))
- rx_status->flag |= RX_FLAG_HT;
- rx_status->rate_idx = mac_ctrl->MCS;
- if(mac_ctrl->SGI)
- rx_status->flag |= RX_FLAG_SHORT_GI;
-#else
- rx_status->rate_idx = esp_wmac_rate2idx(0xc);//ESP_RATE_54
-#endif
- } else {
- rx_status->rate_idx = esp_wmac_rate2idx(mac_ctrl->rate);
- }
- if (mac_ctrl->rxend_state == RX_FCS_ERR)
- rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
-
- /* Mic error frame flag */
- if (mac_ctrl->rxend_state == RX_TKIPMIC_ERR || mac_ctrl->rxend_state == RX_CCMPMIC_ERR){
- if(atomic_read(&sip->epub->wl.tkip_key_set) == 1){
- rx_status->flag|= RX_FLAG_MMIC_ERROR;
- atomic_set(&sip->epub->wl.tkip_key_set, 0);
- printk("mic err\n");
- } else {
- printk("mic err discard\n");
- }
- }
-
- //esp_dbg(ESP_DBG_LOG, "%s freq: %u; signal: %d; rate_idx %d; flag: %d \n", __func__, rx_status->freq, rx_status->signal, rx_status->rate_idx, rx_status->flag);
-
- do {
- struct ieee80211_hdr * wh = (struct ieee80211_hdr *)((u8 *)skb->data);
-
- if (ieee80211_is_beacon(wh->frame_control) || ieee80211_is_probe_resp(wh->frame_control)) {
- struct ieee80211_mgmt * mgmt = (struct ieee80211_mgmt *)((u8 *)skb->data);
- u8 *start = NULL;
- size_t baselen, len = skb->len;
- int inconsistency = 0;
-
- if (ieee80211_is_beacon(wh->frame_control)) {
- start = mgmt->u.beacon.variable;
- baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt;
- bcn_counter++;
- } else if(ieee80211_is_probe_resp(wh->frame_control)) {
- start = mgmt->u.probe_resp.variable;
- baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt;
- probe_rsp_counter++;
- }
-
- if (baselen > len)
- return -1;
-
- inconsistency = sip_channel_value_inconsistency(start, len-baselen, mac_ctrl->channel);
-
- if (inconsistency) {
- return -1;
- }
- }
-
-#ifdef KERNEL_IV_WAR
- /* some kernel e.g. 3.0.8 wrongly handles non-encrypted pkt like eapol */
- if (ieee80211_is_data(wh->frame_control)) {
- if( !ieee80211_has_protected(wh->frame_control)) {
- esp_sip_dbg(ESP_DBG_TRACE, "%s kiv_war, add iv_stripped flag \n", __func__);
- rx_status->flag |= RX_FLAG_IV_STRIPPED;
- } else {
- if ((atomic_read(&sip->epub->wl.ptk_cnt) == 0 && !(wh->addr1[0] & 0x1)) ||
- (atomic_read(&sip->epub->wl.gtk_cnt) == 0 && (wh->addr1[0] & 0x1)))
- {
- esp_dbg(ESP_DBG_TRACE, "%s ==kiv_war, got bogus enc pkt==\n", __func__);
- rx_status->flag |= RX_FLAG_IV_STRIPPED;
- //show_buf(skb->data, 32);
- }
-
- esp_sip_dbg(ESP_DBG_TRACE, "%s kiv_war, got enc pkt \n", __func__);
- }
- }
-#endif /* KERNEL_IV_WAR*/
- } while (0);
-
- return 0;
-}
-
-static struct esp_mac_rx_ctrl *sip_parse_normal_mac_ctrl(struct sk_buff *skb, int * pkt_len_enc, int *buf_len, int *pulled_len)
-{
- struct esp_mac_rx_ctrl *mac_ctrl = NULL;
- struct sip_hdr *hdr =(struct sip_hdr *)skb->data;
- int len_in_hdr = hdr->len;
-
- ASSERT(skb != NULL);
- ASSERT(skb->len > SIP_MIN_DATA_PKT_LEN);
-
- skb_pull(skb, sizeof(struct sip_hdr));
- *pulled_len += sizeof(struct sip_hdr);
- mac_ctrl = (struct esp_mac_rx_ctrl *)skb->data;
- if(!mac_ctrl->Aggregation) {
- ASSERT(pkt_len_enc != NULL);
- ASSERT(buf_len != NULL);
- *pkt_len_enc = (mac_ctrl->sig_mode?mac_ctrl->HT_length:mac_ctrl->legacy_length) - FCS_LEN;
- *buf_len = len_in_hdr - sizeof(struct sip_hdr) - sizeof(struct esp_mac_rx_ctrl);
- }
- skb_pull(skb, sizeof(struct esp_mac_rx_ctrl));
- *pulled_len += sizeof(struct esp_mac_rx_ctrl);
-
- return mac_ctrl;
-}
-
-/*
- * for one MPDU (including subframe in AMPDU)
- *
- */
-static struct sk_buff * sip_parse_data_rx_info(struct esp_sip *sip, struct sk_buff *skb, int pkt_len_enc, int buf_len, struct esp_mac_rx_ctrl *mac_ctrl, int *pulled_len) {
- /*
- * | mac_rx_ctrl | real_data_payload | ampdu_entries |
- */
- //without enc
- int pkt_len = 0;
- struct sk_buff *rskb = NULL;
- int ret;
-
- if (mac_ctrl->Aggregation) {
- struct ieee80211_hdr * wh = (struct ieee80211_hdr *)skb->data;
- pkt_len = pkt_len_enc;
- if (ieee80211_has_protected(wh->frame_control))//ampdu, it is CCMP enc
- pkt_len -= 8;
- buf_len = roundup(pkt_len, 4);
- } else
- pkt_len = buf_len - 3 + ((pkt_len_enc - 1) & 0x3);
- esp_dbg(ESP_DBG_TRACE, "%s pkt_len %u, pkt_len_enc %u!, delta %d \n", __func__, pkt_len, pkt_len_enc, pkt_len_enc - pkt_len);
- do {
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39))
- rskb = __dev_alloc_skb(pkt_len_enc + 2, GFP_ATOMIC);
-#else
- rskb = __dev_alloc_skb(pkt_len_enc, GFP_ATOMIC);
-#endif/* NEW_KERNEL */
- if (unlikely(rskb == NULL)) {
- esp_sip_dbg(ESP_DBG_ERROR, "%s no mem for rskb\n", __func__);
- return NULL;
- }
- skb_put(rskb, pkt_len_enc);
- } while(0);
-
- do {
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39))
- do {
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
- int hdrlen;
-
- hdrlen = ieee80211_hdrlen(hdr->frame_control);
- if (unlikely(((unsigned long)(rskb->data + hdrlen)) & 3)) {
- skb_put(rskb, 2);
- skb_pull(rskb, 2);
- }
- } while(0);
-#endif /* < KERNEL_VERSION(2, 6, 39) */
- memcpy(rskb->data, skb->data, pkt_len);
- if (pkt_len_enc > pkt_len) {
- memset(rskb->data + pkt_len, 0, pkt_len_enc - pkt_len);
- }
- /* strip out current pkt, move to the next one */
- skb_pull(skb, buf_len);
- *pulled_len += buf_len;
- } while (0);
-
- ret = sip_parse_mac_rx_info(sip, mac_ctrl, rskb);
- if(ret == -1 && !mac_ctrl->Aggregation) {
- kfree_skb(rskb);
- return NULL;
- }
-
- esp_dbg(ESP_DBG_LOG, "%s after pull headers, skb->len %d rskb->len %d \n", __func__, skb->len, rskb->len);
-
- return rskb;
-}
-
-struct esp_sip * sip_attach(struct esp_pub *epub)
-{
- struct esp_sip *sip = NULL;
- struct sip_pkt *pkt = NULL;
- int i;
-
- sip = kzalloc(sizeof(struct esp_sip), GFP_KERNEL);
- ASSERT(sip != NULL);
-
-#ifdef ESP_RX_COPYBACK_TEST
- /* alloc 64KB for rx test */
- copyback_buf = kzalloc(0x10000, GFP_KERNEL);
-#endif /* ESP_RX_COPYBACK_TEST */
-
- spin_lock_init(&sip->lock);
-
- INIT_LIST_HEAD(&sip->free_ctrl_txbuf);
- INIT_LIST_HEAD(&sip->free_ctrl_rxbuf);
-
- for (i = 0; i < SIP_CTRL_BUF_N; i++) {
- pkt = kzalloc(sizeof(struct sip_pkt), GFP_KERNEL);
-
- if (!pkt) break;
-
- pkt->buf_begin = kzalloc(SIP_CTRL_BUF_SZ, GFP_KERNEL);
-
- if (pkt->buf_begin == NULL) {
- kfree(pkt);
- break;
- }
-
- pkt->buf_len = SIP_CTRL_BUF_SZ;
- pkt->buf = pkt->buf_begin;
-
- if (i < SIP_CTRL_TXBUF_N) {
- list_add_tail(&pkt->list, &sip->free_ctrl_txbuf);
- } else {
- list_add_tail(&pkt->list, &sip->free_ctrl_rxbuf);
- }
- }
-
- spin_lock_init(&sip->rx_lock);
- skb_queue_head_init(&sip->rxq);
-#ifndef RX_SYNC
- INIT_WORK(&sip->rx_process_work, sip_rxq_process);
-#endif/* RX_SYNC */
-
- sip->epub = epub;
- atomic_set(&sip->noise_floor, -96);
-
- atomic_set(&sip->state, SIP_INIT);
- atomic_set(&sip->tx_credits, 0);
-
- return sip;
-}
-
-static void sip_free_init_ctrl_buf(struct esp_sip *sip)
-{
- struct sip_pkt *pkt, *tpkt;
-
- list_for_each_entry_safe(pkt, tpkt,
- &sip->free_ctrl_txbuf, list) {
- list_del(&pkt->list);
- kfree(pkt->buf_begin);
- kfree(pkt);
- }
-
- list_for_each_entry_safe(pkt, tpkt,
- &sip->free_ctrl_rxbuf, list) {
- list_del(&pkt->list);
- kfree(pkt->buf_begin);
- kfree(pkt);
- }
-}
-
-void sip_detach(struct esp_sip *sip)
-{
- int po;
-
- sip_free_init_ctrl_buf(sip);
-
- if (atomic_read(&sip->state) == SIP_RUN) {
-
- sif_disable_target_interrupt(sip->epub);
-
- atomic_set(&sip->state, SIP_STOP);
-
- /* disable irq here */
- sif_disable_irq(sip->epub);
-#ifndef RX_SYNC
- cancel_work_sync(&sip->rx_process_work);
-#endif/* RX_SYNC */
-
- skb_queue_purge(&sip->rxq);
- cancel_work_sync(&sip->epub->sendup_work);
- skb_queue_purge(&sip->epub->rxq);
-
-#ifdef ESP_NO_MAC80211
- unregister_netdev(sip->epub->net_dev);
- wiphy_unregister(sip->epub->wdev->wiphy);
-#else
- if (test_and_clear_bit(ESP_WL_FLAG_HW_REGISTERED, &sip->epub->wl.flags)) {
- ieee80211_unregister_hw(sip->epub->hw);
- }
-#endif
-
- /* cancel all worker/timer */
- cancel_work_sync(&sip->epub->tx_work);
- skb_queue_purge(&sip->epub->txq);
- skb_queue_purge(&sip->epub->txdoneq);
-
- po = get_order(SIP_TX_AGGR_BUF_SIZE);
- free_pages((unsigned long)sip->tx_aggr_buf, po);
- sip->tx_aggr_buf = NULL;
-#if 0
- po = get_order(SIP_RX_AGGR_BUF_SIZE);
- free_pages((unsigned long)sip->rx_aggr_buf, po);
- sip->rx_aggr_buf = NULL;
-#endif
- atomic_set(&sip->state, SIP_INIT);
- } else if (atomic_read(&sip->state) >= SIP_BOOT && atomic_read(&sip->state) <= SIP_WAIT_BOOTUP) {
-
- sif_disable_target_interrupt(sip->epub);
- atomic_set(&sip->state, SIP_STOP);
- sif_disable_irq(sip->epub);
-
- if (sip->rawbuf)
- kfree(sip->rawbuf);
-
- if (atomic_read(&sip->state) == SIP_SEND_INIT) {
-#ifndef RX_SYNC
- cancel_work_sync(&sip->rx_process_work);
-#endif/* RX_SYNC */
- skb_queue_purge(&sip->rxq);
- cancel_work_sync(&sip->epub->sendup_work);
- skb_queue_purge(&sip->epub->rxq);
- }
-
-#ifdef ESP_NO_MAC80211
- unregister_netdev(sip->epub->net_dev);
- wiphy_unregister(sip->epub->wdev->wiphy);
-#else
- if (test_and_clear_bit(ESP_WL_FLAG_HW_REGISTERED, &sip->epub->wl.flags)) {
- ieee80211_unregister_hw(sip->epub->hw);
- }
-#endif
- atomic_set(&sip->state, SIP_INIT);
- } else
- esp_dbg(ESP_DBG_ERROR, "%s wrong state %d\n", __func__, atomic_read(&sip->state));
-
- kfree(sip);
-}
-
-int sip_prepare_boot(struct esp_sip *sip)
-{
- if (atomic_read(&sip->state) != SIP_INIT) {
- esp_dbg(ESP_DBG_ERROR, "%s wrong state %d\n", __func__, atomic_read(&sip->state));
- return -ENOTRECOVERABLE;
- }
-
- if (sip->rawbuf == NULL) {
- sip->rawbuf = kzalloc(SIP_BOOT_BUF_SIZE, GFP_KERNEL);
-
- if (sip->rawbuf == NULL)
- return -ENOMEM;
- }
-
- atomic_set(&sip->state, SIP_PREPARE_BOOT);
-
- return 0;
-}
-
-int sip_write_memory(struct esp_sip *sip, u32 addr, u8 *buf, u16 len)
-{
- struct sip_cmd_write_memory *cmd;
- struct sip_hdr *chdr;
- u16 remains, hdrs, bufsize;
- u32 loadaddr;
- u8 *src;
- int err = 0;
- u32 *t = 0;
-
- ASSERT(sip->rawbuf != NULL);
-
- memset(sip->rawbuf, 0, SIP_BOOT_BUF_SIZE);
-
- chdr = (struct sip_hdr *)sip->rawbuf;
- SIP_HDR_SET_TYPE(chdr->fc[0], SIP_CTRL);
- chdr->c_cmdid = SIP_CMD_WRITE_MEMORY;
-
- remains = len;
- hdrs = sizeof(struct sip_hdr) + sizeof(struct sip_cmd_write_memory);
-
- while (remains) {
- src = &buf[len - remains];
- loadaddr = addr + (len - remains);
-
- if (remains < (SIP_BOOT_BUF_SIZE - hdrs)) {
- /* aligned with 4 bytes */
- bufsize = roundup(remains, 4);
- memset(sip->rawbuf + hdrs, 0, bufsize);
- remains = 0;
- } else {
- bufsize = SIP_BOOT_BUF_SIZE - hdrs;
- remains -= bufsize;
- }
-
- chdr->len = bufsize + hdrs;
- chdr->seq = sip->txseq++;
- cmd = (struct sip_cmd_write_memory *)(sip->rawbuf + SIP_CTRL_HDR_LEN);
- cmd->len = bufsize;
- cmd->addr = loadaddr;
- memcpy(sip->rawbuf+hdrs, src, bufsize);
-
- t = (u32 *)sip->rawbuf;
- esp_dbg(ESP_DBG_TRACE, "%s t0: 0x%08x t1: 0x%08x t2:0x%08x loadaddr 0x%08x \n", __func__, t[0], t[1], t[2], loadaddr);
-
- err = esp_common_write(sip->epub, sip->rawbuf, chdr->len, ESP_SIF_SYNC);
-
- if (err) {
- esp_dbg(ESP_DBG_ERROR, "%s send buffer failed\n", __func__);
- return err;
- }
-
- // 1ms is enough, in fact on dell-d430, need not delay at all.
- mdelay(1);
-
- sip_dec_credit(sip);
- }
-
- return err;
-}
-
-int sip_send_cmd(struct esp_sip *sip, int cid, u32 cmdlen, void *cmd)
-{
- struct sip_hdr *chdr;
- struct sip_pkt *pkt = NULL;
- int ret = 0;
-
- pkt = sip_get_ctrl_buf(sip, SIP_TX_CTRL_BUF);
-
- if (pkt == NULL)
- return -ENOMEM;
-
- chdr = (struct sip_hdr *)pkt->buf_begin;
- chdr->len = SIP_CTRL_HDR_LEN + cmdlen;
- chdr->seq = sip->txseq++;
- chdr->c_cmdid = cid;
-
-
- if (cmd) {
- memset(pkt->buf, 0, cmdlen);
- memcpy(pkt->buf, (u8 *)cmd, cmdlen);
- }
-
- esp_dbg(ESP_DBG_TRACE, "cid %d, len %u, seq %u \n", chdr->c_cmdid, chdr->len, chdr->seq);
-
- esp_dbg(ESP_DBG_TRACE, "c1 0x%08x c2 0x%08x\n", *(u32 *)&pkt->buf[0], *(u32 *)&pkt->buf[4]);
-
- ret = esp_common_write(sip->epub, pkt->buf_begin, chdr->len, ESP_SIF_SYNC);
-
- if (ret)
- esp_dbg(ESP_DBG_ERROR, "%s send cmd %d failed \n", __func__, cid);
-
- sip_dec_credit(sip);
-
- sip_reclaim_ctrl_buf(sip, pkt, SIP_TX_CTRL_BUF);
-
- /*
- * Hack here: reset tx/rx seq before target ram code is up...
- */
- if (cid == SIP_CMD_BOOTUP) {
- sip->rxseq = 0;
- sip->txseq = 0;
- sip->txdataseq = 0;
- }
-
- return ret;
-}
-
-struct sk_buff *
-sip_alloc_ctrl_skbuf(struct esp_sip *sip, u16 len, u32 cid) {
- struct sip_hdr *si = NULL;
- struct ieee80211_tx_info *ti = NULL;
- struct sk_buff *skb = NULL;
-
- ASSERT(len <= sip->tx_blksz);
-
- /* no need to reserve space for net stack */
- skb = __dev_alloc_skb(len, GFP_KERNEL);
-
- if (skb == NULL) {
- esp_dbg(ESP_DBG_ERROR, "no skb for ctrl !\n");
- return NULL;
- }
-
- skb->len = len;
-
- ti = IEEE80211_SKB_CB(skb);
- /* set tx_info flags to 0xffffffff to indicate sip_ctrl pkt */
- ti->flags = 0xffffffff;
- si = (struct sip_hdr *)skb->data;
- memset(si, 0, sizeof(struct sip_hdr));
- SIP_HDR_SET_TYPE(si->fc[0], SIP_CTRL);
- si->len = len;
- si->c_cmdid = cid;
-
- return skb;
-}
-
-void
-sip_free_ctrl_skbuff(struct esp_sip *sip, struct sk_buff *skb)
-{
- memset(IEEE80211_SKB_CB(skb), 0, sizeof(struct ieee80211_tx_info));
- kfree_skb(skb);
-}
-
-static struct sip_pkt *
-sip_get_ctrl_buf(struct esp_sip *sip, SIP_BUF_TYPE bftype) {
- struct sip_pkt *pkt = NULL;
- struct list_head *bflist;
- struct sip_hdr *chdr;
-
- bflist = (bftype == SIP_TX_CTRL_BUF) ? &sip->free_ctrl_txbuf :&sip->free_ctrl_rxbuf;
-
- spin_lock_bh(&sip->lock);
-
- if (list_empty(bflist)) {
- spin_unlock_bh(&sip->lock);
- return NULL;
- }
-
- pkt = list_first_entry(bflist, struct sip_pkt, list);
- list_del(&pkt->list);
- spin_unlock_bh(&sip->lock);
-
- if (bftype == SIP_TX_CTRL_BUF) {
- chdr = (struct sip_hdr *)pkt->buf_begin;
- SIP_HDR_SET_TYPE(chdr->fc[0], SIP_CTRL);
- pkt->buf = pkt->buf_begin + SIP_CTRL_HDR_LEN;
- } else {
- pkt->buf = pkt->buf_begin;
- }
-
- return pkt;
-}
-
-static void
-sip_reclaim_ctrl_buf(struct esp_sip *sip, struct sip_pkt *pkt, SIP_BUF_TYPE bftype)
-{
- struct list_head *bflist = NULL;
-
- if (bftype == SIP_TX_CTRL_BUF)
- bflist = &sip->free_ctrl_txbuf;
- else if (bftype == SIP_RX_CTRL_BUF)
- bflist = &sip->free_ctrl_rxbuf;
- else return;
-
- pkt->buf = pkt->buf_begin;
- pkt->payload_len = 0;
-
- spin_lock_bh(&sip->lock);
- list_add_tail(&pkt->list, bflist);
- spin_unlock_bh(&sip->lock);
-}
-
-int
-sip_poll_bootup_event(struct esp_sip *sip)
-{
- int ret = 0;
-
- esp_dbg(ESP_DBG_TRACE, "polling bootup event... \n");
-
- if (gl_bootup_cplx)
- ret = wait_for_completion_timeout(gl_bootup_cplx, 2 * HZ);
-
- esp_dbg(ESP_DBG_TRACE, "******time remain****** = [%d]\n", ret);
- if (ret <= 0) {
- esp_dbg(ESP_DBG_ERROR, "bootup event timeout\n");
- return -ETIMEDOUT;
- }
-
-#ifndef FPGA_LOOPBACK
- ret = esp_register_mac80211(sip->epub);
-#endif /* !FPGA_LOOPBACK */
-
-#ifdef TEST_MODE
- ret = test_init_netlink(sip);
- if (ret < 0) {
- esp_sip_dbg(ESP_DBG_TRACE, "esp_sdio: failed initializing netlink\n");
- return ret;
- }
-#endif
-
- atomic_set(&sip->state, SIP_RUN);
- esp_dbg(ESP_DBG_TRACE, "target booted up\n");
-
- return ret;
-}
-
-int
-sip_poll_resetting_event(struct esp_sip *sip)
-{
- int ret = 0;
-
- esp_dbg(ESP_DBG_TRACE, "polling resetting event... \n");
-
- if (gl_bootup_cplx)
- ret = wait_for_completion_timeout(gl_bootup_cplx, 10 * HZ);
-
- esp_dbg(ESP_DBG_TRACE, "******time remain****** = [%d]\n", ret);
- if (ret <= 0) {
- esp_dbg(ESP_DBG_ERROR, "resetting event timeout\n");
- return -ETIMEDOUT;
- }
-
- esp_dbg(ESP_DBG_TRACE, "target resetting %d %p\n", ret, gl_bootup_cplx);
-
- return 0;
-}
-
-
-#ifdef FPGA_DEBUG
-
-/* bogus bootup cmd for FPGA debugging */
-int
-sip_send_bootup(struct esp_sip *sip)
-{
- int ret;
- struct sip_cmd_bootup bootcmd;
-
- esp_dbg(ESP_DBG_LOG, "sending bootup\n");
-
- bootcmd.boot_addr = 0;
- ret = sip_send_cmd(sip, SIP_CMD_BOOTUP, sizeof(struct sip_cmd_bootup), &bootcmd);
-
- return ret;
-}
-
-#endif /* FPGA_DEBUG */
-
-bool
-sip_queue_need_stop(struct esp_sip *sip)
-{
- return atomic_read(&sip->tx_data_pkt_queued) >= SIP_STOP_QUEUE_THRESHOLD
- || (atomic_read(&sip->tx_credits) < 8
- && atomic_read(&sip->tx_data_pkt_queued) >= SIP_STOP_QUEUE_THRESHOLD / 4 * 3);
-}
-
-bool
-sip_queue_may_resume(struct esp_sip *sip)
-{
- return atomic_read(&sip->epub->txq_stopped)
- && !test_bit(ESP_WL_FLAG_STOP_TXQ, &sip->epub->wl.flags)
- && ((atomic_read(&sip->tx_credits) >= 16
- && atomic_read(&sip->tx_data_pkt_queued) < SIP_RESUME_QUEUE_THRESHOLD * 2)
- || atomic_read(&sip->tx_data_pkt_queued) < SIP_RESUME_QUEUE_THRESHOLD);
-}
-
-#ifndef FAST_TX_STATUS
-bool
-sip_tx_data_need_stop(struct esp_sip *sip)
-{
- return atomic_read(&sip->pending_tx_status) >= SIP_PENDING_STOP_TX_THRESHOLD;
-}
-
-bool
-sip_tx_data_may_resume(struct esp_sip *sip)
-{
- return atomic_read(&sip->pending_tx_status) < SIP_PENDING_RESUME_TX_THRESHOLD;
-}
-#endif /* FAST_TX_STATUS */
-
-int
-sip_cmd_enqueue(struct esp_sip *sip, struct sk_buff *skb)
-{
- if (!sip || !sip->epub) {
- esp_dbg(ESP_DBG_ERROR, "func %s, sip->epub->txq is NULL\n", __func__);
- return -EINVAL;
- }
-
- if (!skb) {
- esp_dbg(ESP_DBG_ERROR, "func %s, skb is NULL\n", __func__);
- return -EINVAL;
- }
-
- skb_queue_tail(&sip->epub->txq, skb);
-
-#if !defined(FPGA_LOOPBACK) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32))
- ieee80211_queue_work(sip->epub->hw, &sip->epub->tx_work);
-#else
- queue_work(sip->epub->esp_wkq, &sip->epub->tx_work);
-#endif
- return 0;
-}
-
-void sip_tx_data_pkt_enqueue(struct esp_pub *epub, struct sk_buff *skb)
-{
- if(!epub || !epub->sip) {
- if (!epub)
- esp_dbg(ESP_DBG_ERROR, "func %s, epub is NULL\n", __func__);
- else
- esp_dbg(ESP_DBG_ERROR, "func %s, epub->sip is NULL\n", __func__);
-
- return;
- }
- if (!skb) {
- esp_dbg(ESP_DBG_ERROR, "func %s, skb is NULL\n", __func__);
- return;
- }
- skb_queue_tail(&epub->txq, skb);
- atomic_inc(&epub->sip->tx_data_pkt_queued);
- if(sip_queue_need_stop(epub->sip)){
- if (epub->hw) {
- ieee80211_stop_queues(epub->hw);
- atomic_set(&epub->txq_stopped, true);
- }
-
- }
-}
-
-#ifdef FPGA_TXDATA
-int sip_send_tx_data(struct esp_sip *sip)
-{
- struct sk_buff *skb = NULL;
- struct sip_cmd_bss_info_update*bsscmd;
-
- skb = sip_alloc_ctrl_skbuf(epub->sip, sizeof(struct sip_cmd_bss_info_update), SIP_CMD_BSS_INFO_UPDATE);
- if (!skb)
- return -EINVAL;
-
- bsscmd = (struct sip_cmd_bss_info_update *)(skb->data + sizeof(struct sip_tx_info));
- bsscmd->isassoc= (assoc==true)? 1: 0;
- memcpy(bsscmd->bssid, bssid, ETH_ALEN);
- STRACE_SHOW(epub->sip);
- return sip_cmd_enqueue(epub->sip, skb);
-}
-#endif /* FPGA_TXDATA */
-
-#ifdef SIP_DEBUG
-void sip_dump_pending_data(struct esp_pub *epub)
-{
-#if 0
- struct sk_buff *tskb, *tmp;
-
- skb_queue_walk_safe(&epub->txdoneq, tskb, tmp) {
- show_buf(tskb->data, 32);
- }
-#endif //0000
-}
-#else
-void sip_dump_pending_data(struct esp_pub *epub)
-{}
-#endif /* SIP_DEBUG */
-