2 * Copyright (c) 2014 Redpine Signals Inc.
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
19 #include <linux/module.h>
20 #include <linux/firmware.h>
22 #include "rsi_common.h"
25 u32 rsi_zone_enabled
= /* INFO_ZONE |
35 EXPORT_SYMBOL_GPL(rsi_zone_enabled
);
38 * rsi_dbg() - This function outputs informational messages.
39 * @zone: Zone of interest for output message.
40 * @fmt: printf-style format for output message.
44 void rsi_dbg(u32 zone
, const char *fmt
, ...)
54 if (zone
& rsi_zone_enabled
)
58 EXPORT_SYMBOL_GPL(rsi_dbg
);
60 static char *opmode_str(int oper_mode
)
63 case RSI_DEV_OPMODE_WIFI_ALONE
:
70 void rsi_print_version(struct rsi_common
*common
)
72 rsi_dbg(ERR_ZONE
, "================================================\n");
73 rsi_dbg(ERR_ZONE
, "================ RSI Version Info ==============\n");
74 rsi_dbg(ERR_ZONE
, "================================================\n");
75 rsi_dbg(ERR_ZONE
, "FW Version\t: %d.%d.%d\n",
76 common
->lmac_ver
.major
, common
->lmac_ver
.minor
,
77 common
->lmac_ver
.release_num
);
78 rsi_dbg(ERR_ZONE
, "Operating mode\t: %d [%s]",
79 common
->oper_mode
, opmode_str(common
->oper_mode
));
80 rsi_dbg(ERR_ZONE
, "Firmware file\t: %s", common
->priv
->fw_file_name
);
81 rsi_dbg(ERR_ZONE
, "================================================\n");
85 * rsi_prepare_skb() - This function prepares the skb.
86 * @common: Pointer to the driver private structure.
87 * @buffer: Pointer to the packet data.
88 * @pkt_len: Length of the packet.
89 * @extended_desc: Extended descriptor.
91 * Return: Successfully skb.
93 static struct sk_buff
*rsi_prepare_skb(struct rsi_common
*common
,
98 struct ieee80211_tx_info
*info
;
99 struct skb_info
*rx_params
;
100 struct sk_buff
*skb
= NULL
;
102 struct ieee80211_vif
*vif
;
103 struct ieee80211_hdr
*wh
;
105 if (WARN(!pkt_len
, "%s: Dummy pkt received", __func__
))
108 if (pkt_len
> (RSI_RCV_BUFFER_LEN
* 4)) {
109 rsi_dbg(ERR_ZONE
, "%s: Pkt size > max rx buf size %d\n",
111 pkt_len
= RSI_RCV_BUFFER_LEN
* 4;
114 pkt_len
-= extended_desc
;
115 skb
= dev_alloc_skb(pkt_len
+ FRAME_DESC_SZ
);
119 payload_offset
= (extended_desc
+ FRAME_DESC_SZ
);
120 skb_put(skb
, pkt_len
);
121 memcpy((skb
->data
), (buffer
+ payload_offset
), skb
->len
);
122 wh
= (struct ieee80211_hdr
*)skb
->data
;
123 vif
= rsi_get_vif(common
->priv
, wh
->addr1
);
125 info
= IEEE80211_SKB_CB(skb
);
126 rx_params
= (struct skb_info
*)info
->driver_data
;
127 rx_params
->rssi
= rsi_get_rssi(buffer
);
128 rx_params
->channel
= rsi_get_connected_channel(vif
);
134 * rsi_read_pkt() - This function reads frames from the card.
135 * @common: Pointer to the driver private structure.
136 * @rcv_pkt_len: Received pkt length. In case of USB it is 0.
138 * Return: 0 on success, -1 on failure.
140 int rsi_read_pkt(struct rsi_common
*common
, s32 rcv_pkt_len
)
142 u8
*frame_desc
= NULL
, extended_desc
= 0;
143 u32 index
, length
= 0, queueno
= 0;
144 u16 actual_length
= 0, offset
;
145 struct sk_buff
*skb
= NULL
;
149 frame_desc
= &common
->rx_data_pkt
[index
];
150 actual_length
= *(u16
*)&frame_desc
[0];
151 offset
= *(u16
*)&frame_desc
[2];
153 queueno
= rsi_get_queueno(frame_desc
, offset
);
154 length
= rsi_get_length(frame_desc
, offset
);
156 /* Extended descriptor is valid for WLAN queues only */
157 if (queueno
== RSI_WIFI_DATA_Q
|| queueno
== RSI_WIFI_MGMT_Q
)
158 extended_desc
= rsi_get_extended_desc(frame_desc
,
163 rsi_mgmt_pkt_recv(common
, (frame_desc
+ offset
));
165 case RSI_WIFI_DATA_Q
:
166 skb
= rsi_prepare_skb(common
,
167 (frame_desc
+ offset
),
173 rsi_indicate_pkt_to_os(common
, skb
);
176 case RSI_WIFI_MGMT_Q
:
177 rsi_mgmt_pkt_recv(common
, (frame_desc
+ offset
));
181 rsi_dbg(ERR_ZONE
, "%s: pkt from invalid queue: %d\n",
186 index
+= actual_length
;
187 rcv_pkt_len
-= actual_length
;
188 } while (rcv_pkt_len
> 0);
194 EXPORT_SYMBOL_GPL(rsi_read_pkt
);
197 * rsi_tx_scheduler_thread() - This function is a kernel thread to send the
198 * packets to the device.
199 * @common: Pointer to the driver private structure.
203 static void rsi_tx_scheduler_thread(struct rsi_common
*common
)
205 struct rsi_hw
*adapter
= common
->priv
;
206 u32 timeout
= EVENT_WAIT_FOREVER
;
209 if (adapter
->determine_event_timeout
)
210 timeout
= adapter
->determine_event_timeout(adapter
);
211 rsi_wait_event(&common
->tx_thread
.event
, timeout
);
212 rsi_reset_event(&common
->tx_thread
.event
);
214 if (common
->init_done
)
215 rsi_core_qos_processor(common
);
216 } while (atomic_read(&common
->tx_thread
.thread_done
) == 0);
217 complete_and_exit(&common
->tx_thread
.completion
, 0);
221 * rsi_91x_init() - This function initializes os interface operations.
224 * Return: Pointer to the adapter structure on success, NULL on failure .
226 struct rsi_hw
*rsi_91x_init(void)
228 struct rsi_hw
*adapter
= NULL
;
229 struct rsi_common
*common
= NULL
;
232 adapter
= kzalloc(sizeof(*adapter
), GFP_KERNEL
);
236 adapter
->priv
= kzalloc(sizeof(*common
), GFP_KERNEL
);
237 if (adapter
->priv
== NULL
) {
238 rsi_dbg(ERR_ZONE
, "%s: Failed in allocation of memory\n",
243 common
= adapter
->priv
;
244 common
->priv
= adapter
;
247 for (ii
= 0; ii
< NUM_SOFT_QUEUES
; ii
++)
248 skb_queue_head_init(&common
->tx_queue
[ii
]);
250 rsi_init_event(&common
->tx_thread
.event
);
251 mutex_init(&common
->mutex
);
252 mutex_init(&common
->tx_lock
);
253 mutex_init(&common
->rx_lock
);
255 if (rsi_create_kthread(common
,
257 rsi_tx_scheduler_thread
,
259 rsi_dbg(ERR_ZONE
, "%s: Unable to init tx thrd\n", __func__
);
263 rsi_default_ps_params(adapter
);
264 spin_lock_init(&adapter
->ps_lock
);
265 timer_setup(&common
->roc_timer
, rsi_roc_timeout
, 0);
266 init_completion(&common
->wlan_init_completion
);
267 common
->init_done
= true;
275 EXPORT_SYMBOL_GPL(rsi_91x_init
);
278 * rsi_91x_deinit() - This function de-intializes os intf operations.
279 * @adapter: Pointer to the adapter structure.
283 void rsi_91x_deinit(struct rsi_hw
*adapter
)
285 struct rsi_common
*common
= adapter
->priv
;
288 rsi_dbg(INFO_ZONE
, "%s: Performing deinit os ops\n", __func__
);
290 rsi_kill_thread(&common
->tx_thread
);
292 for (ii
= 0; ii
< NUM_SOFT_QUEUES
; ii
++)
293 skb_queue_purge(&common
->tx_queue
[ii
]);
295 common
->init_done
= false;
298 kfree(adapter
->rsi_dev
);
301 EXPORT_SYMBOL_GPL(rsi_91x_deinit
);
304 * rsi_91x_hal_module_init() - This function is invoked when the module is
305 * loaded into the kernel.
306 * It registers the client driver.
309 * Return: 0 on success, -1 on failure.
311 static int rsi_91x_hal_module_init(void)
313 rsi_dbg(INIT_ZONE
, "%s: Module init called\n", __func__
);
318 * rsi_91x_hal_module_exit() - This function is called at the time of
319 * removing/unloading the module.
320 * It unregisters the client driver.
325 static void rsi_91x_hal_module_exit(void)
327 rsi_dbg(INIT_ZONE
, "%s: Module exit called\n", __func__
);
330 module_init(rsi_91x_hal_module_init
);
331 module_exit(rsi_91x_hal_module_exit
);
332 MODULE_AUTHOR("Redpine Signals Inc");
333 MODULE_DESCRIPTION("Station driver for RSI 91x devices");
334 MODULE_SUPPORTED_DEVICE("RSI-91x");
335 MODULE_VERSION("0.1");
336 MODULE_LICENSE("Dual BSD/GPL");