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

rxtx.c (19375B)


      1// SPDX-License-Identifier: GPL-2.0+
      2/*
      3 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
      4 * All rights reserved.
      5 *
      6 * Purpose: handle WMAC/802.3/802.11 rx & tx functions
      7 *
      8 * Author: Lyndon Chen
      9 *
     10 * Date: May 20, 2003
     11 *
     12 * Functions:
     13 *      vnt_generate_tx_parameter - Generate tx dma required parameter.
     14 *      vnt_get_rsvtime- get frame reserved time
     15 *      vnt_fill_cts_head- fulfill CTS ctl header
     16 *
     17 * Revision History:
     18 *
     19 */
     20
     21#include <linux/etherdevice.h>
     22#include "device.h"
     23#include "rxtx.h"
     24#include "card.h"
     25#include "mac.h"
     26#include "rf.h"
     27#include "usbpipe.h"
     28
     29static const u16 vnt_time_stampoff[2][MAX_RATE] = {
     30	/* Long Preamble */
     31	{384, 288, 226, 209, 54, 43, 37, 31, 28, 25, 24, 23},
     32
     33	/* Short Preamble */
     34	{384, 192, 130, 113, 54, 43, 37, 31, 28, 25, 24, 23},
     35};
     36
     37#define DATADUR_B       10
     38#define DATADUR_A       11
     39
     40static const u8 vnt_phy_signal[] = {
     41	0x00,	/* RATE_1M  */
     42	0x01,	/* RATE_2M  */
     43	0x02,	/* RATE_5M  */
     44	0x03,	/* RATE_11M */
     45	0x8b,	/* RATE_6M  */
     46	0x8f,	/* RATE_9M  */
     47	0x8a,	/* RATE_12M */
     48	0x8e,	/* RATE_18M */
     49	0x89,	/* RATE_24M */
     50	0x8d,	/* RATE_36M */
     51	0x88,	/* RATE_48M */
     52	0x8c	/* RATE_54M */
     53};
     54
     55static struct vnt_usb_send_context
     56	*vnt_get_free_context(struct vnt_private *priv)
     57{
     58	struct vnt_usb_send_context *context = NULL;
     59	int ii;
     60
     61	for (ii = 0; ii < priv->num_tx_context; ii++) {
     62		if (!priv->tx_context[ii])
     63			return NULL;
     64
     65		context = priv->tx_context[ii];
     66		if (!context->in_use) {
     67			context->in_use = true;
     68			return context;
     69		}
     70	}
     71
     72	if (ii == priv->num_tx_context) {
     73		dev_dbg(&priv->usb->dev, "%s No Free Tx Context\n", __func__);
     74
     75		ieee80211_stop_queues(priv->hw);
     76	}
     77
     78	return NULL;
     79}
     80
     81/* Get Length, Service, and Signal fields of Phy for Tx */
     82static void vnt_get_phy_field(struct vnt_private *priv, u32 frame_length,
     83			      u16 tx_rate, u8 pkt_type,
     84			      struct vnt_phy_field *phy)
     85{
     86	u32 bit_count;
     87	u32 count = 0;
     88	u32 tmp;
     89	int ext_bit;
     90	int i;
     91	u8 mask = 0;
     92	u8 preamble_type = priv->preamble_type;
     93
     94	bit_count = frame_length * 8;
     95	ext_bit = false;
     96
     97	switch (tx_rate) {
     98	case RATE_1M:
     99		count = bit_count;
    100		break;
    101	case RATE_2M:
    102		count = bit_count / 2;
    103		break;
    104	case RATE_5M:
    105		count = DIV_ROUND_UP(bit_count * 10, 55);
    106		break;
    107	case RATE_11M:
    108		count = bit_count / 11;
    109		tmp = count * 11;
    110
    111		if (tmp != bit_count) {
    112			count++;
    113
    114			if ((bit_count - tmp) <= 3)
    115				ext_bit = true;
    116		}
    117
    118		break;
    119	}
    120
    121	if (tx_rate > RATE_11M) {
    122		if (pkt_type == PK_TYPE_11A)
    123			mask = BIT(4);
    124	} else if (tx_rate > RATE_1M) {
    125		if (preamble_type == PREAMBLE_SHORT)
    126			mask = BIT(3);
    127	}
    128
    129	i = tx_rate > RATE_54M ? RATE_54M : tx_rate;
    130	phy->signal = vnt_phy_signal[i] | mask;
    131	phy->service = 0x00;
    132
    133	if (pkt_type == PK_TYPE_11B) {
    134		if (ext_bit)
    135			phy->service |= 0x80;
    136		phy->len = cpu_to_le16((u16)count);
    137	} else {
    138		phy->len = cpu_to_le16((u16)frame_length);
    139	}
    140}
    141
    142static __le16 vnt_time_stamp_off(struct vnt_private *priv, u16 rate)
    143{
    144	return cpu_to_le16(vnt_time_stampoff[priv->preamble_type % 2]
    145							[rate % MAX_RATE]);
    146}
    147
    148static __le16 vnt_rxtx_rsvtime_le16(struct vnt_usb_send_context *context)
    149{
    150	struct vnt_private *priv = context->priv;
    151	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(context->skb);
    152	struct ieee80211_rate *rate = ieee80211_get_tx_rate(priv->hw, info);
    153
    154	return ieee80211_generic_frame_duration(priv->hw,
    155						 info->control.vif, info->band,
    156						 context->frame_len,
    157						 rate);
    158}
    159
    160static __le16 vnt_get_rts_duration(struct vnt_usb_send_context *context)
    161{
    162	struct vnt_private *priv = context->priv;
    163	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(context->skb);
    164
    165	return ieee80211_rts_duration(priv->hw, priv->vif,
    166				      context->frame_len, info);
    167}
    168
    169static __le16 vnt_get_cts_duration(struct vnt_usb_send_context *context)
    170{
    171	struct vnt_private *priv = context->priv;
    172	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(context->skb);
    173
    174	return ieee80211_ctstoself_duration(priv->hw, priv->vif,
    175					    context->frame_len, info);
    176}
    177
    178static void vnt_rxtx_datahead_g(struct vnt_usb_send_context *tx_context,
    179				struct vnt_tx_datahead_g *buf)
    180{
    181	struct vnt_private *priv = tx_context->priv;
    182	struct ieee80211_hdr *hdr =
    183				(struct ieee80211_hdr *)tx_context->skb->data;
    184	u32 frame_len = tx_context->frame_len;
    185	u16 rate = tx_context->tx_rate;
    186
    187	/* Get SignalField,ServiceField,Length */
    188	vnt_get_phy_field(priv, frame_len, rate, tx_context->pkt_type, &buf->a);
    189	vnt_get_phy_field(priv, frame_len, priv->top_cck_basic_rate,
    190			  PK_TYPE_11B, &buf->b);
    191
    192	/* Get Duration and TimeStamp */
    193	buf->duration_a = hdr->duration_id;
    194	buf->duration_b = hdr->duration_id;
    195	buf->time_stamp_off_a = vnt_time_stamp_off(priv, rate);
    196	buf->time_stamp_off_b = vnt_time_stamp_off(priv,
    197						   priv->top_cck_basic_rate);
    198}
    199
    200static void vnt_rxtx_datahead_ab(struct vnt_usb_send_context *tx_context,
    201				 struct vnt_tx_datahead_ab *buf)
    202{
    203	struct vnt_private *priv = tx_context->priv;
    204	struct ieee80211_hdr *hdr =
    205				(struct ieee80211_hdr *)tx_context->skb->data;
    206	u32 frame_len = tx_context->frame_len;
    207	u16 rate = tx_context->tx_rate;
    208
    209	/* Get SignalField,ServiceField,Length */
    210	vnt_get_phy_field(priv, frame_len, rate,
    211			  tx_context->pkt_type, &buf->ab);
    212
    213	/* Get Duration and TimeStampOff */
    214	buf->duration = hdr->duration_id;
    215	buf->time_stamp_off = vnt_time_stamp_off(priv, rate);
    216}
    217
    218static void vnt_fill_ieee80211_rts(struct vnt_usb_send_context *tx_context,
    219				   struct ieee80211_rts *rts, __le16 duration)
    220{
    221	struct ieee80211_hdr *hdr =
    222				(struct ieee80211_hdr *)tx_context->skb->data;
    223
    224	rts->duration = duration;
    225	rts->frame_control =
    226		cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);
    227
    228	ether_addr_copy(rts->ra, hdr->addr1);
    229	ether_addr_copy(rts->ta, hdr->addr2);
    230}
    231
    232static void vnt_rxtx_rts_g_head(struct vnt_usb_send_context *tx_context,
    233				struct vnt_rts_g *buf)
    234{
    235	struct vnt_private *priv = tx_context->priv;
    236	u16 rts_frame_len = 20;
    237
    238	vnt_get_phy_field(priv, rts_frame_len, priv->top_cck_basic_rate,
    239			  PK_TYPE_11B, &buf->b);
    240	vnt_get_phy_field(priv, rts_frame_len, priv->top_ofdm_basic_rate,
    241			  tx_context->pkt_type, &buf->a);
    242
    243	buf->duration_bb = vnt_get_rts_duration(tx_context);
    244	buf->duration_aa = buf->duration_bb;
    245	buf->duration_ba = buf->duration_bb;
    246
    247	vnt_fill_ieee80211_rts(tx_context, &buf->data, buf->duration_aa);
    248
    249	vnt_rxtx_datahead_g(tx_context, &buf->data_head);
    250}
    251
    252static void vnt_rxtx_rts_ab_head(struct vnt_usb_send_context *tx_context,
    253				 struct vnt_rts_ab *buf)
    254{
    255	struct vnt_private *priv = tx_context->priv;
    256	u16 rts_frame_len = 20;
    257
    258	vnt_get_phy_field(priv, rts_frame_len, priv->top_ofdm_basic_rate,
    259			  tx_context->pkt_type, &buf->ab);
    260
    261	buf->duration = vnt_get_rts_duration(tx_context);
    262
    263	vnt_fill_ieee80211_rts(tx_context, &buf->data, buf->duration);
    264
    265	vnt_rxtx_datahead_ab(tx_context, &buf->data_head);
    266}
    267
    268static void vnt_fill_cts_head(struct vnt_usb_send_context *tx_context,
    269			      union vnt_tx_data_head *head)
    270{
    271	struct vnt_private *priv = tx_context->priv;
    272	struct vnt_cts *buf = &head->cts_g;
    273	u32 cts_frame_len = 14;
    274
    275	/* Get SignalField,ServiceField,Length */
    276	vnt_get_phy_field(priv, cts_frame_len, priv->top_cck_basic_rate,
    277			  PK_TYPE_11B, &buf->b);
    278	/* Get CTSDuration_ba */
    279	buf->duration_ba = vnt_get_cts_duration(tx_context);
    280	/*Get CTS Frame body*/
    281	buf->data.duration = buf->duration_ba;
    282	buf->data.frame_control =
    283		cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS);
    284
    285	ether_addr_copy(buf->data.ra, priv->current_net_addr);
    286
    287	vnt_rxtx_datahead_g(tx_context, &buf->data_head);
    288}
    289
    290/* returns true if mic_hdr is needed */
    291static bool vnt_fill_txkey(struct vnt_tx_buffer *tx_buffer, struct sk_buff *skb)
    292{
    293	struct vnt_tx_fifo_head *fifo = &tx_buffer->fifo_head;
    294	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
    295	struct ieee80211_key_conf *tx_key = info->control.hw_key;
    296	struct vnt_mic_hdr *mic_hdr;
    297	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
    298	u64 pn64;
    299	u16 payload_len = skb->len;
    300	u8 *iv = ((u8 *)hdr + ieee80211_get_hdrlen_from_skb(skb));
    301
    302	/* strip header and icv len from payload */
    303	payload_len -= ieee80211_get_hdrlen_from_skb(skb);
    304	payload_len -= tx_key->icv_len;
    305
    306	switch (tx_key->cipher) {
    307	case WLAN_CIPHER_SUITE_WEP40:
    308	case WLAN_CIPHER_SUITE_WEP104:
    309		memcpy(fifo->tx_key, iv, 3);
    310		memcpy(fifo->tx_key + 3, tx_key->key, tx_key->keylen);
    311
    312		if (tx_key->keylen == WLAN_KEY_LEN_WEP40) {
    313			memcpy(fifo->tx_key + 8, iv, 3);
    314			memcpy(fifo->tx_key + 11,
    315			       tx_key->key, WLAN_KEY_LEN_WEP40);
    316		}
    317
    318		fifo->frag_ctl |= cpu_to_le16(FRAGCTL_LEGACY);
    319		break;
    320	case WLAN_CIPHER_SUITE_TKIP:
    321		ieee80211_get_tkip_p2k(tx_key, skb, fifo->tx_key);
    322
    323		fifo->frag_ctl |= cpu_to_le16(FRAGCTL_TKIP);
    324		break;
    325	case WLAN_CIPHER_SUITE_CCMP:
    326		if (info->control.use_cts_prot) {
    327			if (info->control.use_rts)
    328				mic_hdr = &tx_buffer->tx_head.tx_rts.tx.mic.hdr;
    329			else
    330				mic_hdr = &tx_buffer->tx_head.tx_cts.tx.mic.hdr;
    331		} else {
    332			mic_hdr = &tx_buffer->tx_head.tx_ab.tx.mic.hdr;
    333		}
    334
    335		mic_hdr->id = 0x59;
    336		mic_hdr->payload_len = cpu_to_be16(payload_len);
    337		ether_addr_copy(mic_hdr->mic_addr2, hdr->addr2);
    338
    339		pn64 = atomic64_read(&tx_key->tx_pn);
    340		mic_hdr->ccmp_pn[5] = pn64;
    341		mic_hdr->ccmp_pn[4] = pn64 >> 8;
    342		mic_hdr->ccmp_pn[3] = pn64 >> 16;
    343		mic_hdr->ccmp_pn[2] = pn64 >> 24;
    344		mic_hdr->ccmp_pn[1] = pn64 >> 32;
    345		mic_hdr->ccmp_pn[0] = pn64 >> 40;
    346
    347		if (ieee80211_has_a4(hdr->frame_control))
    348			mic_hdr->hlen = cpu_to_be16(28);
    349		else
    350			mic_hdr->hlen = cpu_to_be16(22);
    351
    352		ether_addr_copy(mic_hdr->addr1, hdr->addr1);
    353		ether_addr_copy(mic_hdr->addr2, hdr->addr2);
    354		ether_addr_copy(mic_hdr->addr3, hdr->addr3);
    355
    356		mic_hdr->frame_control = cpu_to_le16(le16_to_cpu(hdr->frame_control) & 0xc78f);
    357		mic_hdr->seq_ctrl = cpu_to_le16(le16_to_cpu(hdr->seq_ctrl) & 0xf);
    358
    359		if (ieee80211_has_a4(hdr->frame_control))
    360			ether_addr_copy(mic_hdr->addr4, hdr->addr4);
    361
    362		memcpy(fifo->tx_key, tx_key->key, WLAN_KEY_LEN_CCMP);
    363
    364		fifo->frag_ctl |= cpu_to_le16(FRAGCTL_AES);
    365		return true;
    366	default:
    367		break;
    368	}
    369
    370	return false;
    371}
    372
    373static void vnt_rxtx_rts(struct vnt_usb_send_context *tx_context)
    374{
    375	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_context->skb);
    376	struct vnt_tx_buffer *tx_buffer = tx_context->tx_buffer;
    377	union vnt_tx_head *tx_head = &tx_buffer->tx_head;
    378	struct vnt_rrv_time_rts *buf = &tx_head->tx_rts.rts;
    379	union vnt_tx_data_head *head = &tx_head->tx_rts.tx.head;
    380
    381	buf->rts_rrv_time_aa = vnt_get_rts_duration(tx_context);
    382	buf->rts_rrv_time_ba = buf->rts_rrv_time_aa;
    383	buf->rts_rrv_time_bb = buf->rts_rrv_time_aa;
    384
    385	buf->rrv_time_a = vnt_rxtx_rsvtime_le16(tx_context);
    386	buf->rrv_time_b = buf->rrv_time_a;
    387
    388	if (info->control.hw_key) {
    389		if (vnt_fill_txkey(tx_buffer, tx_context->skb))
    390			head = &tx_head->tx_rts.tx.mic.head;
    391	}
    392
    393	vnt_rxtx_rts_g_head(tx_context, &head->rts_g);
    394}
    395
    396static void vnt_rxtx_cts(struct vnt_usb_send_context *tx_context)
    397{
    398	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_context->skb);
    399	struct vnt_tx_buffer *tx_buffer = tx_context->tx_buffer;
    400	union vnt_tx_head *tx_head = &tx_buffer->tx_head;
    401	struct vnt_rrv_time_cts *buf = &tx_head->tx_cts.cts;
    402	union vnt_tx_data_head *head = &tx_head->tx_cts.tx.head;
    403
    404	buf->rrv_time_a = vnt_rxtx_rsvtime_le16(tx_context);
    405	buf->rrv_time_b = buf->rrv_time_a;
    406
    407	buf->cts_rrv_time_ba = vnt_get_cts_duration(tx_context);
    408
    409	if (info->control.hw_key) {
    410		if (vnt_fill_txkey(tx_buffer, tx_context->skb))
    411			head = &tx_head->tx_cts.tx.mic.head;
    412	}
    413
    414	vnt_fill_cts_head(tx_context, head);
    415}
    416
    417static void vnt_rxtx_ab(struct vnt_usb_send_context *tx_context)
    418{
    419	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_context->skb);
    420	struct vnt_tx_buffer *tx_buffer = tx_context->tx_buffer;
    421	union vnt_tx_head *tx_head = &tx_buffer->tx_head;
    422	struct vnt_rrv_time_ab *buf = &tx_head->tx_ab.ab;
    423	union vnt_tx_data_head *head = &tx_head->tx_ab.tx.head;
    424
    425	buf->rrv_time = vnt_rxtx_rsvtime_le16(tx_context);
    426
    427	if (info->control.hw_key) {
    428		if (vnt_fill_txkey(tx_buffer, tx_context->skb))
    429			head = &tx_head->tx_ab.tx.mic.head;
    430	}
    431
    432	if (info->control.use_rts) {
    433		buf->rts_rrv_time = vnt_get_rts_duration(tx_context);
    434
    435		vnt_rxtx_rts_ab_head(tx_context, &head->rts_ab);
    436
    437		return;
    438	}
    439
    440	vnt_rxtx_datahead_ab(tx_context, &head->data_head_ab);
    441}
    442
    443static void vnt_generate_tx_parameter(struct vnt_usb_send_context *tx_context)
    444{
    445	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_context->skb);
    446
    447	if (info->control.use_cts_prot) {
    448		if (info->control.use_rts) {
    449			vnt_rxtx_rts(tx_context);
    450
    451			return;
    452		}
    453
    454		vnt_rxtx_cts(tx_context);
    455
    456		return;
    457	}
    458
    459	vnt_rxtx_ab(tx_context);
    460}
    461
    462static u16 vnt_get_hdr_size(struct ieee80211_tx_info *info)
    463{
    464	u16 size = sizeof(struct vnt_tx_datahead_ab);
    465
    466	if (info->control.use_cts_prot) {
    467		if (info->control.use_rts)
    468			size = sizeof(struct vnt_rts_g);
    469		else
    470			size = sizeof(struct vnt_cts);
    471	} else if (info->control.use_rts) {
    472		size = sizeof(struct vnt_rts_ab);
    473	}
    474
    475	if (info->control.hw_key) {
    476		if (info->control.hw_key->cipher == WLAN_CIPHER_SUITE_CCMP)
    477			size += sizeof(struct vnt_mic_hdr);
    478	}
    479
    480	/* Get rrv_time header */
    481	if (info->control.use_cts_prot) {
    482		if (info->control.use_rts)
    483			size += sizeof(struct vnt_rrv_time_rts);
    484		else
    485			size += sizeof(struct vnt_rrv_time_cts);
    486	} else {
    487		size += sizeof(struct vnt_rrv_time_ab);
    488	}
    489
    490	size += sizeof(struct vnt_tx_fifo_head);
    491
    492	return size;
    493}
    494
    495int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb)
    496{
    497	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
    498	struct ieee80211_tx_rate *tx_rate = &info->control.rates[0];
    499	struct ieee80211_rate *rate;
    500	struct ieee80211_hdr *hdr;
    501	struct vnt_tx_buffer *tx_buffer;
    502	struct vnt_tx_fifo_head *tx_buffer_head;
    503	struct vnt_usb_send_context *tx_context;
    504	unsigned long flags;
    505	u8 pkt_type;
    506
    507	hdr = (struct ieee80211_hdr *)(skb->data);
    508
    509	rate = ieee80211_get_tx_rate(priv->hw, info);
    510
    511	if (rate->hw_value > RATE_11M) {
    512		if (info->band == NL80211_BAND_5GHZ) {
    513			pkt_type = PK_TYPE_11A;
    514		} else {
    515			if (tx_rate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
    516				if (priv->basic_rates & VNT_B_RATES)
    517					pkt_type = PK_TYPE_11GB;
    518				else
    519					pkt_type = PK_TYPE_11GA;
    520			} else {
    521				pkt_type = PK_TYPE_11A;
    522			}
    523		}
    524	} else {
    525		pkt_type = PK_TYPE_11B;
    526	}
    527
    528	spin_lock_irqsave(&priv->lock, flags);
    529
    530	tx_context = vnt_get_free_context(priv);
    531	if (!tx_context) {
    532		dev_dbg(&priv->usb->dev, "%s No free context\n", __func__);
    533		spin_unlock_irqrestore(&priv->lock, flags);
    534		return -ENOMEM;
    535	}
    536
    537	tx_context->pkt_type = pkt_type;
    538	tx_context->frame_len = skb->len + 4;
    539	tx_context->tx_rate =  rate->hw_value;
    540
    541	spin_unlock_irqrestore(&priv->lock, flags);
    542
    543	tx_context->skb = skb_clone(skb, GFP_ATOMIC);
    544	if (!tx_context->skb) {
    545		tx_context->in_use = false;
    546		return -ENOMEM;
    547	}
    548
    549	tx_buffer = skb_push(skb, vnt_get_hdr_size(info));
    550	tx_context->tx_buffer = tx_buffer;
    551	tx_buffer_head = &tx_buffer->fifo_head;
    552
    553	tx_context->type = CONTEXT_DATA_PACKET;
    554
    555	/*Set fifo controls */
    556	if (pkt_type == PK_TYPE_11A)
    557		tx_buffer_head->fifo_ctl = 0;
    558	else if (pkt_type == PK_TYPE_11B)
    559		tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11B);
    560	else if (pkt_type == PK_TYPE_11GB)
    561		tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GB);
    562	else if (pkt_type == PK_TYPE_11GA)
    563		tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GA);
    564
    565	if (!ieee80211_is_data(hdr->frame_control)) {
    566		tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT |
    567							FIFOCTL_ISDMA0);
    568		tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_TMOEN);
    569
    570		tx_buffer_head->time_stamp =
    571			cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
    572	} else {
    573		tx_buffer_head->time_stamp =
    574			cpu_to_le16(DEFAULT_MSDU_LIFETIME_RES_64us);
    575	}
    576
    577	if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
    578		tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_NEEDACK);
    579
    580	if (ieee80211_has_retry(hdr->frame_control))
    581		tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LRETRY);
    582
    583	if (info->control.use_rts)
    584		tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_RTS);
    585
    586	if (ieee80211_has_a4(hdr->frame_control))
    587		tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LHEAD);
    588
    589	tx_buffer_head->frag_ctl =
    590			cpu_to_le16(ieee80211_hdrlen(hdr->frame_control) << 10);
    591
    592	if (info->control.hw_key)
    593		tx_context->frame_len += info->control.hw_key->icv_len;
    594
    595	tx_buffer_head->current_rate = cpu_to_le16(rate->hw_value);
    596
    597	vnt_generate_tx_parameter(tx_context);
    598
    599	tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_NONFRAG);
    600
    601	priv->seq_counter = (le16_to_cpu(hdr->seq_ctrl) &
    602						IEEE80211_SCTL_SEQ) >> 4;
    603
    604	spin_lock_irqsave(&priv->lock, flags);
    605
    606	if (vnt_tx_context(priv, tx_context, skb)) {
    607		dev_kfree_skb(tx_context->skb);
    608		spin_unlock_irqrestore(&priv->lock, flags);
    609		return -EIO;
    610	}
    611
    612	dev_kfree_skb(skb);
    613
    614	spin_unlock_irqrestore(&priv->lock, flags);
    615
    616	return 0;
    617}
    618
    619static int vnt_beacon_xmit(struct vnt_private *priv, struct sk_buff *skb)
    620{
    621	struct vnt_tx_short_buf_head *short_head;
    622	struct ieee80211_tx_info *info;
    623	struct vnt_usb_send_context *context;
    624	struct ieee80211_mgmt *mgmt_hdr;
    625	unsigned long flags;
    626	u32 frame_size = skb->len + 4;
    627	u16 current_rate;
    628
    629	spin_lock_irqsave(&priv->lock, flags);
    630
    631	context = vnt_get_free_context(priv);
    632	if (!context) {
    633		dev_dbg(&priv->usb->dev, "%s No free context!\n", __func__);
    634		spin_unlock_irqrestore(&priv->lock, flags);
    635		return -ENOMEM;
    636	}
    637
    638	context->skb = skb;
    639
    640	spin_unlock_irqrestore(&priv->lock, flags);
    641
    642	mgmt_hdr = (struct ieee80211_mgmt *)skb->data;
    643	short_head = skb_push(skb, sizeof(*short_head));
    644
    645	if (priv->bb_type == BB_TYPE_11A) {
    646		current_rate = RATE_6M;
    647
    648		/* Get SignalField,ServiceField,Length */
    649		vnt_get_phy_field(priv, frame_size, current_rate,
    650				  PK_TYPE_11A, &short_head->ab);
    651
    652		/* Get TimeStampOff */
    653		short_head->time_stamp_off =
    654				vnt_time_stamp_off(priv, current_rate);
    655	} else {
    656		current_rate = RATE_1M;
    657		short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_11B);
    658
    659		/* Get SignalField,ServiceField,Length */
    660		vnt_get_phy_field(priv, frame_size, current_rate,
    661				  PK_TYPE_11B, &short_head->ab);
    662
    663		/* Get TimeStampOff */
    664		short_head->time_stamp_off =
    665			vnt_time_stamp_off(priv, current_rate);
    666	}
    667
    668	/* Get Duration */
    669	short_head->duration = mgmt_hdr->duration;
    670
    671	/* time stamp always 0 */
    672	mgmt_hdr->u.beacon.timestamp = 0;
    673
    674	info = IEEE80211_SKB_CB(skb);
    675	if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
    676		struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)mgmt_hdr;
    677
    678		hdr->duration_id = 0;
    679		hdr->seq_ctrl = cpu_to_le16(priv->seq_counter << 4);
    680	}
    681
    682	priv->seq_counter++;
    683	if (priv->seq_counter > 0x0fff)
    684		priv->seq_counter = 0;
    685
    686	context->type = CONTEXT_BEACON_PACKET;
    687
    688	spin_lock_irqsave(&priv->lock, flags);
    689
    690	if (vnt_tx_context(priv, context, skb))
    691		ieee80211_free_txskb(priv->hw, context->skb);
    692
    693	spin_unlock_irqrestore(&priv->lock, flags);
    694
    695	return 0;
    696}
    697
    698int vnt_beacon_make(struct vnt_private *priv, struct ieee80211_vif *vif)
    699{
    700	struct sk_buff *beacon;
    701
    702	beacon = ieee80211_beacon_get(priv->hw, vif);
    703	if (!beacon)
    704		return -ENOMEM;
    705
    706	if (vnt_beacon_xmit(priv, beacon)) {
    707		ieee80211_free_txskb(priv->hw, beacon);
    708		return -ENODEV;
    709	}
    710
    711	return 0;
    712}
    713
    714int vnt_beacon_enable(struct vnt_private *priv, struct ieee80211_vif *vif,
    715		      struct ieee80211_bss_conf *conf)
    716{
    717	vnt_mac_reg_bits_off(priv, MAC_REG_TCR, TCR_AUTOBCNTX);
    718
    719	vnt_mac_reg_bits_off(priv, MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
    720
    721	vnt_mac_set_beacon_interval(priv, conf->beacon_int);
    722
    723	vnt_clear_current_tsf(priv);
    724
    725	vnt_mac_reg_bits_on(priv, MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
    726
    727	vnt_reset_next_tbtt(priv, conf->beacon_int);
    728
    729	return vnt_beacon_make(priv, vif);
    730}