cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

main.c (18767B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 *  Copyright (C) 2008, cozybit Inc.
      4 *  Copyright (C) 2003-2006, Marvell International Ltd.
      5 */
      6#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
      7
      8#include <linux/hardirq.h>
      9#include <linux/slab.h>
     10
     11#include <linux/etherdevice.h>
     12#include <linux/module.h>
     13#include "libertas_tf.h"
     14
     15/* thinfirm version: 5.132.X.pX */
     16#define LBTF_FW_VER_MIN		0x05840300
     17#define LBTF_FW_VER_MAX		0x0584ffff
     18
     19/* Module parameters */
     20unsigned int lbtf_debug;
     21EXPORT_SYMBOL_GPL(lbtf_debug);
     22module_param_named(libertas_tf_debug, lbtf_debug, int, 0644);
     23
     24struct workqueue_struct *lbtf_wq;
     25
     26static const struct ieee80211_channel lbtf_channels[] = {
     27	{ .center_freq = 2412, .hw_value = 1 },
     28	{ .center_freq = 2417, .hw_value = 2 },
     29	{ .center_freq = 2422, .hw_value = 3 },
     30	{ .center_freq = 2427, .hw_value = 4 },
     31	{ .center_freq = 2432, .hw_value = 5 },
     32	{ .center_freq = 2437, .hw_value = 6 },
     33	{ .center_freq = 2442, .hw_value = 7 },
     34	{ .center_freq = 2447, .hw_value = 8 },
     35	{ .center_freq = 2452, .hw_value = 9 },
     36	{ .center_freq = 2457, .hw_value = 10 },
     37	{ .center_freq = 2462, .hw_value = 11 },
     38	{ .center_freq = 2467, .hw_value = 12 },
     39	{ .center_freq = 2472, .hw_value = 13 },
     40	{ .center_freq = 2484, .hw_value = 14 },
     41};
     42
     43/* This table contains the hardware specific values for the modulation rates. */
     44static const struct ieee80211_rate lbtf_rates[] = {
     45	{ .bitrate = 10,
     46	  .hw_value = 0, },
     47	{ .bitrate = 20,
     48	  .hw_value = 1,
     49	  .flags = IEEE80211_RATE_SHORT_PREAMBLE },
     50	{ .bitrate = 55,
     51	  .hw_value = 2,
     52	  .flags = IEEE80211_RATE_SHORT_PREAMBLE },
     53	{ .bitrate = 110,
     54	  .hw_value = 3,
     55	  .flags = IEEE80211_RATE_SHORT_PREAMBLE },
     56	{ .bitrate = 60,
     57	  .hw_value = 5,
     58	  .flags = 0 },
     59	{ .bitrate = 90,
     60	  .hw_value = 6,
     61	  .flags = 0 },
     62	{ .bitrate = 120,
     63	  .hw_value = 7,
     64	  .flags = 0 },
     65	{ .bitrate = 180,
     66	  .hw_value = 8,
     67	  .flags = 0 },
     68	{ .bitrate = 240,
     69	  .hw_value = 9,
     70	  .flags = 0 },
     71	{ .bitrate = 360,
     72	  .hw_value = 10,
     73	  .flags = 0 },
     74	{ .bitrate = 480,
     75	  .hw_value = 11,
     76	  .flags = 0 },
     77	{ .bitrate = 540,
     78	  .hw_value = 12,
     79	  .flags = 0 },
     80};
     81
     82static void lbtf_cmd_work(struct work_struct *work)
     83{
     84	struct lbtf_private *priv = container_of(work, struct lbtf_private,
     85					 cmd_work);
     86
     87	lbtf_deb_enter(LBTF_DEB_CMD);
     88
     89	spin_lock_irq(&priv->driver_lock);
     90	/* command response? */
     91	if (priv->cmd_response_rxed) {
     92		priv->cmd_response_rxed = 0;
     93		spin_unlock_irq(&priv->driver_lock);
     94		lbtf_process_rx_command(priv);
     95		spin_lock_irq(&priv->driver_lock);
     96	}
     97
     98	if (priv->cmd_timed_out && priv->cur_cmd) {
     99		struct cmd_ctrl_node *cmdnode = priv->cur_cmd;
    100
    101		if (++priv->nr_retries > 10) {
    102			lbtf_complete_command(priv, cmdnode,
    103					      -ETIMEDOUT);
    104			priv->nr_retries = 0;
    105		} else {
    106			priv->cur_cmd = NULL;
    107
    108			/* Stick it back at the _top_ of the pending
    109			 * queue for immediate resubmission */
    110			list_add(&cmdnode->list, &priv->cmdpendingq);
    111		}
    112	}
    113	priv->cmd_timed_out = 0;
    114	spin_unlock_irq(&priv->driver_lock);
    115
    116	/* Execute the next command */
    117	if (!priv->cur_cmd)
    118		lbtf_execute_next_command(priv);
    119
    120	lbtf_deb_leave(LBTF_DEB_CMD);
    121}
    122
    123/*
    124 *  This function handles the timeout of command sending.
    125 *  It will re-send the same command again.
    126 */
    127static void command_timer_fn(struct timer_list *t)
    128{
    129	struct lbtf_private *priv = from_timer(priv, t, command_timer);
    130	unsigned long flags;
    131	lbtf_deb_enter(LBTF_DEB_CMD);
    132
    133	spin_lock_irqsave(&priv->driver_lock, flags);
    134
    135	if (!priv->cur_cmd) {
    136		printk(KERN_DEBUG "libertastf: command timer expired; "
    137				  "no pending command\n");
    138		goto out;
    139	}
    140
    141	printk(KERN_DEBUG "libertas: command %x timed out\n",
    142		le16_to_cpu(priv->cur_cmd->cmdbuf->command));
    143
    144	priv->cmd_timed_out = 1;
    145	queue_work(lbtf_wq, &priv->cmd_work);
    146out:
    147	spin_unlock_irqrestore(&priv->driver_lock, flags);
    148	lbtf_deb_leave(LBTF_DEB_CMD);
    149}
    150
    151static int lbtf_init_adapter(struct lbtf_private *priv)
    152{
    153	lbtf_deb_enter(LBTF_DEB_MAIN);
    154	eth_broadcast_addr(priv->current_addr);
    155	mutex_init(&priv->lock);
    156
    157	priv->vif = NULL;
    158	timer_setup(&priv->command_timer, command_timer_fn, 0);
    159
    160	INIT_LIST_HEAD(&priv->cmdfreeq);
    161	INIT_LIST_HEAD(&priv->cmdpendingq);
    162
    163	spin_lock_init(&priv->driver_lock);
    164
    165	/* Allocate the command buffers */
    166	if (lbtf_allocate_cmd_buffer(priv))
    167		return -1;
    168
    169	lbtf_deb_leave(LBTF_DEB_MAIN);
    170	return 0;
    171}
    172
    173static void lbtf_free_adapter(struct lbtf_private *priv)
    174{
    175	lbtf_deb_enter(LBTF_DEB_MAIN);
    176	lbtf_free_cmd_buffer(priv);
    177	del_timer(&priv->command_timer);
    178	lbtf_deb_leave(LBTF_DEB_MAIN);
    179}
    180
    181static void lbtf_op_tx(struct ieee80211_hw *hw,
    182		       struct ieee80211_tx_control *control,
    183		       struct sk_buff *skb)
    184{
    185	struct lbtf_private *priv = hw->priv;
    186
    187	priv->skb_to_tx = skb;
    188	queue_work(lbtf_wq, &priv->tx_work);
    189	/*
    190	 * queue will be restarted when we receive transmission feedback if
    191	 * there are no buffered multicast frames to send
    192	 */
    193	ieee80211_stop_queues(priv->hw);
    194}
    195
    196static void lbtf_tx_work(struct work_struct *work)
    197{
    198	struct lbtf_private *priv = container_of(work, struct lbtf_private,
    199					 tx_work);
    200	unsigned int len;
    201	struct ieee80211_tx_info *info;
    202	struct txpd *txpd;
    203	struct sk_buff *skb = NULL;
    204	int err;
    205
    206	lbtf_deb_enter(LBTF_DEB_MACOPS | LBTF_DEB_TX);
    207
    208	if ((priv->vif->type == NL80211_IFTYPE_AP) &&
    209	    (!skb_queue_empty(&priv->bc_ps_buf)))
    210		skb = skb_dequeue(&priv->bc_ps_buf);
    211	else if (priv->skb_to_tx) {
    212		skb = priv->skb_to_tx;
    213		priv->skb_to_tx = NULL;
    214	} else {
    215		lbtf_deb_leave(LBTF_DEB_MACOPS | LBTF_DEB_TX);
    216		return;
    217	}
    218
    219	len = skb->len;
    220	info  = IEEE80211_SKB_CB(skb);
    221	txpd = skb_push(skb, sizeof(struct txpd));
    222
    223	if (priv->surpriseremoved) {
    224		dev_kfree_skb_any(skb);
    225		lbtf_deb_leave(LBTF_DEB_MACOPS | LBTF_DEB_TX);
    226		return;
    227	}
    228
    229	memset(txpd, 0, sizeof(struct txpd));
    230	/* Activate per-packet rate selection */
    231	txpd->tx_control |= cpu_to_le32(MRVL_PER_PACKET_RATE |
    232			     ieee80211_get_tx_rate(priv->hw, info)->hw_value);
    233
    234	/* copy destination address from 802.11 header */
    235	BUILD_BUG_ON(sizeof(txpd->tx_dest_addr) != ETH_ALEN);
    236	memcpy(&txpd->tx_dest_addr, skb->data + sizeof(struct txpd) + 4,
    237		ETH_ALEN);
    238	txpd->tx_packet_length = cpu_to_le16(len);
    239	txpd->tx_packet_location = cpu_to_le32(sizeof(struct txpd));
    240	lbtf_deb_hex(LBTF_DEB_TX, "TX Data", skb->data, min_t(unsigned int, skb->len, 100));
    241	BUG_ON(priv->tx_skb);
    242	spin_lock_irq(&priv->driver_lock);
    243	priv->tx_skb = skb;
    244	err = priv->ops->hw_host_to_card(priv, MVMS_DAT, skb->data, skb->len);
    245	spin_unlock_irq(&priv->driver_lock);
    246	if (err) {
    247		dev_kfree_skb_any(skb);
    248		priv->tx_skb = NULL;
    249		pr_err("TX error: %d", err);
    250	}
    251	lbtf_deb_leave(LBTF_DEB_MACOPS | LBTF_DEB_TX);
    252}
    253
    254static int lbtf_op_start(struct ieee80211_hw *hw)
    255{
    256	struct lbtf_private *priv = hw->priv;
    257
    258	lbtf_deb_enter(LBTF_DEB_MACOPS);
    259
    260	priv->capability = WLAN_CAPABILITY_SHORT_PREAMBLE;
    261	priv->radioon = RADIO_ON;
    262	priv->mac_control = CMD_ACT_MAC_RX_ON | CMD_ACT_MAC_TX_ON;
    263	lbtf_set_mac_control(priv);
    264	lbtf_set_radio_control(priv);
    265
    266	lbtf_deb_leave(LBTF_DEB_MACOPS);
    267	return 0;
    268}
    269
    270static void lbtf_op_stop(struct ieee80211_hw *hw)
    271{
    272	struct lbtf_private *priv = hw->priv;
    273	unsigned long flags;
    274	struct sk_buff *skb;
    275
    276	struct cmd_ctrl_node *cmdnode;
    277
    278	lbtf_deb_enter(LBTF_DEB_MACOPS);
    279
    280	/* Flush pending command nodes */
    281	spin_lock_irqsave(&priv->driver_lock, flags);
    282	list_for_each_entry(cmdnode, &priv->cmdpendingq, list) {
    283		cmdnode->result = -ENOENT;
    284		cmdnode->cmdwaitqwoken = 1;
    285		wake_up_interruptible(&cmdnode->cmdwait_q);
    286	}
    287
    288	spin_unlock_irqrestore(&priv->driver_lock, flags);
    289	cancel_work_sync(&priv->cmd_work);
    290	cancel_work_sync(&priv->tx_work);
    291	while ((skb = skb_dequeue(&priv->bc_ps_buf)))
    292		dev_kfree_skb_any(skb);
    293	priv->radioon = RADIO_OFF;
    294	lbtf_set_radio_control(priv);
    295
    296	lbtf_deb_leave(LBTF_DEB_MACOPS);
    297}
    298
    299static int lbtf_op_add_interface(struct ieee80211_hw *hw,
    300			struct ieee80211_vif *vif)
    301{
    302	struct lbtf_private *priv = hw->priv;
    303	lbtf_deb_enter(LBTF_DEB_MACOPS);
    304	if (priv->vif != NULL)
    305		return -EOPNOTSUPP;
    306
    307	priv->vif = vif;
    308	switch (vif->type) {
    309	case NL80211_IFTYPE_MESH_POINT:
    310	case NL80211_IFTYPE_AP:
    311		lbtf_set_mode(priv, LBTF_AP_MODE);
    312		break;
    313	case NL80211_IFTYPE_STATION:
    314		lbtf_set_mode(priv, LBTF_STA_MODE);
    315		break;
    316	default:
    317		priv->vif = NULL;
    318		return -EOPNOTSUPP;
    319	}
    320	lbtf_set_mac_address(priv, (u8 *) vif->addr);
    321	lbtf_deb_leave(LBTF_DEB_MACOPS);
    322	return 0;
    323}
    324
    325static void lbtf_op_remove_interface(struct ieee80211_hw *hw,
    326			struct ieee80211_vif *vif)
    327{
    328	struct lbtf_private *priv = hw->priv;
    329	lbtf_deb_enter(LBTF_DEB_MACOPS);
    330
    331	if (priv->vif->type == NL80211_IFTYPE_AP ||
    332	    priv->vif->type == NL80211_IFTYPE_MESH_POINT)
    333		lbtf_beacon_ctrl(priv, 0, 0);
    334	lbtf_set_mode(priv, LBTF_PASSIVE_MODE);
    335	lbtf_set_bssid(priv, 0, NULL);
    336	priv->vif = NULL;
    337	lbtf_deb_leave(LBTF_DEB_MACOPS);
    338}
    339
    340static int lbtf_op_config(struct ieee80211_hw *hw, u32 changed)
    341{
    342	struct lbtf_private *priv = hw->priv;
    343	struct ieee80211_conf *conf = &hw->conf;
    344	lbtf_deb_enter(LBTF_DEB_MACOPS);
    345
    346	if (conf->chandef.chan->center_freq != priv->cur_freq) {
    347		priv->cur_freq = conf->chandef.chan->center_freq;
    348		lbtf_set_channel(priv, conf->chandef.chan->hw_value);
    349	}
    350	lbtf_deb_leave(LBTF_DEB_MACOPS);
    351	return 0;
    352}
    353
    354static u64 lbtf_op_prepare_multicast(struct ieee80211_hw *hw,
    355				     struct netdev_hw_addr_list *mc_list)
    356{
    357	struct lbtf_private *priv = hw->priv;
    358	int i;
    359	struct netdev_hw_addr *ha;
    360	int mc_count = netdev_hw_addr_list_count(mc_list);
    361
    362	if (!mc_count || mc_count > MRVDRV_MAX_MULTICAST_LIST_SIZE)
    363		return mc_count;
    364
    365	priv->nr_of_multicastmacaddr = mc_count;
    366	i = 0;
    367	netdev_hw_addr_list_for_each(ha, mc_list)
    368		memcpy(&priv->multicastlist[i++], ha->addr, ETH_ALEN);
    369
    370	return mc_count;
    371}
    372
    373#define SUPPORTED_FIF_FLAGS  FIF_ALLMULTI
    374static void lbtf_op_configure_filter(struct ieee80211_hw *hw,
    375			unsigned int changed_flags,
    376			unsigned int *new_flags,
    377			u64 multicast)
    378{
    379	struct lbtf_private *priv = hw->priv;
    380	int old_mac_control = priv->mac_control;
    381
    382	lbtf_deb_enter(LBTF_DEB_MACOPS);
    383
    384	changed_flags &= SUPPORTED_FIF_FLAGS;
    385	*new_flags &= SUPPORTED_FIF_FLAGS;
    386
    387	if (!changed_flags) {
    388		lbtf_deb_leave(LBTF_DEB_MACOPS);
    389		return;
    390	}
    391
    392	priv->mac_control &= ~CMD_ACT_MAC_PROMISCUOUS_ENABLE;
    393	if (*new_flags & (FIF_ALLMULTI) ||
    394	    multicast > MRVDRV_MAX_MULTICAST_LIST_SIZE) {
    395		priv->mac_control |= CMD_ACT_MAC_ALL_MULTICAST_ENABLE;
    396		priv->mac_control &= ~CMD_ACT_MAC_MULTICAST_ENABLE;
    397	} else if (multicast) {
    398		priv->mac_control |= CMD_ACT_MAC_MULTICAST_ENABLE;
    399		priv->mac_control &= ~CMD_ACT_MAC_ALL_MULTICAST_ENABLE;
    400		lbtf_cmd_set_mac_multicast_addr(priv);
    401	} else {
    402		priv->mac_control &= ~(CMD_ACT_MAC_MULTICAST_ENABLE |
    403				       CMD_ACT_MAC_ALL_MULTICAST_ENABLE);
    404		if (priv->nr_of_multicastmacaddr) {
    405			priv->nr_of_multicastmacaddr = 0;
    406			lbtf_cmd_set_mac_multicast_addr(priv);
    407		}
    408	}
    409
    410
    411	if (priv->mac_control != old_mac_control)
    412		lbtf_set_mac_control(priv);
    413
    414	lbtf_deb_leave(LBTF_DEB_MACOPS);
    415}
    416
    417static void lbtf_op_bss_info_changed(struct ieee80211_hw *hw,
    418			struct ieee80211_vif *vif,
    419			struct ieee80211_bss_conf *bss_conf,
    420			u32 changes)
    421{
    422	struct lbtf_private *priv = hw->priv;
    423	struct sk_buff *beacon;
    424	lbtf_deb_enter(LBTF_DEB_MACOPS);
    425
    426	if (changes & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_INT)) {
    427		switch (priv->vif->type) {
    428		case NL80211_IFTYPE_AP:
    429		case NL80211_IFTYPE_MESH_POINT:
    430			beacon = ieee80211_beacon_get(hw, vif);
    431			if (beacon) {
    432				lbtf_beacon_set(priv, beacon);
    433				kfree_skb(beacon);
    434				lbtf_beacon_ctrl(priv, 1,
    435						 bss_conf->beacon_int);
    436			}
    437			break;
    438		default:
    439			break;
    440		}
    441	}
    442
    443	if (changes & BSS_CHANGED_BSSID) {
    444		bool activate = !is_zero_ether_addr(bss_conf->bssid);
    445		lbtf_set_bssid(priv, activate, bss_conf->bssid);
    446	}
    447
    448	if (changes & BSS_CHANGED_ERP_PREAMBLE) {
    449		if (bss_conf->use_short_preamble)
    450			priv->preamble = CMD_TYPE_SHORT_PREAMBLE;
    451		else
    452			priv->preamble = CMD_TYPE_LONG_PREAMBLE;
    453		lbtf_set_radio_control(priv);
    454	}
    455
    456	lbtf_deb_leave(LBTF_DEB_MACOPS);
    457}
    458
    459static int lbtf_op_get_survey(struct ieee80211_hw *hw, int idx,
    460				struct survey_info *survey)
    461{
    462	struct lbtf_private *priv = hw->priv;
    463	struct ieee80211_conf *conf = &hw->conf;
    464
    465	if (idx != 0)
    466		return -ENOENT;
    467
    468	survey->channel = conf->chandef.chan;
    469	survey->filled = SURVEY_INFO_NOISE_DBM;
    470	survey->noise = priv->noise;
    471
    472	return 0;
    473}
    474
    475static const struct ieee80211_ops lbtf_ops = {
    476	.tx			= lbtf_op_tx,
    477	.start			= lbtf_op_start,
    478	.stop			= lbtf_op_stop,
    479	.add_interface		= lbtf_op_add_interface,
    480	.remove_interface	= lbtf_op_remove_interface,
    481	.config			= lbtf_op_config,
    482	.prepare_multicast	= lbtf_op_prepare_multicast,
    483	.configure_filter	= lbtf_op_configure_filter,
    484	.bss_info_changed	= lbtf_op_bss_info_changed,
    485	.get_survey		= lbtf_op_get_survey,
    486};
    487
    488int lbtf_rx(struct lbtf_private *priv, struct sk_buff *skb)
    489{
    490	struct ieee80211_rx_status stats;
    491	struct rxpd *prxpd;
    492	int need_padding;
    493	struct ieee80211_hdr *hdr;
    494
    495	lbtf_deb_enter(LBTF_DEB_RX);
    496
    497	if (priv->radioon != RADIO_ON) {
    498		lbtf_deb_rx("rx before we turned on the radio");
    499		goto done;
    500	}
    501
    502	prxpd = (struct rxpd *) skb->data;
    503
    504	memset(&stats, 0, sizeof(stats));
    505	if (!(prxpd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK)))
    506		stats.flag |= RX_FLAG_FAILED_FCS_CRC;
    507	stats.freq = priv->cur_freq;
    508	stats.band = NL80211_BAND_2GHZ;
    509	stats.signal = prxpd->snr - prxpd->nf;
    510	priv->noise = prxpd->nf;
    511	/* Marvell rate index has a hole at value 4 */
    512	if (prxpd->rx_rate > 4)
    513		--prxpd->rx_rate;
    514	stats.rate_idx = prxpd->rx_rate;
    515	skb_pull(skb, sizeof(struct rxpd));
    516
    517	hdr = (struct ieee80211_hdr *)skb->data;
    518
    519	need_padding = ieee80211_is_data_qos(hdr->frame_control);
    520	need_padding ^= ieee80211_has_a4(hdr->frame_control);
    521	need_padding ^= ieee80211_is_data_qos(hdr->frame_control) &&
    522			(*ieee80211_get_qos_ctl(hdr) &
    523			 IEEE80211_QOS_CTL_A_MSDU_PRESENT);
    524
    525	if (need_padding) {
    526		memmove(skb->data + 2, skb->data, skb->len);
    527		skb_reserve(skb, 2);
    528	}
    529
    530	memcpy(IEEE80211_SKB_RXCB(skb), &stats, sizeof(stats));
    531
    532	lbtf_deb_rx("rx data: skb->len-sizeof(RxPd) = %d-%zd = %zd\n",
    533	       skb->len, sizeof(struct rxpd), skb->len - sizeof(struct rxpd));
    534	lbtf_deb_hex(LBTF_DEB_RX, "RX Data", skb->data,
    535	             min_t(unsigned int, skb->len, 100));
    536
    537	ieee80211_rx_irqsafe(priv->hw, skb);
    538
    539done:
    540	lbtf_deb_leave(LBTF_DEB_RX);
    541	return 0;
    542}
    543EXPORT_SYMBOL_GPL(lbtf_rx);
    544
    545/*
    546 * lbtf_add_card: Add and initialize the card.
    547 *
    548 *  Returns: pointer to struct lbtf_priv.
    549 */
    550struct lbtf_private *lbtf_add_card(void *card, struct device *dmdev,
    551				   const struct lbtf_ops *ops)
    552{
    553	struct ieee80211_hw *hw;
    554	struct lbtf_private *priv = NULL;
    555
    556	lbtf_deb_enter(LBTF_DEB_MAIN);
    557
    558	hw = ieee80211_alloc_hw(sizeof(struct lbtf_private), &lbtf_ops);
    559	if (!hw)
    560		goto done;
    561
    562	priv = hw->priv;
    563	if (lbtf_init_adapter(priv))
    564		goto err_init_adapter;
    565
    566	priv->hw = hw;
    567	priv->card = card;
    568	priv->ops = ops;
    569	priv->tx_skb = NULL;
    570	priv->radioon = RADIO_OFF;
    571
    572	hw->queues = 1;
    573	ieee80211_hw_set(hw, HOST_BROADCAST_PS_BUFFERING);
    574	ieee80211_hw_set(hw, SIGNAL_DBM);
    575	hw->extra_tx_headroom = sizeof(struct txpd);
    576	memcpy(priv->channels, lbtf_channels, sizeof(lbtf_channels));
    577	memcpy(priv->rates, lbtf_rates, sizeof(lbtf_rates));
    578	priv->band.n_bitrates = ARRAY_SIZE(lbtf_rates);
    579	priv->band.bitrates = priv->rates;
    580	priv->band.n_channels = ARRAY_SIZE(lbtf_channels);
    581	priv->band.channels = priv->channels;
    582	hw->wiphy->bands[NL80211_BAND_2GHZ] = &priv->band;
    583	hw->wiphy->interface_modes =
    584		BIT(NL80211_IFTYPE_STATION) |
    585		BIT(NL80211_IFTYPE_ADHOC);
    586	skb_queue_head_init(&priv->bc_ps_buf);
    587
    588	wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
    589
    590	SET_IEEE80211_DEV(hw, dmdev);
    591
    592	INIT_WORK(&priv->cmd_work, lbtf_cmd_work);
    593	INIT_WORK(&priv->tx_work, lbtf_tx_work);
    594
    595	if (priv->ops->hw_prog_firmware(priv)) {
    596		lbtf_deb_usbd(dmdev, "Error programming the firmware\n");
    597		priv->ops->hw_reset_device(priv);
    598		goto err_init_adapter;
    599	}
    600
    601	eth_broadcast_addr(priv->current_addr);
    602	if (lbtf_update_hw_spec(priv))
    603		goto err_init_adapter;
    604
    605	if (priv->fwrelease < LBTF_FW_VER_MIN ||
    606	    priv->fwrelease > LBTF_FW_VER_MAX) {
    607		goto err_init_adapter;
    608	}
    609
    610	/* The firmware seems to start with the radio enabled. Turn it
    611	 * off before an actual mac80211 start callback is invoked.
    612	 */
    613	lbtf_set_radio_control(priv);
    614
    615	if (ieee80211_register_hw(hw))
    616		goto err_init_adapter;
    617
    618	dev_info(dmdev, "libertastf: Marvell WLAN 802.11 thinfirm adapter\n");
    619	goto done;
    620
    621err_init_adapter:
    622	lbtf_free_adapter(priv);
    623	ieee80211_free_hw(hw);
    624	priv = NULL;
    625
    626done:
    627	lbtf_deb_leave_args(LBTF_DEB_MAIN, "priv %p", priv);
    628	return priv;
    629}
    630EXPORT_SYMBOL_GPL(lbtf_add_card);
    631
    632
    633int lbtf_remove_card(struct lbtf_private *priv)
    634{
    635	struct ieee80211_hw *hw = priv->hw;
    636
    637	lbtf_deb_enter(LBTF_DEB_MAIN);
    638
    639	priv->surpriseremoved = 1;
    640	del_timer(&priv->command_timer);
    641	lbtf_free_adapter(priv);
    642	priv->hw = NULL;
    643	ieee80211_unregister_hw(hw);
    644	ieee80211_free_hw(hw);
    645
    646	lbtf_deb_leave(LBTF_DEB_MAIN);
    647	return 0;
    648}
    649EXPORT_SYMBOL_GPL(lbtf_remove_card);
    650
    651void lbtf_send_tx_feedback(struct lbtf_private *priv, u8 retrycnt, u8 fail)
    652{
    653	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(priv->tx_skb);
    654
    655	ieee80211_tx_info_clear_status(info);
    656	/*
    657	 * Commented out, otherwise we never go beyond 1Mbit/s using mac80211
    658	 * default pid rc algorithm.
    659	 *
    660	 * info->status.retry_count = MRVL_DEFAULT_RETRIES - retrycnt;
    661	 */
    662	if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && !fail)
    663		info->flags |= IEEE80211_TX_STAT_ACK;
    664	skb_pull(priv->tx_skb, sizeof(struct txpd));
    665	ieee80211_tx_status_irqsafe(priv->hw, priv->tx_skb);
    666	priv->tx_skb = NULL;
    667	if (!priv->skb_to_tx && skb_queue_empty(&priv->bc_ps_buf))
    668		ieee80211_wake_queues(priv->hw);
    669	else
    670		queue_work(lbtf_wq, &priv->tx_work);
    671}
    672EXPORT_SYMBOL_GPL(lbtf_send_tx_feedback);
    673
    674void lbtf_bcn_sent(struct lbtf_private *priv)
    675{
    676	struct sk_buff *skb = NULL;
    677
    678	if (priv->vif->type != NL80211_IFTYPE_AP)
    679		return;
    680
    681	if (skb_queue_empty(&priv->bc_ps_buf)) {
    682		bool tx_buff_bc = false;
    683
    684		while ((skb = ieee80211_get_buffered_bc(priv->hw, priv->vif))) {
    685			skb_queue_tail(&priv->bc_ps_buf, skb);
    686			tx_buff_bc = true;
    687		}
    688		if (tx_buff_bc) {
    689			ieee80211_stop_queues(priv->hw);
    690			queue_work(lbtf_wq, &priv->tx_work);
    691		}
    692	}
    693
    694	skb = ieee80211_beacon_get(priv->hw, priv->vif);
    695
    696	if (skb) {
    697		lbtf_beacon_set(priv, skb);
    698		kfree_skb(skb);
    699	}
    700}
    701EXPORT_SYMBOL_GPL(lbtf_bcn_sent);
    702
    703static int __init lbtf_init_module(void)
    704{
    705	lbtf_deb_enter(LBTF_DEB_MAIN);
    706	lbtf_wq = alloc_workqueue("libertastf", WQ_MEM_RECLAIM, 0);
    707	if (lbtf_wq == NULL) {
    708		printk(KERN_ERR "libertastf: couldn't create workqueue\n");
    709		return -ENOMEM;
    710	}
    711	lbtf_deb_leave(LBTF_DEB_MAIN);
    712	return 0;
    713}
    714
    715static void __exit lbtf_exit_module(void)
    716{
    717	lbtf_deb_enter(LBTF_DEB_MAIN);
    718	destroy_workqueue(lbtf_wq);
    719	lbtf_deb_leave(LBTF_DEB_MAIN);
    720}
    721
    722module_init(lbtf_init_module);
    723module_exit(lbtf_exit_module);
    724
    725MODULE_DESCRIPTION("Libertas WLAN Thinfirm Driver Library");
    726MODULE_AUTHOR("Cozybit Inc.");
    727MODULE_LICENSE("GPL");