aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mwifiex/util.c
diff options
context:
space:
mode:
authorBing Zhao <bzhao@marvell.com>2011-03-21 21:00:50 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-03-30 14:15:17 -0400
commit5e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4e (patch)
treede22c4c414412501e62894de65040bf30db28c64 /drivers/net/wireless/mwifiex/util.c
parent903946e6e21ef4dd678acafb8881cabde9182caf (diff)
wireless: mwifiex: initial commit for Marvell mwifiex driver
This driver adds WiFi support for Marvell 802.11n based chipsets with SDIO interface. Currently only SD8787 is supported. More chipsets will be supported later. drivers/net/wireless/mwifiex/ Signed-off-by: Nishant Sarmukadam <nishants@marvell.com> Signed-off-by: Amitkumar Karwar <akarwar@marvell.com> Signed-off-by: Kiran Divekar <dkiran@marvell.com> Signed-off-by: Bing Zhao <bzhao@marvell.com> Signed-off-by: Yogesh Ashok Powar <yogeshp@marvell.com> Signed-off-by: Marc Yang <yangyang@marvell.com> Signed-off-by: Ramesh Radhakrishnan <rramesh@marvell.com> Signed-off-by: Frank Huang <frankh@marvell.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/mwifiex/util.c')
-rw-r--r--drivers/net/wireless/mwifiex/util.c252
1 files changed, 252 insertions, 0 deletions
diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c
new file mode 100644
index 000000000000..205022aa52f5
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/util.c
@@ -0,0 +1,252 @@
1/*
2 * Marvell Wireless LAN device driver: utility functions
3 *
4 * Copyright (C) 2011, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#include "decl.h"
21#include "ioctl.h"
22#include "util.h"
23#include "fw.h"
24#include "main.h"
25#include "wmm.h"
26#include "11n.h"
27
28/*
29 * Firmware initialization complete callback handler.
30 *
31 * This function wakes up the function waiting on the init
32 * wait queue for the firmware initialization to complete.
33 */
34int mwifiex_init_fw_complete(struct mwifiex_adapter *adapter)
35{
36
37 adapter->init_wait_q_woken = true;
38 wake_up_interruptible(&adapter->init_wait_q);
39 return 0;
40}
41
42/*
43 * Firmware shutdown complete callback handler.
44 *
45 * This function sets the hardware status to not ready and wakes up
46 * the function waiting on the init wait queue for the firmware
47 * shutdown to complete.
48 */
49int mwifiex_shutdown_fw_complete(struct mwifiex_adapter *adapter)
50{
51 adapter->hw_status = MWIFIEX_HW_STATUS_NOT_READY;
52 adapter->init_wait_q_woken = true;
53 wake_up_interruptible(&adapter->init_wait_q);
54 return 0;
55}
56
57/*
58 * IOCTL request handler to send function init/shutdown command
59 * to firmware.
60 *
61 * This function prepares the correct firmware command and
62 * issues it.
63 */
64int mwifiex_misc_ioctl_init_shutdown(struct mwifiex_adapter *adapter,
65 struct mwifiex_wait_queue *wait,
66 u32 func_init_shutdown)
67{
68 struct mwifiex_private *priv = adapter->priv[wait->bss_index];
69 int ret;
70 u16 cmd;
71
72 if (func_init_shutdown == MWIFIEX_FUNC_INIT) {
73 cmd = HostCmd_CMD_FUNC_INIT;
74 } else if (func_init_shutdown == MWIFIEX_FUNC_SHUTDOWN) {
75 cmd = HostCmd_CMD_FUNC_SHUTDOWN;
76 } else {
77 dev_err(adapter->dev, "unsupported parameter\n");
78 return -1;
79 }
80
81 /* Send command to firmware */
82 ret = mwifiex_prepare_cmd(priv, cmd, HostCmd_ACT_GEN_SET,
83 0, wait, NULL);
84
85 if (!ret)
86 ret = -EINPROGRESS;
87
88 return ret;
89}
90
91/*
92 * IOCTL request handler to set/get debug information.
93 *
94 * This function collates/sets the information from/to different driver
95 * structures.
96 */
97int mwifiex_get_debug_info(struct mwifiex_private *priv,
98 struct mwifiex_debug_info *info)
99{
100 struct mwifiex_adapter *adapter = priv->adapter;
101
102 if (info) {
103 memcpy(info->packets_out,
104 priv->wmm.packets_out,
105 sizeof(priv->wmm.packets_out));
106 info->max_tx_buf_size = (u32) adapter->max_tx_buf_size;
107 info->tx_buf_size = (u32) adapter->tx_buf_size;
108 info->rx_tbl_num = mwifiex_get_rx_reorder_tbl(
109 priv, info->rx_tbl);
110 info->tx_tbl_num = mwifiex_get_tx_ba_stream_tbl(
111 priv, info->tx_tbl);
112 info->ps_mode = adapter->ps_mode;
113 info->ps_state = adapter->ps_state;
114 info->is_deep_sleep = adapter->is_deep_sleep;
115 info->pm_wakeup_card_req = adapter->pm_wakeup_card_req;
116 info->pm_wakeup_fw_try = adapter->pm_wakeup_fw_try;
117 info->is_hs_configured = adapter->is_hs_configured;
118 info->hs_activated = adapter->hs_activated;
119 info->num_cmd_host_to_card_failure
120 = adapter->dbg.num_cmd_host_to_card_failure;
121 info->num_cmd_sleep_cfm_host_to_card_failure
122 = adapter->dbg.num_cmd_sleep_cfm_host_to_card_failure;
123 info->num_tx_host_to_card_failure
124 = adapter->dbg.num_tx_host_to_card_failure;
125 info->num_event_deauth = adapter->dbg.num_event_deauth;
126 info->num_event_disassoc = adapter->dbg.num_event_disassoc;
127 info->num_event_link_lost = adapter->dbg.num_event_link_lost;
128 info->num_cmd_deauth = adapter->dbg.num_cmd_deauth;
129 info->num_cmd_assoc_success =
130 adapter->dbg.num_cmd_assoc_success;
131 info->num_cmd_assoc_failure =
132 adapter->dbg.num_cmd_assoc_failure;
133 info->num_tx_timeout = adapter->dbg.num_tx_timeout;
134 info->num_cmd_timeout = adapter->dbg.num_cmd_timeout;
135 info->timeout_cmd_id = adapter->dbg.timeout_cmd_id;
136 info->timeout_cmd_act = adapter->dbg.timeout_cmd_act;
137 memcpy(info->last_cmd_id, adapter->dbg.last_cmd_id,
138 sizeof(adapter->dbg.last_cmd_id));
139 memcpy(info->last_cmd_act, adapter->dbg.last_cmd_act,
140 sizeof(adapter->dbg.last_cmd_act));
141 info->last_cmd_index = adapter->dbg.last_cmd_index;
142 memcpy(info->last_cmd_resp_id, adapter->dbg.last_cmd_resp_id,
143 sizeof(adapter->dbg.last_cmd_resp_id));
144 info->last_cmd_resp_index = adapter->dbg.last_cmd_resp_index;
145 memcpy(info->last_event, adapter->dbg.last_event,
146 sizeof(adapter->dbg.last_event));
147 info->last_event_index = adapter->dbg.last_event_index;
148 info->data_sent = adapter->data_sent;
149 info->cmd_sent = adapter->cmd_sent;
150 info->cmd_resp_received = adapter->cmd_resp_received;
151 }
152
153 return 0;
154}
155
156/*
157 * This function processes the received packet before sending it to the
158 * kernel.
159 *
160 * It extracts the SKB from the received buffer and sends it to kernel.
161 * In case the received buffer does not contain the data in SKB format,
162 * the function creates a blank SKB, fills it with the data from the
163 * received buffer and then sends this new SKB to the kernel.
164 */
165int mwifiex_recv_packet(struct mwifiex_adapter *adapter, struct sk_buff *skb)
166{
167 struct mwifiex_rxinfo *rx_info = NULL;
168 struct mwifiex_private *priv = NULL;
169
170 if (!skb)
171 return -1;
172
173 rx_info = MWIFIEX_SKB_RXCB(skb);
174 priv = mwifiex_bss_index_to_priv(adapter, rx_info->bss_index);
175 if (!priv)
176 return -1;
177
178 skb->dev = priv->netdev;
179 skb->protocol = eth_type_trans(skb, priv->netdev);
180 skb->ip_summed = CHECKSUM_NONE;
181 priv->stats.rx_bytes += skb->len;
182 priv->stats.rx_packets++;
183 if (in_interrupt())
184 netif_rx(skb);
185 else
186 netif_rx_ni(skb);
187
188 return 0;
189}
190
191/*
192 * Receive packet completion callback handler.
193 *
194 * This function updates the statistics and frees the buffer SKB.
195 */
196int mwifiex_recv_complete(struct mwifiex_adapter *adapter,
197 struct sk_buff *skb, int status)
198{
199 struct mwifiex_private *priv = NULL;
200 struct mwifiex_rxinfo *rx_info = NULL;
201
202 if (!skb)
203 return 0;
204
205 rx_info = MWIFIEX_SKB_RXCB(skb);
206 priv = mwifiex_bss_index_to_priv(adapter, rx_info->bss_index);
207
208 if (priv && (status == -1))
209 priv->stats.rx_dropped++;
210
211 dev_kfree_skb_any(skb);
212
213 return 0;
214}
215
216/*
217 * IOCTL completion callback handler.
218 *
219 * This function is called when a pending IOCTL is completed.
220 *
221 * If work queue support is enabled, the function wakes up the
222 * corresponding waiting function. Otherwise, it processes the
223 * IOCTL response and frees the response buffer.
224 */
225int mwifiex_ioctl_complete(struct mwifiex_adapter *adapter,
226 struct mwifiex_wait_queue *wait_queue,
227 int status)
228{
229 enum mwifiex_error_code status_code =
230 (enum mwifiex_error_code) wait_queue->status;
231
232 atomic_dec(&adapter->ioctl_pending);
233
234 dev_dbg(adapter->dev, "cmd: IOCTL completed: status=%d,"
235 " status_code=%#x\n", status, status_code);
236
237 if (wait_queue->enabled) {
238 *wait_queue->condition = true;
239 wait_queue->status = status;
240 if (status && (status_code == MWIFIEX_ERROR_CMD_TIMEOUT))
241 dev_err(adapter->dev, "cmd timeout\n");
242 else
243 wake_up_interruptible(wait_queue->wait);
244 } else {
245 if (status)
246 dev_err(adapter->dev, "cmd failed: status_code=%#x\n",
247 status_code);
248 kfree(wait_queue);
249 }
250
251 return 0;
252}