2 * Marvell Wireless LAN device driver: utility functions
4 * Copyright (C) 2011, Marvell International Ltd.
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.
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.
29 * Firmware initialization complete callback handler.
31 * This function wakes up the function waiting on the init
32 * wait queue for the firmware initialization to complete.
34 int mwifiex_init_fw_complete(struct mwifiex_adapter
*adapter
)
37 adapter
->init_wait_q_woken
= true;
38 wake_up_interruptible(&adapter
->init_wait_q
);
43 * Firmware shutdown complete callback handler.
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.
49 int mwifiex_shutdown_fw_complete(struct mwifiex_adapter
*adapter
)
51 adapter
->hw_status
= MWIFIEX_HW_STATUS_NOT_READY
;
52 adapter
->init_wait_q_woken
= true;
53 wake_up_interruptible(&adapter
->init_wait_q
);
58 * This function sends init/shutdown command
61 int mwifiex_init_shutdown_fw(struct mwifiex_private
*priv
,
62 u32 func_init_shutdown
)
66 if (func_init_shutdown
== MWIFIEX_FUNC_INIT
) {
67 cmd
= HostCmd_CMD_FUNC_INIT
;
68 } else if (func_init_shutdown
== MWIFIEX_FUNC_SHUTDOWN
) {
69 cmd
= HostCmd_CMD_FUNC_SHUTDOWN
;
71 dev_err(priv
->adapter
->dev
, "unsupported parameter\n");
75 return mwifiex_send_cmd_sync(priv
, cmd
, HostCmd_ACT_GEN_SET
, 0, NULL
);
77 EXPORT_SYMBOL_GPL(mwifiex_init_shutdown_fw
);
80 * IOCTL request handler to set/get debug information.
82 * This function collates/sets the information from/to different driver
85 int mwifiex_get_debug_info(struct mwifiex_private
*priv
,
86 struct mwifiex_debug_info
*info
)
88 struct mwifiex_adapter
*adapter
= priv
->adapter
;
91 memcpy(info
->packets_out
,
92 priv
->wmm
.packets_out
,
93 sizeof(priv
->wmm
.packets_out
));
94 info
->curr_tx_buf_size
= (u32
) adapter
->curr_tx_buf_size
;
95 info
->tx_buf_size
= (u32
) adapter
->tx_buf_size
;
96 info
->rx_tbl_num
= mwifiex_get_rx_reorder_tbl(priv
,
98 info
->tx_tbl_num
= mwifiex_get_tx_ba_stream_tbl(priv
,
100 info
->ps_mode
= adapter
->ps_mode
;
101 info
->ps_state
= adapter
->ps_state
;
102 info
->is_deep_sleep
= adapter
->is_deep_sleep
;
103 info
->pm_wakeup_card_req
= adapter
->pm_wakeup_card_req
;
104 info
->pm_wakeup_fw_try
= adapter
->pm_wakeup_fw_try
;
105 info
->is_hs_configured
= adapter
->is_hs_configured
;
106 info
->hs_activated
= adapter
->hs_activated
;
107 info
->num_cmd_host_to_card_failure
108 = adapter
->dbg
.num_cmd_host_to_card_failure
;
109 info
->num_cmd_sleep_cfm_host_to_card_failure
110 = adapter
->dbg
.num_cmd_sleep_cfm_host_to_card_failure
;
111 info
->num_tx_host_to_card_failure
112 = adapter
->dbg
.num_tx_host_to_card_failure
;
113 info
->num_event_deauth
= adapter
->dbg
.num_event_deauth
;
114 info
->num_event_disassoc
= adapter
->dbg
.num_event_disassoc
;
115 info
->num_event_link_lost
= adapter
->dbg
.num_event_link_lost
;
116 info
->num_cmd_deauth
= adapter
->dbg
.num_cmd_deauth
;
117 info
->num_cmd_assoc_success
=
118 adapter
->dbg
.num_cmd_assoc_success
;
119 info
->num_cmd_assoc_failure
=
120 adapter
->dbg
.num_cmd_assoc_failure
;
121 info
->num_tx_timeout
= adapter
->dbg
.num_tx_timeout
;
122 info
->num_cmd_timeout
= adapter
->dbg
.num_cmd_timeout
;
123 info
->timeout_cmd_id
= adapter
->dbg
.timeout_cmd_id
;
124 info
->timeout_cmd_act
= adapter
->dbg
.timeout_cmd_act
;
125 memcpy(info
->last_cmd_id
, adapter
->dbg
.last_cmd_id
,
126 sizeof(adapter
->dbg
.last_cmd_id
));
127 memcpy(info
->last_cmd_act
, adapter
->dbg
.last_cmd_act
,
128 sizeof(adapter
->dbg
.last_cmd_act
));
129 info
->last_cmd_index
= adapter
->dbg
.last_cmd_index
;
130 memcpy(info
->last_cmd_resp_id
, adapter
->dbg
.last_cmd_resp_id
,
131 sizeof(adapter
->dbg
.last_cmd_resp_id
));
132 info
->last_cmd_resp_index
= adapter
->dbg
.last_cmd_resp_index
;
133 memcpy(info
->last_event
, adapter
->dbg
.last_event
,
134 sizeof(adapter
->dbg
.last_event
));
135 info
->last_event_index
= adapter
->dbg
.last_event_index
;
136 info
->data_sent
= adapter
->data_sent
;
137 info
->cmd_sent
= adapter
->cmd_sent
;
138 info
->cmd_resp_received
= adapter
->cmd_resp_received
;
145 * This function processes the received management packet and send it
149 mwifiex_process_mgmt_packet(struct mwifiex_private
*priv
,
158 rx_pd
= (struct rxpd
*)skb
->data
;
160 skb_pull(skb
, le16_to_cpu(rx_pd
->rx_pkt_offset
));
161 skb_pull(skb
, sizeof(pkt_len
));
163 pkt_len
= le16_to_cpu(rx_pd
->rx_pkt_length
);
165 /* Remove address4 */
166 memmove(skb
->data
+ sizeof(struct ieee80211_hdr_3addr
),
167 skb
->data
+ sizeof(struct ieee80211_hdr
),
168 pkt_len
- sizeof(struct ieee80211_hdr
));
170 pkt_len
-= ETH_ALEN
+ sizeof(pkt_len
);
171 rx_pd
->rx_pkt_length
= cpu_to_le16(pkt_len
);
173 cfg80211_rx_mgmt(priv
->wdev
, priv
->roc_cfg
.chan
.center_freq
,
174 CAL_RSSI(rx_pd
->snr
, rx_pd
->nf
), skb
->data
, pkt_len
,
181 * This function processes the received packet before sending it to the
184 * It extracts the SKB from the received buffer and sends it to kernel.
185 * In case the received buffer does not contain the data in SKB format,
186 * the function creates a blank SKB, fills it with the data from the
187 * received buffer and then sends this new SKB to the kernel.
189 int mwifiex_recv_packet(struct mwifiex_private
*priv
, struct sk_buff
*skb
)
194 skb
->dev
= priv
->netdev
;
195 skb
->protocol
= eth_type_trans(skb
, priv
->netdev
);
196 skb
->ip_summed
= CHECKSUM_NONE
;
198 /* This is required only in case of 11n and USB/PCIE as we alloc
199 * a buffer of 4K only if its 11N (to be able to receive 4K
200 * AMSDU packets). In case of SD we allocate buffers based
201 * on the size of packet and hence this is not needed.
203 * Modifying the truesize here as our allocation for each
204 * skb is 4K but we only receive 2K packets and this cause
205 * the kernel to start dropping packets in case where
206 * application has allocated buffer based on 2K size i.e.
207 * if there a 64K packet received (in IP fragments and
208 * application allocates 64K to receive this packet but
209 * this packet would almost double up because we allocate
210 * each 1.5K fragment in 4K and pass it up. As soon as the
211 * 64K limit hits kernel will start to drop rest of the
212 * fragments. Currently we fail the Filesndl-ht.scr script
213 * for UDP, hence this fix
215 if ((priv
->adapter
->iface_type
== MWIFIEX_USB
||
216 priv
->adapter
->iface_type
== MWIFIEX_PCIE
) &&
217 (skb
->truesize
> MWIFIEX_RX_DATA_BUF_SIZE
))
218 skb
->truesize
+= (skb
->len
- MWIFIEX_RX_DATA_BUF_SIZE
);
220 priv
->stats
.rx_bytes
+= skb
->len
;
221 priv
->stats
.rx_packets
++;
231 * IOCTL completion callback handler.
233 * This function is called when a pending IOCTL is completed.
235 * If work queue support is enabled, the function wakes up the
236 * corresponding waiting function. Otherwise, it processes the
237 * IOCTL response and frees the response buffer.
239 int mwifiex_complete_cmd(struct mwifiex_adapter
*adapter
,
240 struct cmd_ctrl_node
*cmd_node
)
242 dev_dbg(adapter
->dev
, "cmd completed: status=%d\n",
243 adapter
->cmd_wait_q
.status
);
245 *(cmd_node
->condition
) = true;
247 if (adapter
->cmd_wait_q
.status
== -ETIMEDOUT
)
248 dev_err(adapter
->dev
, "cmd timeout\n");
250 wake_up_interruptible(&adapter
->cmd_wait_q
.wait
);