// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
* All rights reserved.
*
* File: rxtx.c
*
* Purpose: handle WMAC/802.3/802.11 rx & tx functions
*
* Author: Lyndon Chen
*
* Date: May 20, 2003
*
* Functions:
* vnt_generate_tx_parameter - Generate tx dma required parameter.
* vnt_get_duration_le - get tx data required duration
* vnt_get_rtscts_duration_le- get rtx/cts required duration
* vnt_get_rtscts_rsvtime_le- get rts/cts reserved time
* vnt_get_rsvtime- get frame reserved time
* vnt_fill_cts_head- fulfill CTS ctl header
*
* Revision History:
*
*/
#include <linux/etherdevice.h>
#include "device.h"
#include "rxtx.h"
#include "card.h"
#include "mac.h"
#include "rf.h"
#include "usbpipe.h"
static const u16 vnt_time_stampoff[2][MAX_RATE] = {
/* Long Preamble */
{384, 288, 226, 209, 54, 43, 37, 31, 28, 25, 24, 23},
/* Short Preamble */
{384, 192, 130, 113, 54, 43, 37, 31, 28, 25, 24, 23},
};
static const u16 vnt_fb_opt0[2][5] = {
{RATE_12M, RATE_18M, RATE_24M, RATE_36M, RATE_48M}, /* fallback_rate0 */
{RATE_12M, RATE_12M, RATE_18M, RATE_24M, RATE_36M}, /* fallback_rate1 */
};
static const u16 vnt_fb_opt1[2][5] = {
{RATE_12M, RATE_18M, RATE_24M, RATE_24M, RATE_36M}, /* fallback_rate0 */
{RATE_6M, RATE_6M, RATE_12M, RATE_12M, RATE_18M}, /* fallback_rate1 */
};
#define RTSDUR_BB 0
#define RTSDUR_BA 1
#define RTSDUR_AA 2
#define CTSDUR_BA 3
#define RTSDUR_BA_F0 4
#define RTSDUR_AA_F0 5
#define RTSDUR_BA_F1 6
#define RTSDUR_AA_F1 7
#define CTSDUR_BA_F0 8
#define CTSDUR_BA_F1 9
#define DATADUR_B 10
#define DATADUR_A 11
#define DATADUR_A_F0 12
#define DATADUR_A_F1 13
static struct vnt_usb_send_context
*vnt_get_free_context(struct vnt_private *priv)
{
struct vnt_usb_send_context *context = NULL;
int ii;
dev_dbg(&priv->usb->dev, "%s\n", __func__);
for (ii = 0; ii < priv->num_tx_context; ii++) {
if (!priv->tx_context[ii])
return NULL;
context = priv->tx_context[ii];
if (!context->in_use) {
context->in_use = true;
memset(context->data, 0,
MAX_TOTAL_SIZE_WITH_ALL_HEADERS);
context->hdr = NULL;
return context;
}
}
if (ii == priv->num_tx_context) {
dev_dbg(&priv->usb->dev, "%s No Free Tx Context\n", __func__);
ieee80211_stop_queues(priv->hw);
}
return NULL;
}
static __le16 vnt_time_stamp_off(struct vnt_private *priv, u16 rate)
{
return cpu_to_le16(vnt_time_stampoff[priv->preamble_type % 2]
[rate % MAX_RATE]);
}
static u32 vnt_get_rsvtime(struct vnt_private *priv, u8 pkt_type,
u32 frame_length, u16 rate, int need_ack)
{
u32 data_time, ack_time;
data_time = vnt_get_frame_time(priv->preamble_type, pkt_type,
frame_length, rate);
if (pkt_type == PK_TYPE_11B)
ack_time = vnt_get_frame_time(priv->preamble_type, pkt_type,
14, (u16)priv->top_cck_basic_rate);
else
ack_time = vnt_get_frame_time(priv->preamble_type, pkt_type,
14, (u16)priv->top_ofdm_basic_rate);
if (need_ack)
return data_time + priv->sifs + ack_time;
return data_time;
}
static __le16 vnt_rxtx_rsvtime_le16