diff options
Diffstat (limited to 'drivers/net/wireless/realtek/rtlwifi/base.c')
-rw-r--r-- | drivers/net/wireless/realtek/rtlwifi/base.c | 96 |
1 files changed, 22 insertions, 74 deletions
diff --git a/drivers/net/wireless/realtek/rtlwifi/base.c b/drivers/net/wireless/realtek/rtlwifi/base.c index 927b7d231576..61f12f86fcd4 100644 --- a/drivers/net/wireless/realtek/rtlwifi/base.c +++ b/drivers/net/wireless/realtek/rtlwifi/base.c @@ -571,9 +571,9 @@ int rtl_init_core(struct ieee80211_hw *hw) spin_lock_init(&rtlpriv->locks.iqk_lock); /* <5> init list */ INIT_LIST_HEAD(&rtlpriv->entry_list); - INIT_LIST_HEAD(&rtlpriv->c2hcmd_list); INIT_LIST_HEAD(&rtlpriv->scan_list.list); skb_queue_head_init(&rtlpriv->tx_report.queue); + skb_queue_head_init(&rtlpriv->c2hcmd_queue); rtlmac->link_state = MAC80211_NOLINK; @@ -2262,56 +2262,36 @@ void rtl_fwevt_wq_callback(void *data) rtlpriv->cfg->ops->c2h_command_handle(hw); } -void rtl_c2hcmd_enqueue(struct ieee80211_hw *hw, u8 tag, u8 len, u8 *val) +void rtl_c2hcmd_enqueue(struct ieee80211_hw *hw, struct sk_buff *skb) { struct rtl_priv *rtlpriv = rtl_priv(hw); unsigned long flags; - struct rtl_c2hcmd *c2hcmd; - - c2hcmd = kmalloc(sizeof(*c2hcmd), - in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); - - if (!c2hcmd) - goto label_err; - - c2hcmd->val = kmalloc(len, - in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); - - if (!c2hcmd->val) - goto label_err2; - - /* fill data */ - c2hcmd->tag = tag; - c2hcmd->len = len; - memcpy(c2hcmd->val, val, len); /* enqueue */ spin_lock_irqsave(&rtlpriv->locks.c2hcmd_lock, flags); - list_add_tail(&c2hcmd->list, &rtlpriv->c2hcmd_list); + __skb_queue_tail(&rtlpriv->c2hcmd_queue, skb); spin_unlock_irqrestore(&rtlpriv->locks.c2hcmd_lock, flags); /* wake up wq */ queue_delayed_work(rtlpriv->works.rtl_wq, &rtlpriv->works.c2hcmd_wq, 0); - - return; - -label_err2: - kfree(c2hcmd); - -label_err: - RT_TRACE(rtlpriv, COMP_CMD, DBG_WARNING, - "C2H cmd enqueue fail.\n"); } EXPORT_SYMBOL(rtl_c2hcmd_enqueue); -void rtl_c2h_content_parsing(struct ieee80211_hw *hw, u8 cmd_id, - u8 cmd_len, u8 *cmd_buf) +static void rtl_c2h_content_parsing(struct ieee80211_hw *hw, + struct sk_buff *skb) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_hal_ops *hal_ops = rtlpriv->cfg->ops; const struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops; + u8 cmd_id, cmd_seq, cmd_len; + u8 *cmd_buf = NULL; + + cmd_id = skb->data[0]; + cmd_seq = skb->data[1]; + cmd_len = skb->len - 2; + cmd_buf = skb->data + 2; switch (cmd_id) { case C2H_DBG: @@ -2347,67 +2327,35 @@ void rtl_c2h_content_parsing(struct ieee80211_hw *hw, u8 cmd_id, } } -void rtl_c2h_packet_handler(struct ieee80211_hw *hw, u8 *buffer, u8 len) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 c2h_cmd_id = 0, c2h_cmd_seq = 0, c2h_cmd_len = 0; - u8 *tmp_buf = NULL; - - c2h_cmd_id = buffer[0]; - c2h_cmd_seq = buffer[1]; - c2h_cmd_len = len - 2; - tmp_buf = buffer + 2; - - RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, - "[C2H packet], c2hCmdId=0x%x, c2hCmdSeq=0x%x, c2hCmdLen=%d\n", - c2h_cmd_id, c2h_cmd_seq, c2h_cmd_len); - - RT_PRINT_DATA(rtlpriv, COMP_FW, DBG_TRACE, - "[C2H packet], Content Hex:\n", tmp_buf, c2h_cmd_len); - - switch (c2h_cmd_id) { - case C2H_BT_INFO: - case C2H_BT_MP: - rtl_c2hcmd_enqueue(hw, c2h_cmd_id, c2h_cmd_len, tmp_buf); - break; - default: - rtl_c2h_content_parsing(hw, c2h_cmd_id, c2h_cmd_len, tmp_buf); - break; - } -} -EXPORT_SYMBOL_GPL(rtl_c2h_packet_handler); - void rtl_c2hcmd_launcher(struct ieee80211_hw *hw, int exec) { struct rtl_priv *rtlpriv = rtl_priv(hw); + struct sk_buff *skb; unsigned long flags; - struct rtl_c2hcmd *c2hcmd; int i; for (i = 0; i < 200; i++) { /* dequeue a task */ spin_lock_irqsave(&rtlpriv->locks.c2hcmd_lock, flags); - c2hcmd = list_first_entry_or_null(&rtlpriv->c2hcmd_list, - struct rtl_c2hcmd, list); - - if (c2hcmd) - list_del(&c2hcmd->list); + skb = __skb_dequeue(&rtlpriv->c2hcmd_queue); spin_unlock_irqrestore(&rtlpriv->locks.c2hcmd_lock, flags); /* do it */ - if (!c2hcmd) + if (!skb) break; + RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, "C2H rx_desc_shift=%d\n", + *((u8 *)skb->cb)); + RT_PRINT_DATA(rtlpriv, COMP_FW, DBG_DMESG, + "C2H data: ", skb->data, skb->len); + if (exec) - rtl_c2h_content_parsing(hw, c2hcmd->tag, - c2hcmd->len, c2hcmd->val); + rtl_c2h_content_parsing(hw, skb); /* free */ - kfree(c2hcmd->val); - - kfree(c2hcmd); + dev_kfree_skb_any(skb); } } |