Commit | Line | Data |
---|---|---|
5e6e3a92 BZ |
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 | */ | |
34 | int 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 | */ | |
49 | int 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 | /* | |
600f5d90 | 58 | * This function sends init/shutdown command |
5e6e3a92 | 59 | * to firmware. |
5e6e3a92 | 60 | */ |
600f5d90 AK |
61 | int mwifiex_init_shutdown_fw(struct mwifiex_private *priv, |
62 | u32 func_init_shutdown) | |
5e6e3a92 | 63 | { |
5e6e3a92 BZ |
64 | int ret; |
65 | u16 cmd; | |
66 | ||
67 | if (func_init_shutdown == MWIFIEX_FUNC_INIT) { | |
68 | cmd = HostCmd_CMD_FUNC_INIT; | |
69 | } else if (func_init_shutdown == MWIFIEX_FUNC_SHUTDOWN) { | |
70 | cmd = HostCmd_CMD_FUNC_SHUTDOWN; | |
71 | } else { | |
600f5d90 | 72 | dev_err(priv->adapter->dev, "unsupported parameter\n"); |
5e6e3a92 BZ |
73 | return -1; |
74 | } | |
75 | ||
76 | /* Send command to firmware */ | |
600f5d90 | 77 | ret = mwifiex_send_cmd_sync(priv, cmd, HostCmd_ACT_GEN_SET, 0, NULL); |
5e6e3a92 BZ |
78 | |
79 | return ret; | |
80 | } | |
600f5d90 | 81 | EXPORT_SYMBOL_GPL(mwifiex_init_shutdown_fw); |
5e6e3a92 BZ |
82 | |
83 | /* | |
84 | * IOCTL request handler to set/get debug information. | |
85 | * | |
86 | * This function collates/sets the information from/to different driver | |
87 | * structures. | |
88 | */ | |
89 | int mwifiex_get_debug_info(struct mwifiex_private *priv, | |
90 | struct mwifiex_debug_info *info) | |
91 | { | |
92 | struct mwifiex_adapter *adapter = priv->adapter; | |
93 | ||
94 | if (info) { | |
95 | memcpy(info->packets_out, | |
96 | priv->wmm.packets_out, | |
97 | sizeof(priv->wmm.packets_out)); | |
98 | info->max_tx_buf_size = (u32) adapter->max_tx_buf_size; | |
99 | info->tx_buf_size = (u32) adapter->tx_buf_size; | |
100 | info->rx_tbl_num = mwifiex_get_rx_reorder_tbl( | |
101 | priv, info->rx_tbl); | |
102 | info->tx_tbl_num = mwifiex_get_tx_ba_stream_tbl( | |
103 | priv, info->tx_tbl); | |
104 | info->ps_mode = adapter->ps_mode; | |
105 | info->ps_state = adapter->ps_state; | |
106 | info->is_deep_sleep = adapter->is_deep_sleep; | |
107 | info->pm_wakeup_card_req = adapter->pm_wakeup_card_req; | |
108 | info->pm_wakeup_fw_try = adapter->pm_wakeup_fw_try; | |
109 | info->is_hs_configured = adapter->is_hs_configured; | |
110 | info->hs_activated = adapter->hs_activated; | |
111 | info->num_cmd_host_to_card_failure | |
112 | = adapter->dbg.num_cmd_host_to_card_failure; | |
113 | info->num_cmd_sleep_cfm_host_to_card_failure | |
114 | = adapter->dbg.num_cmd_sleep_cfm_host_to_card_failure; | |
115 | info->num_tx_host_to_card_failure | |
116 | = adapter->dbg.num_tx_host_to_card_failure; | |
117 | info->num_event_deauth = adapter->dbg.num_event_deauth; | |
118 | info->num_event_disassoc = adapter->dbg.num_event_disassoc; | |
119 | info->num_event_link_lost = adapter->dbg.num_event_link_lost; | |
120 | info->num_cmd_deauth = adapter->dbg.num_cmd_deauth; | |
121 | info->num_cmd_assoc_success = | |
122 | adapter->dbg.num_cmd_assoc_success; | |
123 | info->num_cmd_assoc_failure = | |
124 | adapter->dbg.num_cmd_assoc_failure; | |
125 | info->num_tx_timeout = adapter->dbg.num_tx_timeout; | |
126 | info->num_cmd_timeout = adapter->dbg.num_cmd_timeout; | |
127 | info->timeout_cmd_id = adapter->dbg.timeout_cmd_id; | |
128 | info->timeout_cmd_act = adapter->dbg.timeout_cmd_act; | |
129 | memcpy(info->last_cmd_id, adapter->dbg.last_cmd_id, | |
130 | sizeof(adapter->dbg.last_cmd_id)); | |
131 | memcpy(info->last_cmd_act, adapter->dbg.last_cmd_act, | |
132 | sizeof(adapter->dbg.last_cmd_act)); | |
133 | info->last_cmd_index = adapter->dbg.last_cmd_index; | |
134 | memcpy(info->last_cmd_resp_id, adapter->dbg.last_cmd_resp_id, | |
135 | sizeof(adapter->dbg.last_cmd_resp_id)); | |
136 | info->last_cmd_resp_index = adapter->dbg.last_cmd_resp_index; | |
137 | memcpy(info->last_event, adapter->dbg.last_event, | |
138 | sizeof(adapter->dbg.last_event)); | |
139 | info->last_event_index = adapter->dbg.last_event_index; | |
140 | info->data_sent = adapter->data_sent; | |
141 | info->cmd_sent = adapter->cmd_sent; | |
142 | info->cmd_resp_received = adapter->cmd_resp_received; | |
143 | } | |
144 | ||
145 | return 0; | |
146 | } | |
147 | ||
148 | /* | |
149 | * This function processes the received packet before sending it to the | |
150 | * kernel. | |
151 | * | |
152 | * It extracts the SKB from the received buffer and sends it to kernel. | |
153 | * In case the received buffer does not contain the data in SKB format, | |
154 | * the function creates a blank SKB, fills it with the data from the | |
155 | * received buffer and then sends this new SKB to the kernel. | |
156 | */ | |
157 | int mwifiex_recv_packet(struct mwifiex_adapter *adapter, struct sk_buff *skb) | |
158 | { | |
159 | struct mwifiex_rxinfo *rx_info = NULL; | |
160 | struct mwifiex_private *priv = NULL; | |
161 | ||
162 | if (!skb) | |
163 | return -1; | |
164 | ||
165 | rx_info = MWIFIEX_SKB_RXCB(skb); | |
166 | priv = mwifiex_bss_index_to_priv(adapter, rx_info->bss_index); | |
167 | if (!priv) | |
168 | return -1; | |
169 | ||
170 | skb->dev = priv->netdev; | |
171 | skb->protocol = eth_type_trans(skb, priv->netdev); | |
172 | skb->ip_summed = CHECKSUM_NONE; | |
173 | priv->stats.rx_bytes += skb->len; | |
174 | priv->stats.rx_packets++; | |
175 | if (in_interrupt()) | |
176 | netif_rx(skb); | |
177 | else | |
178 | netif_rx_ni(skb); | |
179 | ||
180 | return 0; | |
181 | } | |
182 | ||
183 | /* | |
184 | * Receive packet completion callback handler. | |
185 | * | |
186 | * This function updates the statistics and frees the buffer SKB. | |
187 | */ | |
188 | int mwifiex_recv_complete(struct mwifiex_adapter *adapter, | |
189 | struct sk_buff *skb, int status) | |
190 | { | |
191 | struct mwifiex_private *priv = NULL; | |
192 | struct mwifiex_rxinfo *rx_info = NULL; | |
193 | ||
194 | if (!skb) | |
195 | return 0; | |
196 | ||
197 | rx_info = MWIFIEX_SKB_RXCB(skb); | |
198 | priv = mwifiex_bss_index_to_priv(adapter, rx_info->bss_index); | |
199 | ||
200 | if (priv && (status == -1)) | |
201 | priv->stats.rx_dropped++; | |
202 | ||
203 | dev_kfree_skb_any(skb); | |
204 | ||
205 | return 0; | |
206 | } | |
207 | ||
208 | /* | |
209 | * IOCTL completion callback handler. | |
210 | * | |
211 | * This function is called when a pending IOCTL is completed. | |
212 | * | |
213 | * If work queue support is enabled, the function wakes up the | |
214 | * corresponding waiting function. Otherwise, it processes the | |
215 | * IOCTL response and frees the response buffer. | |
216 | */ | |
600f5d90 | 217 | int mwifiex_complete_cmd(struct mwifiex_adapter *adapter) |
5e6e3a92 | 218 | { |
600f5d90 AK |
219 | atomic_dec(&adapter->cmd_pending); |
220 | dev_dbg(adapter->dev, "cmd completed: status=%d\n", | |
221 | adapter->cmd_wait_q.status); | |
5e6e3a92 | 222 | |
600f5d90 | 223 | adapter->cmd_wait_q.condition = true; |
5e6e3a92 | 224 | |
600f5d90 AK |
225 | if (adapter->cmd_wait_q.status == -ETIMEDOUT) |
226 | dev_err(adapter->dev, "cmd timeout\n"); | |
227 | else | |
228 | wake_up_interruptible(&adapter->cmd_wait_q.wait); | |
5e6e3a92 BZ |
229 | |
230 | return 0; | |
231 | } |