summaryrefslogtreecommitdiffstats
path: root/drivers/staging/vt6655
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-11 08:27:49 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-11 08:27:49 +0000
commitace9429bb58fd418f0c81d4c2835699bddf6bde6 (patch)
treeb2d64bc10158fdd5497876388cd68142ca374ed3 /drivers/staging/vt6655
parentInitial commit. (diff)
downloadlinux-ace9429bb58fd418f0c81d4c2835699bddf6bde6.tar.xz
linux-ace9429bb58fd418f0c81d4c2835699bddf6bde6.zip
Adding upstream version 6.6.15.upstream/6.6.15
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'drivers/staging/vt6655')
-rw-r--r--drivers/staging/vt6655/Kconfig6
-rw-r--r--drivers/staging/vt6655/Makefile15
-rw-r--r--drivers/staging/vt6655/TODO21
-rw-r--r--drivers/staging/vt6655/baseband.c2257
-rw-r--r--drivers/staging/vt6655/baseband.h72
-rw-r--r--drivers/staging/vt6655/card.c836
-rw-r--r--drivers/staging/vt6655/card.h62
-rw-r--r--drivers/staging/vt6655/channel.c135
-rw-r--r--drivers/staging/vt6655/channel.h17
-rw-r--r--drivers/staging/vt6655/desc.h249
-rw-r--r--drivers/staging/vt6655/device.h292
-rw-r--r--drivers/staging/vt6655/device_cfg.h44
-rw-r--r--drivers/staging/vt6655/device_main.c1864
-rw-r--r--drivers/staging/vt6655/dpc.c145
-rw-r--r--drivers/staging/vt6655/dpc.h21
-rw-r--r--drivers/staging/vt6655/key.c143
-rw-r--r--drivers/staging/vt6655/key.h51
-rw-r--r--drivers/staging/vt6655/mac.c851
-rw-r--r--drivers/staging/vt6655/mac.h580
-rw-r--r--drivers/staging/vt6655/power.c144
-rw-r--r--drivers/staging/vt6655/power.h29
-rw-r--r--drivers/staging/vt6655/rf.c535
-rw-r--r--drivers/staging/vt6655/rf.h75
-rw-r--r--drivers/staging/vt6655/rxtx.c1462
-rw-r--r--drivers/staging/vt6655/rxtx.h185
-rw-r--r--drivers/staging/vt6655/srom.c140
-rw-r--r--drivers/staging/vt6655/srom.h85
-rw-r--r--drivers/staging/vt6655/test9
28 files changed, 10325 insertions, 0 deletions
diff --git a/drivers/staging/vt6655/Kconfig b/drivers/staging/vt6655/Kconfig
new file mode 100644
index 0000000000..077f62ebe8
--- /dev/null
+++ b/drivers/staging/vt6655/Kconfig
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+config VT6655
+ tristate "VIA Technologies VT6655 support"
+ depends on PCI && HAS_IOPORT && MAC80211 && m
+ help
+ This is a vendor-written driver for VIA VT6655.
diff --git a/drivers/staging/vt6655/Makefile b/drivers/staging/vt6655/Makefile
new file mode 100644
index 0000000000..e70357ec0a
--- /dev/null
+++ b/drivers/staging/vt6655/Makefile
@@ -0,0 +1,15 @@
+# SPDX-License-Identifier: GPL-2.0
+
+vt6655_stage-y += device_main.o \
+ card.o \
+ channel.o \
+ mac.o \
+ baseband.o \
+ rxtx.o \
+ dpc.o \
+ power.o \
+ srom.o \
+ key.o \
+ rf.o
+
+obj-$(CONFIG_VT6655) += vt6655_stage.o
diff --git a/drivers/staging/vt6655/TODO b/drivers/staging/vt6655/TODO
new file mode 100644
index 0000000000..63607ef9c9
--- /dev/null
+++ b/drivers/staging/vt6655/TODO
@@ -0,0 +1,21 @@
+TODO:
+- remove __cplusplus ifdefs -- done
+- prepare for merge with vt6656 driver:
+ - rename DEVICE_PRT() to DBG_PRT() -- done
+ - share 80211*.h includes
+ - split rf.c
+ - remove dead code
+ - abstract VT3253 chipset specific code
+- add common vt665x infrastructure
+- kill ttype.h
+- switch to use LIB80211
+- switch to use MAC80211
+- verify unsigned long usage for x86-64 arch
+- reduce .data footprint
+- use kernel coding style
+- checkpatch.pl fixes
+- sparse fixes
+- integrate with drivers/net/wireless
+
+Please send any patches to Greg Kroah-Hartman <greg@kroah.com>
+and Forest Bond <forest@alittletooquiet.net>.
diff --git a/drivers/staging/vt6655/baseband.c b/drivers/staging/vt6655/baseband.c
new file mode 100644
index 0000000000..696d4dd03a
--- /dev/null
+++ b/drivers/staging/vt6655/baseband.c
@@ -0,0 +1,2257 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * Purpose: Implement functions to access baseband
+ *
+ * Author: Kyle Hsu
+ *
+ * Date: Aug.22, 2002
+ *
+ * Functions:
+ * bb_get_frame_time - Calculate data frame transmitting time
+ * bb_read_embedded - Embedded read baseband register via MAC
+ * bb_write_embedded - Embedded write baseband register via MAC
+ * bb_vt3253_init - VIA VT3253 baseband chip init code
+ *
+ * Revision History:
+ * 06-10-2003 Bryan YC Fan: Re-write codes to support VT3253 spec.
+ * 08-07-2003 Bryan YC Fan: Add MAXIM2827/2825 and RFMD2959 support.
+ * 08-26-2003 Kyle Hsu : Modify BBuGetFrameTime() and
+ * BBvCalculateParameter().
+ * cancel the setting of MAC_REG_SOFTPWRCTL on
+ * BBbVT3253Init().
+ * Add the comments.
+ * 09-01-2003 Bryan YC Fan: RF & BB tables updated.
+ * Modified BBvLoopbackOn & BBvLoopbackOff().
+ *
+ *
+ */
+
+#include "mac.h"
+#include "baseband.h"
+#include "srom.h"
+#include "rf.h"
+
+/*--------------------- Static Classes ----------------------------*/
+
+/*--------------------- Static Variables --------------------------*/
+
+/*--------------------- Static Functions --------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+
+/*--------------------- Static Definitions -------------------------*/
+
+/*--------------------- Static Classes ----------------------------*/
+
+/*--------------------- Static Variables --------------------------*/
+
+#define CB_VT3253_INIT_FOR_RFMD 446
+static const unsigned char by_vt3253_init_tab_rfmd[CB_VT3253_INIT_FOR_RFMD][2] = {
+ {0x00, 0x30},
+ {0x01, 0x00},
+ {0x02, 0x00},
+ {0x03, 0x00},
+ {0x04, 0x00},
+ {0x05, 0x00},
+ {0x06, 0x00},
+ {0x07, 0x00},
+ {0x08, 0x70},
+ {0x09, 0x45},
+ {0x0a, 0x2a},
+ {0x0b, 0x76},
+ {0x0c, 0x00},
+ {0x0d, 0x01},
+ {0x0e, 0x80},
+ {0x0f, 0x00},
+ {0x10, 0x00},
+ {0x11, 0x00},
+ {0x12, 0x00},
+ {0x13, 0x00},
+ {0x14, 0x00},
+ {0x15, 0x00},
+ {0x16, 0x00},
+ {0x17, 0x00},
+ {0x18, 0x00},
+ {0x19, 0x00},
+ {0x1a, 0x00},
+ {0x1b, 0x9d},
+ {0x1c, 0x05},
+ {0x1d, 0x00},
+ {0x1e, 0x00},
+ {0x1f, 0x00},
+ {0x20, 0x00},
+ {0x21, 0x00},
+ {0x22, 0x00},
+ {0x23, 0x00},
+ {0x24, 0x00},
+ {0x25, 0x4a},
+ {0x26, 0x00},
+ {0x27, 0x00},
+ {0x28, 0x00},
+ {0x29, 0x00},
+ {0x2a, 0x00},
+ {0x2b, 0x00},
+ {0x2c, 0x00},
+ {0x2d, 0xa8},
+ {0x2e, 0x1a},
+ {0x2f, 0x0c},
+ {0x30, 0x26},
+ {0x31, 0x5b},
+ {0x32, 0x00},
+ {0x33, 0x00},
+ {0x34, 0x00},
+ {0x35, 0x00},
+ {0x36, 0xaa},
+ {0x37, 0xaa},
+ {0x38, 0xff},
+ {0x39, 0xff},
+ {0x3a, 0x00},
+ {0x3b, 0x00},
+ {0x3c, 0x00},
+ {0x3d, 0x0d},
+ {0x3e, 0x51},
+ {0x3f, 0x04},
+ {0x40, 0x00},
+ {0x41, 0x08},
+ {0x42, 0x00},
+ {0x43, 0x08},
+ {0x44, 0x06},
+ {0x45, 0x14},
+ {0x46, 0x05},
+ {0x47, 0x08},
+ {0x48, 0x00},
+ {0x49, 0x00},
+ {0x4a, 0x00},
+ {0x4b, 0x00},
+ {0x4c, 0x09},
+ {0x4d, 0x80},
+ {0x4e, 0x00},
+ {0x4f, 0xc5},
+ {0x50, 0x14},
+ {0x51, 0x19},
+ {0x52, 0x00},
+ {0x53, 0x00},
+ {0x54, 0x00},
+ {0x55, 0x00},
+ {0x56, 0x00},
+ {0x57, 0x00},
+ {0x58, 0x00},
+ {0x59, 0xb0},
+ {0x5a, 0x00},
+ {0x5b, 0x00},
+ {0x5c, 0x00},
+ {0x5d, 0x00},
+ {0x5e, 0x00},
+ {0x5f, 0x00},
+ {0x60, 0x44},
+ {0x61, 0x04},
+ {0x62, 0x00},
+ {0x63, 0x00},
+ {0x64, 0x00},
+ {0x65, 0x00},
+ {0x66, 0x04},
+ {0x67, 0xb7},
+ {0x68, 0x00},
+ {0x69, 0x00},
+ {0x6a, 0x00},
+ {0x6b, 0x00},
+ {0x6c, 0x00},
+ {0x6d, 0x03},
+ {0x6e, 0x01},
+ {0x6f, 0x00},
+ {0x70, 0x00},
+ {0x71, 0x00},
+ {0x72, 0x00},
+ {0x73, 0x00},
+ {0x74, 0x00},
+ {0x75, 0x00},
+ {0x76, 0x00},
+ {0x77, 0x00},
+ {0x78, 0x00},
+ {0x79, 0x00},
+ {0x7a, 0x00},
+ {0x7b, 0x00},
+ {0x7c, 0x00},
+ {0x7d, 0x00},
+ {0x7e, 0x00},
+ {0x7f, 0x00},
+ {0x80, 0x0b},
+ {0x81, 0x00},
+ {0x82, 0x3c},
+ {0x83, 0x00},
+ {0x84, 0x00},
+ {0x85, 0x00},
+ {0x86, 0x00},
+ {0x87, 0x00},
+ {0x88, 0x08},
+ {0x89, 0x00},
+ {0x8a, 0x08},
+ {0x8b, 0xa6},
+ {0x8c, 0x84},
+ {0x8d, 0x47},
+ {0x8e, 0xbb},
+ {0x8f, 0x02},
+ {0x90, 0x21},
+ {0x91, 0x0c},
+ {0x92, 0x04},
+ {0x93, 0x22},
+ {0x94, 0x00},
+ {0x95, 0x00},
+ {0x96, 0x00},
+ {0x97, 0xeb},
+ {0x98, 0x00},
+ {0x99, 0x00},
+ {0x9a, 0x00},
+ {0x9b, 0x00},
+ {0x9c, 0x00},
+ {0x9d, 0x00},
+ {0x9e, 0x00},
+ {0x9f, 0x00},
+ {0xa0, 0x00},
+ {0xa1, 0x00},
+ {0xa2, 0x00},
+ {0xa3, 0x00},
+ {0xa4, 0x00},
+ {0xa5, 0x00},
+ {0xa6, 0x10},
+ {0xa7, 0x04},
+ {0xa8, 0x10},
+ {0xa9, 0x00},
+ {0xaa, 0x8f},
+ {0xab, 0x00},
+ {0xac, 0x00},
+ {0xad, 0x00},
+ {0xae, 0x00},
+ {0xaf, 0x80},
+ {0xb0, 0x38},
+ {0xb1, 0x00},
+ {0xb2, 0x00},
+ {0xb3, 0x00},
+ {0xb4, 0xee},
+ {0xb5, 0xff},
+ {0xb6, 0x10},
+ {0xb7, 0x00},
+ {0xb8, 0x00},
+ {0xb9, 0x00},
+ {0xba, 0x00},
+ {0xbb, 0x03},
+ {0xbc, 0x00},
+ {0xbd, 0x00},
+ {0xbe, 0x00},
+ {0xbf, 0x00},
+ {0xc0, 0x10},
+ {0xc1, 0x10},
+ {0xc2, 0x18},
+ {0xc3, 0x20},
+ {0xc4, 0x10},
+ {0xc5, 0x00},
+ {0xc6, 0x22},
+ {0xc7, 0x14},
+ {0xc8, 0x0f},
+ {0xc9, 0x08},
+ {0xca, 0xa4},
+ {0xcb, 0xa7},
+ {0xcc, 0x3c},
+ {0xcd, 0x10},
+ {0xce, 0x20},
+ {0xcf, 0x00},
+ {0xd0, 0x00},
+ {0xd1, 0x10},
+ {0xd2, 0x00},
+ {0xd3, 0x00},
+ {0xd4, 0x10},
+ {0xd5, 0x33},
+ {0xd6, 0x70},
+ {0xd7, 0x01},
+ {0xd8, 0x00},
+ {0xd9, 0x00},
+ {0xda, 0x00},
+ {0xdb, 0x00},
+ {0xdc, 0x00},
+ {0xdd, 0x00},
+ {0xde, 0x00},
+ {0xdf, 0x00},
+ {0xe0, 0x00},
+ {0xe1, 0x00},
+ {0xe2, 0xcc},
+ {0xe3, 0x04},
+ {0xe4, 0x08},
+ {0xe5, 0x10},
+ {0xe6, 0x00},
+ {0xe7, 0x0e},
+ {0xe8, 0x88},
+ {0xe9, 0xd4},
+ {0xea, 0x05},
+ {0xeb, 0xf0},
+ {0xec, 0x79},
+ {0xed, 0x0f},
+ {0xee, 0x04},
+ {0xef, 0x04},
+ {0xf0, 0x00},
+ {0xf1, 0x00},
+ {0xf2, 0x00},
+ {0xf3, 0x00},
+ {0xf4, 0x00},
+ {0xf5, 0x00},
+ {0xf6, 0x00},
+ {0xf7, 0x00},
+ {0xf8, 0x00},
+ {0xf9, 0x00},
+ {0xF0, 0x00},
+ {0xF1, 0xF8},
+ {0xF0, 0x80},
+ {0xF0, 0x00},
+ {0xF1, 0xF4},
+ {0xF0, 0x81},
+ {0xF0, 0x01},
+ {0xF1, 0xF0},
+ {0xF0, 0x82},
+ {0xF0, 0x02},
+ {0xF1, 0xEC},
+ {0xF0, 0x83},
+ {0xF0, 0x03},
+ {0xF1, 0xE8},
+ {0xF0, 0x84},
+ {0xF0, 0x04},
+ {0xF1, 0xE4},
+ {0xF0, 0x85},
+ {0xF0, 0x05},
+ {0xF1, 0xE0},
+ {0xF0, 0x86},
+ {0xF0, 0x06},
+ {0xF1, 0xDC},
+ {0xF0, 0x87},
+ {0xF0, 0x07},
+ {0xF1, 0xD8},
+ {0xF0, 0x88},
+ {0xF0, 0x08},
+ {0xF1, 0xD4},
+ {0xF0, 0x89},
+ {0xF0, 0x09},
+ {0xF1, 0xD0},
+ {0xF0, 0x8A},
+ {0xF0, 0x0A},
+ {0xF1, 0xCC},
+ {0xF0, 0x8B},
+ {0xF0, 0x0B},
+ {0xF1, 0xC8},
+ {0xF0, 0x8C},
+ {0xF0, 0x0C},
+ {0xF1, 0xC4},
+ {0xF0, 0x8D},
+ {0xF0, 0x0D},
+ {0xF1, 0xC0},
+ {0xF0, 0x8E},
+ {0xF0, 0x0E},
+ {0xF1, 0xBC},
+ {0xF0, 0x8F},
+ {0xF0, 0x0F},
+ {0xF1, 0xB8},
+ {0xF0, 0x90},
+ {0xF0, 0x10},
+ {0xF1, 0xB4},
+ {0xF0, 0x91},
+ {0xF0, 0x11},
+ {0xF1, 0xB0},
+ {0xF0, 0x92},
+ {0xF0, 0x12},
+ {0xF1, 0xAC},
+ {0xF0, 0x93},
+ {0xF0, 0x13},
+ {0xF1, 0xA8},
+ {0xF0, 0x94},
+ {0xF0, 0x14},
+ {0xF1, 0xA4},
+ {0xF0, 0x95},
+ {0xF0, 0x15},
+ {0xF1, 0xA0},
+ {0xF0, 0x96},
+ {0xF0, 0x16},
+ {0xF1, 0x9C},
+ {0xF0, 0x97},
+ {0xF0, 0x17},
+ {0xF1, 0x98},
+ {0xF0, 0x98},
+ {0xF0, 0x18},
+ {0xF1, 0x94},
+ {0xF0, 0x99},
+ {0xF0, 0x19},
+ {0xF1, 0x90},
+ {0xF0, 0x9A},
+ {0xF0, 0x1A},
+ {0xF1, 0x8C},
+ {0xF0, 0x9B},
+ {0xF0, 0x1B},
+ {0xF1, 0x88},
+ {0xF0, 0x9C},
+ {0xF0, 0x1C},
+ {0xF1, 0x84},
+ {0xF0, 0x9D},
+ {0xF0, 0x1D},
+ {0xF1, 0x80},
+ {0xF0, 0x9E},
+ {0xF0, 0x1E},
+ {0xF1, 0x7C},
+ {0xF0, 0x9F},
+ {0xF0, 0x1F},
+ {0xF1, 0x78},
+ {0xF0, 0xA0},
+ {0xF0, 0x20},
+ {0xF1, 0x74},
+ {0xF0, 0xA1},
+ {0xF0, 0x21},
+ {0xF1, 0x70},
+ {0xF0, 0xA2},
+ {0xF0, 0x22},
+ {0xF1, 0x6C},
+ {0xF0, 0xA3},
+ {0xF0, 0x23},
+ {0xF1, 0x68},
+ {0xF0, 0xA4},
+ {0xF0, 0x24},
+ {0xF1, 0x64},
+ {0xF0, 0xA5},
+ {0xF0, 0x25},
+ {0xF1, 0x60},
+ {0xF0, 0xA6},
+ {0xF0, 0x26},
+ {0xF1, 0x5C},
+ {0xF0, 0xA7},
+ {0xF0, 0x27},
+ {0xF1, 0x58},
+ {0xF0, 0xA8},
+ {0xF0, 0x28},
+ {0xF1, 0x54},
+ {0xF0, 0xA9},
+ {0xF0, 0x29},
+ {0xF1, 0x50},
+ {0xF0, 0xAA},
+ {0xF0, 0x2A},
+ {0xF1, 0x4C},
+ {0xF0, 0xAB},
+ {0xF0, 0x2B},
+ {0xF1, 0x48},
+ {0xF0, 0xAC},
+ {0xF0, 0x2C},
+ {0xF1, 0x44},
+ {0xF0, 0xAD},
+ {0xF0, 0x2D},
+ {0xF1, 0x40},
+ {0xF0, 0xAE},
+ {0xF0, 0x2E},
+ {0xF1, 0x3C},
+ {0xF0, 0xAF},
+ {0xF0, 0x2F},
+ {0xF1, 0x38},
+ {0xF0, 0xB0},
+ {0xF0, 0x30},
+ {0xF1, 0x34},
+ {0xF0, 0xB1},
+ {0xF0, 0x31},
+ {0xF1, 0x30},
+ {0xF0, 0xB2},
+ {0xF0, 0x32},
+ {0xF1, 0x2C},
+ {0xF0, 0xB3},
+ {0xF0, 0x33},
+ {0xF1, 0x28},
+ {0xF0, 0xB4},
+ {0xF0, 0x34},
+ {0xF1, 0x24},
+ {0xF0, 0xB5},
+ {0xF0, 0x35},
+ {0xF1, 0x20},
+ {0xF0, 0xB6},
+ {0xF0, 0x36},
+ {0xF1, 0x1C},
+ {0xF0, 0xB7},
+ {0xF0, 0x37},
+ {0xF1, 0x18},
+ {0xF0, 0xB8},
+ {0xF0, 0x38},
+ {0xF1, 0x14},
+ {0xF0, 0xB9},
+ {0xF0, 0x39},
+ {0xF1, 0x10},
+ {0xF0, 0xBA},
+ {0xF0, 0x3A},
+ {0xF1, 0x0C},
+ {0xF0, 0xBB},
+ {0xF0, 0x3B},
+ {0xF1, 0x08},
+ {0xF0, 0x00},
+ {0xF0, 0x3C},
+ {0xF1, 0x04},
+ {0xF0, 0xBD},
+ {0xF0, 0x3D},
+ {0xF1, 0x00},
+ {0xF0, 0xBE},
+ {0xF0, 0x3E},
+ {0xF1, 0x00},
+ {0xF0, 0xBF},
+ {0xF0, 0x3F},
+ {0xF1, 0x00},
+ {0xF0, 0xC0},
+ {0xF0, 0x00},
+};
+
+#define CB_VT3253B0_INIT_FOR_RFMD 256
+static const unsigned char vt3253b0_rfmd[CB_VT3253B0_INIT_FOR_RFMD][2] = {
+ {0x00, 0x31},
+ {0x01, 0x00},
+ {0x02, 0x00},
+ {0x03, 0x00},
+ {0x04, 0x00},
+ {0x05, 0x81},
+ {0x06, 0x00},
+ {0x07, 0x00},
+ {0x08, 0x38},
+ {0x09, 0x45},
+ {0x0a, 0x2a},
+ {0x0b, 0x76},
+ {0x0c, 0x00},
+ {0x0d, 0x00},
+ {0x0e, 0x80},
+ {0x0f, 0x00},
+ {0x10, 0x00},
+ {0x11, 0x00},
+ {0x12, 0x00},
+ {0x13, 0x00},
+ {0x14, 0x00},
+ {0x15, 0x00},
+ {0x16, 0x00},
+ {0x17, 0x00},
+ {0x18, 0x00},
+ {0x19, 0x00},
+ {0x1a, 0x00},
+ {0x1b, 0x8e},
+ {0x1c, 0x06},
+ {0x1d, 0x00},
+ {0x1e, 0x00},
+ {0x1f, 0x00},
+ {0x20, 0x00},
+ {0x21, 0x00},
+ {0x22, 0x00},
+ {0x23, 0x00},
+ {0x24, 0x00},
+ {0x25, 0x4a},
+ {0x26, 0x00},
+ {0x27, 0x00},
+ {0x28, 0x00},
+ {0x29, 0x00},
+ {0x2a, 0x00},
+ {0x2b, 0x00},
+ {0x2c, 0x00},
+ {0x2d, 0x34},
+ {0x2e, 0x18},
+ {0x2f, 0x0c},
+ {0x30, 0x26},
+ {0x31, 0x5b},
+ {0x32, 0x00},
+ {0x33, 0x00},
+ {0x34, 0x00},
+ {0x35, 0x00},
+ {0x36, 0xaa},
+ {0x37, 0xaa},
+ {0x38, 0xff},
+ {0x39, 0xff},
+ {0x3a, 0xf8},
+ {0x3b, 0x00},
+ {0x3c, 0x00},
+ {0x3d, 0x09},
+ {0x3e, 0x0d},
+ {0x3f, 0x04},
+ {0x40, 0x00},
+ {0x41, 0x08},
+ {0x42, 0x00},
+ {0x43, 0x08},
+ {0x44, 0x08},
+ {0x45, 0x14},
+ {0x46, 0x05},
+ {0x47, 0x08},
+ {0x48, 0x00},
+ {0x49, 0x00},
+ {0x4a, 0x00},
+ {0x4b, 0x00},
+ {0x4c, 0x09},
+ {0x4d, 0x80},
+ {0x4e, 0x00},
+ {0x4f, 0xc5},
+ {0x50, 0x14},
+ {0x51, 0x19},
+ {0x52, 0x00},
+ {0x53, 0x00},
+ {0x54, 0x00},
+ {0x55, 0x00},
+ {0x56, 0x00},
+ {0x57, 0x00},
+ {0x58, 0x00},
+ {0x59, 0xb0},
+ {0x5a, 0x00},
+ {0x5b, 0x00},
+ {0x5c, 0x00},
+ {0x5d, 0x00},
+ {0x5e, 0x00},
+ {0x5f, 0x00},
+ {0x60, 0x39},
+ {0x61, 0x83},
+ {0x62, 0x00},
+ {0x63, 0x00},
+ {0x64, 0x00},
+ {0x65, 0x00},
+ {0x66, 0xc0},
+ {0x67, 0x49},
+ {0x68, 0x00},
+ {0x69, 0x00},
+ {0x6a, 0x00},
+ {0x6b, 0x00},
+ {0x6c, 0x00},
+ {0x6d, 0x03},
+ {0x6e, 0x01},
+ {0x6f, 0x00},
+ {0x70, 0x00},
+ {0x71, 0x00},
+ {0x72, 0x00},
+ {0x73, 0x00},
+ {0x74, 0x00},
+ {0x75, 0x00},
+ {0x76, 0x00},
+ {0x77, 0x00},
+ {0x78, 0x00},
+ {0x79, 0x00},
+ {0x7a, 0x00},
+ {0x7b, 0x00},
+ {0x7c, 0x00},
+ {0x7d, 0x00},
+ {0x7e, 0x00},
+ {0x7f, 0x00},
+ {0x80, 0x89},
+ {0x81, 0x00},
+ {0x82, 0x0e},
+ {0x83, 0x00},
+ {0x84, 0x00},
+ {0x85, 0x00},
+ {0x86, 0x00},
+ {0x87, 0x00},
+ {0x88, 0x08},
+ {0x89, 0x00},
+ {0x8a, 0x0e},
+ {0x8b, 0xa7},
+ {0x8c, 0x88},
+ {0x8d, 0x47},
+ {0x8e, 0xaa},
+ {0x8f, 0x02},
+ {0x90, 0x23},
+ {0x91, 0x0c},
+ {0x92, 0x06},
+ {0x93, 0x08},
+ {0x94, 0x00},
+ {0x95, 0x00},
+ {0x96, 0x00},
+ {0x97, 0xeb},
+ {0x98, 0x00},
+ {0x99, 0x00},
+ {0x9a, 0x00},
+ {0x9b, 0x00},
+ {0x9c, 0x00},
+ {0x9d, 0x00},
+ {0x9e, 0x00},
+ {0x9f, 0x00},
+ {0xa0, 0x00},
+ {0xa1, 0x00},
+ {0xa2, 0x00},
+ {0xa3, 0xcd},
+ {0xa4, 0x07},
+ {0xa5, 0x33},
+ {0xa6, 0x18},
+ {0xa7, 0x00},
+ {0xa8, 0x18},
+ {0xa9, 0x00},
+ {0xaa, 0x28},
+ {0xab, 0x00},
+ {0xac, 0x00},
+ {0xad, 0x00},
+ {0xae, 0x00},
+ {0xaf, 0x18},
+ {0xb0, 0x38},
+ {0xb1, 0x30},
+ {0xb2, 0x00},
+ {0xb3, 0x00},
+ {0xb4, 0x00},
+ {0xb5, 0x00},
+ {0xb6, 0x84},
+ {0xb7, 0xfd},
+ {0xb8, 0x00},
+ {0xb9, 0x00},
+ {0xba, 0x00},
+ {0xbb, 0x03},
+ {0xbc, 0x00},
+ {0xbd, 0x00},
+ {0xbe, 0x00},
+ {0xbf, 0x00},
+ {0xc0, 0x10},
+ {0xc1, 0x20},
+ {0xc2, 0x18},
+ {0xc3, 0x20},
+ {0xc4, 0x10},
+ {0xc5, 0x2c},
+ {0xc6, 0x1e},
+ {0xc7, 0x10},
+ {0xc8, 0x12},
+ {0xc9, 0x01},
+ {0xca, 0x6f},
+ {0xcb, 0xa7},
+ {0xcc, 0x3c},
+ {0xcd, 0x10},
+ {0xce, 0x00},
+ {0xcf, 0x22},
+ {0xd0, 0x00},
+ {0xd1, 0x10},
+ {0xd2, 0x00},
+ {0xd3, 0x00},
+ {0xd4, 0x10},
+ {0xd5, 0x33},
+ {0xd6, 0x80},
+ {0xd7, 0x21},
+ {0xd8, 0x00},
+ {0xd9, 0x00},
+ {0xda, 0x00},
+ {0xdb, 0x00},
+ {0xdc, 0x00},
+ {0xdd, 0x00},
+ {0xde, 0x00},
+ {0xdf, 0x00},
+ {0xe0, 0x00},
+ {0xe1, 0xB3},
+ {0xe2, 0x00},
+ {0xe3, 0x00},
+ {0xe4, 0x00},
+ {0xe5, 0x10},
+ {0xe6, 0x00},
+ {0xe7, 0x18},
+ {0xe8, 0x08},
+ {0xe9, 0xd4},
+ {0xea, 0x00},
+ {0xeb, 0xff},
+ {0xec, 0x79},
+ {0xed, 0x10},
+ {0xee, 0x30},
+ {0xef, 0x02},
+ {0xf0, 0x00},
+ {0xf1, 0x09},
+ {0xf2, 0x00},
+ {0xf3, 0x00},
+ {0xf4, 0x00},
+ {0xf5, 0x00},
+ {0xf6, 0x00},
+ {0xf7, 0x00},
+ {0xf8, 0x00},
+ {0xf9, 0x00},
+ {0xfa, 0x00},
+ {0xfb, 0x00},
+ {0xfc, 0x00},
+ {0xfd, 0x00},
+ {0xfe, 0x00},
+ {0xff, 0x00},
+};
+
+#define CB_VT3253B0_AGC_FOR_RFMD2959 195
+/* For RFMD2959 */
+static
+unsigned char byVT3253B0_AGC4_RFMD2959[CB_VT3253B0_AGC_FOR_RFMD2959][2] = {
+ {0xF0, 0x00},
+ {0xF1, 0x3E},
+ {0xF0, 0x80},
+ {0xF0, 0x00},
+ {0xF1, 0x3E},
+ {0xF0, 0x81},
+ {0xF0, 0x01},
+ {0xF1, 0x3E},
+ {0xF0, 0x82},
+ {0xF0, 0x02},
+ {0xF1, 0x3E},
+ {0xF0, 0x83},
+ {0xF0, 0x03},
+ {0xF1, 0x3B},
+ {0xF0, 0x84},
+ {0xF0, 0x04},
+ {0xF1, 0x39},
+ {0xF0, 0x85},
+ {0xF0, 0x05},
+ {0xF1, 0x38},
+ {0xF0, 0x86},
+ {0xF0, 0x06},
+ {0xF1, 0x37},
+ {0xF0, 0x87},
+ {0xF0, 0x07},
+ {0xF1, 0x36},
+ {0xF0, 0x88},
+ {0xF0, 0x08},
+ {0xF1, 0x35},
+ {0xF0, 0x89},
+ {0xF0, 0x09},
+ {0xF1, 0x35},
+ {0xF0, 0x8A},
+ {0xF0, 0x0A},
+ {0xF1, 0x34},
+ {0xF0, 0x8B},
+ {0xF0, 0x0B},
+ {0xF1, 0x34},
+ {0xF0, 0x8C},
+ {0xF0, 0x0C},
+ {0xF1, 0x33},
+ {0xF0, 0x8D},
+ {0xF0, 0x0D},
+ {0xF1, 0x32},
+ {0xF0, 0x8E},
+ {0xF0, 0x0E},
+ {0xF1, 0x31},
+ {0xF0, 0x8F},
+ {0xF0, 0x0F},
+ {0xF1, 0x30},
+ {0xF0, 0x90},
+ {0xF0, 0x10},
+ {0xF1, 0x2F},
+ {0xF0, 0x91},
+ {0xF0, 0x11},
+ {0xF1, 0x2F},
+ {0xF0, 0x92},
+ {0xF0, 0x12},
+ {0xF1, 0x2E},
+ {0xF0, 0x93},
+ {0xF0, 0x13},
+ {0xF1, 0x2D},
+ {0xF0, 0x94},
+ {0xF0, 0x14},
+ {0xF1, 0x2C},
+ {0xF0, 0x95},
+ {0xF0, 0x15},
+ {0xF1, 0x2B},
+ {0xF0, 0x96},
+ {0xF0, 0x16},
+ {0xF1, 0x2B},
+ {0xF0, 0x97},
+ {0xF0, 0x17},
+ {0xF1, 0x2A},
+ {0xF0, 0x98},
+ {0xF0, 0x18},
+ {0xF1, 0x29},
+ {0xF0, 0x99},
+ {0xF0, 0x19},
+ {0xF1, 0x28},
+ {0xF0, 0x9A},
+ {0xF0, 0x1A},
+ {0xF1, 0x27},
+ {0xF0, 0x9B},
+ {0xF0, 0x1B},
+ {0xF1, 0x26},
+ {0xF0, 0x9C},
+ {0xF0, 0x1C},
+ {0xF1, 0x25},
+ {0xF0, 0x9D},
+ {0xF0, 0x1D},
+ {0xF1, 0x24},
+ {0xF0, 0x9E},
+ {0xF0, 0x1E},
+ {0xF1, 0x24},
+ {0xF0, 0x9F},
+ {0xF0, 0x1F},
+ {0xF1, 0x23},
+ {0xF0, 0xA0},
+ {0xF0, 0x20},
+ {0xF1, 0x22},
+ {0xF0, 0xA1},
+ {0xF0, 0x21},
+ {0xF1, 0x21},
+ {0xF0, 0xA2},
+ {0xF0, 0x22},
+ {0xF1, 0x20},
+ {0xF0, 0xA3},
+ {0xF0, 0x23},
+ {0xF1, 0x20},
+ {0xF0, 0xA4},
+ {0xF0, 0x24},
+ {0xF1, 0x1F},
+ {0xF0, 0xA5},
+ {0xF0, 0x25},
+ {0xF1, 0x1E},
+ {0xF0, 0xA6},
+ {0xF0, 0x26},
+ {0xF1, 0x1D},
+ {0xF0, 0xA7},
+ {0xF0, 0x27},
+ {0xF1, 0x1C},
+ {0xF0, 0xA8},
+ {0xF0, 0x28},
+ {0xF1, 0x1B},
+ {0xF0, 0xA9},
+ {0xF0, 0x29},
+ {0xF1, 0x1B},
+ {0xF0, 0xAA},
+ {0xF0, 0x2A},
+ {0xF1, 0x1A},
+ {0xF0, 0xAB},
+ {0xF0, 0x2B},
+ {0xF1, 0x1A},
+ {0xF0, 0xAC},
+ {0xF0, 0x2C},
+ {0xF1, 0x19},
+ {0xF0, 0xAD},
+ {0xF0, 0x2D},
+ {0xF1, 0x18},
+ {0xF0, 0xAE},
+ {0xF0, 0x2E},
+ {0xF1, 0x17},
+ {0xF0, 0xAF},
+ {0xF0, 0x2F},
+ {0xF1, 0x16},
+ {0xF0, 0xB0},
+ {0xF0, 0x30},
+ {0xF1, 0x15},
+ {0xF0, 0xB1},
+ {0xF0, 0x31},
+ {0xF1, 0x15},
+ {0xF0, 0xB2},
+ {0xF0, 0x32},
+ {0xF1, 0x15},
+ {0xF0, 0xB3},
+ {0xF0, 0x33},
+ {0xF1, 0x14},
+ {0xF0, 0xB4},
+ {0xF0, 0x34},
+ {0xF1, 0x13},
+ {0xF0, 0xB5},
+ {0xF0, 0x35},
+ {0xF1, 0x12},
+ {0xF0, 0xB6},
+ {0xF0, 0x36},
+ {0xF1, 0x11},
+ {0xF0, 0xB7},
+ {0xF0, 0x37},
+ {0xF1, 0x10},
+ {0xF0, 0xB8},
+ {0xF0, 0x38},
+ {0xF1, 0x0F},
+ {0xF0, 0xB9},
+ {0xF0, 0x39},
+ {0xF1, 0x0E},
+ {0xF0, 0xBA},
+ {0xF0, 0x3A},
+ {0xF1, 0x0D},
+ {0xF0, 0xBB},
+ {0xF0, 0x3B},
+ {0xF1, 0x0C},
+ {0xF0, 0xBC},
+ {0xF0, 0x3C},
+ {0xF1, 0x0B},
+ {0xF0, 0xBD},
+ {0xF0, 0x3D},
+ {0xF1, 0x0B},
+ {0xF0, 0xBE},
+ {0xF0, 0x3E},
+ {0xF1, 0x0A},
+ {0xF0, 0xBF},
+ {0xF0, 0x3F},
+ {0xF1, 0x09},
+ {0xF0, 0x00},
+};
+
+#define CB_VT3253B0_INIT_FOR_AIROHA2230 256
+/* For AIROHA */
+static
+unsigned char byVT3253B0_AIROHA2230[CB_VT3253B0_INIT_FOR_AIROHA2230][2] = {
+ {0x00, 0x31},
+ {0x01, 0x00},
+ {0x02, 0x00},
+ {0x03, 0x00},
+ {0x04, 0x00},
+ {0x05, 0x80},
+ {0x06, 0x00},
+ {0x07, 0x00},
+ {0x08, 0x70},
+ {0x09, 0x41},
+ {0x0a, 0x2A},
+ {0x0b, 0x76},
+ {0x0c, 0x00},
+ {0x0d, 0x00},
+ {0x0e, 0x80},
+ {0x0f, 0x00},
+ {0x10, 0x00},
+ {0x11, 0x00},
+ {0x12, 0x00},
+ {0x13, 0x00},
+ {0x14, 0x00},
+ {0x15, 0x00},
+ {0x16, 0x00},
+ {0x17, 0x00},
+ {0x18, 0x00},
+ {0x19, 0x00},
+ {0x1a, 0x00},
+ {0x1b, 0x8f},
+ {0x1c, 0x09},
+ {0x1d, 0x00},
+ {0x1e, 0x00},
+ {0x1f, 0x00},
+ {0x20, 0x00},
+ {0x21, 0x00},
+ {0x22, 0x00},
+ {0x23, 0x00},
+ {0x24, 0x00},
+ {0x25, 0x4a},
+ {0x26, 0x00},
+ {0x27, 0x00},
+ {0x28, 0x00},
+ {0x29, 0x00},
+ {0x2a, 0x00},
+ {0x2b, 0x00},
+ {0x2c, 0x00},
+ {0x2d, 0x4a},
+ {0x2e, 0x00},
+ {0x2f, 0x0a},
+ {0x30, 0x26},
+ {0x31, 0x5b},
+ {0x32, 0x00},
+ {0x33, 0x00},
+ {0x34, 0x00},
+ {0x35, 0x00},
+ {0x36, 0xaa},
+ {0x37, 0xaa},
+ {0x38, 0xff},
+ {0x39, 0xff},
+ {0x3a, 0x79},
+ {0x3b, 0x00},
+ {0x3c, 0x00},
+ {0x3d, 0x0b},
+ {0x3e, 0x48},
+ {0x3f, 0x04},
+ {0x40, 0x00},
+ {0x41, 0x08},
+ {0x42, 0x00},
+ {0x43, 0x08},
+ {0x44, 0x08},
+ {0x45, 0x14},
+ {0x46, 0x05},
+ {0x47, 0x09},
+ {0x48, 0x00},
+ {0x49, 0x00},
+ {0x4a, 0x00},
+ {0x4b, 0x00},
+ {0x4c, 0x09},
+ {0x4d, 0x73},
+ {0x4e, 0x00},
+ {0x4f, 0xc5},
+ {0x50, 0x15},
+ {0x51, 0x19},
+ {0x52, 0x00},
+ {0x53, 0x00},
+ {0x54, 0x00},
+ {0x55, 0x00},
+ {0x56, 0x00},
+ {0x57, 0x00},
+ {0x58, 0x00},
+ {0x59, 0xb0},
+ {0x5a, 0x00},
+ {0x5b, 0x00},
+ {0x5c, 0x00},
+ {0x5d, 0x00},
+ {0x5e, 0x00},
+ {0x5f, 0x00},
+ {0x60, 0xe4},
+ {0x61, 0x80},
+ {0x62, 0x00},
+ {0x63, 0x00},
+ {0x64, 0x00},
+ {0x65, 0x00},
+ {0x66, 0x98},
+ {0x67, 0x0a},
+ {0x68, 0x00},
+ {0x69, 0x00},
+ {0x6a, 0x00},
+ {0x6b, 0x00},
+ {0x6c, 0x00}, /* RobertYu:20050125, request by JJSue */
+ {0x6d, 0x03},
+ {0x6e, 0x01},
+ {0x6f, 0x00},
+ {0x70, 0x00},
+ {0x71, 0x00},
+ {0x72, 0x00},
+ {0x73, 0x00},
+ {0x74, 0x00},
+ {0x75, 0x00},
+ {0x76, 0x00},
+ {0x77, 0x00},
+ {0x78, 0x00},
+ {0x79, 0x00},
+ {0x7a, 0x00},
+ {0x7b, 0x00},
+ {0x7c, 0x00},
+ {0x7d, 0x00},
+ {0x7e, 0x00},
+ {0x7f, 0x00},
+ {0x80, 0x8c},
+ {0x81, 0x01},
+ {0x82, 0x09},
+ {0x83, 0x00},
+ {0x84, 0x00},
+ {0x85, 0x00},
+ {0x86, 0x00},
+ {0x87, 0x00},
+ {0x88, 0x08},
+ {0x89, 0x00},
+ {0x8a, 0x0f},
+ {0x8b, 0xb7},
+ {0x8c, 0x88},
+ {0x8d, 0x47},
+ {0x8e, 0xaa},
+ {0x8f, 0x02},
+ {0x90, 0x22},
+ {0x91, 0x00},
+ {0x92, 0x00},
+ {0x93, 0x00},
+ {0x94, 0x00},
+ {0x95, 0x00},
+ {0x96, 0x00},
+ {0x97, 0xeb},
+ {0x98, 0x00},
+ {0x99, 0x00},
+ {0x9a, 0x00},
+ {0x9b, 0x00},
+ {0x9c, 0x00},
+ {0x9d, 0x00},
+ {0x9e, 0x00},
+ {0x9f, 0x01},
+ {0xa0, 0x00},
+ {0xa1, 0x00},
+ {0xa2, 0x00},
+ {0xa3, 0x00},
+ {0xa4, 0x00},
+ {0xa5, 0x00},
+ {0xa6, 0x10},
+ {0xa7, 0x00},
+ {0xa8, 0x18},
+ {0xa9, 0x00},
+ {0xaa, 0x00},
+ {0xab, 0x00},
+ {0xac, 0x00},
+ {0xad, 0x00},
+ {0xae, 0x00},
+ {0xaf, 0x18},
+ {0xb0, 0x38},
+ {0xb1, 0x30},
+ {0xb2, 0x00},
+ {0xb3, 0x00},
+ {0xb4, 0xff},
+ {0xb5, 0x0f},
+ {0xb6, 0xe4},
+ {0xb7, 0xe2},
+ {0xb8, 0x00},
+ {0xb9, 0x00},
+ {0xba, 0x00},
+ {0xbb, 0x03},
+ {0xbc, 0x01},
+ {0xbd, 0x00},
+ {0xbe, 0x00},
+ {0xbf, 0x00},
+ {0xc0, 0x18},
+ {0xc1, 0x20},
+ {0xc2, 0x07},
+ {0xc3, 0x18},
+ {0xc4, 0xff},
+ {0xc5, 0x2c},
+ {0xc6, 0x0c},
+ {0xc7, 0x0a},
+ {0xc8, 0x0e},
+ {0xc9, 0x01},
+ {0xca, 0x68},
+ {0xcb, 0xa7},
+ {0xcc, 0x3c},
+ {0xcd, 0x10},
+ {0xce, 0x00},
+ {0xcf, 0x25},
+ {0xd0, 0x40},
+ {0xd1, 0x12},
+ {0xd2, 0x00},
+ {0xd3, 0x00},
+ {0xd4, 0x10},
+ {0xd5, 0x28},
+ {0xd6, 0x80},
+ {0xd7, 0x2A},
+ {0xd8, 0x00},
+ {0xd9, 0x00},
+ {0xda, 0x00},
+ {0xdb, 0x00},
+ {0xdc, 0x00},
+ {0xdd, 0x00},
+ {0xde, 0x00},
+ {0xdf, 0x00},
+ {0xe0, 0x00},
+ {0xe1, 0xB3},
+ {0xe2, 0x00},
+ {0xe3, 0x00},
+ {0xe4, 0x00},
+ {0xe5, 0x10},
+ {0xe6, 0x00},
+ {0xe7, 0x1C},
+ {0xe8, 0x00},
+ {0xe9, 0xf4},
+ {0xea, 0x00},
+ {0xeb, 0xff},
+ {0xec, 0x79},
+ {0xed, 0x20},
+ {0xee, 0x30},
+ {0xef, 0x01},
+ {0xf0, 0x00},
+ {0xf1, 0x3e},
+ {0xf2, 0x00},
+ {0xf3, 0x00},
+ {0xf4, 0x00},
+ {0xf5, 0x00},
+ {0xf6, 0x00},
+ {0xf7, 0x00},
+ {0xf8, 0x00},
+ {0xf9, 0x00},
+ {0xfa, 0x00},
+ {0xfb, 0x00},
+ {0xfc, 0x00},
+ {0xfd, 0x00},
+ {0xfe, 0x00},
+ {0xff, 0x00},
+};
+
+#define CB_VT3253B0_INIT_FOR_UW2451 256
+/* For UW2451 */
+static unsigned char byVT3253B0_UW2451[CB_VT3253B0_INIT_FOR_UW2451][2] = {
+ {0x00, 0x31},
+ {0x01, 0x00},
+ {0x02, 0x00},
+ {0x03, 0x00},
+ {0x04, 0x00},
+ {0x05, 0x81},
+ {0x06, 0x00},
+ {0x07, 0x00},
+ {0x08, 0x38},
+ {0x09, 0x45},
+ {0x0a, 0x28},
+ {0x0b, 0x76},
+ {0x0c, 0x00},
+ {0x0d, 0x00},
+ {0x0e, 0x80},
+ {0x0f, 0x00},
+ {0x10, 0x00},
+ {0x11, 0x00},
+ {0x12, 0x00},
+ {0x13, 0x00},
+ {0x14, 0x00},
+ {0x15, 0x00},
+ {0x16, 0x00},
+ {0x17, 0x00},
+ {0x18, 0x00},
+ {0x19, 0x00},
+ {0x1a, 0x00},
+ {0x1b, 0x8f},
+ {0x1c, 0x0f},
+ {0x1d, 0x00},
+ {0x1e, 0x00},
+ {0x1f, 0x00},
+ {0x20, 0x00},
+ {0x21, 0x00},
+ {0x22, 0x00},
+ {0x23, 0x00},
+ {0x24, 0x00},
+ {0x25, 0x4a},
+ {0x26, 0x00},
+ {0x27, 0x00},
+ {0x28, 0x00},
+ {0x29, 0x00},
+ {0x2a, 0x00},
+ {0x2b, 0x00},
+ {0x2c, 0x00},
+ {0x2d, 0x18},
+ {0x2e, 0x00},
+ {0x2f, 0x0a},
+ {0x30, 0x26},
+ {0x31, 0x5b},
+ {0x32, 0x00},
+ {0x33, 0x00},
+ {0x34, 0x00},
+ {0x35, 0x00},
+ {0x36, 0xaa},
+ {0x37, 0xaa},
+ {0x38, 0xff},
+ {0x39, 0xff},
+ {0x3a, 0x00},
+ {0x3b, 0x00},
+ {0x3c, 0x00},
+ {0x3d, 0x03},
+ {0x3e, 0x1d},
+ {0x3f, 0x04},
+ {0x40, 0x00},
+ {0x41, 0x08},
+ {0x42, 0x00},
+ {0x43, 0x08},
+ {0x44, 0x08},
+ {0x45, 0x14},
+ {0x46, 0x05},
+ {0x47, 0x09},
+ {0x48, 0x00},
+ {0x49, 0x00},
+ {0x4a, 0x00},
+ {0x4b, 0x00},
+ {0x4c, 0x09},
+ {0x4d, 0x90},
+ {0x4e, 0x00},
+ {0x4f, 0xc5},
+ {0x50, 0x15},
+ {0x51, 0x19},
+ {0x52, 0x00},
+ {0x53, 0x00},
+ {0x54, 0x00},
+ {0x55, 0x00},
+ {0x56, 0x00},
+ {0x57, 0x00},
+ {0x58, 0x00},
+ {0x59, 0xb0},
+ {0x5a, 0x00},
+ {0x5b, 0x00},
+ {0x5c, 0x00},
+ {0x5d, 0x00},
+ {0x5e, 0x00},
+ {0x5f, 0x00},
+ {0x60, 0xb3},
+ {0x61, 0x81},
+ {0x62, 0x00},
+ {0x63, 0x00},
+ {0x64, 0x00},
+ {0x65, 0x00},
+ {0x66, 0x57},
+ {0x67, 0x6c},
+ {0x68, 0x00},
+ {0x69, 0x00},
+ {0x6a, 0x00},
+ {0x6b, 0x00},
+ {0x6c, 0x00}, /* RobertYu:20050125, request by JJSue */
+ {0x6d, 0x03},
+ {0x6e, 0x01},
+ {0x6f, 0x00},
+ {0x70, 0x00},
+ {0x71, 0x00},
+ {0x72, 0x00},
+ {0x73, 0x00},
+ {0x74, 0x00},
+ {0x75, 0x00},
+ {0x76, 0x00},
+ {0x77, 0x00},
+ {0x78, 0x00},
+ {0x79, 0x00},
+ {0x7a, 0x00},
+ {0x7b, 0x00},
+ {0x7c, 0x00},
+ {0x7d, 0x00},
+ {0x7e, 0x00},
+ {0x7f, 0x00},
+ {0x80, 0x8c},
+ {0x81, 0x00},
+ {0x82, 0x0e},
+ {0x83, 0x00},
+ {0x84, 0x00},
+ {0x85, 0x00},
+ {0x86, 0x00},
+ {0x87, 0x00},
+ {0x88, 0x08},
+ {0x89, 0x00},
+ {0x8a, 0x0e},
+ {0x8b, 0xa7},
+ {0x8c, 0x88},
+ {0x8d, 0x47},
+ {0x8e, 0xaa},
+ {0x8f, 0x02},
+ {0x90, 0x00},
+ {0x91, 0x00},
+ {0x92, 0x00},
+ {0x93, 0x00},
+ {0x94, 0x00},
+ {0x95, 0x00},
+ {0x96, 0x00},
+ {0x97, 0xe3},
+ {0x98, 0x00},
+ {0x99, 0x00},
+ {0x9a, 0x00},
+ {0x9b, 0x00},
+ {0x9c, 0x00},
+ {0x9d, 0x00},
+ {0x9e, 0x00},
+ {0x9f, 0x00},
+ {0xa0, 0x00},
+ {0xa1, 0x00},
+ {0xa2, 0x00},
+ {0xa3, 0x00},
+ {0xa4, 0x00},
+ {0xa5, 0x00},
+ {0xa6, 0x10},
+ {0xa7, 0x00},
+ {0xa8, 0x18},
+ {0xa9, 0x00},
+ {0xaa, 0x00},
+ {0xab, 0x00},
+ {0xac, 0x00},
+ {0xad, 0x00},
+ {0xae, 0x00},
+ {0xaf, 0x18},
+ {0xb0, 0x18},
+ {0xb1, 0x30},
+ {0xb2, 0x00},
+ {0xb3, 0x00},
+ {0xb4, 0x00},
+ {0xb5, 0x00},
+ {0xb6, 0x00},
+ {0xb7, 0x00},
+ {0xb8, 0x00},
+ {0xb9, 0x00},
+ {0xba, 0x00},
+ {0xbb, 0x03},
+ {0xbc, 0x01},
+ {0xbd, 0x00},
+ {0xbe, 0x00},
+ {0xbf, 0x00},
+ {0xc0, 0x10},
+ {0xc1, 0x20},
+ {0xc2, 0x00},
+ {0xc3, 0x20},
+ {0xc4, 0x00},
+ {0xc5, 0x2c},
+ {0xc6, 0x1c},
+ {0xc7, 0x10},
+ {0xc8, 0x10},
+ {0xc9, 0x01},
+ {0xca, 0x68},
+ {0xcb, 0xa7},
+ {0xcc, 0x3c},
+ {0xcd, 0x09},
+ {0xce, 0x00},
+ {0xcf, 0x20},
+ {0xd0, 0x40},
+ {0xd1, 0x10},
+ {0xd2, 0x00},
+ {0xd3, 0x00},
+ {0xd4, 0x20},
+ {0xd5, 0x28},
+ {0xd6, 0xa0},
+ {0xd7, 0x2a},
+ {0xd8, 0x00},
+ {0xd9, 0x00},
+ {0xda, 0x00},
+ {0xdb, 0x00},
+ {0xdc, 0x00},
+ {0xdd, 0x00},
+ {0xde, 0x00},
+ {0xdf, 0x00},
+ {0xe0, 0x00},
+ {0xe1, 0xd3},
+ {0xe2, 0xc0},
+ {0xe3, 0x00},
+ {0xe4, 0x00},
+ {0xe5, 0x10},
+ {0xe6, 0x00},
+ {0xe7, 0x12},
+ {0xe8, 0x12},
+ {0xe9, 0x34},
+ {0xea, 0x00},
+ {0xeb, 0xff},
+ {0xec, 0x79},
+ {0xed, 0x20},
+ {0xee, 0x30},
+ {0xef, 0x01},
+ {0xf0, 0x00},
+ {0xf1, 0x3e},
+ {0xf2, 0x00},
+ {0xf3, 0x00},
+ {0xf4, 0x00},
+ {0xf5, 0x00},
+ {0xf6, 0x00},
+ {0xf7, 0x00},
+ {0xf8, 0x00},
+ {0xf9, 0x00},
+ {0xfa, 0x00},
+ {0xfb, 0x00},
+ {0xfc, 0x00},
+ {0xfd, 0x00},
+ {0xfe, 0x00},
+ {0xff, 0x00},
+};
+
+#define CB_VT3253B0_AGC 193
+/* For AIROHA */
+static unsigned char byVT3253B0_AGC[CB_VT3253B0_AGC][2] = {
+ {0xF0, 0x00},
+ {0xF1, 0x00},
+ {0xF0, 0x80},
+ {0xF0, 0x01},
+ {0xF1, 0x00},
+ {0xF0, 0x81},
+ {0xF0, 0x02},
+ {0xF1, 0x02},
+ {0xF0, 0x82},
+ {0xF0, 0x03},
+ {0xF1, 0x04},
+ {0xF0, 0x83},
+ {0xF0, 0x03},
+ {0xF1, 0x04},
+ {0xF0, 0x84},
+ {0xF0, 0x04},
+ {0xF1, 0x06},
+ {0xF0, 0x85},
+ {0xF0, 0x05},
+ {0xF1, 0x06},
+ {0xF0, 0x86},
+ {0xF0, 0x06},
+ {0xF1, 0x06},
+ {0xF0, 0x87},
+ {0xF0, 0x07},
+ {0xF1, 0x08},
+ {0xF0, 0x88},
+ {0xF0, 0x08},
+ {0xF1, 0x08},
+ {0xF0, 0x89},
+ {0xF0, 0x09},
+ {0xF1, 0x0A},
+ {0xF0, 0x8A},
+ {0xF0, 0x0A},
+ {0xF1, 0x0A},
+ {0xF0, 0x8B},
+ {0xF0, 0x0B},
+ {0xF1, 0x0C},
+ {0xF0, 0x8C},
+ {0xF0, 0x0C},
+ {0xF1, 0x0C},
+ {0xF0, 0x8D},
+ {0xF0, 0x0D},
+ {0xF1, 0x0E},
+ {0xF0, 0x8E},
+ {0xF0, 0x0E},
+ {0xF1, 0x0E},
+ {0xF0, 0x8F},
+ {0xF0, 0x0F},
+ {0xF1, 0x10},
+ {0xF0, 0x90},
+ {0xF0, 0x10},
+ {0xF1, 0x10},
+ {0xF0, 0x91},
+ {0xF0, 0x11},
+ {0xF1, 0x12},
+ {0xF0, 0x92},
+ {0xF0, 0x12},
+ {0xF1, 0x12},
+ {0xF0, 0x93},
+ {0xF0, 0x13},
+ {0xF1, 0x14},
+ {0xF0, 0x94},
+ {0xF0, 0x14},
+ {0xF1, 0x14},
+ {0xF0, 0x95},
+ {0xF0, 0x15},
+ {0xF1, 0x16},
+ {0xF0, 0x96},
+ {0xF0, 0x16},
+ {0xF1, 0x16},
+ {0xF0, 0x97},
+ {0xF0, 0x17},
+ {0xF1, 0x18},
+ {0xF0, 0x98},
+ {0xF0, 0x18},
+ {0xF1, 0x18},
+ {0xF0, 0x99},
+ {0xF0, 0x19},
+ {0xF1, 0x1A},
+ {0xF0, 0x9A},
+ {0xF0, 0x1A},
+ {0xF1, 0x1A},
+ {0xF0, 0x9B},
+ {0xF0, 0x1B},
+ {0xF1, 0x1C},
+ {0xF0, 0x9C},
+ {0xF0, 0x1C},
+ {0xF1, 0x1C},
+ {0xF0, 0x9D},
+ {0xF0, 0x1D},
+ {0xF1, 0x1E},
+ {0xF0, 0x9E},
+ {0xF0, 0x1E},
+ {0xF1, 0x1E},
+ {0xF0, 0x9F},
+ {0xF0, 0x1F},
+ {0xF1, 0x20},
+ {0xF0, 0xA0},
+ {0xF0, 0x20},
+ {0xF1, 0x20},
+ {0xF0, 0xA1},
+ {0xF0, 0x21},
+ {0xF1, 0x22},
+ {0xF0, 0xA2},
+ {0xF0, 0x22},
+ {0xF1, 0x22},
+ {0xF0, 0xA3},
+ {0xF0, 0x23},
+ {0xF1, 0x24},
+ {0xF0, 0xA4},
+ {0xF0, 0x24},
+ {0xF1, 0x24},
+ {0xF0, 0xA5},
+ {0xF0, 0x25},
+ {0xF1, 0x26},
+ {0xF0, 0xA6},
+ {0xF0, 0x26},
+ {0xF1, 0x26},
+ {0xF0, 0xA7},
+ {0xF0, 0x27},
+ {0xF1, 0x28},
+ {0xF0, 0xA8},
+ {0xF0, 0x28},
+ {0xF1, 0x28},
+ {0xF0, 0xA9},
+ {0xF0, 0x29},
+ {0xF1, 0x2A},
+ {0xF0, 0xAA},
+ {0xF0, 0x2A},
+ {0xF1, 0x2A},
+ {0xF0, 0xAB},
+ {0xF0, 0x2B},
+ {0xF1, 0x2C},
+ {0xF0, 0xAC},
+ {0xF0, 0x2C},
+ {0xF1, 0x2C},
+ {0xF0, 0xAD},
+ {0xF0, 0x2D},
+ {0xF1, 0x2E},
+ {0xF0, 0xAE},
+ {0xF0, 0x2E},
+ {0xF1, 0x2E},
+ {0xF0, 0xAF},
+ {0xF0, 0x2F},
+ {0xF1, 0x30},
+ {0xF0, 0xB0},
+ {0xF0, 0x30},
+ {0xF1, 0x30},
+ {0xF0, 0xB1},
+ {0xF0, 0x31},
+ {0xF1, 0x32},
+ {0xF0, 0xB2},
+ {0xF0, 0x32},
+ {0xF1, 0x32},
+ {0xF0, 0xB3},
+ {0xF0, 0x33},
+ {0xF1, 0x34},
+ {0xF0, 0xB4},
+ {0xF0, 0x34},
+ {0xF1, 0x34},
+ {0xF0, 0xB5},
+ {0xF0, 0x35},
+ {0xF1, 0x36},
+ {0xF0, 0xB6},
+ {0xF0, 0x36},
+ {0xF1, 0x36},
+ {0xF0, 0xB7},
+ {0xF0, 0x37},
+ {0xF1, 0x38},
+ {0xF0, 0xB8},
+ {0xF0, 0x38},
+ {0xF1, 0x38},
+ {0xF0, 0xB9},
+ {0xF0, 0x39},
+ {0xF1, 0x3A},
+ {0xF0, 0xBA},
+ {0xF0, 0x3A},
+ {0xF1, 0x3A},
+ {0xF0, 0xBB},
+ {0xF0, 0x3B},
+ {0xF1, 0x3C},
+ {0xF0, 0xBC},
+ {0xF0, 0x3C},
+ {0xF1, 0x3C},
+ {0xF0, 0xBD},
+ {0xF0, 0x3D},
+ {0xF1, 0x3E},
+ {0xF0, 0xBE},
+ {0xF0, 0x3E},
+ {0xF1, 0x3E},
+ {0xF0, 0xBF},
+ {0xF0, 0x00},
+};
+
+static const unsigned short awc_frame_time[MAX_RATE] = {
+ 10, 20, 55, 110, 24, 36, 48, 72, 96, 144, 192, 216
+};
+
+/*--------------------- Export Variables --------------------------*/
+/*
+ * Description: Calculate data frame transmitting time
+ *
+ * Parameters:
+ * In:
+ * preamble_type - Preamble Type
+ * by_pkt_type - PK_TYPE_11A, PK_TYPE_11B, PK_TYPE_11GB, PK_TYPE_11GA
+ * cb_frame_length - Baseband Type
+ * tx_rate - Tx Rate
+ * Out:
+ *
+ * Return Value: FrameTime
+ *
+ */
+unsigned int bb_get_frame_time(unsigned char preamble_type,
+ unsigned char by_pkt_type,
+ unsigned int cb_frame_length,
+ unsigned short tx_rate)
+{
+ unsigned int frame_time;
+ unsigned int preamble;
+ unsigned int tmp;
+ unsigned int rate_idx = (unsigned int)tx_rate;
+ unsigned int rate = 0;
+
+ if (rate_idx > RATE_54M)
+ return 0;
+
+ rate = (unsigned int)awc_frame_time[rate_idx];
+
+ if (rate_idx <= 3) { /* CCK mode */
+ if (preamble_type == PREAMBLE_SHORT)
+ preamble = 96;
+ else
+ preamble = 192;
+ frame_time = (cb_frame_length * 80) / rate; /* ????? */
+ tmp = (frame_time * rate) / 80;
+ if (cb_frame_length != tmp)
+ frame_time++;
+
+ return preamble + frame_time;
+ }
+ frame_time = (cb_frame_length * 8 + 22) / rate; /* ???????? */
+ tmp = ((frame_time * rate) - 22) / 8;
+ if (cb_frame_length != tmp)
+ frame_time++;
+
+ frame_time = frame_time * 4; /* ??????? */
+ if (by_pkt_type != PK_TYPE_11A)
+ frame_time += 6; /* ?????? */
+
+ return 20 + frame_time; /* ?????? */
+}
+
+/*
+ * Description: Calculate Length, Service, and Signal fields of Phy for Tx
+ *
+ * Parameters:
+ * In:
+ * priv - Device Structure
+ * frame_length - Tx Frame Length
+ * tx_rate - Tx Rate
+ * Out:
+ * struct vnt_phy_field *phy
+ * - pointer to Phy Length field
+ * - pointer to Phy Service field
+ * - pointer to Phy Signal field
+ *
+ * Return Value: none
+ *
+ */
+void vnt_get_phy_field(struct vnt_private *priv, u32 frame_length,
+ u16 tx_rate, u8 pkt_type, struct vnt_phy_field *phy)
+{
+ u32 bit_count;
+ u32 count = 0;
+ u32 tmp;
+ int ext_bit;
+ u8 preamble_type = priv->preamble_type;
+
+ bit_count = frame_length * 8;
+ ext_bit = false;
+
+ switch (tx_rate) {
+ case RATE_1M:
+ count = bit_count;
+
+ phy->signal = 0x00;
+
+ break;
+ case RATE_2M:
+ count = bit_count / 2;
+
+ if (preamble_type == PREAMBLE_SHORT)
+ phy->signal = 0x09;
+ else
+ phy->signal = 0x01;
+
+ break;
+ case RATE_5M:
+ count = (bit_count * 10) / 55;
+ tmp = (count * 55) / 10;
+
+ if (tmp != bit_count)
+ count++;
+
+ if (preamble_type == PREAMBLE_SHORT)
+ phy->signal = 0x0a;
+ else
+ phy->signal = 0x02;
+
+ break;
+ case RATE_11M:
+ count = bit_count / 11;
+ tmp = count * 11;
+
+ if (tmp != bit_count) {
+ count++;
+
+ if ((bit_count - tmp) <= 3)
+ ext_bit = true;
+ }
+
+ if (preamble_type == PREAMBLE_SHORT)
+ phy->signal = 0x0b;
+ else
+ phy->signal = 0x03;
+
+ break;
+ case RATE_6M:
+ if (pkt_type == PK_TYPE_11A)
+ phy->signal = 0x9b;
+ else
+ phy->signal = 0x8b;
+
+ break;
+ case RATE_9M:
+ if (pkt_type == PK_TYPE_11A)
+ phy->signal = 0x9f;
+ else
+ phy->signal = 0x8f;
+
+ break;
+ case RATE_12M:
+ if (pkt_type == PK_TYPE_11A)
+ phy->signal = 0x9a;
+ else
+ phy->signal = 0x8a;
+
+ break;
+ case RATE_18M:
+ if (pkt_type == PK_TYPE_11A)
+ phy->signal = 0x9e;
+ else
+ phy->signal = 0x8e;
+
+ break;
+ case RATE_24M:
+ if (pkt_type == PK_TYPE_11A)
+ phy->signal = 0x99;
+ else
+ phy->signal = 0x89;
+
+ break;
+ case RATE_36M:
+ if (pkt_type == PK_TYPE_11A)
+ phy->signal = 0x9d;
+ else
+ phy->signal = 0x8d;
+
+ break;
+ case RATE_48M:
+ if (pkt_type == PK_TYPE_11A)
+ phy->signal = 0x98;
+ else
+ phy->signal = 0x88;
+
+ break;
+ case RATE_54M:
+ if (pkt_type == PK_TYPE_11A)
+ phy->signal = 0x9c;
+ else
+ phy->signal = 0x8c;
+ break;
+ default:
+ if (pkt_type == PK_TYPE_11A)
+ phy->signal = 0x9c;
+ else
+ phy->signal = 0x8c;
+ break;
+ }
+
+ if (pkt_type == PK_TYPE_11B) {
+ phy->service = 0x00;
+ if (ext_bit)
+ phy->service |= 0x80;
+ phy->len = cpu_to_le16((u16)count);
+ } else {
+ phy->service = 0x00;
+ phy->len = cpu_to_le16((u16)frame_length);
+ }
+}
+
+/*
+ * Description: Read a byte from BASEBAND, by embedded programming
+ *
+ * Parameters:
+ * In:
+ * iobase - I/O base address
+ * by_bb_addr - address of register in Baseband
+ * Out:
+ * pby_data - data read
+ *
+ * Return Value: true if succeeded; false if failed.
+ *
+ */
+bool bb_read_embedded(struct vnt_private *priv, unsigned char by_bb_addr,
+ unsigned char *pby_data)
+{
+ void __iomem *iobase = priv->port_offset;
+ unsigned short ww;
+ unsigned char by_value;
+
+ /* BB reg offset */
+ iowrite8(by_bb_addr, iobase + MAC_REG_BBREGADR);
+
+ /* turn on REGR */
+ vt6655_mac_reg_bits_on(iobase, MAC_REG_BBREGCTL, BBREGCTL_REGR);
+ /* W_MAX_TIMEOUT is the timeout period */
+ for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+ by_value = ioread8(iobase + MAC_REG_BBREGCTL);
+ if (by_value & BBREGCTL_DONE)
+ break;
+ }
+
+ /* get BB data */
+ *pby_data = ioread8(iobase + MAC_REG_BBREGDATA);
+
+ if (ww == W_MAX_TIMEOUT) {
+ pr_debug(" DBG_PORT80(0x30)\n");
+ return false;
+ }
+ return true;
+}
+
+/*
+ * Description: Write a Byte to BASEBAND, by embedded programming
+ *
+ * Parameters:
+ * In:
+ * iobase - I/O base address
+ * by_bb_addr - address of register in Baseband
+ * by_data - data to write
+ * Out:
+ * none
+ *
+ * Return Value: true if succeeded; false if failed.
+ *
+ */
+bool bb_write_embedded(struct vnt_private *priv, unsigned char by_bb_addr,
+ unsigned char by_data)
+{
+ void __iomem *iobase = priv->port_offset;
+ unsigned short ww;
+ unsigned char by_value;
+
+ /* BB reg offset */
+ iowrite8(by_bb_addr, iobase + MAC_REG_BBREGADR);
+ /* set BB data */
+ iowrite8(by_data, iobase + MAC_REG_BBREGDATA);
+
+ /* turn on BBREGCTL_REGW */
+ vt6655_mac_reg_bits_on(iobase, MAC_REG_BBREGCTL, BBREGCTL_REGW);
+ /* W_MAX_TIMEOUT is the timeout period */
+ for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+ by_value = ioread8(iobase + MAC_REG_BBREGCTL);
+ if (by_value & BBREGCTL_DONE)
+ break;
+ }
+
+ if (ww == W_MAX_TIMEOUT) {
+ pr_debug(" DBG_PORT80(0x31)\n");
+ return false;
+ }
+ return true;
+}
+
+/*
+ * Description: VIA VT3253 Baseband chip init function
+ *
+ * Parameters:
+ * In:
+ * iobase - I/O base address
+ * byRevId - Revision ID
+ * byRFType - RF type
+ * Out:
+ * none
+ *
+ * Return Value: true if succeeded; false if failed.
+ *
+ */
+
+bool bb_vt3253_init(struct vnt_private *priv)
+{
+ bool result = true;
+ int ii;
+ void __iomem *iobase = priv->port_offset;
+ unsigned char by_rf_type = priv->byRFType;
+ unsigned char by_local_id = priv->local_id;
+
+ if (by_rf_type == RF_RFMD2959) {
+ if (by_local_id <= REV_ID_VT3253_A1) {
+ for (ii = 0; ii < CB_VT3253_INIT_FOR_RFMD; ii++)
+ result &= bb_write_embedded(priv,
+ by_vt3253_init_tab_rfmd[ii][0],
+ by_vt3253_init_tab_rfmd[ii][1]);
+
+ } else {
+ for (ii = 0; ii < CB_VT3253B0_INIT_FOR_RFMD; ii++)
+ result &= bb_write_embedded(priv,
+ vt3253b0_rfmd[ii][0],
+ vt3253b0_rfmd[ii][1]);
+
+ for (ii = 0; ii < CB_VT3253B0_AGC_FOR_RFMD2959; ii++)
+ result &= bb_write_embedded(priv,
+ byVT3253B0_AGC4_RFMD2959[ii][0],
+ byVT3253B0_AGC4_RFMD2959[ii][1]);
+
+ iowrite32(0x23, iobase + MAC_REG_ITRTMSET);
+ vt6655_mac_reg_bits_on(iobase, MAC_REG_PAPEDELAY, BIT(0));
+ }
+ priv->abyBBVGA[0] = 0x18;
+ priv->abyBBVGA[1] = 0x0A;
+ priv->abyBBVGA[2] = 0x0;
+ priv->abyBBVGA[3] = 0x0;
+ priv->dbm_threshold[0] = -70;
+ priv->dbm_threshold[1] = -50;
+ priv->dbm_threshold[2] = 0;
+ priv->dbm_threshold[3] = 0;
+ } else if ((by_rf_type == RF_AIROHA) || (by_rf_type == RF_AL2230S)) {
+ for (ii = 0; ii < CB_VT3253B0_INIT_FOR_AIROHA2230; ii++)
+ result &= bb_write_embedded(priv,
+ byVT3253B0_AIROHA2230[ii][0],
+ byVT3253B0_AIROHA2230[ii][1]);
+
+ for (ii = 0; ii < CB_VT3253B0_AGC; ii++)
+ result &= bb_write_embedded(priv,
+ byVT3253B0_AGC[ii][0], byVT3253B0_AGC[ii][1]);
+
+ priv->abyBBVGA[0] = 0x1C;
+ priv->abyBBVGA[1] = 0x10;
+ priv->abyBBVGA[2] = 0x0;
+ priv->abyBBVGA[3] = 0x0;
+ priv->dbm_threshold[0] = -70;
+ priv->dbm_threshold[1] = -48;
+ priv->dbm_threshold[2] = 0;
+ priv->dbm_threshold[3] = 0;
+ } else if (by_rf_type == RF_UW2451) {
+ for (ii = 0; ii < CB_VT3253B0_INIT_FOR_UW2451; ii++)
+ result &= bb_write_embedded(priv,
+ byVT3253B0_UW2451[ii][0],
+ byVT3253B0_UW2451[ii][1]);
+
+ for (ii = 0; ii < CB_VT3253B0_AGC; ii++)
+ result &= bb_write_embedded(priv,
+ byVT3253B0_AGC[ii][0],
+ byVT3253B0_AGC[ii][1]);
+
+ iowrite8(0x23, iobase + MAC_REG_ITRTMSET);
+ vt6655_mac_reg_bits_on(iobase, MAC_REG_PAPEDELAY, BIT(0));
+
+ priv->abyBBVGA[0] = 0x14;
+ priv->abyBBVGA[1] = 0x0A;
+ priv->abyBBVGA[2] = 0x0;
+ priv->abyBBVGA[3] = 0x0;
+ priv->dbm_threshold[0] = -60;
+ priv->dbm_threshold[1] = -50;
+ priv->dbm_threshold[2] = 0;
+ priv->dbm_threshold[3] = 0;
+ } else if (by_rf_type == RF_VT3226) {
+ for (ii = 0; ii < CB_VT3253B0_INIT_FOR_AIROHA2230; ii++)
+ result &= bb_write_embedded(priv,
+ byVT3253B0_AIROHA2230[ii][0],
+ byVT3253B0_AIROHA2230[ii][1]);
+
+ for (ii = 0; ii < CB_VT3253B0_AGC; ii++)
+ result &= bb_write_embedded(priv,
+ byVT3253B0_AGC[ii][0], byVT3253B0_AGC[ii][1]);
+
+ priv->abyBBVGA[0] = 0x1C;
+ priv->abyBBVGA[1] = 0x10;
+ priv->abyBBVGA[2] = 0x0;
+ priv->abyBBVGA[3] = 0x0;
+ priv->dbm_threshold[0] = -70;
+ priv->dbm_threshold[1] = -48;
+ priv->dbm_threshold[2] = 0;
+ priv->dbm_threshold[3] = 0;
+ /* Fix VT3226 DFC system timing issue */
+ vt6655_mac_word_reg_bits_on(iobase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_RFLEOPT);
+ /* {{ RobertYu: 20050104 */
+ } else {
+ /* No VGA Table now */
+ priv->bUpdateBBVGA = false;
+ priv->abyBBVGA[0] = 0x1C;
+ }
+
+ if (by_local_id > REV_ID_VT3253_A1) {
+ bb_write_embedded(priv, 0x04, 0x7F);
+ bb_write_embedded(priv, 0x0D, 0x01);
+ }
+
+ return result;
+}
+
+/*
+ * Description: Set ShortSlotTime mode
+ *
+ * Parameters:
+ * In:
+ * priv - Device Structure
+ * Out:
+ * none
+ *
+ * Return Value: none
+ *
+ */
+void
+bb_set_short_slot_time(struct vnt_private *priv)
+{
+ unsigned char by_bb_rx_conf = 0;
+ unsigned char by_bb_vga = 0;
+
+ bb_read_embedded(priv, 0x0A, &by_bb_rx_conf); /* CR10 */
+
+ if (priv->short_slot_time)
+ by_bb_rx_conf &= 0xDF; /* 1101 1111 */
+ else
+ by_bb_rx_conf |= 0x20; /* 0010 0000 */
+
+ /* patch for 3253B0 Baseband with Cardbus module */
+ bb_read_embedded(priv, 0xE7, &by_bb_vga);
+ if (by_bb_vga == priv->abyBBVGA[0])
+ by_bb_rx_conf |= 0x20; /* 0010 0000 */
+
+ bb_write_embedded(priv, 0x0A, by_bb_rx_conf); /* CR10 */
+}
+
+void bb_set_vga_gain_offset(struct vnt_private *priv, unsigned char by_data)
+{
+ unsigned char by_bb_rx_conf = 0;
+
+ bb_write_embedded(priv, 0xE7, by_data);
+
+ bb_read_embedded(priv, 0x0A, &by_bb_rx_conf); /* CR10 */
+ /* patch for 3253B0 Baseband with Cardbus module */
+ if (by_data == priv->abyBBVGA[0])
+ by_bb_rx_conf |= 0x20; /* 0010 0000 */
+ else if (priv->short_slot_time)
+ by_bb_rx_conf &= 0xDF; /* 1101 1111 */
+ else
+ by_bb_rx_conf |= 0x20; /* 0010 0000 */
+ priv->byBBVGACurrent = by_data;
+ bb_write_embedded(priv, 0x0A, by_bb_rx_conf); /* CR10 */
+}
+
+/*
+ * Description: Baseband SoftwareReset
+ *
+ * Parameters:
+ * In:
+ * iobase - I/O base address
+ * Out:
+ * none
+ *
+ * Return Value: none
+ *
+ */
+void
+bb_software_reset(struct vnt_private *priv)
+{
+ bb_write_embedded(priv, 0x50, 0x40);
+ bb_write_embedded(priv, 0x50, 0);
+ bb_write_embedded(priv, 0x9C, 0x01);
+ bb_write_embedded(priv, 0x9C, 0);
+}
+
+/*
+ * Description: Set Tx Antenna mode
+ *
+ * Parameters:
+ * In:
+ * priv - Device Structure
+ * by_antenna_mode - Antenna Mode
+ * Out:
+ * none
+ *
+ * Return Value: none
+ *
+ */
+
+void
+bb_set_tx_antenna_mode(struct vnt_private *priv, unsigned char by_antenna_mode)
+{
+ unsigned char by_bb_tx_conf;
+
+ bb_read_embedded(priv, 0x09, &by_bb_tx_conf); /* CR09 */
+ if (by_antenna_mode == ANT_DIVERSITY) {
+ /* bit 1 is diversity */
+ by_bb_tx_conf |= 0x02;
+ } else if (by_antenna_mode == ANT_A) {
+ /* bit 2 is ANTSEL */
+ by_bb_tx_conf &= 0xF9; /* 1111 1001 */
+ } else if (by_antenna_mode == ANT_B) {
+ by_bb_tx_conf &= 0xFD; /* 1111 1101 */
+ by_bb_tx_conf |= 0x04;
+ }
+ bb_write_embedded(priv, 0x09, by_bb_tx_conf); /* CR09 */
+}
+
+/*
+ * Description: Set Rx Antenna mode
+ *
+ * Parameters:
+ * In:
+ * priv - Device Structure
+ * by_antenna_mode - Antenna Mode
+ * Out:
+ * none
+ *
+ * Return Value: none
+ *
+ */
+
+void
+bb_set_rx_antenna_mode(struct vnt_private *priv, unsigned char by_antenna_mode)
+{
+ unsigned char by_bb_rx_conf;
+
+ bb_read_embedded(priv, 0x0A, &by_bb_rx_conf); /* CR10 */
+ if (by_antenna_mode == ANT_DIVERSITY) {
+ by_bb_rx_conf |= 0x01;
+
+ } else if (by_antenna_mode == ANT_A) {
+ by_bb_rx_conf &= 0xFC; /* 1111 1100 */
+ } else if (by_antenna_mode == ANT_B) {
+ by_bb_rx_conf &= 0xFE; /* 1111 1110 */
+ by_bb_rx_conf |= 0x02;
+ }
+ bb_write_embedded(priv, 0x0A, by_bb_rx_conf); /* CR10 */
+}
+
+/*
+ * Description: bb_set_deep_sleep
+ *
+ * Parameters:
+ * In:
+ * priv - Device Structure
+ * Out:
+ * none
+ *
+ * Return Value: none
+ *
+ */
+void
+bb_set_deep_sleep(struct vnt_private *priv, unsigned char by_local_id)
+{
+ bb_write_embedded(priv, 0x0C, 0x17); /* CR12 */
+ bb_write_embedded(priv, 0x0D, 0xB9); /* CR13 */
+}
+
diff --git a/drivers/staging/vt6655/baseband.h b/drivers/staging/vt6655/baseband.h
new file mode 100644
index 0000000000..e4a02c240a
--- /dev/null
+++ b/drivers/staging/vt6655/baseband.h
@@ -0,0 +1,72 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * Purpose: Implement functions to access baseband
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Jun. 5, 2002
+ *
+ */
+
+#ifndef __BASEBAND_H__
+#define __BASEBAND_H__
+
+#include "device.h"
+
+/*
+ * Registers in the BASEBAND
+ */
+#define BB_MAX_CONTEXT_SIZE 256
+
+/*
+ * Baseband RF pair definition in eeprom (Bits 6..0)
+ */
+
+#define PREAMBLE_LONG 0
+#define PREAMBLE_SHORT 1
+
+#define F5G 0
+#define F2_4G 1
+
+#define TOP_RATE_54M 0x80000000
+#define TOP_RATE_48M 0x40000000
+#define TOP_RATE_36M 0x20000000
+#define TOP_RATE_24M 0x10000000
+#define TOP_RATE_18M 0x08000000
+#define TOP_RATE_12M 0x04000000
+#define TOP_RATE_11M 0x02000000
+#define TOP_RATE_9M 0x01000000
+#define TOP_RATE_6M 0x00800000
+#define TOP_RATE_55M 0x00400000
+#define TOP_RATE_2M 0x00200000
+#define TOP_RATE_1M 0x00100000
+
+unsigned int bb_get_frame_time(unsigned char preamble_type,
+ unsigned char by_pkt_type,
+ unsigned int cb_frame_length,
+ unsigned short w_rate);
+
+void vnt_get_phy_field(struct vnt_private *priv, u32 frame_length,
+ u16 tx_rate, u8 pkt_type, struct vnt_phy_field *phy);
+
+bool bb_read_embedded(struct vnt_private *priv, unsigned char by_bb_addr,
+ unsigned char *pby_data);
+bool bb_write_embedded(struct vnt_private *priv, unsigned char by_bb_addr,
+ unsigned char by_data);
+
+void bb_set_short_slot_time(struct vnt_private *priv);
+void bb_set_vga_gain_offset(struct vnt_private *priv, unsigned char by_data);
+
+/* VT3253 Baseband */
+bool bb_vt3253_init(struct vnt_private *priv);
+void bb_software_reset(struct vnt_private *priv);
+void bb_set_tx_antenna_mode(struct vnt_private *priv,
+ unsigned char by_antenna_mode);
+void bb_set_rx_antenna_mode(struct vnt_private *priv,
+ unsigned char by_antenna_mode);
+void bb_set_deep_sleep(struct vnt_private *priv, unsigned char by_local_id);
+
+#endif /* __BASEBAND_H__ */
diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c
new file mode 100644
index 0000000000..c680925b9c
--- /dev/null
+++ b/drivers/staging/vt6655/card.c
@@ -0,0 +1,836 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * Purpose: Provide functions to setup NIC operation mode
+ * Functions:
+ * s_vSafeResetTx - Rest Tx
+ * CARDvSetRSPINF - Set RSPINF
+ * CARDvUpdateBasicTopRate - Update BasicTopRate
+ * CARDbAddBasicRate - Add to BasicRateSet
+ * CARDbIsOFDMinBasicRate - Check if any OFDM rate is in BasicRateSet
+ * CARDqGetTSFOffset - Calculate TSFOffset
+ * vt6655_get_current_tsf - Read Current NIC TSF counter
+ * CARDqGetNextTBTT - Calculate Next Beacon TSF counter
+ * CARDvSetFirstNextTBTT - Set NIC Beacon time
+ * CARDvUpdateNextTBTT - Sync. NIC Beacon time
+ * CARDbRadioPowerOff - Turn Off NIC Radio Power
+ *
+ * Revision History:
+ * 06-10-2003 Bryan YC Fan: Re-write codes to support VT3253 spec.
+ * 08-26-2003 Kyle Hsu: Modify the definition type of iobase.
+ * 09-01-2003 Bryan YC Fan: Add vUpdateIFS().
+ *
+ */
+
+#include "card.h"
+#include "baseband.h"
+#include "mac.h"
+#include "desc.h"
+#include "rf.h"
+#include "power.h"
+
+/*--------------------- Static Definitions -------------------------*/
+
+#define C_SIFS_A 16 /* micro sec. */
+#define C_SIFS_BG 10
+
+#define C_EIFS 80 /* micro sec. */
+
+#define C_SLOT_SHORT 9 /* micro sec. */
+#define C_SLOT_LONG 20
+
+#define C_CWMIN_A 15 /* slot time */
+#define C_CWMIN_B 31
+
+#define C_CWMAX 1023 /* slot time */
+
+#define WAIT_BEACON_TX_DOWN_TMO 3 /* Times */
+
+/*--------------------- Static Variables --------------------------*/
+
+static const unsigned short cwRXBCNTSFOff[MAX_RATE] = {
+ 17, 17, 17, 17, 34, 23, 17, 11, 8, 5, 4, 3};
+
+/*--------------------- Static Functions --------------------------*/
+
+static void vt6655_mac_set_bb_type(void __iomem *iobase, u32 mask)
+{
+ u32 reg_value;
+
+ reg_value = ioread32(iobase + MAC_REG_ENCFG);
+ reg_value = reg_value & ~ENCFG_BBTYPE_MASK;
+ reg_value = reg_value | mask;
+ iowrite32(reg_value, iobase + MAC_REG_ENCFG);
+}
+
+/*--------------------- Export Functions --------------------------*/
+
+/*
+ * Description: Calculate TxRate and RsvTime fields for RSPINF in OFDM mode.
+ *
+ * Parameters:
+ * In:
+ * wRate - Tx Rate
+ * byPktType - Tx Packet type
+ * Out:
+ * pbyTxRate - pointer to RSPINF TxRate field
+ * pbyRsvTime - pointer to RSPINF RsvTime field
+ *
+ * Return Value: none
+ */
+static void s_vCalculateOFDMRParameter(unsigned char rate,
+ u8 bb_type,
+ unsigned char *pbyTxRate,
+ unsigned char *pbyRsvTime)
+{
+ switch (rate) {
+ case RATE_6M:
+ if (bb_type == BB_TYPE_11A) { /* 5GHZ */
+ *pbyTxRate = 0x9B;
+ *pbyRsvTime = 44;
+ } else {
+ *pbyTxRate = 0x8B;
+ *pbyRsvTime = 50;
+ }
+ break;
+
+ case RATE_9M:
+ if (bb_type == BB_TYPE_11A) { /* 5GHZ */
+ *pbyTxRate = 0x9F;
+ *pbyRsvTime = 36;
+ } else {
+ *pbyTxRate = 0x8F;
+ *pbyRsvTime = 42;
+ }
+ break;
+
+ case RATE_12M:
+ if (bb_type == BB_TYPE_11A) { /* 5GHZ */
+ *pbyTxRate = 0x9A;
+ *pbyRsvTime = 32;
+ } else {
+ *pbyTxRate = 0x8A;
+ *pbyRsvTime = 38;
+ }
+ break;
+
+ case RATE_18M:
+ if (bb_type == BB_TYPE_11A) { /* 5GHZ */
+ *pbyTxRate = 0x9E;
+ *pbyRsvTime = 28;
+ } else {
+ *pbyTxRate = 0x8E;
+ *pbyRsvTime = 34;
+ }
+ break;
+
+ case RATE_36M:
+ if (bb_type == BB_TYPE_11A) { /* 5GHZ */
+ *pbyTxRate = 0x9D;
+ *pbyRsvTime = 24;
+ } else {
+ *pbyTxRate = 0x8D;
+ *pbyRsvTime = 30;
+ }
+ break;
+
+ case RATE_48M:
+ if (bb_type == BB_TYPE_11A) { /* 5GHZ */
+ *pbyTxRate = 0x98;
+ *pbyRsvTime = 24;
+ } else {
+ *pbyTxRate = 0x88;
+ *pbyRsvTime = 30;
+ }
+ break;
+
+ case RATE_54M:
+ if (bb_type == BB_TYPE_11A) { /* 5GHZ */
+ *pbyTxRate = 0x9C;
+ *pbyRsvTime = 24;
+ } else {
+ *pbyTxRate = 0x8C;
+ *pbyRsvTime = 30;
+ }
+ break;
+
+ case RATE_24M:
+ default:
+ if (bb_type == BB_TYPE_11A) { /* 5GHZ */
+ *pbyTxRate = 0x99;
+ *pbyRsvTime = 28;
+ } else {
+ *pbyTxRate = 0x89;
+ *pbyRsvTime = 34;
+ }
+ break;
+ }
+}
+
+/*--------------------- Export Functions --------------------------*/
+
+/*
+ * Description: Update IFS
+ *
+ * Parameters:
+ * In:
+ * priv - The adapter to be set
+ * Out:
+ * none
+ *
+ * Return Value: None.
+ */
+bool CARDbSetPhyParameter(struct vnt_private *priv, u8 bb_type)
+{
+ unsigned char byCWMaxMin = 0;
+ unsigned char bySlot = 0;
+ unsigned char bySIFS = 0;
+ unsigned char byDIFS = 0;
+ int i;
+
+ /* Set SIFS, DIFS, EIFS, SlotTime, CwMin */
+ if (bb_type == BB_TYPE_11A) {
+ vt6655_mac_set_bb_type(priv->port_offset, BB_TYPE_11A);
+ bb_write_embedded(priv, 0x88, 0x03);
+ bySlot = C_SLOT_SHORT;
+ bySIFS = C_SIFS_A;
+ byDIFS = C_SIFS_A + 2 * C_SLOT_SHORT;
+ byCWMaxMin = 0xA4;
+ } else if (bb_type == BB_TYPE_11B) {
+ vt6655_mac_set_bb_type(priv->port_offset, BB_TYPE_11B);
+ bb_write_embedded(priv, 0x88, 0x02);
+ bySlot = C_SLOT_LONG;
+ bySIFS = C_SIFS_BG;
+ byDIFS = C_SIFS_BG + 2 * C_SLOT_LONG;
+ byCWMaxMin = 0xA5;
+ } else { /* PK_TYPE_11GA & PK_TYPE_11GB */
+ vt6655_mac_set_bb_type(priv->port_offset, BB_TYPE_11G);
+ bb_write_embedded(priv, 0x88, 0x08);
+ bySIFS = C_SIFS_BG;
+
+ if (priv->short_slot_time) {
+ bySlot = C_SLOT_SHORT;
+ byDIFS = C_SIFS_BG + 2 * C_SLOT_SHORT;
+ } else {
+ bySlot = C_SLOT_LONG;
+ byDIFS = C_SIFS_BG + 2 * C_SLOT_LONG;
+ }
+
+ byCWMaxMin = 0xa4;
+
+ for (i = RATE_54M; i >= RATE_6M; i--) {
+ if (priv->basic_rates & ((u32)(0x1 << i))) {
+ byCWMaxMin |= 0x1;
+ break;
+ }
+ }
+ }
+
+ if (priv->byRFType == RF_RFMD2959) {
+ /*
+ * bcs TX_PE will reserve 3 us hardware's processing
+ * time here is 2 us.
+ */
+ bySIFS -= 3;
+ byDIFS -= 3;
+ /*
+ * TX_PE will reserve 3 us for MAX2829 A mode only, it is for
+ * better TX throughput; MAC will need 2 us to process, so the
+ * SIFS, DIFS can be shorter by 2 us.
+ */
+ }
+
+ if (priv->bySIFS != bySIFS) {
+ priv->bySIFS = bySIFS;
+ iowrite8(priv->bySIFS, priv->port_offset + MAC_REG_SIFS);
+ }
+ if (priv->byDIFS != byDIFS) {
+ priv->byDIFS = byDIFS;
+ iowrite8(priv->byDIFS, priv->port_offset + MAC_REG_DIFS);
+ }
+ if (priv->byEIFS != C_EIFS) {
+ priv->byEIFS = C_EIFS;
+ iowrite8(priv->byEIFS, priv->port_offset + MAC_REG_EIFS);
+ }
+ if (priv->bySlot != bySlot) {
+ priv->bySlot = bySlot;
+ iowrite8(priv->bySlot, priv->port_offset + MAC_REG_SLOT);
+
+ bb_set_short_slot_time(priv);
+ }
+ if (priv->byCWMaxMin != byCWMaxMin) {
+ priv->byCWMaxMin = byCWMaxMin;
+ iowrite8(priv->byCWMaxMin, priv->port_offset + MAC_REG_CWMAXMIN0);
+ }
+
+ priv->byPacketType = CARDbyGetPktType(priv);
+
+ CARDvSetRSPINF(priv, bb_type);
+
+ return true;
+}
+
+/*
+ * Description: Sync. TSF counter to BSS
+ * Get TSF offset and write to HW
+ *
+ * Parameters:
+ * In:
+ * priv - The adapter to be sync.
+ * byRxRate - data rate of receive beacon
+ * qwBSSTimestamp - Rx BCN's TSF
+ * qwLocalTSF - Local TSF
+ * Out:
+ * none
+ *
+ * Return Value: none
+ */
+bool CARDbUpdateTSF(struct vnt_private *priv, unsigned char byRxRate,
+ u64 qwBSSTimestamp)
+{
+ u64 local_tsf;
+ u64 qwTSFOffset = 0;
+
+ local_tsf = vt6655_get_current_tsf(priv);
+
+ if (qwBSSTimestamp != local_tsf) {
+ qwTSFOffset = CARDqGetTSFOffset(byRxRate, qwBSSTimestamp,
+ local_tsf);
+ /* adjust TSF, HW's TSF add TSF Offset reg */
+ qwTSFOffset = le64_to_cpu(qwTSFOffset);
+ iowrite32((u32)qwTSFOffset, priv->port_offset + MAC_REG_TSFOFST);
+ iowrite32((u32)(qwTSFOffset >> 32), priv->port_offset + MAC_REG_TSFOFST + 4);
+ vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_TFTCTL, TFTCTL_TSFSYNCEN);
+ }
+ return true;
+}
+
+/*
+ * Description: Set NIC TSF counter for first Beacon time
+ * Get NEXTTBTT from adjusted TSF and Beacon Interval
+ *
+ * Parameters:
+ * In:
+ * priv - The adapter to be set.
+ * wBeaconInterval - Beacon Interval
+ * Out:
+ * none
+ *
+ * Return Value: true if succeed; otherwise false
+ */
+bool CARDbSetBeaconPeriod(struct vnt_private *priv,
+ unsigned short wBeaconInterval)
+{
+ u64 qwNextTBTT;
+
+ qwNextTBTT = vt6655_get_current_tsf(priv); /* Get Local TSF counter */
+
+ qwNextTBTT = CARDqGetNextTBTT(qwNextTBTT, wBeaconInterval);
+
+ /* set HW beacon interval */
+ iowrite16(wBeaconInterval, priv->port_offset + MAC_REG_BI);
+ priv->wBeaconInterval = wBeaconInterval;
+ /* Set NextTBTT */
+ qwNextTBTT = le64_to_cpu(qwNextTBTT);
+ iowrite32((u32)qwNextTBTT, priv->port_offset + MAC_REG_NEXTTBTT);
+ iowrite32((u32)(qwNextTBTT >> 32), priv->port_offset + MAC_REG_NEXTTBTT + 4);
+ vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN);
+
+ return true;
+}
+
+/*
+ * Description: Turn off Radio power
+ *
+ * Parameters:
+ * In:
+ * priv - The adapter to be turned off
+ * Out:
+ * none
+ *
+ */
+void CARDbRadioPowerOff(struct vnt_private *priv)
+{
+ if (priv->radio_off)
+ return;
+
+ switch (priv->byRFType) {
+ case RF_RFMD2959:
+ vt6655_mac_word_reg_bits_off(priv->port_offset, MAC_REG_SOFTPWRCTL,
+ SOFTPWRCTL_TXPEINV);
+ vt6655_mac_word_reg_bits_on(priv->port_offset, MAC_REG_SOFTPWRCTL,
+ SOFTPWRCTL_SWPE1);
+ break;
+
+ case RF_AIROHA:
+ case RF_AL2230S:
+ vt6655_mac_word_reg_bits_off(priv->port_offset, MAC_REG_SOFTPWRCTL,
+ SOFTPWRCTL_SWPE2);
+ vt6655_mac_word_reg_bits_off(priv->port_offset, MAC_REG_SOFTPWRCTL,
+ SOFTPWRCTL_SWPE3);
+ break;
+ }
+
+ vt6655_mac_reg_bits_off(priv->port_offset, MAC_REG_HOSTCR, HOSTCR_RXON);
+
+ bb_set_deep_sleep(priv, priv->local_id);
+
+ priv->radio_off = true;
+ pr_debug("chester power off\n");
+ vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_GPIOCTL0, LED_ACTSET); /* LED issue */
+}
+
+void CARDvSafeResetTx(struct vnt_private *priv)
+{
+ unsigned int uu;
+ struct vnt_tx_desc *pCurrTD;
+
+ /* initialize TD index */
+ priv->apTailTD[0] = &priv->apTD0Rings[0];
+ priv->apCurrTD[0] = &priv->apTD0Rings[0];
+
+ priv->apTailTD[1] = &priv->apTD1Rings[0];
+ priv->apCurrTD[1] = &priv->apTD1Rings[0];
+
+ for (uu = 0; uu < TYPE_MAXTD; uu++)
+ priv->iTDUsed[uu] = 0;
+
+ for (uu = 0; uu < priv->opts.tx_descs[0]; uu++) {
+ pCurrTD = &priv->apTD0Rings[uu];
+ pCurrTD->td0.owner = OWNED_BY_HOST;
+ /* init all Tx Packet pointer to NULL */
+ }
+ for (uu = 0; uu < priv->opts.tx_descs[1]; uu++) {
+ pCurrTD = &priv->apTD1Rings[uu];
+ pCurrTD->td0.owner = OWNED_BY_HOST;
+ /* init all Tx Packet pointer to NULL */
+ }
+
+ /* set MAC TD pointer */
+ vt6655_mac_set_curr_tx_desc_addr(TYPE_TXDMA0, priv, priv->td0_pool_dma);
+
+ vt6655_mac_set_curr_tx_desc_addr(TYPE_AC0DMA, priv, priv->td1_pool_dma);
+
+ /* set MAC Beacon TX pointer */
+ iowrite32((u32)priv->tx_beacon_dma, priv->port_offset + MAC_REG_BCNDMAPTR);
+}
+
+/*
+ * Description:
+ * Reset Rx
+ *
+ * Parameters:
+ * In:
+ * priv - Pointer to the adapter
+ * Out:
+ * none
+ *
+ * Return Value: none
+ */
+void CARDvSafeResetRx(struct vnt_private *priv)
+{
+ unsigned int uu;
+ struct vnt_rx_desc *pDesc;
+
+ /* initialize RD index */
+ priv->pCurrRD[0] = &priv->aRD0Ring[0];
+ priv->pCurrRD[1] = &priv->aRD1Ring[0];
+
+ /* init state, all RD is chip's */
+ for (uu = 0; uu < priv->opts.rx_descs0; uu++) {
+ pDesc = &priv->aRD0Ring[uu];
+ pDesc->rd0.res_count = cpu_to_le16(priv->rx_buf_sz);
+ pDesc->rd0.owner = OWNED_BY_NIC;
+ pDesc->rd1.req_count = cpu_to_le16(priv->rx_buf_sz);
+ }
+
+ /* init state, all RD is chip's */
+ for (uu = 0; uu < priv->opts.rx_descs1; uu++) {
+ pDesc = &priv->aRD1Ring[uu];
+ pDesc->rd0.res_count = cpu_to_le16(priv->rx_buf_sz);
+ pDesc->rd0.owner = OWNED_BY_NIC;
+ pDesc->rd1.req_count = cpu_to_le16(priv->rx_buf_sz);
+ }
+
+ /* set perPkt mode */
+ iowrite32(RX_PERPKT, priv->port_offset + MAC_REG_RXDMACTL0);
+ iowrite32(RX_PERPKT, priv->port_offset + MAC_REG_RXDMACTL1);
+ /* set MAC RD pointer */
+ vt6655_mac_set_curr_rx_0_desc_addr(priv, priv->rd0_pool_dma);
+
+ vt6655_mac_set_curr_rx_1_desc_addr(priv, priv->rd1_pool_dma);
+}
+
+/*
+ * Description: Get response Control frame rate in CCK mode
+ *
+ * Parameters:
+ * In:
+ * priv - The adapter to be set
+ * wRateIdx - Receiving data rate
+ * Out:
+ * none
+ *
+ * Return Value: response Control frame rate
+ */
+static unsigned short CARDwGetCCKControlRate(struct vnt_private *priv,
+ unsigned short wRateIdx)
+{
+ unsigned int ui = (unsigned int)wRateIdx;
+
+ while (ui > RATE_1M) {
+ if (priv->basic_rates & ((u32)0x1 << ui))
+ return (unsigned short)ui;
+
+ ui--;
+ }
+ return (unsigned short)RATE_1M;
+}
+
+/*
+ * Description: Get response Control frame rate in OFDM mode
+ *
+ * Parameters:
+ * In:
+ * priv - The adapter to be set
+ * wRateIdx - Receiving data rate
+ * Out:
+ * none
+ *
+ * Return Value: response Control frame rate
+ */
+static unsigned short CARDwGetOFDMControlRate(struct vnt_private *priv,
+ unsigned short wRateIdx)
+{
+ unsigned int ui = (unsigned int)wRateIdx;
+
+ pr_debug("BASIC RATE: %X\n", priv->basic_rates);
+
+ if (!CARDbIsOFDMinBasicRate((void *)priv)) {
+ pr_debug("%s:(NO OFDM) %d\n", __func__, wRateIdx);
+ if (wRateIdx > RATE_24M)
+ wRateIdx = RATE_24M;
+ return wRateIdx;
+ }
+ while (ui > RATE_11M) {
+ if (priv->basic_rates & ((u32)0x1 << ui)) {
+ pr_debug("%s : %d\n", __func__, ui);
+ return (unsigned short)ui;
+ }
+ ui--;
+ }
+ pr_debug("%s: 6M\n", __func__);
+ return (unsigned short)RATE_24M;
+}
+
+/*
+ * Description: Set RSPINF
+ *
+ * Parameters:
+ * In:
+ * priv - The adapter to be set
+ * Out:
+ * none
+ *
+ * Return Value: None.
+ */
+void CARDvSetRSPINF(struct vnt_private *priv, u8 bb_type)
+{
+ union vnt_phy_field_swap phy;
+ unsigned char byTxRate, byRsvTime; /* For OFDM */
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ /* Set to Page1 */
+ VT6655_MAC_SELECT_PAGE1(priv->port_offset);
+
+ /* RSPINF_b_1 */
+ vnt_get_phy_field(priv, 14,
+ CARDwGetCCKControlRate(priv, RATE_1M),
+ PK_TYPE_11B, &phy.field_read);
+
+ /* swap over to get correct write order */
+ swap(phy.swap[0], phy.swap[1]);
+
+ iowrite32(phy.field_write, priv->port_offset + MAC_REG_RSPINF_B_1);
+
+ /* RSPINF_b_2 */
+ vnt_get_phy_field(priv, 14,
+ CARDwGetCCKControlRate(priv, RATE_2M),
+ PK_TYPE_11B, &phy.field_read);
+
+ swap(phy.swap[0], phy.swap[1]);
+
+ iowrite32(phy.field_write, priv->port_offset + MAC_REG_RSPINF_B_2);
+
+ /* RSPINF_b_5 */
+ vnt_get_phy_field(priv, 14,
+ CARDwGetCCKControlRate(priv, RATE_5M),
+ PK_TYPE_11B, &phy.field_read);
+
+ swap(phy.swap[0], phy.swap[1]);
+
+ iowrite32(phy.field_write, priv->port_offset + MAC_REG_RSPINF_B_5);
+
+ /* RSPINF_b_11 */
+ vnt_get_phy_field(priv, 14,
+ CARDwGetCCKControlRate(priv, RATE_11M),
+ PK_TYPE_11B, &phy.field_read);
+
+ swap(phy.swap[0], phy.swap[1]);
+
+ iowrite32(phy.field_write, priv->port_offset + MAC_REG_RSPINF_B_11);
+
+ /* RSPINF_a_6 */
+ s_vCalculateOFDMRParameter(RATE_6M,
+ bb_type,
+ &byTxRate,
+ &byRsvTime);
+ iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_6);
+ /* RSPINF_a_9 */
+ s_vCalculateOFDMRParameter(RATE_9M,
+ bb_type,
+ &byTxRate,
+ &byRsvTime);
+ iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_9);
+ /* RSPINF_a_12 */
+ s_vCalculateOFDMRParameter(RATE_12M,
+ bb_type,
+ &byTxRate,
+ &byRsvTime);
+ iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_12);
+ /* RSPINF_a_18 */
+ s_vCalculateOFDMRParameter(RATE_18M,
+ bb_type,
+ &byTxRate,
+ &byRsvTime);
+ iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_18);
+ /* RSPINF_a_24 */
+ s_vCalculateOFDMRParameter(RATE_24M,
+ bb_type,
+ &byTxRate,
+ &byRsvTime);
+ iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_24);
+ /* RSPINF_a_36 */
+ s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)priv,
+ RATE_36M),
+ bb_type,
+ &byTxRate,
+ &byRsvTime);
+ iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_36);
+ /* RSPINF_a_48 */
+ s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)priv,
+ RATE_48M),
+ bb_type,
+ &byTxRate,
+ &byRsvTime);
+ iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_48);
+ /* RSPINF_a_54 */
+ s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)priv,
+ RATE_54M),
+ bb_type,
+ &byTxRate,
+ &byRsvTime);
+ iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_54);
+ /* RSPINF_a_72 */
+ s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)priv,
+ RATE_54M),
+ bb_type,
+ &byTxRate,
+ &byRsvTime);
+ iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_72);
+ /* Set to Page0 */
+ VT6655_MAC_SELECT_PAGE0(priv->port_offset);
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+void CARDvUpdateBasicTopRate(struct vnt_private *priv)
+{
+ unsigned char byTopOFDM = RATE_24M, byTopCCK = RATE_1M;
+ unsigned char ii;
+
+ /* Determines the highest basic rate. */
+ for (ii = RATE_54M; ii >= RATE_6M; ii--) {
+ if ((priv->basic_rates) & ((u32)(1 << ii))) {
+ byTopOFDM = ii;
+ break;
+ }
+ }
+ priv->byTopOFDMBasicRate = byTopOFDM;
+
+ for (ii = RATE_11M;; ii--) {
+ if ((priv->basic_rates) & ((u32)(1 << ii))) {
+ byTopCCK = ii;
+ break;
+ }
+ if (ii == RATE_1M)
+ break;
+ }
+ priv->byTopCCKBasicRate = byTopCCK;
+}
+
+bool CARDbIsOFDMinBasicRate(struct vnt_private *priv)
+{
+ int ii;
+
+ for (ii = RATE_54M; ii >= RATE_6M; ii--) {
+ if ((priv->basic_rates) & ((u32)BIT(ii)))
+ return true;
+ }
+ return false;
+}
+
+unsigned char CARDbyGetPktType(struct vnt_private *priv)
+{
+ if (priv->byBBType == BB_TYPE_11A || priv->byBBType == BB_TYPE_11B)
+ return (unsigned char)priv->byBBType;
+ else if (CARDbIsOFDMinBasicRate((void *)priv))
+ return PK_TYPE_11GA;
+ else
+ return PK_TYPE_11GB;
+}
+
+/*
+ * Description: Calculate TSF offset of two TSF input
+ * Get TSF Offset from RxBCN's TSF and local TSF
+ *
+ * Parameters:
+ * In:
+ * priv - The adapter to be sync.
+ * qwTSF1 - Rx BCN's TSF
+ * qwTSF2 - Local TSF
+ * Out:
+ * none
+ *
+ * Return Value: TSF Offset value
+ */
+u64 CARDqGetTSFOffset(unsigned char byRxRate, u64 qwTSF1, u64 qwTSF2)
+{
+ unsigned short wRxBcnTSFOffst;
+
+ wRxBcnTSFOffst = cwRXBCNTSFOff[byRxRate % MAX_RATE];
+
+ qwTSF2 += (u64)wRxBcnTSFOffst;
+
+ return qwTSF1 - qwTSF2;
+}
+
+/*
+ * Description: Read NIC TSF counter
+ * Get local TSF counter
+ *
+ * Parameters:
+ * In:
+ * priv - The adapter to be read
+ * Out:
+ * none
+ *
+ * Return Value: Current TSF counter
+ */
+u64 vt6655_get_current_tsf(struct vnt_private *priv)
+{
+ void __iomem *iobase = priv->port_offset;
+ unsigned short ww;
+ unsigned char data;
+ u32 low, high;
+
+ vt6655_mac_reg_bits_on(iobase, MAC_REG_TFTCTL, TFTCTL_TSFCNTRRD);
+ for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+ data = ioread8(iobase + MAC_REG_TFTCTL);
+ if (!(data & TFTCTL_TSFCNTRRD))
+ break;
+ }
+ if (ww == W_MAX_TIMEOUT)
+ return 0;
+ low = ioread32(iobase + MAC_REG_TSFCNTR);
+ high = ioread32(iobase + MAC_REG_TSFCNTR + 4);
+ return le64_to_cpu(low + ((u64)high << 32));
+}
+
+/*
+ * Description: Read NIC TSF counter
+ * Get NEXTTBTT from adjusted TSF and Beacon Interval
+ *
+ * Parameters:
+ * In:
+ * qwTSF - Current TSF counter
+ * wbeaconInterval - Beacon Interval
+ * Out:
+ * qwCurrTSF - Current TSF counter
+ *
+ * Return Value: TSF value of next Beacon
+ */
+u64 CARDqGetNextTBTT(u64 qwTSF, unsigned short wBeaconInterval)
+{
+ u32 beacon_int;
+
+ beacon_int = wBeaconInterval * 1024;
+ if (beacon_int) {
+ do_div(qwTSF, beacon_int);
+ qwTSF += 1;
+ qwTSF *= beacon_int;
+ }
+
+ return qwTSF;
+}
+
+/*
+ * Description: Set NIC TSF counter for first Beacon time
+ * Get NEXTTBTT from adjusted TSF and Beacon Interval
+ *
+ * Parameters:
+ * In:
+ * iobase - IO Base
+ * wBeaconInterval - Beacon Interval
+ * Out:
+ * none
+ *
+ * Return Value: none
+ */
+void CARDvSetFirstNextTBTT(struct vnt_private *priv,
+ unsigned short wBeaconInterval)
+{
+ void __iomem *iobase = priv->port_offset;
+ u64 qwNextTBTT;
+
+ qwNextTBTT = vt6655_get_current_tsf(priv); /* Get Local TSF counter */
+
+ qwNextTBTT = CARDqGetNextTBTT(qwNextTBTT, wBeaconInterval);
+ /* Set NextTBTT */
+ qwNextTBTT = le64_to_cpu(qwNextTBTT);
+ iowrite32((u32)qwNextTBTT, iobase + MAC_REG_NEXTTBTT);
+ iowrite32((u32)(qwNextTBTT >> 32), iobase + MAC_REG_NEXTTBTT + 4);
+ vt6655_mac_reg_bits_on(iobase, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN);
+}
+
+/*
+ * Description: Sync NIC TSF counter for Beacon time
+ * Get NEXTTBTT and write to HW
+ *
+ * Parameters:
+ * In:
+ * priv - The adapter to be set
+ * qwTSF - Current TSF counter
+ * wBeaconInterval - Beacon Interval
+ * Out:
+ * none
+ *
+ * Return Value: none
+ */
+void CARDvUpdateNextTBTT(struct vnt_private *priv, u64 qwTSF,
+ unsigned short wBeaconInterval)
+{
+ void __iomem *iobase = priv->port_offset;
+
+ qwTSF = CARDqGetNextTBTT(qwTSF, wBeaconInterval);
+ /* Set NextTBTT */
+ qwTSF = le64_to_cpu(qwTSF);
+ iowrite32((u32)qwTSF, iobase + MAC_REG_NEXTTBTT);
+ iowrite32((u32)(qwTSF >> 32), iobase + MAC_REG_NEXTTBTT + 4);
+ vt6655_mac_reg_bits_on(iobase, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN);
+ pr_debug("Card:Update Next TBTT[%8llx]\n", qwTSF);
+}
diff --git a/drivers/staging/vt6655/card.h b/drivers/staging/vt6655/card.h
new file mode 100644
index 0000000000..22dc359a65
--- /dev/null
+++ b/drivers/staging/vt6655/card.h
@@ -0,0 +1,62 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * Purpose: Provide functions to setup NIC operation mode
+ *
+ * Author: Tevin Chen
+ *
+ * Date: May 21, 1996
+ *
+ */
+
+#ifndef __CARD_H__
+#define __CARD_H__
+
+#include <linux/types.h>
+#include <linux/nl80211.h>
+
+/*
+ * Loopback mode
+ *
+ * LOBYTE is MAC LB mode, HIBYTE is MII LB mode
+ */
+#define CARD_LB_NONE MAKEWORD(MAC_LB_NONE, 0)
+/* PHY must ISO, avoid MAC loopback packet go out */
+#define CARD_LB_MAC MAKEWORD(MAC_LB_INTERNAL, 0)
+#define CARD_LB_PHY MAKEWORD(MAC_LB_EXT, 0)
+
+#define DEFAULT_MSDU_LIFETIME 512 /* ms */
+#define DEFAULT_MSDU_LIFETIME_RES_64us 8000 /* 64us */
+
+#define DEFAULT_MGN_LIFETIME 8 /* ms */
+#define DEFAULT_MGN_LIFETIME_RES_64us 125 /* 64us */
+
+#define CB_MAX_CHANNEL_24G 14
+#define CB_MAX_CHANNEL_5G 42
+#define CB_MAX_CHANNEL (CB_MAX_CHANNEL_24G + CB_MAX_CHANNEL_5G)
+
+struct vnt_private;
+
+void CARDvSetRSPINF(struct vnt_private *priv, u8 bb_type);
+void CARDvUpdateBasicTopRate(struct vnt_private *priv);
+bool CARDbIsOFDMinBasicRate(struct vnt_private *priv);
+void CARDvSetFirstNextTBTT(struct vnt_private *priv,
+ unsigned short wBeaconInterval);
+void CARDvUpdateNextTBTT(struct vnt_private *priv, u64 qwTSF,
+ unsigned short wBeaconInterval);
+u64 vt6655_get_current_tsf(struct vnt_private *priv);
+u64 CARDqGetNextTBTT(u64 qwTSF, unsigned short wBeaconInterval);
+u64 CARDqGetTSFOffset(unsigned char byRxRate, u64 qwTSF1, u64 qwTSF2);
+unsigned char CARDbyGetPktType(struct vnt_private *priv);
+void CARDvSafeResetTx(struct vnt_private *priv);
+void CARDvSafeResetRx(struct vnt_private *priv);
+void CARDbRadioPowerOff(struct vnt_private *priv);
+bool CARDbSetPhyParameter(struct vnt_private *priv, u8 bb_type);
+bool CARDbUpdateTSF(struct vnt_private *priv, unsigned char byRxRate,
+ u64 qwBSSTimestamp);
+bool CARDbSetBeaconPeriod(struct vnt_private *priv,
+ unsigned short wBeaconInterval);
+
+#endif /* __CARD_H__ */
diff --git a/drivers/staging/vt6655/channel.c b/drivers/staging/vt6655/channel.c
new file mode 100644
index 0000000000..4122875ebc
--- /dev/null
+++ b/drivers/staging/vt6655/channel.c
@@ -0,0 +1,135 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ */
+
+#include "baseband.h"
+#include "channel.h"
+#include "device.h"
+#include "rf.h"
+
+static struct ieee80211_rate vnt_rates_bg[] = {
+ { .bitrate = 10, .hw_value = RATE_1M },
+ { .bitrate = 20, .hw_value = RATE_2M },
+ { .bitrate = 55, .hw_value = RATE_5M },
+ { .bitrate = 110, .hw_value = RATE_11M },
+ { .bitrate = 60, .hw_value = RATE_6M },
+ { .bitrate = 90, .hw_value = RATE_9M },
+ { .bitrate = 120, .hw_value = RATE_12M },
+ { .bitrate = 180, .hw_value = RATE_18M },
+ { .bitrate = 240, .hw_value = RATE_24M },
+ { .bitrate = 360, .hw_value = RATE_36M },
+ { .bitrate = 480, .hw_value = RATE_48M },
+ { .bitrate = 540, .hw_value = RATE_54M },
+};
+
+static struct ieee80211_channel vnt_channels_2ghz[] = {
+ { .center_freq = 2412, .hw_value = 1 },
+ { .center_freq = 2417, .hw_value = 2 },
+ { .center_freq = 2422, .hw_value = 3 },
+ { .center_freq = 2427, .hw_value = 4 },
+ { .center_freq = 2432, .hw_value = 5 },
+ { .center_freq = 2437, .hw_value = 6 },
+ { .center_freq = 2442, .hw_value = 7 },
+ { .center_freq = 2447, .hw_value = 8 },
+ { .center_freq = 2452, .hw_value = 9 },
+ { .center_freq = 2457, .hw_value = 10 },
+ { .center_freq = 2462, .hw_value = 11 },
+ { .center_freq = 2467, .hw_value = 12 },
+ { .center_freq = 2472, .hw_value = 13 },
+ { .center_freq = 2484, .hw_value = 14 }
+};
+
+static struct ieee80211_supported_band vnt_supported_2ghz_band = {
+ .channels = vnt_channels_2ghz,
+ .n_channels = ARRAY_SIZE(vnt_channels_2ghz),
+ .bitrates = vnt_rates_bg,
+ .n_bitrates = ARRAY_SIZE(vnt_rates_bg),
+};
+
+static void vnt_init_band(struct vnt_private *priv,
+ struct ieee80211_supported_band *supported_band,
+ enum nl80211_band band)
+{
+ int i;
+
+ for (i = 0; i < supported_band->n_channels; i++) {
+ supported_band->channels[i].max_power = 0x3f;
+ supported_band->channels[i].flags =
+ IEEE80211_CHAN_NO_HT40;
+ }
+
+ priv->hw->wiphy->bands[band] = supported_band;
+}
+
+void vnt_init_bands(struct vnt_private *priv)
+{
+ vnt_init_band(priv, &vnt_supported_2ghz_band, NL80211_BAND_2GHZ);
+}
+
+/**
+ * set_channel() - Set NIC media channel
+ *
+ * @priv: The adapter to be set
+ * @ch: Channel to be set
+ *
+ * Return Value: true if succeeded; false if failed.
+ *
+ */
+bool set_channel(struct vnt_private *priv, struct ieee80211_channel *ch)
+{
+ bool ret = true;
+
+ if (priv->byCurrentCh == ch->hw_value)
+ return ret;
+
+ /* Set VGA to max sensitivity */
+ if (priv->bUpdateBBVGA &&
+ priv->byBBVGACurrent != priv->abyBBVGA[0]) {
+ priv->byBBVGACurrent = priv->abyBBVGA[0];
+
+ bb_set_vga_gain_offset(priv, priv->byBBVGACurrent);
+ }
+
+ /* clear NAV */
+ vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_MACCR, MACCR_CLRNAV);
+
+ /* TX_PE will reserve 3 us for MAX2829 A mode only,
+ * it is for better TX throughput
+ */
+
+ priv->byCurrentCh = ch->hw_value;
+ ret &= RFbSelectChannel(priv, priv->byRFType,
+ ch->hw_value);
+
+ /* Init Synthesizer Table */
+ if (priv->bEnablePSMode)
+ rf_write_wake_prog_syn(priv, priv->byRFType, ch->hw_value);
+
+ bb_software_reset(priv);
+
+ if (priv->local_id > REV_ID_VT3253_B1) {
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ /* set HW default power register */
+ VT6655_MAC_SELECT_PAGE1(priv->port_offset);
+ RFbSetPower(priv, RATE_1M, priv->byCurrentCh);
+ iowrite8(priv->byCurPwr, priv->port_offset + MAC_REG_PWRCCK);
+ RFbSetPower(priv, RATE_6M, priv->byCurrentCh);
+ iowrite8(priv->byCurPwr, priv->port_offset + MAC_REG_PWROFDM);
+ VT6655_MAC_SELECT_PAGE0(priv->port_offset);
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+ }
+
+ if (priv->byBBType == BB_TYPE_11B)
+ RFbSetPower(priv, RATE_1M, priv->byCurrentCh);
+ else
+ RFbSetPower(priv, RATE_6M, priv->byCurrentCh);
+
+ return ret;
+}
diff --git a/drivers/staging/vt6655/channel.h b/drivers/staging/vt6655/channel.h
new file mode 100644
index 0000000000..78b2d82317
--- /dev/null
+++ b/drivers/staging/vt6655/channel.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ */
+
+#ifndef _CHANNEL_H_
+#define _CHANNEL_H_
+
+#include "card.h"
+
+void vnt_init_bands(struct vnt_private *priv);
+
+bool set_channel(struct vnt_private *priv, struct ieee80211_channel *ch);
+
+#endif /* _CHANNEL_H_ */
diff --git a/drivers/staging/vt6655/desc.h b/drivers/staging/vt6655/desc.h
new file mode 100644
index 0000000000..17a40c53b8
--- /dev/null
+++ b/drivers/staging/vt6655/desc.h
@@ -0,0 +1,249 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * Purpose:The header file of descriptor
+ *
+ * Revision History:
+ *
+ * Author: Tevin Chen
+ *
+ * Date: May 21, 1996
+ *
+ */
+
+#ifndef __DESC_H__
+#define __DESC_H__
+
+#include <linux/types.h>
+#include <linux/mm.h>
+#include "linux/ieee80211.h"
+
+#define B_OWNED_BY_CHIP 1
+#define B_OWNED_BY_HOST 0
+
+/* Bits in the RSR register */
+#define RSR_ADDRBROAD 0x80
+#define RSR_ADDRMULTI 0x40
+#define RSR_ADDRUNI 0x00
+#define RSR_IVLDTYP 0x20
+#define RSR_IVLDLEN 0x10 /* invalid len (> 2312 byte) */
+#define RSR_BSSIDOK 0x08
+#define RSR_CRCOK 0x04
+#define RSR_BCNSSIDOK 0x02
+#define RSR_ADDROK 0x01
+
+/* Bits in the new RSR register */
+#define NEWRSR_DECRYPTOK 0x10
+#define NEWRSR_CFPIND 0x08
+#define NEWRSR_HWUTSF 0x04
+#define NEWRSR_BCNHITAID 0x02
+#define NEWRSR_BCNHITAID0 0x01
+
+/* Bits in the TSR0 register */
+#define TSR0_PWRSTS1_2 0xC0
+#define TSR0_PWRSTS7 0x20
+#define TSR0_NCR 0x1F
+
+/* Bits in the TSR1 register */
+#define TSR1_TERR 0x80
+#define TSR1_PWRSTS4_6 0x70
+#define TSR1_RETRYTMO 0x08
+#define TSR1_TMO 0x04
+#define TSR1_PWRSTS3 0x02
+#define ACK_DATA 0x01
+
+/* Bits in the TCR register */
+#define EDMSDU 0x04 /* end of sdu */
+#define TCR_EDP 0x02 /* end of packet */
+#define TCR_STP 0x01 /* start of packet */
+
+/* max transmit or receive buffer size */
+#define CB_MAX_BUF_SIZE 2900U
+ /* NOTE: must be multiple of 4 */
+#define CB_MAX_TX_BUF_SIZE CB_MAX_BUF_SIZE
+#define CB_MAX_RX_BUF_SIZE_NORMAL CB_MAX_BUF_SIZE
+
+#define CB_BEACON_BUF_SIZE 512U
+
+#define CB_MAX_RX_DESC 128
+#define CB_MIN_RX_DESC 16
+#define CB_MAX_TX_DESC 64
+#define CB_MIN_TX_DESC 16
+
+#define CB_MAX_RECEIVED_PACKETS 16
+ /*
+ * limit our receive routine to indicating
+ * this many at a time for 2 reasons:
+ * 1. driver flow control to protocol layer
+ * 2. limit the time used in ISR routine
+ */
+
+#define CB_EXTRA_RD_NUM 32
+#define CB_RD_NUM 32
+#define CB_TD_NUM 32
+
+/*
+ * max number of physical segments in a single NDIS packet. Above this
+ * threshold, the packet is copied into a single physically contiguous buffer
+ */
+#define CB_MAX_SEGMENT 4
+
+#define CB_MIN_MAP_REG_NUM 4
+#define CB_MAX_MAP_REG_NUM CB_MAX_TX_DESC
+
+#define CB_PROTOCOL_RESERVED_SECTION 16
+
+/*
+ * if retrys excess 15 times , tx will abort, and if tx fifo underflow,
+ * tx will fail, we should try to resend it
+ */
+#define CB_MAX_TX_ABORT_RETRY 3
+
+/* WMAC definition FIFO Control */
+#define FIFOCTL_AUTO_FB_1 0x1000
+#define FIFOCTL_AUTO_FB_0 0x0800
+#define FIFOCTL_GRPACK 0x0400
+#define FIFOCTL_11GA 0x0300
+#define FIFOCTL_11GB 0x0200
+#define FIFOCTL_11B 0x0100
+#define FIFOCTL_11A 0x0000
+#define FIFOCTL_RTS 0x0080
+#define FIFOCTL_ISDMA0 0x0040
+#define FIFOCTL_GENINT 0x0020
+#define FIFOCTL_TMOEN 0x0010
+#define FIFOCTL_LRETRY 0x0008
+#define FIFOCTL_CRCDIS 0x0004
+#define FIFOCTL_NEEDACK 0x0002
+#define FIFOCTL_LHEAD 0x0001
+
+/* WMAC definition Frag Control */
+#define FRAGCTL_AES 0x0300
+#define FRAGCTL_TKIP 0x0200
+#define FRAGCTL_LEGACY 0x0100
+#define FRAGCTL_NONENCRYPT 0x0000
+#define FRAGCTL_ENDFRAG 0x0003
+#define FRAGCTL_MIDFRAG 0x0002
+#define FRAGCTL_STAFRAG 0x0001
+#define FRAGCTL_NONFRAG 0x0000
+
+#define TYPE_TXDMA0 0
+#define TYPE_AC0DMA 1
+#define TYPE_ATIMDMA 2
+#define TYPE_SYNCDMA 3
+#define TYPE_MAXTD 2
+
+#define TYPE_BEACONDMA 4
+
+#define TYPE_RXDMA0 0
+#define TYPE_RXDMA1 1
+#define TYPE_MAXRD 2
+
+/* TD_INFO flags control bit */
+#define TD_FLAGS_NETIF_SKB 0x01 /* check if need release skb */
+/* check if called from private skb (hostap) */
+#define TD_FLAGS_PRIV_SKB 0x02
+#define TD_FLAGS_PS_RETRY 0x04 /* check if PS STA frame re-transmit */
+
+/*
+ * ref_sk_buff is used for mapping the skb structure between pre-built
+ * driver-obj & running kernel. Since different kernel version (2.4x) may
+ * change skb structure, i.e. pre-built driver-obj may link to older skb that
+ * leads error.
+ */
+
+struct vnt_rd_info {
+ struct sk_buff *skb;
+ dma_addr_t skb_dma;
+};
+
+struct vnt_rdes0 {
+ volatile __le16 res_count;
+#ifdef __BIG_ENDIAN
+ union {
+ volatile u16 f15_reserved;
+ struct {
+ volatile u8 f8_reserved1;
+ volatile u8 owner:1;
+ volatile u8 f7_reserved:7;
+ } __packed;
+ } __packed;
+#else
+ u16 f15_reserved:15;
+ u16 owner:1;
+#endif
+} __packed;
+
+struct vnt_rdes1 {
+ __le16 req_count;
+ u16 reserved;
+} __packed;
+
+/* Rx descriptor*/
+struct vnt_rx_desc {
+ volatile struct vnt_rdes0 rd0;
+ volatile struct vnt_rdes1 rd1;
+ volatile __le32 buff_addr;
+ volatile __le32 next_desc;
+ struct vnt_rx_desc *next __aligned(8);
+ struct vnt_rd_info *rd_info __aligned(8);
+} __packed;
+
+struct vnt_tdes0 {
+ volatile u8 tsr0;
+ volatile u8 tsr1;
+#ifdef __BIG_ENDIAN
+ union {
+ volatile u16 f15_txtime;
+ struct {
+ volatile u8 f8_reserved;
+ volatile u8 owner:1;
+ volatile u8 f7_reserved:7;
+ } __packed;
+ } __packed;
+#else
+ volatile u16 f15_txtime:15;
+ volatile u16 owner:1;
+#endif
+} __packed;
+
+struct vnt_tdes1 {
+ volatile __le16 req_count;
+ volatile u8 tcr;
+ volatile u8 reserved;
+} __packed;
+
+struct vnt_td_info {
+ void *mic_hdr;
+ struct sk_buff *skb;
+ unsigned char *buf;
+ dma_addr_t buf_dma;
+ u16 req_count;
+ u8 flags;
+};
+
+/* transmit descriptor */
+struct vnt_tx_desc {
+ volatile struct vnt_tdes0 td0;
+ volatile struct vnt_tdes1 td1;
+ volatile __le32 buff_addr;
+ volatile __le32 next_desc;
+ struct vnt_tx_desc *next __aligned(8);
+ struct vnt_td_info *td_info __aligned(8);
+} __packed;
+
+/* Length, Service, and Signal fields of Phy for Tx */
+struct vnt_phy_field {
+ u8 signal;
+ u8 service;
+ __le16 len;
+} __packed;
+
+union vnt_phy_field_swap {
+ struct vnt_phy_field field_read;
+ u16 swap[2];
+ u32 field_write;
+};
+
+#endif /* __DESC_H__ */
diff --git a/drivers/staging/vt6655/device.h b/drivers/staging/vt6655/device.h
new file mode 100644
index 0000000000..c272a4ab2f
--- /dev/null
+++ b/drivers/staging/vt6655/device.h
@@ -0,0 +1,292 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * Purpose: MAC Data structure
+ *
+ * Author: Tevin Chen
+ *
+ * Date: Mar 17, 1997
+ *
+ */
+
+#ifndef __DEVICE_H__
+#define __DEVICE_H__
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/interrupt.h>
+#include <linux/crc32.h>
+#include <net/mac80211.h>
+
+/* device specific */
+
+#include "device_cfg.h"
+#include "card.h"
+#include "srom.h"
+#include "desc.h"
+#include "key.h"
+#include "mac.h"
+
+/*--------------------- Export Definitions -------------------------*/
+
+#define RATE_1M 0
+#define RATE_2M 1
+#define RATE_5M 2
+#define RATE_11M 3
+#define RATE_6M 4
+#define RATE_9M 5
+#define RATE_12M 6
+#define RATE_18M 7
+#define RATE_24M 8
+#define RATE_36M 9
+#define RATE_48M 10
+#define RATE_54M 11
+#define MAX_RATE 12
+
+#define AUTO_FB_NONE 0
+#define AUTO_FB_0 1
+#define AUTO_FB_1 2
+
+#define FB_RATE0 0
+#define FB_RATE1 1
+
+/* Antenna Mode */
+#define ANT_A 0
+#define ANT_B 1
+#define ANT_DIVERSITY 2
+#define ANT_RXD_TXA 3
+#define ANT_RXD_TXB 4
+#define ANT_UNKNOWN 0xFF
+
+#define BB_VGA_LEVEL 4
+#define BB_VGA_CHANGE_THRESHOLD 16
+
+#define MAKE_BEACON_RESERVED 10 /* (us) */
+
+/* BUILD OBJ mode */
+
+#define AVAIL_TD(p, q) ((p)->opts.tx_descs[(q)] - ((p)->iTDUsed[(q)]))
+
+/* 0:11A 1:11B 2:11G */
+#define BB_TYPE_11A 0
+#define BB_TYPE_11B 1
+#define BB_TYPE_11G 2
+
+/* 0:11a, 1:11b, 2:11gb (only CCK in BasicRate), 3:11ga (OFDM in BasicRate) */
+#define PK_TYPE_11A 0
+#define PK_TYPE_11B 1
+#define PK_TYPE_11GB 2
+#define PK_TYPE_11GA 3
+
+#define OWNED_BY_HOST 0
+#define OWNED_BY_NIC 1
+
+struct vnt_options {
+ int rx_descs0; /* Number of RX descriptors0 */
+ int rx_descs1; /* Number of RX descriptors1 */
+ int tx_descs[2]; /* Number of TX descriptors 0, 1 */
+ int int_works; /* interrupt limits */
+ int short_retry;
+ int long_retry;
+ int bbp_type;
+ u32 flags;
+};
+
+struct vnt_private {
+ struct pci_dev *pcid;
+ /* mac80211 */
+ struct ieee80211_hw *hw;
+ struct ieee80211_vif *vif;
+ unsigned long key_entry_inuse;
+ u32 basic_rates;
+ u16 current_aid;
+ int mc_list_count;
+ u8 mac_hw;
+
+/* dma addr, rx/tx pool */
+ dma_addr_t pool_dma;
+ dma_addr_t rd0_pool_dma;
+ dma_addr_t rd1_pool_dma;
+
+ dma_addr_t td0_pool_dma;
+ dma_addr_t td1_pool_dma;
+
+ dma_addr_t tx_bufs_dma0;
+ dma_addr_t tx_bufs_dma1;
+ dma_addr_t tx_beacon_dma;
+
+ unsigned char *tx0_bufs;
+ unsigned char *tx1_bufs;
+ unsigned char *tx_beacon_bufs;
+
+ void __iomem *port_offset;
+ u32 memaddr;
+ u32 ioaddr;
+
+ spinlock_t lock;
+
+ volatile int iTDUsed[TYPE_MAXTD];
+
+ struct vnt_tx_desc *apCurrTD[TYPE_MAXTD];
+ struct vnt_tx_desc *apTailTD[TYPE_MAXTD];
+
+ struct vnt_tx_desc *apTD0Rings;
+ struct vnt_tx_desc *apTD1Rings;
+
+ struct vnt_rx_desc *aRD0Ring;
+ struct vnt_rx_desc *aRD1Ring;
+ struct vnt_rx_desc *pCurrRD[TYPE_MAXRD];
+
+ struct vnt_options opts;
+
+ u32 flags;
+
+ u32 rx_buf_sz;
+ u8 rx_rate;
+
+ u32 rx_bytes;
+
+ /* Version control */
+ unsigned char local_id;
+ unsigned char byRFType;
+
+ unsigned char max_pwr_level;
+ unsigned char byZoneType;
+ bool bZoneRegExist;
+ unsigned char byOriginalZonetype;
+
+ unsigned char abyCurrentNetAddr[ETH_ALEN]; __aligned(2)
+ bool bLinkPass; /* link status: OK or fail */
+
+ unsigned int current_rssi;
+ unsigned char byCurrSQ;
+
+ unsigned long dwTxAntennaSel;
+ unsigned long dwRxAntennaSel;
+ unsigned char byAntennaCount;
+ unsigned char byRxAntennaMode;
+ unsigned char byTxAntennaMode;
+ bool bTxRxAntInv;
+
+ unsigned char *pbyTmpBuff;
+ unsigned int uSIFS; /* Current SIFS */
+ unsigned int uDIFS; /* Current DIFS */
+ unsigned int uEIFS; /* Current EIFS */
+ unsigned int uSlot; /* Current SlotTime */
+ unsigned int uCwMin; /* Current CwMin */
+ unsigned int uCwMax; /* CwMax is fixed on 1023. */
+ /* PHY parameter */
+ unsigned char bySIFS;
+ unsigned char byDIFS;
+ unsigned char byEIFS;
+ unsigned char bySlot;
+ unsigned char byCWMaxMin;
+
+ u8 byBBType; /* 0:11A, 1:11B, 2:11G */
+ u8 byPacketType; /*
+ * 0:11a,1:11b,2:11gb (only CCK
+ * in BasicRate), 3:11ga (OFDM in
+ * Basic Rate)
+ */
+ unsigned short wBasicRate;
+ unsigned char byACKRate;
+ unsigned char byTopOFDMBasicRate;
+ unsigned char byTopCCKBasicRate;
+
+ unsigned char byMinChannel;
+ unsigned char byMaxChannel;
+
+ unsigned char preamble_type;
+ unsigned char byShortPreamble;
+
+ unsigned short wCurrentRate;
+ unsigned char byShortRetryLimit;
+ unsigned char byLongRetryLimit;
+ enum nl80211_iftype op_mode;
+ bool bBSSIDFilter;
+ unsigned short wMaxTransmitMSDULifetime;
+
+ bool bEncryptionEnable;
+ bool bLongHeader;
+ bool short_slot_time;
+ bool bProtectMode;
+ bool bNonERPPresent;
+ bool bBarkerPreambleMd;
+
+ bool bRadioControlOff;
+ bool radio_off;
+ bool bEnablePSMode;
+ unsigned short wListenInterval;
+ bool bPWBitOn;
+
+ /* GPIO Radio Control */
+ unsigned char byRadioCtl;
+ unsigned char byGPIO;
+ bool hw_radio_off;
+ bool bPrvActive4RadioOFF;
+ bool bGPIOBlockRead;
+
+ /* Beacon related */
+ unsigned short wSeqCounter;
+ unsigned short wBCNBufLen;
+ bool bBeaconBufReady;
+ bool bBeaconSent;
+ bool bIsBeaconBufReadySet;
+ unsigned int cbBeaconBufReadySetCnt;
+ bool bFixRate;
+ u16 byCurrentCh;
+
+ bool bAES;
+
+ unsigned char byAutoFBCtrl;
+
+ /* For Update BaseBand VGA Gain Offset */
+ bool bUpdateBBVGA;
+ unsigned int uBBVGADiffCount;
+ unsigned char byBBVGANew;
+ unsigned char byBBVGACurrent;
+ unsigned char abyBBVGA[BB_VGA_LEVEL];
+ long dbm_threshold[BB_VGA_LEVEL];
+
+ unsigned char byBBPreEDRSSI;
+ unsigned char byBBPreEDIndex;
+
+ unsigned long dwDiagRefCount;
+
+ /* For FOE Tuning */
+ unsigned char byFOETuning;
+
+ /* For RF Power table */
+ unsigned char byCCKPwr;
+ unsigned char byOFDMPwrG;
+ unsigned char byCurPwr;
+ char byCurPwrdBm;
+ unsigned char abyCCKPwrTbl[CB_MAX_CHANNEL_24G + 1];
+ unsigned char abyOFDMPwrTbl[CB_MAX_CHANNEL + 1];
+ char abyCCKDefaultPwr[CB_MAX_CHANNEL_24G + 1];
+ char abyOFDMDefaultPwr[CB_MAX_CHANNEL + 1];
+ char abyRegPwr[CB_MAX_CHANNEL + 1];
+ char abyLocalPwr[CB_MAX_CHANNEL + 1];
+
+ /* BaseBand Loopback Use */
+ unsigned char byBBCR4d;
+ unsigned char byBBCRc9;
+ unsigned char byBBCR88;
+ unsigned char byBBCR09;
+
+ unsigned char abyEEPROM[EEP_MAX_CONTEXT_SIZE]; /* unsigned long alignment */
+
+ unsigned short wBeaconInterval;
+ u16 wake_up_count;
+
+ struct work_struct interrupt_work;
+
+ struct ieee80211_low_level_stats low_stats;
+};
+
+#endif
diff --git a/drivers/staging/vt6655/device_cfg.h b/drivers/staging/vt6655/device_cfg.h
new file mode 100644
index 0000000000..2d647a3619
--- /dev/null
+++ b/drivers/staging/vt6655/device_cfg.h
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * Purpose: Driver configuration header
+ * Author: Lyndon Chen
+ *
+ * Date: Dec 17, 2002
+ *
+ */
+
+#ifndef __DEVICE_CONFIG_H
+#define __DEVICE_CONFIG_H
+
+#include <linux/types.h>
+
+#define VID_TABLE_SIZE 64
+#define MCAST_TABLE_SIZE 64
+#define MCAM_SIZE 32
+#define VCAM_SIZE 32
+#define TX_QUEUE_NO 8
+
+#define DEVICE_NAME "vt6655"
+#define DEVICE_FULL_DRV_NAM "VIA Networking Solomon-A/B/G Wireless LAN Adapter Driver"
+
+#ifndef MAJOR_VERSION
+#define MAJOR_VERSION 1
+#endif
+
+#ifndef MINOR_VERSION
+#define MINOR_VERSION 17
+#endif
+
+#ifndef DEVICE_VERSION
+#define DEVICE_VERSION "1.19.12"
+#endif
+
+#include <linux/fs.h>
+#include <linux/fcntl.h>
+
+#define PKT_BUF_SZ 2390
+
+#endif
diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c
new file mode 100644
index 0000000000..45e5eccadb
--- /dev/null
+++ b/drivers/staging/vt6655/device_main.c
@@ -0,0 +1,1864 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * Purpose: driver entry for initial, open, close, tx and rx.
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: Jan 8, 2003
+ *
+ * Functions:
+ *
+ * vt6655_probe - module initial (insmod) driver entry
+ * vt6655_remove - module remove entry
+ * device_free_info - device structure resource free function
+ * device_print_info - print out resource
+ * device_rx_srv - rx service function
+ * device_alloc_rx_buf - rx buffer pre-allocated function
+ * device_free_rx_buf - free rx buffer function
+ * device_free_tx_buf - free tx buffer function
+ * device_init_rd0_ring - initial rd dma0 ring
+ * device_init_rd1_ring - initial rd dma1 ring
+ * device_init_td0_ring - initial tx dma0 ring buffer
+ * device_init_td1_ring - initial tx dma1 ring buffer
+ * device_init_registers - initial MAC & BBP & RF internal registers.
+ * device_init_rings - initial tx/rx ring buffer
+ * device_free_rings - free all allocated ring buffer
+ * device_tx_srv - tx interrupt service function
+ *
+ * Revision History:
+ */
+
+#include <linux/file.h>
+#include "device.h"
+#include "card.h"
+#include "channel.h"
+#include "baseband.h"
+#include "mac.h"
+#include "power.h"
+#include "rxtx.h"
+#include "dpc.h"
+#include "rf.h"
+#include <linux/delay.h>
+#include <linux/kthread.h>
+#include <linux/slab.h>
+
+/*--------------------- Static Definitions -------------------------*/
+/*
+ * Define module options
+ */
+MODULE_AUTHOR("VIA Networking Technologies, Inc., <lyndonchen@vntek.com.tw>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("VIA Networking Solomon-A/B/G Wireless LAN Adapter Driver");
+
+#define DEVICE_PARAM(N, D)
+
+#define RX_DESC_MIN0 16
+#define RX_DESC_MAX0 128
+#define RX_DESC_DEF0 32
+DEVICE_PARAM(RxDescriptors0, "Number of receive descriptors0");
+
+#define RX_DESC_MIN1 16
+#define RX_DESC_MAX1 128
+#define RX_DESC_DEF1 32
+DEVICE_PARAM(RxDescriptors1, "Number of receive descriptors1");
+
+#define TX_DESC_MIN0 16
+#define TX_DESC_MAX0 128
+#define TX_DESC_DEF0 32
+DEVICE_PARAM(TxDescriptors0, "Number of transmit descriptors0");
+
+#define TX_DESC_MIN1 16
+#define TX_DESC_MAX1 128
+#define TX_DESC_DEF1 64
+DEVICE_PARAM(TxDescriptors1, "Number of transmit descriptors1");
+
+#define INT_WORKS_DEF 20
+#define INT_WORKS_MIN 10
+#define INT_WORKS_MAX 64
+
+DEVICE_PARAM(int_works, "Number of packets per interrupt services");
+
+#define RTS_THRESH_DEF 2347
+
+#define FRAG_THRESH_DEF 2346
+
+#define SHORT_RETRY_MIN 0
+#define SHORT_RETRY_MAX 31
+#define SHORT_RETRY_DEF 8
+
+DEVICE_PARAM(ShortRetryLimit, "Short frame retry limits");
+
+#define LONG_RETRY_MIN 0
+#define LONG_RETRY_MAX 15
+#define LONG_RETRY_DEF 4
+
+DEVICE_PARAM(LongRetryLimit, "long frame retry limits");
+
+/* BasebandType[] baseband type selected
+ * 0: indicate 802.11a type
+ * 1: indicate 802.11b type
+ * 2: indicate 802.11g type
+ */
+#define BBP_TYPE_MIN 0
+#define BBP_TYPE_MAX 2
+#define BBP_TYPE_DEF 2
+
+DEVICE_PARAM(BasebandType, "baseband type");
+
+/*
+ * Static vars definitions
+ */
+static const struct pci_device_id vt6655_pci_id_table[] = {
+ { PCI_VDEVICE(VIA, 0x3253) },
+ { 0, }
+};
+
+/*--------------------- Static Functions --------------------------*/
+
+static int vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent);
+static void device_free_info(struct vnt_private *priv);
+static void device_print_info(struct vnt_private *priv);
+
+static void vt6655_mac_write_bssid_addr(void __iomem *iobase, const u8 *mac_addr);
+static void vt6655_mac_read_ether_addr(void __iomem *iobase, u8 *mac_addr);
+
+static int device_init_rd0_ring(struct vnt_private *priv);
+static int device_init_rd1_ring(struct vnt_private *priv);
+static int device_init_td0_ring(struct vnt_private *priv);
+static int device_init_td1_ring(struct vnt_private *priv);
+
+static int device_rx_srv(struct vnt_private *priv, unsigned int idx);
+static int device_tx_srv(struct vnt_private *priv, unsigned int idx);
+static bool device_alloc_rx_buf(struct vnt_private *, struct vnt_rx_desc *);
+static void device_free_rx_buf(struct vnt_private *priv,
+ struct vnt_rx_desc *rd);
+static void device_init_registers(struct vnt_private *priv);
+static void device_free_tx_buf(struct vnt_private *, struct vnt_tx_desc *);
+static void device_free_td0_ring(struct vnt_private *priv);
+static void device_free_td1_ring(struct vnt_private *priv);
+static void device_free_rd0_ring(struct vnt_private *priv);
+static void device_free_rd1_ring(struct vnt_private *priv);
+static void device_free_rings(struct vnt_private *priv);
+
+/*--------------------- Export Variables --------------------------*/
+
+/*--------------------- Export Functions --------------------------*/
+
+static void vt6655_remove(struct pci_dev *pcid)
+{
+ struct vnt_private *priv = pci_get_drvdata(pcid);
+
+ if (!priv)
+ return;
+ device_free_info(priv);
+}
+
+static void device_get_options(struct vnt_private *priv)
+{
+ struct vnt_options *opts = &priv->opts;
+
+ opts->rx_descs0 = RX_DESC_DEF0;
+ opts->rx_descs1 = RX_DESC_DEF1;
+ opts->tx_descs[0] = TX_DESC_DEF0;
+ opts->tx_descs[1] = TX_DESC_DEF1;
+ opts->int_works = INT_WORKS_DEF;
+
+ opts->short_retry = SHORT_RETRY_DEF;
+ opts->long_retry = LONG_RETRY_DEF;
+ opts->bbp_type = BBP_TYPE_DEF;
+}
+
+static void
+device_set_options(struct vnt_private *priv)
+{
+ priv->byShortRetryLimit = priv->opts.short_retry;
+ priv->byLongRetryLimit = priv->opts.long_retry;
+ priv->byBBType = priv->opts.bbp_type;
+ priv->byPacketType = priv->byBBType;
+ priv->byAutoFBCtrl = AUTO_FB_0;
+ priv->bUpdateBBVGA = true;
+ priv->preamble_type = 0;
+
+ pr_debug(" byShortRetryLimit= %d\n", (int)priv->byShortRetryLimit);
+ pr_debug(" byLongRetryLimit= %d\n", (int)priv->byLongRetryLimit);
+ pr_debug(" preamble_type= %d\n", (int)priv->preamble_type);
+ pr_debug(" byShortPreamble= %d\n", (int)priv->byShortPreamble);
+ pr_debug(" byBBType= %d\n", (int)priv->byBBType);
+}
+
+static void vt6655_mac_write_bssid_addr(void __iomem *iobase, const u8 *mac_addr)
+{
+ iowrite8(1, iobase + MAC_REG_PAGE1SEL);
+ for (int i = 0; i < 6; i++)
+ iowrite8(mac_addr[i], iobase + MAC_REG_BSSID0 + i);
+ iowrite8(0, iobase + MAC_REG_PAGE1SEL);
+}
+
+static void vt6655_mac_read_ether_addr(void __iomem *iobase, u8 *mac_addr)
+{
+ iowrite8(1, iobase + MAC_REG_PAGE1SEL);
+ for (int i = 0; i < 6; i++)
+ mac_addr[i] = ioread8(iobase + MAC_REG_PAR0 + i);
+ iowrite8(0, iobase + MAC_REG_PAGE1SEL);
+}
+
+static void vt6655_mac_dma_ctl(void __iomem *iobase, u8 reg_index)
+{
+ u32 reg_value;
+
+ reg_value = ioread32(iobase + reg_index);
+ if (reg_value & DMACTL_RUN)
+ iowrite32(DMACTL_WAKE, iobase + reg_index);
+ else
+ iowrite32(DMACTL_RUN, iobase + reg_index);
+}
+
+static void vt6655_mac_set_bits(void __iomem *iobase, u32 mask)
+{
+ u32 reg_value;
+
+ reg_value = ioread32(iobase + MAC_REG_ENCFG);
+ reg_value = reg_value | mask;
+ iowrite32(reg_value, iobase + MAC_REG_ENCFG);
+}
+
+static void vt6655_mac_clear_bits(void __iomem *iobase, u32 mask)
+{
+ u32 reg_value;
+
+ reg_value = ioread32(iobase + MAC_REG_ENCFG);
+ reg_value = reg_value & ~mask;
+ iowrite32(reg_value, iobase + MAC_REG_ENCFG);
+}
+
+static void vt6655_mac_en_protect_md(void __iomem *iobase)
+{
+ vt6655_mac_set_bits(iobase, ENCFG_PROTECTMD);
+}
+
+static void vt6655_mac_dis_protect_md(void __iomem *iobase)
+{
+ vt6655_mac_clear_bits(iobase, ENCFG_PROTECTMD);
+}
+
+static void vt6655_mac_en_barker_preamble_md(void __iomem *iobase)
+{
+ vt6655_mac_set_bits(iobase, ENCFG_BARKERPREAM);
+}
+
+static void vt6655_mac_dis_barker_preamble_md(void __iomem *iobase)
+{
+ vt6655_mac_clear_bits(iobase, ENCFG_BARKERPREAM);
+}
+
+/*
+ * Initialisation of MAC & BBP registers
+ */
+
+static void device_init_registers(struct vnt_private *priv)
+{
+ unsigned long flags;
+ unsigned int ii;
+ unsigned char byValue;
+ unsigned char byCCKPwrdBm = 0;
+ unsigned char byOFDMPwrdBm = 0;
+
+ MACbShutdown(priv);
+ bb_software_reset(priv);
+
+ /* Do MACbSoftwareReset in MACvInitialize */
+ MACbSoftwareReset(priv);
+
+ priv->bAES = false;
+
+ /* Only used in 11g type, sync with ERP IE */
+ priv->bProtectMode = false;
+
+ priv->bNonERPPresent = false;
+ priv->bBarkerPreambleMd = false;
+ priv->wCurrentRate = RATE_1M;
+ priv->byTopOFDMBasicRate = RATE_24M;
+ priv->byTopCCKBasicRate = RATE_1M;
+
+ /* init MAC */
+ MACvInitialize(priv);
+
+ /* Get Local ID */
+ priv->local_id = ioread8(priv->port_offset + MAC_REG_LOCALID);
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ SROMvReadAllContents(priv->port_offset, priv->abyEEPROM);
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ /* Get Channel range */
+ priv->byMinChannel = 1;
+ priv->byMaxChannel = CB_MAX_CHANNEL;
+
+ /* Get Antena */
+ byValue = SROMbyReadEmbedded(priv->port_offset, EEP_OFS_ANTENNA);
+ if (byValue & EEP_ANTINV)
+ priv->bTxRxAntInv = true;
+ else
+ priv->bTxRxAntInv = false;
+
+ byValue &= (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN);
+ /* if not set default is All */
+ if (byValue == 0)
+ byValue = (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN);
+
+ if (byValue == (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN)) {
+ priv->byAntennaCount = 2;
+ priv->byTxAntennaMode = ANT_B;
+ priv->dwTxAntennaSel = 1;
+ priv->dwRxAntennaSel = 1;
+
+ if (priv->bTxRxAntInv)
+ priv->byRxAntennaMode = ANT_A;
+ else
+ priv->byRxAntennaMode = ANT_B;
+ } else {
+ priv->byAntennaCount = 1;
+ priv->dwTxAntennaSel = 0;
+ priv->dwRxAntennaSel = 0;
+
+ if (byValue & EEP_ANTENNA_AUX) {
+ priv->byTxAntennaMode = ANT_A;
+
+ if (priv->bTxRxAntInv)
+ priv->byRxAntennaMode = ANT_B;
+ else
+ priv->byRxAntennaMode = ANT_A;
+ } else {
+ priv->byTxAntennaMode = ANT_B;
+
+ if (priv->bTxRxAntInv)
+ priv->byRxAntennaMode = ANT_A;
+ else
+ priv->byRxAntennaMode = ANT_B;
+ }
+ }
+
+ /* Set initial antenna mode */
+ bb_set_tx_antenna_mode(priv, priv->byTxAntennaMode);
+ bb_set_rx_antenna_mode(priv, priv->byRxAntennaMode);
+
+ /* zonetype initial */
+ priv->byOriginalZonetype = priv->abyEEPROM[EEP_OFS_ZONETYPE];
+
+ if (!priv->bZoneRegExist)
+ priv->byZoneType = priv->abyEEPROM[EEP_OFS_ZONETYPE];
+
+ pr_debug("priv->byZoneType = %x\n", priv->byZoneType);
+
+ /* Init RF module */
+ RFbInit(priv);
+
+ /* Get Desire Power Value */
+ priv->byCurPwr = 0xFF;
+ priv->byCCKPwr = SROMbyReadEmbedded(priv->port_offset, EEP_OFS_PWR_CCK);
+ priv->byOFDMPwrG = SROMbyReadEmbedded(priv->port_offset,
+ EEP_OFS_PWR_OFDMG);
+
+ /* Load power Table */
+ for (ii = 0; ii < CB_MAX_CHANNEL_24G; ii++) {
+ priv->abyCCKPwrTbl[ii + 1] =
+ SROMbyReadEmbedded(priv->port_offset,
+ (unsigned char)(ii + EEP_OFS_CCK_PWR_TBL));
+ if (priv->abyCCKPwrTbl[ii + 1] == 0)
+ priv->abyCCKPwrTbl[ii + 1] = priv->byCCKPwr;
+
+ priv->abyOFDMPwrTbl[ii + 1] =
+ SROMbyReadEmbedded(priv->port_offset,
+ (unsigned char)(ii + EEP_OFS_OFDM_PWR_TBL));
+ if (priv->abyOFDMPwrTbl[ii + 1] == 0)
+ priv->abyOFDMPwrTbl[ii + 1] = priv->byOFDMPwrG;
+
+ priv->abyCCKDefaultPwr[ii + 1] = byCCKPwrdBm;
+ priv->abyOFDMDefaultPwr[ii + 1] = byOFDMPwrdBm;
+ }
+
+ /* recover 12,13 ,14channel for EUROPE by 11 channel */
+ for (ii = 11; ii < 14; ii++) {
+ priv->abyCCKPwrTbl[ii] = priv->abyCCKPwrTbl[10];
+ priv->abyOFDMPwrTbl[ii] = priv->abyOFDMPwrTbl[10];
+ }
+
+ /* Load OFDM A Power Table */
+ for (ii = 0; ii < CB_MAX_CHANNEL_5G; ii++) {
+ priv->abyOFDMPwrTbl[ii + CB_MAX_CHANNEL_24G + 1] =
+ SROMbyReadEmbedded(priv->port_offset,
+ (unsigned char)(ii + EEP_OFS_OFDMA_PWR_TBL));
+
+ priv->abyOFDMDefaultPwr[ii + CB_MAX_CHANNEL_24G + 1] =
+ SROMbyReadEmbedded(priv->port_offset,
+ (unsigned char)(ii + EEP_OFS_OFDMA_PWR_dBm));
+ }
+
+ if (priv->local_id > REV_ID_VT3253_B1) {
+ VT6655_MAC_SELECT_PAGE1(priv->port_offset);
+
+ iowrite8(MSRCTL1_TXPWR | MSRCTL1_CSAPAREN, priv->port_offset + MAC_REG_MSRCTL + 1);
+
+ VT6655_MAC_SELECT_PAGE0(priv->port_offset);
+ }
+
+ /* use relative tx timeout and 802.11i D4 */
+ vt6655_mac_word_reg_bits_on(priv->port_offset, MAC_REG_CFG,
+ (CFG_TKIPOPT | CFG_NOTXTIMEOUT));
+
+ /* set performance parameter by registry */
+ vt6655_mac_set_short_retry_limit(priv, priv->byShortRetryLimit);
+ MACvSetLongRetryLimit(priv, priv->byLongRetryLimit);
+
+ /* reset TSF counter */
+ iowrite8(TFTCTL_TSFCNTRST, priv->port_offset + MAC_REG_TFTCTL);
+ /* enable TSF counter */
+ iowrite8(TFTCTL_TSFCNTREN, priv->port_offset + MAC_REG_TFTCTL);
+
+ /* initialize BBP registers */
+ bb_vt3253_init(priv);
+
+ if (priv->bUpdateBBVGA) {
+ priv->byBBVGACurrent = priv->abyBBVGA[0];
+ priv->byBBVGANew = priv->byBBVGACurrent;
+ bb_set_vga_gain_offset(priv, priv->abyBBVGA[0]);
+ }
+
+ bb_set_rx_antenna_mode(priv, priv->byRxAntennaMode);
+ bb_set_tx_antenna_mode(priv, priv->byTxAntennaMode);
+
+ /* Set BB and packet type at the same time. */
+ /* Set Short Slot Time, xIFS, and RSPINF. */
+ priv->wCurrentRate = RATE_54M;
+
+ priv->radio_off = false;
+
+ priv->byRadioCtl = SROMbyReadEmbedded(priv->port_offset,
+ EEP_OFS_RADIOCTL);
+ priv->hw_radio_off = false;
+
+ if (priv->byRadioCtl & EEP_RADIOCTL_ENABLE) {
+ /* Get GPIO */
+ priv->byGPIO = ioread8(priv->port_offset + MAC_REG_GPIOCTL1);
+
+ if (((priv->byGPIO & GPIO0_DATA) &&
+ !(priv->byRadioCtl & EEP_RADIOCTL_INV)) ||
+ (!(priv->byGPIO & GPIO0_DATA) &&
+ (priv->byRadioCtl & EEP_RADIOCTL_INV)))
+ priv->hw_radio_off = true;
+ }
+
+ if (priv->hw_radio_off || priv->bRadioControlOff)
+ CARDbRadioPowerOff(priv);
+
+ /* get Permanent network address */
+ SROMvReadEtherAddress(priv->port_offset, priv->abyCurrentNetAddr);
+ pr_debug("Network address = %pM\n", priv->abyCurrentNetAddr);
+
+ /* reset Tx pointer */
+ CARDvSafeResetRx(priv);
+ /* reset Rx pointer */
+ CARDvSafeResetTx(priv);
+
+ if (priv->local_id <= REV_ID_VT3253_A1)
+ vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_RCR, RCR_WPAERR);
+
+ /* Turn On Rx DMA */
+ vt6655_mac_dma_ctl(priv->port_offset, MAC_REG_RXDMACTL0);
+ vt6655_mac_dma_ctl(priv->port_offset, MAC_REG_RXDMACTL1);
+
+ /* start the adapter */
+ iowrite8(HOSTCR_MACEN | HOSTCR_RXON | HOSTCR_TXON, priv->port_offset + MAC_REG_HOSTCR);
+}
+
+static void device_print_info(struct vnt_private *priv)
+{
+ dev_info(&priv->pcid->dev, "MAC=%pM IO=0x%lx Mem=0x%lx IRQ=%d\n",
+ priv->abyCurrentNetAddr, (unsigned long)priv->ioaddr,
+ (unsigned long)priv->port_offset, priv->pcid->irq);
+}
+
+static void device_free_info(struct vnt_private *priv)
+{
+ if (!priv)
+ return;
+
+ if (priv->mac_hw)
+ ieee80211_unregister_hw(priv->hw);
+
+ if (priv->port_offset)
+ iounmap(priv->port_offset);
+
+ if (priv->pcid)
+ pci_release_regions(priv->pcid);
+
+ if (priv->hw)
+ ieee80211_free_hw(priv->hw);
+}
+
+static bool device_init_rings(struct vnt_private *priv)
+{
+ void *vir_pool;
+
+ /*allocate all RD/TD rings a single pool*/
+ vir_pool = dma_alloc_coherent(&priv->pcid->dev,
+ priv->opts.rx_descs0 * sizeof(struct vnt_rx_desc) +
+ priv->opts.rx_descs1 * sizeof(struct vnt_rx_desc) +
+ priv->opts.tx_descs[0] * sizeof(struct vnt_tx_desc) +
+ priv->opts.tx_descs[1] * sizeof(struct vnt_tx_desc),
+ &priv->pool_dma, GFP_ATOMIC);
+ if (!vir_pool) {
+ dev_err(&priv->pcid->dev, "allocate desc dma memory failed\n");
+ return false;
+ }
+
+ priv->aRD0Ring = vir_pool;
+ priv->aRD1Ring = vir_pool +
+ priv->opts.rx_descs0 * sizeof(struct vnt_rx_desc);
+
+ priv->rd0_pool_dma = priv->pool_dma;
+ priv->rd1_pool_dma = priv->rd0_pool_dma +
+ priv->opts.rx_descs0 * sizeof(struct vnt_rx_desc);
+
+ priv->tx0_bufs = dma_alloc_coherent(&priv->pcid->dev,
+ priv->opts.tx_descs[0] * PKT_BUF_SZ +
+ priv->opts.tx_descs[1] * PKT_BUF_SZ +
+ CB_BEACON_BUF_SIZE +
+ CB_MAX_BUF_SIZE,
+ &priv->tx_bufs_dma0, GFP_ATOMIC);
+ if (!priv->tx0_bufs) {
+ dev_err(&priv->pcid->dev, "allocate buf dma memory failed\n");
+
+ dma_free_coherent(&priv->pcid->dev,
+ priv->opts.rx_descs0 * sizeof(struct vnt_rx_desc) +
+ priv->opts.rx_descs1 * sizeof(struct vnt_rx_desc) +
+ priv->opts.tx_descs[0] * sizeof(struct vnt_tx_desc) +
+ priv->opts.tx_descs[1] * sizeof(struct vnt_tx_desc),
+ vir_pool, priv->pool_dma);
+ return false;
+ }
+
+ priv->td0_pool_dma = priv->rd1_pool_dma +
+ priv->opts.rx_descs1 * sizeof(struct vnt_rx_desc);
+
+ priv->td1_pool_dma = priv->td0_pool_dma +
+ priv->opts.tx_descs[0] * sizeof(struct vnt_tx_desc);
+
+ /* vir_pool: pvoid type */
+ priv->apTD0Rings = vir_pool
+ + priv->opts.rx_descs0 * sizeof(struct vnt_rx_desc)
+ + priv->opts.rx_descs1 * sizeof(struct vnt_rx_desc);
+
+ priv->apTD1Rings = vir_pool
+ + priv->opts.rx_descs0 * sizeof(struct vnt_rx_desc)
+ + priv->opts.rx_descs1 * sizeof(struct vnt_rx_desc)
+ + priv->opts.tx_descs[0] * sizeof(struct vnt_tx_desc);
+
+ priv->tx1_bufs = priv->tx0_bufs +
+ priv->opts.tx_descs[0] * PKT_BUF_SZ;
+
+ priv->tx_beacon_bufs = priv->tx1_bufs +
+ priv->opts.tx_descs[1] * PKT_BUF_SZ;
+
+ priv->pbyTmpBuff = priv->tx_beacon_bufs +
+ CB_BEACON_BUF_SIZE;
+
+ priv->tx_bufs_dma1 = priv->tx_bufs_dma0 +
+ priv->opts.tx_descs[0] * PKT_BUF_SZ;
+
+ priv->tx_beacon_dma = priv->tx_bufs_dma1 +
+ priv->opts.tx_descs[1] * PKT_BUF_SZ;
+
+ return true;
+}
+
+static void device_free_rings(struct vnt_private *priv)
+{
+ dma_free_coherent(&priv->pcid->dev,
+ priv->opts.rx_descs0 * sizeof(struct vnt_rx_desc) +
+ priv->opts.rx_descs1 * sizeof(struct vnt_rx_desc) +
+ priv->opts.tx_descs[0] * sizeof(struct vnt_tx_desc) +
+ priv->opts.tx_descs[1] * sizeof(struct vnt_tx_desc),
+ priv->aRD0Ring, priv->pool_dma);
+
+ dma_free_coherent(&priv->pcid->dev,
+ priv->opts.tx_descs[0] * PKT_BUF_SZ +
+ priv->opts.tx_descs[1] * PKT_BUF_SZ +
+ CB_BEACON_BUF_SIZE +
+ CB_MAX_BUF_SIZE,
+ priv->tx0_bufs, priv->tx_bufs_dma0);
+}
+
+static int device_init_rd0_ring(struct vnt_private *priv)
+{
+ int i;
+ dma_addr_t curr = priv->rd0_pool_dma;
+ struct vnt_rx_desc *desc;
+ int ret;
+
+ /* Init the RD0 ring entries */
+ for (i = 0; i < priv->opts.rx_descs0;
+ i ++, curr += sizeof(struct vnt_rx_desc)) {
+ desc = &priv->aRD0Ring[i];
+ desc->rd_info = kzalloc(sizeof(*desc->rd_info), GFP_KERNEL);
+ if (!desc->rd_info) {
+ ret = -ENOMEM;
+ goto err_free_desc;
+ }
+
+ if (!device_alloc_rx_buf(priv, desc)) {
+ dev_err(&priv->pcid->dev, "can not alloc rx bufs\n");
+ ret = -ENOMEM;
+ goto err_free_rd;
+ }
+
+ desc->next = &priv->aRD0Ring[(i + 1) % priv->opts.rx_descs0];
+ desc->next_desc = cpu_to_le32(curr + sizeof(struct vnt_rx_desc));
+ }
+
+ if (i > 0)
+ priv->aRD0Ring[i - 1].next_desc = cpu_to_le32(priv->rd0_pool_dma);
+ priv->pCurrRD[0] = &priv->aRD0Ring[0];
+
+ return 0;
+
+err_free_rd:
+ kfree(desc->rd_info);
+
+err_free_desc:
+ while (i--) {
+ desc = &priv->aRD0Ring[i];
+ device_free_rx_buf(priv, desc);
+ kfree(desc->rd_info);
+ }
+
+ return ret;
+}
+
+static int device_init_rd1_ring(struct vnt_private *priv)
+{
+ int i;
+ dma_addr_t curr = priv->rd1_pool_dma;
+ struct vnt_rx_desc *desc;
+ int ret;
+
+ /* Init the RD1 ring entries */
+ for (i = 0; i < priv->opts.rx_descs1;
+ i ++, curr += sizeof(struct vnt_rx_desc)) {
+ desc = &priv->aRD1Ring[i];
+ desc->rd_info = kzalloc(sizeof(*desc->rd_info), GFP_KERNEL);
+ if (!desc->rd_info) {
+ ret = -ENOMEM;
+ goto err_free_desc;
+ }
+
+ if (!device_alloc_rx_buf(priv, desc)) {
+ dev_err(&priv->pcid->dev, "can not alloc rx bufs\n");
+ ret = -ENOMEM;
+ goto err_free_rd;
+ }
+
+ desc->next = &priv->aRD1Ring[(i + 1) % priv->opts.rx_descs1];
+ desc->next_desc = cpu_to_le32(curr + sizeof(struct vnt_rx_desc));
+ }
+
+ if (i > 0)
+ priv->aRD1Ring[i - 1].next_desc = cpu_to_le32(priv->rd1_pool_dma);
+ priv->pCurrRD[1] = &priv->aRD1Ring[0];
+
+ return 0;
+
+err_free_rd:
+ kfree(desc->rd_info);
+
+err_free_desc:
+ while (i--) {
+ desc = &priv->aRD1Ring[i];
+ device_free_rx_buf(priv, desc);
+ kfree(desc->rd_info);
+ }
+
+ return ret;
+}
+
+static void device_free_rd0_ring(struct vnt_private *priv)
+{
+ int i;
+
+ for (i = 0; i < priv->opts.rx_descs0; i++) {
+ struct vnt_rx_desc *desc = &priv->aRD0Ring[i];
+
+ device_free_rx_buf(priv, desc);
+ kfree(desc->rd_info);
+ }
+}
+
+static void device_free_rd1_ring(struct vnt_private *priv)
+{
+ int i;
+
+ for (i = 0; i < priv->opts.rx_descs1; i++) {
+ struct vnt_rx_desc *desc = &priv->aRD1Ring[i];
+
+ device_free_rx_buf(priv, desc);
+ kfree(desc->rd_info);
+ }
+}
+
+static int device_init_td0_ring(struct vnt_private *priv)
+{
+ int i;
+ dma_addr_t curr;
+ struct vnt_tx_desc *desc;
+ int ret;
+
+ curr = priv->td0_pool_dma;
+ for (i = 0; i < priv->opts.tx_descs[0];
+ i++, curr += sizeof(struct vnt_tx_desc)) {
+ desc = &priv->apTD0Rings[i];
+ desc->td_info = kzalloc(sizeof(*desc->td_info), GFP_KERNEL);
+ if (!desc->td_info) {
+ ret = -ENOMEM;
+ goto err_free_desc;
+ }
+
+ desc->td_info->buf = priv->tx0_bufs + i * PKT_BUF_SZ;
+ desc->td_info->buf_dma = priv->tx_bufs_dma0 + i * PKT_BUF_SZ;
+
+ desc->next = &(priv->apTD0Rings[(i + 1) % priv->opts.tx_descs[0]]);
+ desc->next_desc = cpu_to_le32(curr +
+ sizeof(struct vnt_tx_desc));
+ }
+
+ if (i > 0)
+ priv->apTD0Rings[i - 1].next_desc = cpu_to_le32(priv->td0_pool_dma);
+ priv->apTailTD[0] = priv->apCurrTD[0] = &priv->apTD0Rings[0];
+
+ return 0;
+
+err_free_desc:
+ while (i--) {
+ desc = &priv->apTD0Rings[i];
+ kfree(desc->td_info);
+ }
+
+ return ret;
+}
+
+static int device_init_td1_ring(struct vnt_private *priv)
+{
+ int i;
+ dma_addr_t curr;
+ struct vnt_tx_desc *desc;
+ int ret;
+
+ /* Init the TD ring entries */
+ curr = priv->td1_pool_dma;
+ for (i = 0; i < priv->opts.tx_descs[1];
+ i++, curr += sizeof(struct vnt_tx_desc)) {
+ desc = &priv->apTD1Rings[i];
+ desc->td_info = kzalloc(sizeof(*desc->td_info), GFP_KERNEL);
+ if (!desc->td_info) {
+ ret = -ENOMEM;
+ goto err_free_desc;
+ }
+
+ desc->td_info->buf = priv->tx1_bufs + i * PKT_BUF_SZ;
+ desc->td_info->buf_dma = priv->tx_bufs_dma1 + i * PKT_BUF_SZ;
+
+ desc->next = &(priv->apTD1Rings[(i + 1) % priv->opts.tx_descs[1]]);
+ desc->next_desc = cpu_to_le32(curr + sizeof(struct vnt_tx_desc));
+ }
+
+ if (i > 0)
+ priv->apTD1Rings[i - 1].next_desc = cpu_to_le32(priv->td1_pool_dma);
+ priv->apTailTD[1] = priv->apCurrTD[1] = &priv->apTD1Rings[0];
+
+ return 0;
+
+err_free_desc:
+ while (i--) {
+ desc = &priv->apTD1Rings[i];
+ kfree(desc->td_info);
+ }
+
+ return ret;
+}
+
+static void device_free_td0_ring(struct vnt_private *priv)
+{
+ int i;
+
+ for (i = 0; i < priv->opts.tx_descs[0]; i++) {
+ struct vnt_tx_desc *desc = &priv->apTD0Rings[i];
+ struct vnt_td_info *td_info = desc->td_info;
+
+ dev_kfree_skb(td_info->skb);
+ kfree(desc->td_info);
+ }
+}
+
+static void device_free_td1_ring(struct vnt_private *priv)
+{
+ int i;
+
+ for (i = 0; i < priv->opts.tx_descs[1]; i++) {
+ struct vnt_tx_desc *desc = &priv->apTD1Rings[i];
+ struct vnt_td_info *td_info = desc->td_info;
+
+ dev_kfree_skb(td_info->skb);
+ kfree(desc->td_info);
+ }
+}
+
+/*-----------------------------------------------------------------*/
+
+static int device_rx_srv(struct vnt_private *priv, unsigned int idx)
+{
+ struct vnt_rx_desc *rd;
+ int works = 0;
+
+ for (rd = priv->pCurrRD[idx];
+ rd->rd0.owner == OWNED_BY_HOST;
+ rd = rd->next) {
+ if (works++ > 15)
+ break;
+
+ if (!rd->rd_info->skb)
+ break;
+
+ if (vnt_receive_frame(priv, rd)) {
+ if (!device_alloc_rx_buf(priv, rd)) {
+ dev_err(&priv->pcid->dev,
+ "can not allocate rx buf\n");
+ break;
+ }
+ }
+ rd->rd0.owner = OWNED_BY_NIC;
+ }
+
+ priv->pCurrRD[idx] = rd;
+
+ return works;
+}
+
+static bool device_alloc_rx_buf(struct vnt_private *priv,
+ struct vnt_rx_desc *rd)
+{
+ struct vnt_rd_info *rd_info = rd->rd_info;
+
+ rd_info->skb = dev_alloc_skb((int)priv->rx_buf_sz);
+ if (!rd_info->skb)
+ return false;
+
+ rd_info->skb_dma =
+ dma_map_single(&priv->pcid->dev,
+ skb_put(rd_info->skb, skb_tailroom(rd_info->skb)),
+ priv->rx_buf_sz, DMA_FROM_DEVICE);
+ if (dma_mapping_error(&priv->pcid->dev, rd_info->skb_dma)) {
+ dev_kfree_skb(rd_info->skb);
+ rd_info->skb = NULL;
+ return false;
+ }
+
+ *((unsigned int *)&rd->rd0) = 0; /* FIX cast */
+
+ rd->rd0.res_count = cpu_to_le16(priv->rx_buf_sz);
+ rd->rd0.owner = OWNED_BY_NIC;
+ rd->rd1.req_count = cpu_to_le16(priv->rx_buf_sz);
+ rd->buff_addr = cpu_to_le32(rd_info->skb_dma);
+
+ return true;
+}
+
+static void device_free_rx_buf(struct vnt_private *priv,
+ struct vnt_rx_desc *rd)
+{
+ struct vnt_rd_info *rd_info = rd->rd_info;
+
+ dma_unmap_single(&priv->pcid->dev, rd_info->skb_dma,
+ priv->rx_buf_sz, DMA_FROM_DEVICE);
+ dev_kfree_skb(rd_info->skb);
+}
+
+static const u8 fallback_rate0[5][5] = {
+ {RATE_18M, RATE_18M, RATE_12M, RATE_12M, RATE_12M},
+ {RATE_24M, RATE_24M, RATE_18M, RATE_12M, RATE_12M},
+ {RATE_36M, RATE_36M, RATE_24M, RATE_18M, RATE_18M},
+ {RATE_48M, RATE_48M, RATE_36M, RATE_24M, RATE_24M},
+ {RATE_54M, RATE_54M, RATE_48M, RATE_36M, RATE_36M}
+};
+
+static const u8 fallback_rate1[5][5] = {
+ {RATE_18M, RATE_18M, RATE_12M, RATE_6M, RATE_6M},
+ {RATE_24M, RATE_24M, RATE_18M, RATE_6M, RATE_6M},
+ {RATE_36M, RATE_36M, RATE_24M, RATE_12M, RATE_12M},
+ {RATE_48M, RATE_48M, RATE_24M, RATE_12M, RATE_12M},
+ {RATE_54M, RATE_54M, RATE_36M, RATE_18M, RATE_18M}
+};
+
+static int vnt_int_report_rate(struct vnt_private *priv,
+ struct vnt_td_info *context, u8 tsr0, u8 tsr1)
+{
+ struct vnt_tx_fifo_head *fifo_head;
+ struct ieee80211_tx_info *info;
+ struct ieee80211_rate *rate;
+ u16 fb_option;
+ u8 tx_retry = (tsr0 & TSR0_NCR);
+ s8 idx;
+
+ if (!context)
+ return -ENOMEM;
+
+ if (!context->skb)
+ return -EINVAL;
+
+ fifo_head = (struct vnt_tx_fifo_head *)context->buf;
+ fb_option = (le16_to_cpu(fifo_head->fifo_ctl) &
+ (FIFOCTL_AUTO_FB_0 | FIFOCTL_AUTO_FB_1));
+
+ info = IEEE80211_SKB_CB(context->skb);
+ idx = info->control.rates[0].idx;
+
+ if (fb_option && !(tsr1 & TSR1_TERR)) {
+ u8 tx_rate;
+ u8 retry = tx_retry;
+
+ rate = ieee80211_get_tx_rate(priv->hw, info);
+ tx_rate = rate->hw_value - RATE_18M;
+
+ if (retry > 4)
+ retry = 4;
+
+ if (fb_option & FIFOCTL_AUTO_FB_0)
+ tx_rate = fallback_rate0[tx_rate][retry];
+ else if (fb_option & FIFOCTL_AUTO_FB_1)
+ tx_rate = fallback_rate1[tx_rate][retry];
+
+ if (info->band == NL80211_BAND_5GHZ)
+ idx = tx_rate - RATE_6M;
+ else
+ idx = tx_rate;
+ }
+
+ ieee80211_tx_info_clear_status(info);
+
+ info->status.rates[0].count = tx_retry;
+
+ if (!(tsr1 & TSR1_TERR)) {
+ info->status.rates[0].idx = idx;
+
+ if (info->flags & IEEE80211_TX_CTL_NO_ACK)
+ info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED;
+ else
+ info->flags |= IEEE80211_TX_STAT_ACK;
+ }
+
+ return 0;
+}
+
+static int device_tx_srv(struct vnt_private *priv, unsigned int idx)
+{
+ struct vnt_tx_desc *desc;
+ int works = 0;
+ unsigned char byTsr0;
+ unsigned char byTsr1;
+
+ for (desc = priv->apTailTD[idx]; priv->iTDUsed[idx] > 0; desc = desc->next) {
+ if (desc->td0.owner == OWNED_BY_NIC)
+ break;
+ if (works++ > 15)
+ break;
+
+ byTsr0 = desc->td0.tsr0;
+ byTsr1 = desc->td0.tsr1;
+
+ /* Only the status of first TD in the chain is correct */
+ if (desc->td1.tcr & TCR_STP) {
+ if ((desc->td_info->flags & TD_FLAGS_NETIF_SKB) != 0) {
+ if (!(byTsr1 & TSR1_TERR)) {
+ if (byTsr0 != 0) {
+ pr_debug(" Tx[%d] OK but has error. tsr1[%02X] tsr0[%02X]\n",
+ (int)idx, byTsr1,
+ byTsr0);
+ }
+ } else {
+ pr_debug(" Tx[%d] dropped & tsr1[%02X] tsr0[%02X]\n",
+ (int)idx, byTsr1, byTsr0);
+ }
+ }
+
+ if (byTsr1 & TSR1_TERR) {
+ if ((desc->td_info->flags & TD_FLAGS_PRIV_SKB) != 0) {
+ pr_debug(" Tx[%d] fail has error. tsr1[%02X] tsr0[%02X]\n",
+ (int)idx, byTsr1, byTsr0);
+ }
+ }
+
+ vnt_int_report_rate(priv, desc->td_info, byTsr0, byTsr1);
+
+ device_free_tx_buf(priv, desc);
+ priv->iTDUsed[idx]--;
+ }
+ }
+
+ priv->apTailTD[idx] = desc;
+
+ return works;
+}
+
+static void device_error(struct vnt_private *priv, unsigned short status)
+{
+ if (status & ISR_FETALERR) {
+ dev_err(&priv->pcid->dev, "Hardware fatal error\n");
+
+ MACbShutdown(priv);
+ return;
+ }
+}
+
+static void device_free_tx_buf(struct vnt_private *priv,
+ struct vnt_tx_desc *desc)
+{
+ struct vnt_td_info *td_info = desc->td_info;
+ struct sk_buff *skb = td_info->skb;
+
+ if (skb)
+ ieee80211_tx_status_irqsafe(priv->hw, skb);
+
+ td_info->skb = NULL;
+ td_info->flags = 0;
+}
+
+static void vnt_check_bb_vga(struct vnt_private *priv)
+{
+ long dbm;
+ int i;
+
+ if (!priv->bUpdateBBVGA)
+ return;
+
+ if (priv->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)
+ return;
+
+ if (!(priv->vif->cfg.assoc && priv->current_rssi))
+ return;
+
+ RFvRSSITodBm(priv, (u8)priv->current_rssi, &dbm);
+
+ for (i = 0; i < BB_VGA_LEVEL; i++) {
+ if (dbm < priv->dbm_threshold[i]) {
+ priv->byBBVGANew = priv->abyBBVGA[i];
+ break;
+ }
+ }
+
+ if (priv->byBBVGANew == priv->byBBVGACurrent) {
+ priv->uBBVGADiffCount = 1;
+ return;
+ }
+
+ priv->uBBVGADiffCount++;
+
+ if (priv->uBBVGADiffCount == 1) {
+ /* first VGA diff gain */
+ bb_set_vga_gain_offset(priv, priv->byBBVGANew);
+
+ dev_dbg(&priv->pcid->dev,
+ "First RSSI[%d] NewGain[%d] OldGain[%d] Count[%d]\n",
+ (int)dbm, priv->byBBVGANew,
+ priv->byBBVGACurrent,
+ (int)priv->uBBVGADiffCount);
+ }
+
+ if (priv->uBBVGADiffCount >= BB_VGA_CHANGE_THRESHOLD) {
+ dev_dbg(&priv->pcid->dev,
+ "RSSI[%d] NewGain[%d] OldGain[%d] Count[%d]\n",
+ (int)dbm, priv->byBBVGANew,
+ priv->byBBVGACurrent,
+ (int)priv->uBBVGADiffCount);
+
+ bb_set_vga_gain_offset(priv, priv->byBBVGANew);
+ }
+}
+
+static void vnt_interrupt_process(struct vnt_private *priv)
+{
+ struct ieee80211_low_level_stats *low_stats = &priv->low_stats;
+ int max_count = 0;
+ u32 mib_counter;
+ u32 isr;
+ unsigned long flags;
+
+ isr = ioread32(priv->port_offset + MAC_REG_ISR);
+
+ if (isr == 0)
+ return;
+
+ if (isr == 0xffffffff) {
+ pr_debug("isr = 0xffff\n");
+ return;
+ }
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ /* Read low level stats */
+ mib_counter = ioread32(priv->port_offset + MAC_REG_MIBCNTR);
+
+ low_stats->dot11RTSSuccessCount += mib_counter & 0xff;
+ low_stats->dot11RTSFailureCount += (mib_counter >> 8) & 0xff;
+ low_stats->dot11ACKFailureCount += (mib_counter >> 16) & 0xff;
+ low_stats->dot11FCSErrorCount += (mib_counter >> 24) & 0xff;
+
+ /*
+ * TBD....
+ * Must do this after doing rx/tx, cause ISR bit is slow
+ * than RD/TD write back
+ * update ISR counter
+ */
+ while (isr && priv->vif) {
+ iowrite32(isr, priv->port_offset + MAC_REG_ISR);
+
+ if (isr & ISR_FETALERR) {
+ pr_debug(" ISR_FETALERR\n");
+ iowrite8(0, priv->port_offset + MAC_REG_SOFTPWRCTL);
+ iowrite16(SOFTPWRCTL_SWPECTI, priv->port_offset + MAC_REG_SOFTPWRCTL);
+ device_error(priv, isr);
+ }
+
+ if (isr & ISR_TBTT) {
+ if (priv->op_mode != NL80211_IFTYPE_ADHOC)
+ vnt_check_bb_vga(priv);
+
+ priv->bBeaconSent = false;
+ if (priv->bEnablePSMode)
+ PSbIsNextTBTTWakeUp((void *)priv);
+
+ if ((priv->op_mode == NL80211_IFTYPE_AP ||
+ priv->op_mode == NL80211_IFTYPE_ADHOC) &&
+ priv->vif->bss_conf.enable_beacon)
+ MACvOneShotTimer1MicroSec(priv,
+ (priv->vif->bss_conf.beacon_int -
+ MAKE_BEACON_RESERVED) << 10);
+
+ /* TODO: adhoc PS mode */
+ }
+
+ if (isr & ISR_BNTX) {
+ if (priv->op_mode == NL80211_IFTYPE_ADHOC) {
+ priv->bIsBeaconBufReadySet = false;
+ priv->cbBeaconBufReadySetCnt = 0;
+ }
+
+ priv->bBeaconSent = true;
+ }
+
+ if (isr & ISR_RXDMA0)
+ max_count += device_rx_srv(priv, TYPE_RXDMA0);
+
+ if (isr & ISR_RXDMA1)
+ max_count += device_rx_srv(priv, TYPE_RXDMA1);
+
+ if (isr & ISR_TXDMA0)
+ max_count += device_tx_srv(priv, TYPE_TXDMA0);
+
+ if (isr & ISR_AC0DMA)
+ max_count += device_tx_srv(priv, TYPE_AC0DMA);
+
+ if (isr & ISR_SOFTTIMER1) {
+ if (priv->vif->bss_conf.enable_beacon)
+ vnt_beacon_make(priv, priv->vif);
+ }
+
+ /* If both buffers available wake the queue */
+ if (AVAIL_TD(priv, TYPE_TXDMA0) &&
+ AVAIL_TD(priv, TYPE_AC0DMA) &&
+ ieee80211_queue_stopped(priv->hw, 0))
+ ieee80211_wake_queues(priv->hw);
+
+ isr = ioread32(priv->port_offset + MAC_REG_ISR);
+
+ vt6655_mac_dma_ctl(priv->port_offset, MAC_REG_RXDMACTL0);
+ vt6655_mac_dma_ctl(priv->port_offset, MAC_REG_RXDMACTL1);
+
+ if (max_count > priv->opts.int_works)
+ break;
+ }
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static void vnt_interrupt_work(struct work_struct *work)
+{
+ struct vnt_private *priv =
+ container_of(work, struct vnt_private, interrupt_work);
+
+ if (priv->vif)
+ vnt_interrupt_process(priv);
+
+ iowrite32(IMR_MASK_VALUE, priv->port_offset + MAC_REG_IMR);
+}
+
+static irqreturn_t vnt_interrupt(int irq, void *arg)
+{
+ struct vnt_private *priv = arg;
+
+ schedule_work(&priv->interrupt_work);
+
+ iowrite32(0, priv->port_offset + MAC_REG_IMR);
+
+ return IRQ_HANDLED;
+}
+
+static int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb)
+{
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ struct vnt_tx_desc *head_td;
+ u32 dma_idx;
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ if (ieee80211_is_data(hdr->frame_control))
+ dma_idx = TYPE_AC0DMA;
+ else
+ dma_idx = TYPE_TXDMA0;
+
+ if (AVAIL_TD(priv, dma_idx) < 1) {
+ spin_unlock_irqrestore(&priv->lock, flags);
+ ieee80211_stop_queues(priv->hw);
+ return -ENOMEM;
+ }
+
+ head_td = priv->apCurrTD[dma_idx];
+
+ head_td->td1.tcr = 0;
+
+ head_td->td_info->skb = skb;
+
+ if (dma_idx == TYPE_AC0DMA)
+ head_td->td_info->flags = TD_FLAGS_NETIF_SKB;
+
+ priv->apCurrTD[dma_idx] = head_td->next;
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ vnt_generate_fifo_header(priv, dma_idx, head_td, skb);
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ priv->bPWBitOn = false;
+
+ /* Set TSR1 & ReqCount in TxDescHead */
+ head_td->td1.tcr |= (TCR_STP | TCR_EDP | EDMSDU);
+ head_td->td1.req_count = cpu_to_le16(head_td->td_info->req_count);
+
+ head_td->buff_addr = cpu_to_le32(head_td->td_info->buf_dma);
+
+ /* Poll Transmit the adapter */
+ wmb();
+ head_td->td0.owner = OWNED_BY_NIC;
+ wmb(); /* second memory barrier */
+
+ if (head_td->td_info->flags & TD_FLAGS_NETIF_SKB)
+ vt6655_mac_dma_ctl(priv->port_offset, MAC_REG_AC0DMACTL);
+ else
+ vt6655_mac_dma_ctl(priv->port_offset, MAC_REG_TXDMACTL0);
+
+ priv->iTDUsed[dma_idx]++;
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return 0;
+}
+
+static void vnt_tx_80211(struct ieee80211_hw *hw,
+ struct ieee80211_tx_control *control,
+ struct sk_buff *skb)
+{
+ struct vnt_private *priv = hw->priv;
+
+ if (vnt_tx_packet(priv, skb))
+ ieee80211_free_txskb(hw, skb);
+}
+
+static int vnt_start(struct ieee80211_hw *hw)
+{
+ struct vnt_private *priv = hw->priv;
+ int ret;
+
+ priv->rx_buf_sz = PKT_BUF_SZ;
+ if (!device_init_rings(priv))
+ return -ENOMEM;
+
+ ret = request_irq(priv->pcid->irq, vnt_interrupt,
+ IRQF_SHARED, "vt6655", priv);
+ if (ret) {
+ dev_dbg(&priv->pcid->dev, "failed to start irq\n");
+ goto err_free_rings;
+ }
+
+ dev_dbg(&priv->pcid->dev, "call device init rd0 ring\n");
+ ret = device_init_rd0_ring(priv);
+ if (ret)
+ goto err_free_irq;
+ ret = device_init_rd1_ring(priv);
+ if (ret)
+ goto err_free_rd0_ring;
+ ret = device_init_td0_ring(priv);
+ if (ret)
+ goto err_free_rd1_ring;
+ ret = device_init_td1_ring(priv);
+ if (ret)
+ goto err_free_td0_ring;
+
+ device_init_registers(priv);
+
+ dev_dbg(&priv->pcid->dev, "enable MAC interrupt\n");
+ iowrite32(IMR_MASK_VALUE, priv->port_offset + MAC_REG_IMR);
+
+ ieee80211_wake_queues(hw);
+
+ return 0;
+
+err_free_td0_ring:
+ device_free_td0_ring(priv);
+err_free_rd1_ring:
+ device_free_rd1_ring(priv);
+err_free_rd0_ring:
+ device_free_rd0_ring(priv);
+err_free_irq:
+ free_irq(priv->pcid->irq, priv);
+err_free_rings:
+ device_free_rings(priv);
+ return ret;
+}
+
+static void vnt_stop(struct ieee80211_hw *hw)
+{
+ struct vnt_private *priv = hw->priv;
+
+ ieee80211_stop_queues(hw);
+
+ cancel_work_sync(&priv->interrupt_work);
+
+ MACbShutdown(priv);
+ MACbSoftwareReset(priv);
+ CARDbRadioPowerOff(priv);
+
+ device_free_td0_ring(priv);
+ device_free_td1_ring(priv);
+ device_free_rd0_ring(priv);
+ device_free_rd1_ring(priv);
+ device_free_rings(priv);
+
+ free_irq(priv->pcid->irq, priv);
+}
+
+static int vnt_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+{
+ struct vnt_private *priv = hw->priv;
+
+ priv->vif = vif;
+
+ switch (vif->type) {
+ case NL80211_IFTYPE_STATION:
+ break;
+ case NL80211_IFTYPE_ADHOC:
+ vt6655_mac_reg_bits_off(priv->port_offset, MAC_REG_RCR, RCR_UNICAST);
+
+ vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_HOSTCR, HOSTCR_ADHOC);
+
+ break;
+ case NL80211_IFTYPE_AP:
+ vt6655_mac_reg_bits_off(priv->port_offset, MAC_REG_RCR, RCR_UNICAST);
+
+ vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_HOSTCR, HOSTCR_AP);
+
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ priv->op_mode = vif->type;
+
+ return 0;
+}
+
+static void vnt_remove_interface(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
+{
+ struct vnt_private *priv = hw->priv;
+
+ switch (vif->type) {
+ case NL80211_IFTYPE_STATION:
+ break;
+ case NL80211_IFTYPE_ADHOC:
+ vt6655_mac_reg_bits_off(priv->port_offset, MAC_REG_TCR, TCR_AUTOBCNTX);
+ vt6655_mac_reg_bits_off(priv->port_offset,
+ MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
+ vt6655_mac_reg_bits_off(priv->port_offset, MAC_REG_HOSTCR, HOSTCR_ADHOC);
+ break;
+ case NL80211_IFTYPE_AP:
+ vt6655_mac_reg_bits_off(priv->port_offset, MAC_REG_TCR, TCR_AUTOBCNTX);
+ vt6655_mac_reg_bits_off(priv->port_offset,
+ MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
+ vt6655_mac_reg_bits_off(priv->port_offset, MAC_REG_HOSTCR, HOSTCR_AP);
+ break;
+ default:
+ break;
+ }
+
+ priv->op_mode = NL80211_IFTYPE_UNSPECIFIED;
+}
+
+static int vnt_config(struct ieee80211_hw *hw, u32 changed)
+{
+ struct vnt_private *priv = hw->priv;
+ struct ieee80211_conf *conf = &hw->conf;
+ u8 bb_type;
+
+ if (changed & IEEE80211_CONF_CHANGE_PS) {
+ if (conf->flags & IEEE80211_CONF_PS)
+ PSvEnablePowerSaving(priv, conf->listen_interval);
+ else
+ PSvDisablePowerSaving(priv);
+ }
+
+ if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) ||
+ (conf->flags & IEEE80211_CONF_OFFCHANNEL)) {
+ set_channel(priv, conf->chandef.chan);
+
+ if (conf->chandef.chan->band == NL80211_BAND_5GHZ)
+ bb_type = BB_TYPE_11A;
+ else
+ bb_type = BB_TYPE_11G;
+
+ if (priv->byBBType != bb_type) {
+ priv->byBBType = bb_type;
+
+ CARDbSetPhyParameter(priv, priv->byBBType);
+ }
+ }
+
+ if (changed & IEEE80211_CONF_CHANGE_POWER) {
+ if (priv->byBBType == BB_TYPE_11B)
+ priv->wCurrentRate = RATE_1M;
+ else
+ priv->wCurrentRate = RATE_54M;
+
+ RFbSetPower(priv, priv->wCurrentRate,
+ conf->chandef.chan->hw_value);
+ }
+
+ return 0;
+}
+
+static void vnt_bss_info_changed(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *conf, u64 changed)
+{
+ struct vnt_private *priv = hw->priv;
+
+ priv->current_aid = vif->cfg.aid;
+
+ if (changed & BSS_CHANGED_BSSID && conf->bssid) {
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ vt6655_mac_write_bssid_addr(priv->port_offset, conf->bssid);
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+ }
+
+ if (changed & BSS_CHANGED_BASIC_RATES) {
+ priv->basic_rates = conf->basic_rates;
+
+ CARDvUpdateBasicTopRate(priv);
+
+ dev_dbg(&priv->pcid->dev,
+ "basic rates %x\n", conf->basic_rates);
+ }
+
+ if (changed & BSS_CHANGED_ERP_PREAMBLE) {
+ if (conf->use_short_preamble) {
+ vt6655_mac_en_barker_preamble_md(priv->port_offset);
+ priv->preamble_type = true;
+ } else {
+ vt6655_mac_dis_barker_preamble_md(priv->port_offset);
+ priv->preamble_type = false;
+ }
+ }
+
+ if (changed & BSS_CHANGED_ERP_CTS_PROT) {
+ if (conf->use_cts_prot)
+ vt6655_mac_en_protect_md(priv->port_offset);
+ else
+ vt6655_mac_dis_protect_md(priv->port_offset);
+ }
+
+ if (changed & BSS_CHANGED_ERP_SLOT) {
+ if (conf->use_short_slot)
+ priv->short_slot_time = true;
+ else
+ priv->short_slot_time = false;
+
+ CARDbSetPhyParameter(priv, priv->byBBType);
+ bb_set_vga_gain_offset(priv, priv->abyBBVGA[0]);
+ }
+
+ if (changed & BSS_CHANGED_TXPOWER)
+ RFbSetPower(priv, priv->wCurrentRate,
+ conf->chandef.chan->hw_value);
+
+ if (changed & BSS_CHANGED_BEACON_ENABLED) {
+ dev_dbg(&priv->pcid->dev,
+ "Beacon enable %d\n", conf->enable_beacon);
+
+ if (conf->enable_beacon) {
+ vnt_beacon_enable(priv, vif, conf);
+
+ vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_TCR, TCR_AUTOBCNTX);
+ } else {
+ vt6655_mac_reg_bits_off(priv->port_offset, MAC_REG_TCR,
+ TCR_AUTOBCNTX);
+ }
+ }
+
+ if (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_BEACON_INFO) &&
+ priv->op_mode != NL80211_IFTYPE_AP) {
+ if (vif->cfg.assoc && conf->beacon_rate) {
+ CARDbUpdateTSF(priv, conf->beacon_rate->hw_value,
+ conf->sync_tsf);
+
+ CARDbSetBeaconPeriod(priv, conf->beacon_int);
+
+ CARDvSetFirstNextTBTT(priv, conf->beacon_int);
+ } else {
+ iowrite8(TFTCTL_TSFCNTRST, priv->port_offset + MAC_REG_TFTCTL);
+ iowrite8(TFTCTL_TSFCNTREN, priv->port_offset + MAC_REG_TFTCTL);
+ }
+ }
+}
+
+static u64 vnt_prepare_multicast(struct ieee80211_hw *hw,
+ struct netdev_hw_addr_list *mc_list)
+{
+ struct vnt_private *priv = hw->priv;
+ struct netdev_hw_addr *ha;
+ u64 mc_filter = 0;
+ u32 bit_nr = 0;
+
+ netdev_hw_addr_list_for_each(ha, mc_list) {
+ bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26;
+
+ mc_filter |= 1ULL << (bit_nr & 0x3f);
+ }
+
+ priv->mc_list_count = mc_list->count;
+
+ return mc_filter;
+}
+
+static void vnt_configure(struct ieee80211_hw *hw,
+ unsigned int changed_flags,
+ unsigned int *total_flags, u64 multicast)
+{
+ struct vnt_private *priv = hw->priv;
+ u8 rx_mode = 0;
+
+ *total_flags &= FIF_ALLMULTI | FIF_OTHER_BSS | FIF_BCN_PRBRESP_PROMISC;
+
+ rx_mode = ioread8(priv->port_offset + MAC_REG_RCR);
+
+ dev_dbg(&priv->pcid->dev, "rx mode in = %x\n", rx_mode);
+
+ if (changed_flags & FIF_ALLMULTI) {
+ if (*total_flags & FIF_ALLMULTI) {
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ if (priv->mc_list_count > 2) {
+ VT6655_MAC_SELECT_PAGE1(priv->port_offset);
+
+ iowrite32(0xffffffff, priv->port_offset + MAC_REG_MAR0);
+ iowrite32(0xffffffff, priv->port_offset + MAC_REG_MAR0 + 4);
+
+ VT6655_MAC_SELECT_PAGE0(priv->port_offset);
+ } else {
+ VT6655_MAC_SELECT_PAGE1(priv->port_offset);
+
+ multicast = le64_to_cpu(multicast);
+ iowrite32((u32)multicast, priv->port_offset + MAC_REG_MAR0);
+ iowrite32((u32)(multicast >> 32),
+ priv->port_offset + MAC_REG_MAR0 + 4);
+
+ VT6655_MAC_SELECT_PAGE0(priv->port_offset);
+ }
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ rx_mode |= RCR_MULTICAST | RCR_BROADCAST;
+ } else {
+ rx_mode &= ~(RCR_MULTICAST | RCR_BROADCAST);
+ }
+ }
+
+ if (changed_flags & (FIF_OTHER_BSS | FIF_BCN_PRBRESP_PROMISC)) {
+ rx_mode |= RCR_MULTICAST | RCR_BROADCAST;
+
+ if (*total_flags & (FIF_OTHER_BSS | FIF_BCN_PRBRESP_PROMISC))
+ rx_mode &= ~RCR_BSSID;
+ else
+ rx_mode |= RCR_BSSID;
+ }
+
+ iowrite8(rx_mode, priv->port_offset + MAC_REG_RCR);
+
+ dev_dbg(&priv->pcid->dev, "rx mode out= %x\n", rx_mode);
+}
+
+static int vnt_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+ struct ieee80211_vif *vif, struct ieee80211_sta *sta,
+ struct ieee80211_key_conf *key)
+{
+ struct vnt_private *priv = hw->priv;
+
+ switch (cmd) {
+ case SET_KEY:
+ if (vnt_set_keys(hw, sta, vif, key))
+ return -EOPNOTSUPP;
+ break;
+ case DISABLE_KEY:
+ if (test_bit(key->hw_key_idx, &priv->key_entry_inuse))
+ clear_bit(key->hw_key_idx, &priv->key_entry_inuse);
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int vnt_get_stats(struct ieee80211_hw *hw,
+ struct ieee80211_low_level_stats *stats)
+{
+ struct vnt_private *priv = hw->priv;
+
+ memcpy(stats, &priv->low_stats, sizeof(*stats));
+
+ return 0;
+}
+
+static u64 vnt_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+{
+ struct vnt_private *priv = hw->priv;
+ u64 tsf;
+
+ tsf = vt6655_get_current_tsf(priv);
+
+ return tsf;
+}
+
+static void vnt_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ u64 tsf)
+{
+ struct vnt_private *priv = hw->priv;
+
+ CARDvUpdateNextTBTT(priv, tsf, vif->bss_conf.beacon_int);
+}
+
+static void vnt_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+{
+ struct vnt_private *priv = hw->priv;
+
+ /* reset TSF counter */
+ iowrite8(TFTCTL_TSFCNTRST, priv->port_offset + MAC_REG_TFTCTL);
+}
+
+static const struct ieee80211_ops vnt_mac_ops = {
+ .tx = vnt_tx_80211,
+ .wake_tx_queue = ieee80211_handle_wake_tx_queue,
+ .start = vnt_start,
+ .stop = vnt_stop,
+ .add_interface = vnt_add_interface,
+ .remove_interface = vnt_remove_interface,
+ .config = vnt_config,
+ .bss_info_changed = vnt_bss_info_changed,
+ .prepare_multicast = vnt_prepare_multicast,
+ .configure_filter = vnt_configure,
+ .set_key = vnt_set_key,
+ .get_stats = vnt_get_stats,
+ .get_tsf = vnt_get_tsf,
+ .set_tsf = vnt_set_tsf,
+ .reset_tsf = vnt_reset_tsf,
+};
+
+static int vnt_init(struct vnt_private *priv)
+{
+ SET_IEEE80211_PERM_ADDR(priv->hw, priv->abyCurrentNetAddr);
+
+ vnt_init_bands(priv);
+
+ if (ieee80211_register_hw(priv->hw))
+ return -ENODEV;
+
+ priv->mac_hw = true;
+
+ CARDbRadioPowerOff(priv);
+
+ return 0;
+}
+
+static int
+vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent)
+{
+ struct vnt_private *priv;
+ struct ieee80211_hw *hw;
+ struct wiphy *wiphy;
+ int rc;
+
+ dev_notice(&pcid->dev,
+ "%s Ver. %s\n", DEVICE_FULL_DRV_NAM, DEVICE_VERSION);
+
+ dev_notice(&pcid->dev,
+ "Copyright (c) 2003 VIA Networking Technologies, Inc.\n");
+
+ hw = ieee80211_alloc_hw(sizeof(*priv), &vnt_mac_ops);
+ if (!hw) {
+ dev_err(&pcid->dev, "could not register ieee80211_hw\n");
+ return -ENOMEM;
+ }
+
+ priv = hw->priv;
+ priv->pcid = pcid;
+
+ spin_lock_init(&priv->lock);
+
+ priv->hw = hw;
+
+ SET_IEEE80211_DEV(priv->hw, &pcid->dev);
+
+ if (pci_enable_device(pcid)) {
+ device_free_info(priv);
+ return -ENODEV;
+ }
+
+ dev_dbg(&pcid->dev,
+ "Before get pci_info memaddr is %x\n", priv->memaddr);
+
+ pci_set_master(pcid);
+
+ priv->memaddr = pci_resource_start(pcid, 0);
+ priv->ioaddr = pci_resource_start(pcid, 1);
+ priv->port_offset = ioremap(priv->memaddr & PCI_BASE_ADDRESS_MEM_MASK,
+ 256);
+ if (!priv->port_offset) {
+ dev_err(&pcid->dev, ": Failed to IO remapping ..\n");
+ device_free_info(priv);
+ return -ENODEV;
+ }
+
+ rc = pci_request_regions(pcid, DEVICE_NAME);
+ if (rc) {
+ dev_err(&pcid->dev, ": Failed to find PCI device\n");
+ device_free_info(priv);
+ return -ENODEV;
+ }
+
+ if (dma_set_mask(&pcid->dev, DMA_BIT_MASK(32))) {
+ dev_err(&pcid->dev, ": Failed to set dma 32 bit mask\n");
+ device_free_info(priv);
+ return -ENODEV;
+ }
+
+ INIT_WORK(&priv->interrupt_work, vnt_interrupt_work);
+
+ /* do reset */
+ if (!MACbSoftwareReset(priv)) {
+ dev_err(&pcid->dev, ": Failed to access MAC hardware..\n");
+ device_free_info(priv);
+ return -ENODEV;
+ }
+ /* initial to reload eeprom */
+ MACvInitialize(priv);
+ vt6655_mac_read_ether_addr(priv->port_offset, priv->abyCurrentNetAddr);
+
+ /* Get RFType */
+ priv->byRFType = SROMbyReadEmbedded(priv->port_offset, EEP_OFS_RFTYPE);
+ priv->byRFType &= RF_MASK;
+
+ dev_dbg(&pcid->dev, "RF Type = %x\n", priv->byRFType);
+
+ device_get_options(priv);
+ device_set_options(priv);
+
+ wiphy = priv->hw->wiphy;
+
+ wiphy->frag_threshold = FRAG_THRESH_DEF;
+ wiphy->rts_threshold = RTS_THRESH_DEF;
+ wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
+ BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP);
+
+ ieee80211_hw_set(priv->hw, TIMING_BEACON_ONLY);
+ ieee80211_hw_set(priv->hw, SIGNAL_DBM);
+ ieee80211_hw_set(priv->hw, RX_INCLUDES_FCS);
+ ieee80211_hw_set(priv->hw, REPORTS_TX_ACK_STATUS);
+ ieee80211_hw_set(priv->hw, SUPPORTS_PS);
+
+ priv->hw->max_signal = 100;
+
+ if (vnt_init(priv)) {
+ device_free_info(priv);
+ return -ENODEV;
+ }
+
+ device_print_info(priv);
+ pci_set_drvdata(pcid, priv);
+
+ return 0;
+}
+
+/*------------------------------------------------------------------*/
+
+static int __maybe_unused vt6655_suspend(struct device *dev_d)
+{
+ struct vnt_private *priv = dev_get_drvdata(dev_d);
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ MACbShutdown(priv);
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return 0;
+}
+
+static int __maybe_unused vt6655_resume(struct device *dev_d)
+{
+ device_wakeup_disable(dev_d);
+
+ return 0;
+}
+
+MODULE_DEVICE_TABLE(pci, vt6655_pci_id_table);
+
+static SIMPLE_DEV_PM_OPS(vt6655_pm_ops, vt6655_suspend, vt6655_resume);
+
+static struct pci_driver device_driver = {
+ .name = DEVICE_NAME,
+ .id_table = vt6655_pci_id_table,
+ .probe = vt6655_probe,
+ .remove = vt6655_remove,
+ .driver.pm = &vt6655_pm_ops,
+};
+
+module_pci_driver(device_driver);
diff --git a/drivers/staging/vt6655/dpc.c b/drivers/staging/vt6655/dpc.c
new file mode 100644
index 0000000000..c6ed3537f4
--- /dev/null
+++ b/drivers/staging/vt6655/dpc.c
@@ -0,0 +1,145 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * Purpose: handle dpc rx functions
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: May 20, 2003
+ *
+ * Functions:
+ *
+ * Revision History:
+ *
+ */
+
+#include "device.h"
+#include "baseband.h"
+#include "rf.h"
+#include "dpc.h"
+
+static bool vnt_rx_data(struct vnt_private *priv, struct sk_buff *skb,
+ u16 bytes_received)
+{
+ struct ieee80211_hw *hw = priv->hw;
+ struct ieee80211_supported_band *sband;
+ struct ieee80211_rx_status rx_status = { 0 };
+ struct ieee80211_hdr *hdr;
+ __le16 fc;
+ u8 *rsr, *new_rsr, *rssi;
+ __le64 *tsf_time;
+ u16 frame_size;
+ int ii, r;
+ u8 *rx_rate;
+ u8 *skb_data;
+ u8 rate_idx = 0;
+ u8 rate[MAX_RATE] = {2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108};
+ long rx_dbm;
+
+ /* [31:16]RcvByteCount ( not include 4-byte Status ) */
+ frame_size = le16_to_cpu(*((__le16 *)(skb->data + 2)));
+ if (frame_size > 2346 || frame_size < 14) {
+ dev_dbg(&priv->pcid->dev, "------- WRONG Length 1\n");
+ return false;
+ }
+
+ skb_data = (u8 *)skb->data;
+
+ rx_rate = skb_data + 1;
+
+ sband = hw->wiphy->bands[hw->conf.chandef.chan->band];
+
+ for (r = RATE_1M; r < MAX_RATE; r++) {
+ if (*rx_rate == rate[r])
+ break;
+ }
+
+ priv->rx_rate = r;
+
+ for (ii = 0; ii < sband->n_bitrates; ii++) {
+ if (sband->bitrates[ii].hw_value == r) {
+ rate_idx = ii;
+ break;
+ }
+ }
+
+ if (ii == sband->n_bitrates) {
+ dev_dbg(&priv->pcid->dev, "Wrong RxRate %x\n", *rx_rate);
+ return false;
+ }
+
+ tsf_time = (__le64 *)(skb_data + bytes_received - 12);
+ new_rsr = skb_data + bytes_received - 3;
+ rssi = skb_data + bytes_received - 2;
+ rsr = skb_data + bytes_received - 1;
+ if (*rsr & (RSR_IVLDTYP | RSR_IVLDLEN))
+ return false;
+
+ RFvRSSITodBm(priv, *rssi, &rx_dbm);
+
+ priv->byBBPreEDRSSI = (u8)rx_dbm + 1;
+ priv->current_rssi = *rssi;
+
+ skb_pull(skb, 4);
+ skb_trim(skb, frame_size);
+
+ rx_status.mactime = le64_to_cpu(*tsf_time);
+ rx_status.band = hw->conf.chandef.chan->band;
+ rx_status.signal = rx_dbm;
+ rx_status.flag = 0;
+ rx_status.freq = hw->conf.chandef.chan->center_freq;
+
+ if (!(*rsr & RSR_CRCOK))
+ rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
+
+ hdr = (struct ieee80211_hdr *)(skb->data);
+ fc = hdr->frame_control;
+
+ rx_status.rate_idx = rate_idx;
+
+ if (ieee80211_has_protected(fc)) {
+ if (priv->local_id > REV_ID_VT3253_A1)
+ rx_status.flag |= RX_FLAG_DECRYPTED;
+
+ /* Drop packet */
+ if (!(*new_rsr & NEWRSR_DECRYPTOK))
+ return false;
+ }
+
+ memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
+
+ ieee80211_rx_irqsafe(priv->hw, skb);
+
+ return true;
+}
+
+bool vnt_receive_frame(struct vnt_private *priv, struct vnt_rx_desc *curr_rd)
+{
+ struct vnt_rd_info *rd_info = curr_rd->rd_info;
+ struct sk_buff *skb;
+ u16 frame_size;
+
+ skb = rd_info->skb;
+
+ dma_unmap_single(&priv->pcid->dev, rd_info->skb_dma,
+ priv->rx_buf_sz, DMA_FROM_DEVICE);
+
+ frame_size = le16_to_cpu(curr_rd->rd1.req_count)
+ - le16_to_cpu(curr_rd->rd0.res_count);
+
+ if ((frame_size > 2364) || (frame_size < 33)) {
+ /* Frame Size error drop this packet.*/
+ dev_dbg(&priv->pcid->dev, "Wrong frame size %d\n", frame_size);
+ dev_kfree_skb_irq(skb);
+ return true;
+ }
+
+ if (vnt_rx_data(priv, skb, frame_size))
+ return true;
+
+ dev_kfree_skb_irq(skb);
+
+ return true;
+}
diff --git a/drivers/staging/vt6655/dpc.h b/drivers/staging/vt6655/dpc.h
new file mode 100644
index 0000000000..40364c0ab7
--- /dev/null
+++ b/drivers/staging/vt6655/dpc.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * Purpose:
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Jun. 27, 2002
+ *
+ */
+
+#ifndef __DPC_H__
+#define __DPC_H__
+
+#include "device.h"
+
+bool vnt_receive_frame(struct vnt_private *priv, struct vnt_rx_desc *curr_rd);
+
+#endif /* __RXTX_H__ */
diff --git a/drivers/staging/vt6655/key.c b/drivers/staging/vt6655/key.c
new file mode 100644
index 0000000000..1469015eb5
--- /dev/null
+++ b/drivers/staging/vt6655/key.c
@@ -0,0 +1,143 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * Purpose: Implement functions for 802.11i Key management
+ *
+ * Author: Jerry Chen
+ *
+ * Date: May 29, 2003
+ *
+ */
+
+#include "key.h"
+#include "mac.h"
+
+static int vnt_set_keymode(struct ieee80211_hw *hw, u8 *mac_addr,
+ struct ieee80211_key_conf *key, u32 key_type,
+ u32 mode, bool onfly_latch)
+{
+ struct vnt_private *priv = hw->priv;
+ u8 broadcast[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+ u16 key_mode = 0;
+ u32 entry = 0;
+ u8 *bssid;
+ u8 key_inx = key->keyidx;
+ u8 i;
+
+ if (mac_addr)
+ bssid = mac_addr;
+ else
+ bssid = &broadcast[0];
+
+ if (key_type != VNT_KEY_DEFAULTKEY) {
+ for (i = 0; i < (MAX_KEY_TABLE - 1); i++) {
+ if (!test_bit(i, &priv->key_entry_inuse)) {
+ set_bit(i, &priv->key_entry_inuse);
+
+ key->hw_key_idx = i;
+ entry = key->hw_key_idx;
+ break;
+ }
+ }
+ }
+
+ switch (key_type) {
+ case VNT_KEY_DEFAULTKEY:
+ /* default key last entry */
+ entry = MAX_KEY_TABLE - 1;
+ key->hw_key_idx = entry;
+ fallthrough;
+ case VNT_KEY_ALLGROUP:
+ key_mode |= VNT_KEY_ALLGROUP;
+ if (onfly_latch)
+ key_mode |= VNT_KEY_ONFLY_ALL;
+ fallthrough;
+ case VNT_KEY_GROUP_ADDRESS:
+ key_mode |= mode;
+ fallthrough;
+ case VNT_KEY_GROUP:
+ key_mode |= (mode << 4);
+ key_mode |= VNT_KEY_GROUP;
+ break;
+ case VNT_KEY_PAIRWISE:
+ key_mode |= mode;
+ key_inx = 4;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (onfly_latch)
+ key_mode |= VNT_KEY_ONFLY;
+
+ if (mode == KEY_CTL_WEP) {
+ if (key->keylen == WLAN_KEY_LEN_WEP40)
+ key->key[15] &= 0x7f;
+ if (key->keylen == WLAN_KEY_LEN_WEP104)
+ key->key[15] |= 0x80;
+ }
+
+ MACvSetKeyEntry(priv, key_mode, entry, key_inx,
+ bssid, (u32 *)key->key, priv->local_id);
+
+ return 0;
+}
+
+int vnt_set_keys(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
+ struct ieee80211_vif *vif, struct ieee80211_key_conf *key)
+{
+ struct ieee80211_bss_conf *conf = &vif->bss_conf;
+ struct vnt_private *priv = hw->priv;
+ u8 *mac_addr = NULL;
+ u8 key_dec_mode = 0;
+ int ret = 0;
+ u32 u;
+
+ if (sta)
+ mac_addr = &sta->addr[0];
+
+ switch (key->cipher) {
+ case 0:
+ for (u = 0 ; u < MAX_KEY_TABLE; u++)
+ MACvDisableKeyEntry(priv, u);
+ return ret;
+
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
+ for (u = 0; u < MAX_KEY_TABLE; u++)
+ MACvDisableKeyEntry(priv, u);
+
+ vnt_set_keymode(hw, mac_addr,
+ key, VNT_KEY_DEFAULTKEY, KEY_CTL_WEP, true);
+
+ key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+
+ return ret;
+ case WLAN_CIPHER_SUITE_TKIP:
+ key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
+ key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+
+ key_dec_mode = KEY_CTL_TKIP;
+
+ break;
+ case WLAN_CIPHER_SUITE_CCMP:
+ key_dec_mode = KEY_CTL_CCMP;
+
+ key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+ }
+
+ if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
+ vnt_set_keymode(hw, mac_addr,
+ key, VNT_KEY_PAIRWISE, key_dec_mode, true);
+ } else {
+ vnt_set_keymode(hw, mac_addr,
+ key, VNT_KEY_DEFAULTKEY, key_dec_mode, true);
+
+ vnt_set_keymode(hw, (u8 *)conf->bssid,
+ key, VNT_KEY_GROUP_ADDRESS, key_dec_mode, true);
+ }
+
+ return 0;
+}
diff --git a/drivers/staging/vt6655/key.h b/drivers/staging/vt6655/key.h
new file mode 100644
index 0000000000..d88da9dfb5
--- /dev/null
+++ b/drivers/staging/vt6655/key.h
@@ -0,0 +1,51 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * Purpose: Implement functions for 802.11i Key management
+ *
+ * Author: Jerry Chen
+ *
+ * Date: May 29, 2003
+ *
+ */
+
+#ifndef __KEY_H__
+#define __KEY_H__
+
+#include <net/mac80211.h>
+
+/*--------------------- Export Definitions -------------------------*/
+#define MAX_GROUP_KEY 4
+#define MAX_KEY_TABLE 11
+#define MAX_KEY_LEN 32
+#define AES_KEY_LEN 16
+
+#define AUTHENTICATOR_KEY 0x10000000
+#define USE_KEYRSC 0x20000000
+#define PAIRWISE_KEY 0x40000000
+#define TRANSMIT_KEY 0x80000000
+
+#define GROUP_KEY 0x00000000
+
+#define KEY_CTL_WEP 0x00
+#define KEY_CTL_NONE 0x01
+#define KEY_CTL_TKIP 0x02
+#define KEY_CTL_CCMP 0x03
+#define KEY_CTL_INVALID 0xFF
+
+#define VNT_KEY_DEFAULTKEY 0x1
+#define VNT_KEY_GROUP_ADDRESS 0x2
+#define VNT_KEY_ALLGROUP 0x4
+#define VNT_KEY_GROUP 0x40
+#define VNT_KEY_PAIRWISE 0x00
+#define VNT_KEY_ONFLY 0x8000
+#define VNT_KEY_ONFLY_ALL 0x4000
+
+struct vnt_private;
+
+int vnt_set_keys(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
+ struct ieee80211_vif *vif, struct ieee80211_key_conf *key);
+
+#endif /* __KEY_H__ */
diff --git a/drivers/staging/vt6655/mac.c b/drivers/staging/vt6655/mac.c
new file mode 100644
index 0000000000..b4ebc7d319
--- /dev/null
+++ b/drivers/staging/vt6655/mac.c
@@ -0,0 +1,851 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * Purpose: MAC routines
+ *
+ * Author: Tevin Chen
+ *
+ * Date: May 21, 1996
+ *
+ * Functions:
+ * vt6655_mac_is_reg_bits_off - Test if All test Bits Off
+ * vt6655_mac_set_short_retry_limit - Set 802.11 Short Retry limit
+ * MACvSetLongRetryLimit - Set 802.11 Long Retry limit
+ * vt6655_mac_set_loopback_mode - Set MAC Loopback Mode
+ * vt6655_mac_save_context - Save Context of MAC Registers
+ * vt6655_mac_restore_context - Restore Context of MAC Registers
+ * MACbSoftwareReset - Software Reset MAC
+ * vt6655_mac_safe_rx_off - Turn Off MAC Rx
+ * vt6655_mac_safe_tx_off - Turn Off MAC Tx
+ * vt6655_mac_safe_stop - Stop MAC function
+ * MACbShutdown - Shut down MAC
+ * MACvInitialize - Initialize MAC
+ * MACvSetCurrRxDescAddr - Set Rx Descriptors Address
+ * MACvSetCurrTx0DescAddr - Set Tx0 Descriptors Address
+ * MACvSetCurrTx1DescAddr - Set Tx1 Descriptors Address
+ * MACvTimer0MicroSDelay - Micro Second Delay Loop by MAC
+ *
+ * Revision History:
+ * 08-22-2003 Kyle Hsu : Porting MAC functions from sim53
+ * 09-03-2003 Bryan YC Fan : Add MACvClearBusSusInd()&
+ * MACvEnableBusSusEn()
+ * 09-18-2003 Jerry Chen : Add MACvSetKeyEntry & MACvDisableKeyEntry
+ *
+ */
+
+#include "mac.h"
+
+void vt6655_mac_reg_bits_on(void __iomem *iobase, const u8 reg_offset, const u8 bit_mask)
+{
+ unsigned char reg_value;
+
+ reg_value = ioread8(iobase + reg_offset);
+ iowrite8(reg_value | bit_mask, iobase + reg_offset);
+}
+
+void vt6655_mac_word_reg_bits_on(void __iomem *iobase, const u8 reg_offset, const u16 bit_mask)
+{
+ unsigned short reg_value;
+
+ reg_value = ioread16(iobase + reg_offset);
+ iowrite16(reg_value | (bit_mask), iobase + reg_offset);
+}
+
+void vt6655_mac_reg_bits_off(void __iomem *iobase, const u8 reg_offset, const u8 bit_mask)
+{
+ unsigned char reg_value;
+
+ reg_value = ioread8(iobase + reg_offset);
+ iowrite8(reg_value & ~(bit_mask), iobase + reg_offset);
+}
+
+void vt6655_mac_word_reg_bits_off(void __iomem *iobase, const u8 reg_offset, const u16 bit_mask)
+{
+ unsigned short reg_value;
+
+ reg_value = ioread16(iobase + reg_offset);
+ iowrite16(reg_value & ~(bit_mask), iobase + reg_offset);
+}
+
+static void vt6655_mac_clear_stck_ds(void __iomem *iobase)
+{
+ u8 reg_value;
+
+ reg_value = ioread8(iobase + MAC_REG_STICKHW);
+ reg_value = reg_value & 0xFC;
+ iowrite8(reg_value, iobase + MAC_REG_STICKHW);
+}
+
+/*
+ * Description:
+ * Test if all test bits off
+ *
+ * Parameters:
+ * In:
+ * io_base - Base Address for MAC
+ * reg_offset - Offset of MAC Register
+ * mask - Test bits
+ * Out:
+ * none
+ *
+ * Return Value: true if all test bits Off; otherwise false
+ *
+ */
+static bool vt6655_mac_is_reg_bits_off(struct vnt_private *priv,
+ unsigned char reg_offset,
+ unsigned char mask)
+{
+ void __iomem *io_base = priv->port_offset;
+
+ return !(ioread8(io_base + reg_offset) & mask);
+}
+
+/*
+ * Description:
+ * Set 802.11 Short Retry Limit
+ *
+ * Parameters:
+ * In:
+ * io_base - Base Address for MAC
+ * retry_limit - Retry Limit
+ * Out:
+ * none
+ *
+ * Return Value: none
+ *
+ */
+void vt6655_mac_set_short_retry_limit(struct vnt_private *priv, unsigned char retry_limit)
+{
+ void __iomem *io_base = priv->port_offset;
+ /* set SRT */
+ iowrite8(retry_limit, io_base + MAC_REG_SRT);
+}
+
+/*
+ * Description:
+ * Set 802.11 Long Retry Limit
+ *
+ * Parameters:
+ * In:
+ * io_base - Base Address for MAC
+ * byRetryLimit- Retry Limit
+ * Out:
+ * none
+ *
+ * Return Value: none
+ *
+ */
+void MACvSetLongRetryLimit(struct vnt_private *priv,
+ unsigned char byRetryLimit)
+{
+ void __iomem *io_base = priv->port_offset;
+ /* set LRT */
+ iowrite8(byRetryLimit, io_base + MAC_REG_LRT);
+}
+
+/*
+ * Description:
+ * Set MAC Loopback mode
+ *
+ * Parameters:
+ * In:
+ * io_base - Base Address for MAC
+ * loopback_mode - Loopback Mode
+ * Out:
+ * none
+ *
+ * Return Value: none
+ *
+ */
+static void vt6655_mac_set_loopback_mode(struct vnt_private *priv, u8 loopback_mode)
+{
+ void __iomem *io_base = priv->port_offset;
+
+ loopback_mode <<= 6;
+ /* set TCR */
+ iowrite8((ioread8(io_base + MAC_REG_TEST) & 0x3f) | loopback_mode, io_base + MAC_REG_TEST);
+}
+
+/*
+ * Description:
+ * Save MAC registers to context buffer
+ *
+ * Parameters:
+ * In:
+ * io_base - Base Address for MAC
+ * Out:
+ * cxt_buf - Context buffer
+ *
+ * Return Value: none
+ *
+ */
+static void vt6655_mac_save_context(struct vnt_private *priv, u8 *cxt_buf)
+{
+ void __iomem *io_base = priv->port_offset;
+
+ /* read page0 register */
+ memcpy_fromio(cxt_buf, io_base, MAC_MAX_CONTEXT_SIZE_PAGE0);
+
+ VT6655_MAC_SELECT_PAGE1(io_base);
+
+ /* read page1 register */
+ memcpy_fromio(cxt_buf + MAC_MAX_CONTEXT_SIZE_PAGE0, io_base,
+ MAC_MAX_CONTEXT_SIZE_PAGE1);
+
+ VT6655_MAC_SELECT_PAGE0(io_base);
+}
+
+/*
+ * Description:
+ * Restore MAC registers from context buffer
+ *
+ * Parameters:
+ * In:
+ * io_base - Base Address for MAC
+ * cxt_buf - Context buffer
+ * Out:
+ * none
+ *
+ * Return Value: none
+ *
+ */
+static void vt6655_mac_restore_context(struct vnt_private *priv, u8 *cxt_buf)
+{
+ void __iomem *io_base = priv->port_offset;
+
+ VT6655_MAC_SELECT_PAGE1(io_base);
+ /* restore page1 */
+ memcpy_toio(io_base, cxt_buf + MAC_MAX_CONTEXT_SIZE_PAGE0,
+ MAC_MAX_CONTEXT_SIZE_PAGE1);
+
+ VT6655_MAC_SELECT_PAGE0(io_base);
+
+ /* restore RCR,TCR,IMR... */
+ memcpy_toio(io_base + MAC_REG_RCR, cxt_buf + MAC_REG_RCR,
+ MAC_REG_ISR - MAC_REG_RCR);
+
+ /* restore MAC Config. */
+ memcpy_toio(io_base + MAC_REG_LRT, cxt_buf + MAC_REG_LRT,
+ MAC_REG_PAGE1SEL - MAC_REG_LRT);
+
+ iowrite8(*(cxt_buf + MAC_REG_CFG), io_base + MAC_REG_CFG);
+
+ /* restore PS Config. */
+ memcpy_toio(io_base + MAC_REG_PSCFG, cxt_buf + MAC_REG_PSCFG,
+ MAC_REG_BBREGCTL - MAC_REG_PSCFG);
+
+ /* restore CURR_RX_DESC_ADDR, CURR_TX_DESC_ADDR */
+ iowrite32(*(u32 *)(cxt_buf + MAC_REG_TXDMAPTR0),
+ io_base + MAC_REG_TXDMAPTR0);
+ iowrite32(*(u32 *)(cxt_buf + MAC_REG_AC0DMAPTR),
+ io_base + MAC_REG_AC0DMAPTR);
+ iowrite32(*(u32 *)(cxt_buf + MAC_REG_BCNDMAPTR),
+ io_base + MAC_REG_BCNDMAPTR);
+ iowrite32(*(u32 *)(cxt_buf + MAC_REG_RXDMAPTR0),
+ io_base + MAC_REG_RXDMAPTR0);
+ iowrite32(*(u32 *)(cxt_buf + MAC_REG_RXDMAPTR1),
+ io_base + MAC_REG_RXDMAPTR1);
+}
+
+/*
+ * Description:
+ * Software Reset MAC
+ *
+ * Parameters:
+ * In:
+ * io_base - Base Address for MAC
+ * Out:
+ * none
+ *
+ * Return Value: true if Reset Success; otherwise false
+ *
+ */
+bool MACbSoftwareReset(struct vnt_private *priv)
+{
+ void __iomem *io_base = priv->port_offset;
+ unsigned short ww;
+
+ /* turn on HOSTCR_SOFTRST, just write 0x01 to reset */
+ iowrite8(0x01, io_base + MAC_REG_HOSTCR);
+
+ for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+ if (!(ioread8(io_base + MAC_REG_HOSTCR) & HOSTCR_SOFTRST))
+ break;
+ }
+ if (ww == W_MAX_TIMEOUT)
+ return false;
+ return true;
+}
+
+/*
+ * Description:
+ * save some important register's value, then do reset, then restore
+ * register's value
+ *
+ * Parameters:
+ * In:
+ * io_base - Base Address for MAC
+ * Out:
+ * none
+ *
+ * Return Value: true if success; otherwise false
+ *
+ */
+static void vt6655_mac_save_soft_reset(struct vnt_private *priv)
+{
+ u8 tmp_reg_data[MAC_MAX_CONTEXT_SIZE_PAGE0 + MAC_MAX_CONTEXT_SIZE_PAGE1];
+
+ /* PATCH....
+ * save some important register's value, then do
+ * reset, then restore register's value
+ */
+ /* save MAC context */
+ vt6655_mac_save_context(priv, tmp_reg_data);
+ /* do reset */
+ MACbSoftwareReset(priv);
+ /* restore MAC context, except CR0 */
+ vt6655_mac_restore_context(priv, tmp_reg_data);
+}
+
+/*
+ * Description:
+ * Turn Off MAC Rx
+ *
+ * Parameters:
+ * In:
+ * io_base - Base Address for MAC
+ * Out:
+ * none
+ *
+ * Return Value: true if success; otherwise false
+ *
+ */
+static bool vt6655_mac_safe_rx_off(struct vnt_private *priv)
+{
+ void __iomem *io_base = priv->port_offset;
+ unsigned short ww;
+
+ /* turn off wow temp for turn off Rx safely */
+
+ /* Clear RX DMA0,1 */
+ iowrite32(DMACTL_CLRRUN, io_base + MAC_REG_RXDMACTL0);
+ iowrite32(DMACTL_CLRRUN, io_base + MAC_REG_RXDMACTL1);
+ for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+ if (!(ioread32(io_base + MAC_REG_RXDMACTL0) & DMACTL_RUN))
+ break;
+ }
+ if (ww == W_MAX_TIMEOUT) {
+ pr_debug(" DBG_PORT80(0x10)\n");
+ return false;
+ }
+ for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+ if (!(ioread32(io_base + MAC_REG_RXDMACTL1) & DMACTL_RUN))
+ break;
+ }
+ if (ww == W_MAX_TIMEOUT) {
+ pr_debug(" DBG_PORT80(0x11)\n");
+ return false;
+ }
+
+ /* try to safe shutdown RX */
+ vt6655_mac_reg_bits_off(io_base, MAC_REG_HOSTCR, HOSTCR_RXON);
+ /* W_MAX_TIMEOUT is the timeout period */
+ for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+ if (!(ioread8(io_base + MAC_REG_HOSTCR) & HOSTCR_RXONST))
+ break;
+ }
+ if (ww == W_MAX_TIMEOUT) {
+ pr_debug(" DBG_PORT80(0x12)\n");
+ return false;
+ }
+ return true;
+}
+
+/*
+ * Description:
+ * Turn Off MAC Tx
+ *
+ * Parameters:
+ * In:
+ * io_base - Base Address for MAC
+ * Out:
+ * none
+ *
+ * Return Value: true if success; otherwise false
+ *
+ */
+static bool vt6655_mac_safe_tx_off(struct vnt_private *priv)
+{
+ void __iomem *io_base = priv->port_offset;
+ unsigned short ww;
+
+ /* Clear TX DMA */
+ /* Tx0 */
+ iowrite32(DMACTL_CLRRUN, io_base + MAC_REG_TXDMACTL0);
+ /* AC0 */
+ iowrite32(DMACTL_CLRRUN, io_base + MAC_REG_AC0DMACTL);
+
+ for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+ if (!(ioread32(io_base + MAC_REG_TXDMACTL0) & DMACTL_RUN))
+ break;
+ }
+ if (ww == W_MAX_TIMEOUT) {
+ pr_debug(" DBG_PORT80(0x20)\n");
+ return false;
+ }
+ for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+ if (!(ioread32(io_base + MAC_REG_AC0DMACTL) & DMACTL_RUN))
+ break;
+ }
+ if (ww == W_MAX_TIMEOUT) {
+ pr_debug(" DBG_PORT80(0x21)\n");
+ return false;
+ }
+
+ /* try to safe shutdown TX */
+ vt6655_mac_reg_bits_off(io_base, MAC_REG_HOSTCR, HOSTCR_TXON);
+
+ /* W_MAX_TIMEOUT is the timeout period */
+ for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+ if (!(ioread8(io_base + MAC_REG_HOSTCR) & HOSTCR_TXONST))
+ break;
+ }
+ if (ww == W_MAX_TIMEOUT) {
+ pr_debug(" DBG_PORT80(0x24)\n");
+ return false;
+ }
+ return true;
+}
+
+/*
+ * Description:
+ * Stop MAC function
+ *
+ * Parameters:
+ * In:
+ * io_base - Base Address for MAC
+ * Out:
+ * none
+ *
+ * Return Value: true if success; otherwise false
+ *
+ */
+static bool vt6655_mac_safe_stop(struct vnt_private *priv)
+{
+ void __iomem *io_base = priv->port_offset;
+
+ vt6655_mac_reg_bits_off(io_base, MAC_REG_TCR, TCR_AUTOBCNTX);
+
+ if (!vt6655_mac_safe_rx_off(priv)) {
+ pr_debug(" vt6655_mac_safe_rx_off == false)\n");
+ vt6655_mac_save_soft_reset(priv);
+ return false;
+ }
+ if (!vt6655_mac_safe_tx_off(priv)) {
+ pr_debug(" vt6655_mac_safe_tx_off == false)\n");
+ vt6655_mac_save_soft_reset(priv);
+ return false;
+ }
+
+ vt6655_mac_reg_bits_off(io_base, MAC_REG_HOSTCR, HOSTCR_MACEN);
+
+ return true;
+}
+
+/*
+ * Description:
+ * Shut Down MAC
+ *
+ * Parameters:
+ * In:
+ * io_base - Base Address for MAC
+ * Out:
+ * none
+ *
+ * Return Value: true if success; otherwise false
+ *
+ */
+bool MACbShutdown(struct vnt_private *priv)
+{
+ void __iomem *io_base = priv->port_offset;
+ /* disable MAC IMR */
+ iowrite32(0, io_base + MAC_REG_IMR);
+ vt6655_mac_set_loopback_mode(priv, MAC_LB_INTERNAL);
+ /* stop the adapter */
+ if (!vt6655_mac_safe_stop(priv)) {
+ vt6655_mac_set_loopback_mode(priv, MAC_LB_NONE);
+ return false;
+ }
+ vt6655_mac_set_loopback_mode(priv, MAC_LB_NONE);
+ return true;
+}
+
+/*
+ * Description:
+ * Initialize MAC
+ *
+ * Parameters:
+ * In:
+ * io_base - Base Address for MAC
+ * Out:
+ * none
+ *
+ * Return Value: none
+ *
+ */
+void MACvInitialize(struct vnt_private *priv)
+{
+ void __iomem *io_base = priv->port_offset;
+ /* clear sticky bits */
+ vt6655_mac_clear_stck_ds(io_base);
+ /* disable force PME-enable */
+ iowrite8(PME_OVR, io_base + MAC_REG_PMC1);
+ /* only 3253 A */
+
+ /* do reset */
+ MACbSoftwareReset(priv);
+
+ /* reset TSF counter */
+ iowrite8(TFTCTL_TSFCNTRST, io_base + MAC_REG_TFTCTL);
+ /* enable TSF counter */
+ iowrite8(TFTCTL_TSFCNTREN, io_base + MAC_REG_TFTCTL);
+}
+
+/*
+ * Description:
+ * Set the chip with current rx descriptor address
+ *
+ * Parameters:
+ * In:
+ * io_base - Base Address for MAC
+ * curr_desc_addr - Descriptor Address
+ * Out:
+ * none
+ *
+ * Return Value: none
+ *
+ */
+void vt6655_mac_set_curr_rx_0_desc_addr(struct vnt_private *priv, u32 curr_desc_addr)
+{
+ void __iomem *io_base = priv->port_offset;
+ unsigned short ww;
+ unsigned char org_dma_ctl;
+
+ org_dma_ctl = ioread8(io_base + MAC_REG_RXDMACTL0);
+ if (org_dma_ctl & DMACTL_RUN)
+ iowrite8(DMACTL_RUN, io_base + MAC_REG_RXDMACTL0 + 2);
+
+ for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+ if (!(ioread8(io_base + MAC_REG_RXDMACTL0) & DMACTL_RUN))
+ break;
+ }
+
+ iowrite32(curr_desc_addr, io_base + MAC_REG_RXDMAPTR0);
+ if (org_dma_ctl & DMACTL_RUN)
+ iowrite8(DMACTL_RUN, io_base + MAC_REG_RXDMACTL0);
+}
+
+/*
+ * Description:
+ * Set the chip with current rx descriptor address
+ *
+ * Parameters:
+ * In:
+ * io_base - Base Address for MAC
+ * curr_desc_addr - Descriptor Address
+ * Out:
+ * none
+ *
+ * Return Value: none
+ *
+ */
+void vt6655_mac_set_curr_rx_1_desc_addr(struct vnt_private *priv, u32 curr_desc_addr)
+{
+ void __iomem *io_base = priv->port_offset;
+ unsigned short ww;
+ unsigned char org_dma_ctl;
+
+ org_dma_ctl = ioread8(io_base + MAC_REG_RXDMACTL1);
+ if (org_dma_ctl & DMACTL_RUN)
+ iowrite8(DMACTL_RUN, io_base + MAC_REG_RXDMACTL1 + 2);
+
+ for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+ if (!(ioread8(io_base + MAC_REG_RXDMACTL1) & DMACTL_RUN))
+ break;
+ }
+
+ iowrite32(curr_desc_addr, io_base + MAC_REG_RXDMAPTR1);
+ if (org_dma_ctl & DMACTL_RUN)
+ iowrite8(DMACTL_RUN, io_base + MAC_REG_RXDMACTL1);
+}
+
+/*
+ * Description:
+ * Set the chip with current tx0 descriptor address
+ *
+ * Parameters:
+ * In:
+ * io_base - Base Address for MAC
+ * curr_desc_addr - Descriptor Address
+ * Out:
+ * none
+ *
+ * Return Value: none
+ *
+ */
+static void vt6655_mac_set_curr_tx_0_desc_addr_ex(struct vnt_private *priv, u32 curr_desc_addr)
+{
+ void __iomem *io_base = priv->port_offset;
+ unsigned short ww;
+ unsigned char org_dma_ctl;
+
+ org_dma_ctl = ioread8(io_base + MAC_REG_TXDMACTL0);
+ if (org_dma_ctl & DMACTL_RUN)
+ iowrite8(DMACTL_RUN, io_base + MAC_REG_TXDMACTL0 + 2);
+
+ for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+ if (!(ioread8(io_base + MAC_REG_TXDMACTL0) & DMACTL_RUN))
+ break;
+ }
+
+ iowrite32(curr_desc_addr, io_base + MAC_REG_TXDMAPTR0);
+ if (org_dma_ctl & DMACTL_RUN)
+ iowrite8(DMACTL_RUN, io_base + MAC_REG_TXDMACTL0);
+}
+
+/*
+ * Description:
+ * Set the chip with current AC0 descriptor address
+ *
+ * Parameters:
+ * In:
+ * io_base - Base Address for MAC
+ * curr_desc_addr - Descriptor Address
+ * Out:
+ * none
+ *
+ * Return Value: none
+ *
+ */
+/* TxDMA1 = AC0DMA */
+static void vt6655_mac_set_curr_ac_0_desc_addr_ex(struct vnt_private *priv, u32 curr_desc_addr)
+{
+ void __iomem *io_base = priv->port_offset;
+ unsigned short ww;
+ unsigned char org_dma_ctl;
+
+ org_dma_ctl = ioread8(io_base + MAC_REG_AC0DMACTL);
+ if (org_dma_ctl & DMACTL_RUN)
+ iowrite8(DMACTL_RUN, io_base + MAC_REG_AC0DMACTL + 2);
+
+ for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+ if (!(ioread8(io_base + MAC_REG_AC0DMACTL) & DMACTL_RUN))
+ break;
+ }
+ if (ww == W_MAX_TIMEOUT)
+ pr_debug(" DBG_PORT80(0x26)\n");
+ iowrite32(curr_desc_addr, io_base + MAC_REG_AC0DMAPTR);
+ if (org_dma_ctl & DMACTL_RUN)
+ iowrite8(DMACTL_RUN, io_base + MAC_REG_AC0DMACTL);
+}
+
+void vt6655_mac_set_curr_tx_desc_addr(int tx_type, struct vnt_private *priv, u32 curr_desc_addr)
+{
+ if (tx_type == TYPE_AC0DMA)
+ vt6655_mac_set_curr_ac_0_desc_addr_ex(priv, curr_desc_addr);
+ else if (tx_type == TYPE_TXDMA0)
+ vt6655_mac_set_curr_tx_0_desc_addr_ex(priv, curr_desc_addr);
+}
+
+/*
+ * Description:
+ * Micro Second Delay via MAC
+ *
+ * Parameters:
+ * In:
+ * io_base - Base Address for MAC
+ * uDelay - Delay time (timer resolution is 4 us)
+ * Out:
+ * none
+ *
+ * Return Value: none
+ *
+ */
+void MACvTimer0MicroSDelay(struct vnt_private *priv, unsigned int uDelay)
+{
+ void __iomem *io_base = priv->port_offset;
+ unsigned char byValue;
+ unsigned int uu, ii;
+
+ iowrite8(0, io_base + MAC_REG_TMCTL0);
+ iowrite32(uDelay, io_base + MAC_REG_TMDATA0);
+ iowrite8((TMCTL_TMD | TMCTL_TE), io_base + MAC_REG_TMCTL0);
+ for (ii = 0; ii < 66; ii++) { /* assume max PCI clock is 66Mhz */
+ for (uu = 0; uu < uDelay; uu++) {
+ byValue = ioread8(io_base + MAC_REG_TMCTL0);
+ if ((byValue == 0) ||
+ (byValue & TMCTL_TSUSP)) {
+ iowrite8(0, io_base + MAC_REG_TMCTL0);
+ return;
+ }
+ }
+ }
+ iowrite8(0, io_base + MAC_REG_TMCTL0);
+}
+
+/*
+ * Description:
+ * Micro Second One shot timer via MAC
+ *
+ * Parameters:
+ * In:
+ * io_base - Base Address for MAC
+ * uDelay - Delay time
+ * Out:
+ * none
+ *
+ * Return Value: none
+ *
+ */
+void MACvOneShotTimer1MicroSec(struct vnt_private *priv,
+ unsigned int uDelayTime)
+{
+ void __iomem *io_base = priv->port_offset;
+
+ iowrite8(0, io_base + MAC_REG_TMCTL1);
+ iowrite32(uDelayTime, io_base + MAC_REG_TMDATA1);
+ iowrite8((TMCTL_TMD | TMCTL_TE), io_base + MAC_REG_TMCTL1);
+}
+
+void MACvSetMISCFifo(struct vnt_private *priv, unsigned short offset,
+ u32 data)
+{
+ void __iomem *io_base = priv->port_offset;
+
+ if (offset > 273)
+ return;
+ iowrite16(offset, io_base + MAC_REG_MISCFFNDEX);
+ iowrite32(data, io_base + MAC_REG_MISCFFDATA);
+ iowrite16(MISCFFCTL_WRITE, io_base + MAC_REG_MISCFFCTL);
+}
+
+bool MACbPSWakeup(struct vnt_private *priv)
+{
+ void __iomem *io_base = priv->port_offset;
+ unsigned int ww;
+ /* Read PSCTL */
+ if (vt6655_mac_is_reg_bits_off(priv, MAC_REG_PSCTL, PSCTL_PS))
+ return true;
+
+ /* Disable PS */
+ vt6655_mac_reg_bits_off(io_base, MAC_REG_PSCTL, PSCTL_PSEN);
+
+ /* Check if SyncFlushOK */
+ for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+ if (ioread8(io_base + MAC_REG_PSCTL) & PSCTL_WAKEDONE)
+ break;
+ }
+ if (ww == W_MAX_TIMEOUT) {
+ pr_debug(" DBG_PORT80(0x33)\n");
+ return false;
+ }
+ return true;
+}
+
+/*
+ * Description:
+ * Set the Key by MISCFIFO
+ *
+ * Parameters:
+ * In:
+ * io_base - Base Address for MAC
+ *
+ * Out:
+ * none
+ *
+ * Return Value: none
+ *
+ */
+
+void MACvSetKeyEntry(struct vnt_private *priv, unsigned short wKeyCtl,
+ unsigned int uEntryIdx, unsigned int uKeyIdx,
+ unsigned char *pbyAddr, u32 *pdwKey,
+ unsigned char local_id)
+{
+ void __iomem *io_base = priv->port_offset;
+ unsigned short offset;
+ u32 data;
+ int ii;
+
+ if (local_id <= 1)
+ return;
+
+ offset = MISCFIFO_KEYETRY0;
+ offset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE);
+
+ data = 0;
+ data |= wKeyCtl;
+ data <<= 16;
+ data |= MAKEWORD(*(pbyAddr + 4), *(pbyAddr + 5));
+ pr_debug("1. offset: %d, Data: %X, KeyCtl:%X\n",
+ offset, data, wKeyCtl);
+
+ iowrite16(offset, io_base + MAC_REG_MISCFFNDEX);
+ iowrite32(data, io_base + MAC_REG_MISCFFDATA);
+ iowrite16(MISCFFCTL_WRITE, io_base + MAC_REG_MISCFFCTL);
+ offset++;
+
+ data = 0;
+ data |= *(pbyAddr + 3);
+ data <<= 8;
+ data |= *(pbyAddr + 2);
+ data <<= 8;
+ data |= *(pbyAddr + 1);
+ data <<= 8;
+ data |= *pbyAddr;
+ pr_debug("2. offset: %d, Data: %X\n", offset, data);
+
+ iowrite16(offset, io_base + MAC_REG_MISCFFNDEX);
+ iowrite32(data, io_base + MAC_REG_MISCFFDATA);
+ iowrite16(MISCFFCTL_WRITE, io_base + MAC_REG_MISCFFCTL);
+ offset++;
+
+ offset += (uKeyIdx * 4);
+ for (ii = 0; ii < 4; ii++) {
+ /* always push 128 bits */
+ pr_debug("3.(%d) offset: %d, Data: %X\n",
+ ii, offset + ii, *pdwKey);
+ iowrite16(offset + ii, io_base + MAC_REG_MISCFFNDEX);
+ iowrite32(*pdwKey++, io_base + MAC_REG_MISCFFDATA);
+ iowrite16(MISCFFCTL_WRITE, io_base + MAC_REG_MISCFFCTL);
+ }
+}
+
+/*
+ * Description:
+ * Disable the Key Entry by MISCFIFO
+ *
+ * Parameters:
+ * In:
+ * io_base - Base Address for MAC
+ *
+ * Out:
+ * none
+ *
+ * Return Value: none
+ *
+ */
+void MACvDisableKeyEntry(struct vnt_private *priv, unsigned int uEntryIdx)
+{
+ void __iomem *io_base = priv->port_offset;
+ unsigned short offset;
+
+ offset = MISCFIFO_KEYETRY0;
+ offset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE);
+
+ iowrite16(offset, io_base + MAC_REG_MISCFFNDEX);
+ iowrite32(0, io_base + MAC_REG_MISCFFDATA);
+ iowrite16(MISCFFCTL_WRITE, io_base + MAC_REG_MISCFFCTL);
+}
diff --git a/drivers/staging/vt6655/mac.h b/drivers/staging/vt6655/mac.h
new file mode 100644
index 0000000000..acf931c3f5
--- /dev/null
+++ b/drivers/staging/vt6655/mac.h
@@ -0,0 +1,580 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * Purpose: MAC routines
+ *
+ * Author: Tevin Chen
+ *
+ * Date: May 21, 1996
+ *
+ * Revision History:
+ * 07-01-2003 Bryan YC Fan: Re-write codes to support VT3253 spec.
+ * 08-25-2003 Kyle Hsu: Porting MAC functions from sim53.
+ * 09-03-2003 Bryan YC Fan: Add vt6655_mac_dis_protect_md & vt6655_mac_en_protect_md
+ */
+
+#ifndef __MAC_H__
+#define __MAC_H__
+
+#include "device.h"
+
+/*--------------------- Export Definitions -------------------------*/
+/* Registers in the MAC */
+#define MAC_MAX_CONTEXT_SIZE_PAGE0 256
+#define MAC_MAX_CONTEXT_SIZE_PAGE1 128
+
+/* Registers not related to 802.11b */
+#define MAC_REG_BCFG0 0x00
+#define MAC_REG_BCFG1 0x01
+#define MAC_REG_FCR0 0x02
+#define MAC_REG_FCR1 0x03
+#define MAC_REG_BISTCMD 0x04
+#define MAC_REG_BISTSR0 0x05
+#define MAC_REG_BISTSR1 0x06
+#define MAC_REG_BISTSR2 0x07
+#define MAC_REG_I2MCSR 0x08
+#define MAC_REG_I2MTGID 0x09
+#define MAC_REG_I2MTGAD 0x0A
+#define MAC_REG_I2MCFG 0x0B
+#define MAC_REG_I2MDIPT 0x0C
+#define MAC_REG_I2MDOPT 0x0E
+#define MAC_REG_PMC0 0x10
+#define MAC_REG_PMC1 0x11
+#define MAC_REG_STICKHW 0x12
+#define MAC_REG_LOCALID 0x14
+#define MAC_REG_TESTCFG 0x15
+#define MAC_REG_JUMPER0 0x16
+#define MAC_REG_JUMPER1 0x17
+#define MAC_REG_TMCTL0 0x18
+#define MAC_REG_TMCTL1 0x19
+#define MAC_REG_TMDATA0 0x1C
+
+/* MAC Parameter related */
+#define MAC_REG_LRT 0x20
+#define MAC_REG_SRT 0x21
+#define MAC_REG_SIFS 0x22
+#define MAC_REG_DIFS 0x23
+#define MAC_REG_EIFS 0x24
+#define MAC_REG_SLOT 0x25
+#define MAC_REG_BI 0x26
+#define MAC_REG_CWMAXMIN0 0x28
+#define MAC_REG_LINKOFFTOTM 0x2A
+#define MAC_REG_SWTMOT 0x2B
+#define MAC_REG_MIBCNTR 0x2C
+#define MAC_REG_RTSOKCNT 0x2C
+#define MAC_REG_RTSFAILCNT 0x2D
+#define MAC_REG_ACKFAILCNT 0x2E
+#define MAC_REG_FCSERRCNT 0x2F
+
+/* TSF Related */
+#define MAC_REG_TSFCNTR 0x30
+#define MAC_REG_NEXTTBTT 0x38
+#define MAC_REG_TSFOFST 0x40
+#define MAC_REG_TFTCTL 0x48
+
+/* WMAC Control/Status Related */
+#define MAC_REG_ENCFG 0x4C
+#define MAC_REG_PAGE1SEL 0x4F
+#define MAC_REG_CFG 0x50
+#define MAC_REG_TEST 0x52
+#define MAC_REG_HOSTCR 0x54
+#define MAC_REG_MACCR 0x55
+#define MAC_REG_RCR 0x56
+#define MAC_REG_TCR 0x57
+#define MAC_REG_IMR 0x58
+#define MAC_REG_ISR 0x5C
+
+/* Power Saving Related */
+#define MAC_REG_PSCFG 0x60
+#define MAC_REG_PSCTL 0x61
+#define MAC_REG_PSPWRSIG 0x62
+#define MAC_REG_BBCR13 0x63
+#define MAC_REG_AIDATIM 0x64
+#define MAC_REG_PWBT 0x66
+#define MAC_REG_WAKEOKTMR 0x68
+#define MAC_REG_CALTMR 0x69
+#define MAC_REG_SYNSPACCNT 0x6A
+#define MAC_REG_WAKSYNOPT 0x6B
+
+/* Baseband/IF Control Group */
+#define MAC_REG_BBREGCTL 0x6C
+#define MAC_REG_CHANNEL 0x6D
+#define MAC_REG_BBREGADR 0x6E
+#define MAC_REG_BBREGDATA 0x6F
+#define MAC_REG_IFREGCTL 0x70
+#define MAC_REG_IFDATA 0x71
+#define MAC_REG_ITRTMSET 0x74
+#define MAC_REG_PAPEDELAY 0x77
+#define MAC_REG_SOFTPWRCTL 0x78
+#define MAC_REG_GPIOCTL0 0x7A
+#define MAC_REG_GPIOCTL1 0x7B
+
+/* MAC DMA Related Group */
+#define MAC_REG_TXDMACTL0 0x7C
+#define MAC_REG_TXDMAPTR0 0x80
+#define MAC_REG_AC0DMACTL 0x84
+#define MAC_REG_AC0DMAPTR 0x88
+#define MAC_REG_BCNDMACTL 0x8C
+#define MAC_REG_BCNDMAPTR 0x90
+#define MAC_REG_RXDMACTL0 0x94
+#define MAC_REG_RXDMAPTR0 0x98
+#define MAC_REG_RXDMACTL1 0x9C
+#define MAC_REG_RXDMAPTR1 0xA0
+#define MAC_REG_SYNCDMACTL 0xA4
+#define MAC_REG_SYNCDMAPTR 0xA8
+#define MAC_REG_ATIMDMACTL 0xAC
+#define MAC_REG_ATIMDMAPTR 0xB0
+
+/* MiscFF PIO related */
+#define MAC_REG_MISCFFNDEX 0xB4
+#define MAC_REG_MISCFFCTL 0xB6
+#define MAC_REG_MISCFFDATA 0xB8
+
+/* Extend SW Timer */
+#define MAC_REG_TMDATA1 0xBC
+
+/* WOW Related Group */
+#define MAC_REG_WAKEUPEN0 0xC0
+#define MAC_REG_WAKEUPEN1 0xC1
+#define MAC_REG_WAKEUPSR0 0xC2
+#define MAC_REG_WAKEUPSR1 0xC3
+#define MAC_REG_WAKE128_0 0xC4
+#define MAC_REG_WAKE128_1 0xD4
+#define MAC_REG_WAKE128_2 0xE4
+#define MAC_REG_WAKE128_3 0xF4
+
+/************** Page 1 ******************/
+#define MAC_REG_CRC_128_0 0x04
+#define MAC_REG_CRC_128_1 0x06
+#define MAC_REG_CRC_128_2 0x08
+#define MAC_REG_CRC_128_3 0x0A
+
+/* MAC Configuration Group */
+#define MAC_REG_PAR0 0x0C
+#define MAC_REG_PAR4 0x10
+#define MAC_REG_BSSID0 0x14
+#define MAC_REG_BSSID4 0x18
+#define MAC_REG_MAR0 0x1C
+#define MAC_REG_MAR4 0x20
+
+/* MAC RSPPKT INFO Group */
+#define MAC_REG_RSPINF_B_1 0x24
+#define MAC_REG_RSPINF_B_2 0x28
+#define MAC_REG_RSPINF_B_5 0x2C
+#define MAC_REG_RSPINF_B_11 0x30
+#define MAC_REG_RSPINF_A_6 0x34
+#define MAC_REG_RSPINF_A_9 0x36
+#define MAC_REG_RSPINF_A_12 0x38
+#define MAC_REG_RSPINF_A_18 0x3A
+#define MAC_REG_RSPINF_A_24 0x3C
+#define MAC_REG_RSPINF_A_36 0x3E
+#define MAC_REG_RSPINF_A_48 0x40
+#define MAC_REG_RSPINF_A_54 0x42
+#define MAC_REG_RSPINF_A_72 0x44
+
+/* 802.11h relative */
+#define MAC_REG_QUIETINIT 0x60
+#define MAC_REG_QUIETGAP 0x62
+#define MAC_REG_QUIETDUR 0x64
+#define MAC_REG_MSRCTL 0x66
+#define MAC_REG_MSRBBSTS 0x67
+#define MAC_REG_MSRSTART 0x68
+#define MAC_REG_MSRDURATION 0x70
+#define MAC_REG_CCAFRACTION 0x72
+#define MAC_REG_PWRCCK 0x73
+#define MAC_REG_PWROFDM 0x7C
+
+/* Bits in the BCFG0 register */
+#define BCFG0_PERROFF 0x40
+#define BCFG0_MRDMDIS 0x20
+#define BCFG0_MRDLDIS 0x10
+#define BCFG0_MWMEN 0x08
+#define BCFG0_VSERREN 0x02
+#define BCFG0_LATMEN 0x01
+
+/* Bits in the BCFG1 register */
+#define BCFG1_CFUNOPT 0x80
+#define BCFG1_CREQOPT 0x40
+#define BCFG1_DMA8 0x10
+#define BCFG1_ARBITOPT 0x08
+#define BCFG1_PCIMEN 0x04
+#define BCFG1_MIOEN 0x02
+#define BCFG1_CISDLYEN 0x01
+
+/* Bits in RAMBIST registers */
+#define BISTCMD_TSTPAT5 0x00
+#define BISTCMD_TSTPATA 0x80
+#define BISTCMD_TSTERR 0x20
+#define BISTCMD_TSTPATF 0x18
+#define BISTCMD_TSTPAT0 0x10
+#define BISTCMD_TSTMODE 0x04
+#define BISTCMD_TSTITTX 0x03
+#define BISTCMD_TSTATRX 0x02
+#define BISTCMD_TSTATTX 0x01
+#define BISTCMD_TSTRX 0x00
+#define BISTSR0_BISTGO 0x01
+#define BISTSR1_TSTSR 0x01
+#define BISTSR2_CMDPRTEN 0x02
+#define BISTSR2_RAMTSTEN 0x01
+
+/* Bits in the I2MCFG EEPROM register */
+#define I2MCFG_BOUNDCTL 0x80
+#define I2MCFG_WAITCTL 0x20
+#define I2MCFG_SCLOECTL 0x10
+#define I2MCFG_WBUSYCTL 0x08
+#define I2MCFG_NORETRY 0x04
+#define I2MCFG_I2MLDSEQ 0x02
+#define I2MCFG_I2CMFAST 0x01
+
+/* Bits in the I2MCSR EEPROM register */
+#define I2MCSR_EEMW 0x80
+#define I2MCSR_EEMR 0x40
+#define I2MCSR_AUTOLD 0x08
+#define I2MCSR_NACK 0x02
+#define I2MCSR_DONE 0x01
+
+/* Bits in the PMC1 register */
+#define SPS_RST 0x80
+#define PCISTIKY 0x40
+#define PME_OVR 0x02
+
+/* Bits in the STICKYHW register */
+#define STICKHW_DS1_SHADOW 0x02
+#define STICKHW_DS0_SHADOW 0x01
+
+/* Bits in the TMCTL register */
+#define TMCTL_TSUSP 0x04
+#define TMCTL_TMD 0x02
+#define TMCTL_TE 0x01
+
+/* Bits in the TFTCTL register */
+#define TFTCTL_HWUTSF 0x80
+#define TFTCTL_TBTTSYNC 0x40
+#define TFTCTL_HWUTSFEN 0x20
+#define TFTCTL_TSFCNTRRD 0x10
+#define TFTCTL_TBTTSYNCEN 0x08
+#define TFTCTL_TSFSYNCEN 0x04
+#define TFTCTL_TSFCNTRST 0x02
+#define TFTCTL_TSFCNTREN 0x01
+
+/* Bits in the EnhanceCFG register */
+#define ENCFG_BARKERPREAM 0x00020000
+#define ENCFG_NXTBTTCFPSTR 0x00010000
+#define ENCFG_BCNSUSCLR 0x00000200
+#define ENCFG_BCNSUSIND 0x00000100
+#define ENCFG_CFP_PROTECTEN 0x00000040
+#define ENCFG_PROTECTMD 0x00000020
+#define ENCFG_HWPARCFP 0x00000010
+#define ENCFG_CFNULRSP 0x00000004
+#define ENCFG_BBTYPE_MASK 0x00000003
+#define ENCFG_BBTYPE_G 0x00000002
+#define ENCFG_BBTYPE_B 0x00000001
+#define ENCFG_BBTYPE_A 0x00000000
+
+/* Bits in the Page1Sel register */
+#define PAGE1_SEL 0x01
+
+/* Bits in the CFG register */
+#define CFG_TKIPOPT 0x80
+#define CFG_RXDMAOPT 0x40
+#define CFG_TMOT_SW 0x20
+#define CFG_TMOT_HWLONG 0x10
+#define CFG_TMOT_HW 0x00
+#define CFG_CFPENDOPT 0x08
+#define CFG_BCNSUSEN 0x04
+#define CFG_NOTXTIMEOUT 0x02
+#define CFG_NOBUFOPT 0x01
+
+/* Bits in the TEST register */
+#define TEST_LBEXT 0x80
+#define TEST_LBINT 0x40
+#define TEST_LBNONE 0x00
+#define TEST_SOFTINT 0x20
+#define TEST_CONTTX 0x10
+#define TEST_TXPE 0x08
+#define TEST_NAVDIS 0x04
+#define TEST_NOCTS 0x02
+#define TEST_NOACK 0x01
+
+/* Bits in the HOSTCR register */
+#define HOSTCR_TXONST 0x80
+#define HOSTCR_RXONST 0x40
+#define HOSTCR_ADHOC 0x20 /* Network Type 1 = Ad-hoc */
+#define HOSTCR_AP 0x10 /* Port Type 1 = AP */
+#define HOSTCR_TXON 0x08 /* 0000 1000 */
+#define HOSTCR_RXON 0x04 /* 0000 0100 */
+#define HOSTCR_MACEN 0x02 /* 0000 0010 */
+#define HOSTCR_SOFTRST 0x01 /* 0000 0001 */
+
+/* Bits in the MACCR register */
+#define MACCR_SYNCFLUSHOK 0x04
+#define MACCR_SYNCFLUSH 0x02
+#define MACCR_CLRNAV 0x01
+
+/* Bits in the MAC_REG_GPIOCTL0 register */
+#define LED_ACTSET 0x01
+#define LED_RFOFF 0x02
+#define LED_NOCONNECT 0x04
+
+/* Bits in the RCR register */
+#define RCR_SSID 0x80
+#define RCR_RXALLTYPE 0x40
+#define RCR_UNICAST 0x20
+#define RCR_BROADCAST 0x10
+#define RCR_MULTICAST 0x08
+#define RCR_WPAERR 0x04
+#define RCR_ERRCRC 0x02
+#define RCR_BSSID 0x01
+
+/* Bits in the TCR register */
+#define TCR_SYNCDCFOPT 0x02
+#define TCR_AUTOBCNTX 0x01 /* Beacon automatically transmit enable */
+
+/* Bits in the IMR register */
+#define IMR_MEASURESTART 0x80000000
+#define IMR_QUIETSTART 0x20000000
+#define IMR_RADARDETECT 0x10000000
+#define IMR_MEASUREEND 0x08000000
+#define IMR_SOFTTIMER1 0x00200000
+#define IMR_RXDMA1 0x00001000 /* 0000 0000 0001 0000 0000 0000 */
+#define IMR_RXNOBUF 0x00000800
+#define IMR_MIBNEARFULL 0x00000400
+#define IMR_SOFTINT 0x00000200
+#define IMR_FETALERR 0x00000100
+#define IMR_WATCHDOG 0x00000080
+#define IMR_SOFTTIMER 0x00000040
+#define IMR_GPIO 0x00000020
+#define IMR_TBTT 0x00000010
+#define IMR_RXDMA0 0x00000008
+#define IMR_BNTX 0x00000004
+#define IMR_AC0DMA 0x00000002
+#define IMR_TXDMA0 0x00000001
+
+/* Bits in the ISR register */
+#define ISR_MEASURESTART 0x80000000
+#define ISR_QUIETSTART 0x20000000
+#define ISR_RADARDETECT 0x10000000
+#define ISR_MEASUREEND 0x08000000
+#define ISR_SOFTTIMER1 0x00200000
+#define ISR_RXDMA1 0x00001000 /* 0000 0000 0001 0000 0000 0000 */
+#define ISR_RXNOBUF 0x00000800 /* 0000 0000 0000 1000 0000 0000 */
+#define ISR_MIBNEARFULL 0x00000400 /* 0000 0000 0000 0100 0000 0000 */
+#define ISR_SOFTINT 0x00000200
+#define ISR_FETALERR 0x00000100
+#define ISR_WATCHDOG 0x00000080
+#define ISR_SOFTTIMER 0x00000040
+#define ISR_GPIO 0x00000020
+#define ISR_TBTT 0x00000010
+#define ISR_RXDMA0 0x00000008
+#define ISR_BNTX 0x00000004
+#define ISR_AC0DMA 0x00000002
+#define ISR_TXDMA0 0x00000001
+
+/* Bits in the PSCFG register */
+#define PSCFG_PHILIPMD 0x40
+#define PSCFG_WAKECALEN 0x20
+#define PSCFG_WAKETMREN 0x10
+#define PSCFG_BBPSPROG 0x08
+#define PSCFG_WAKESYN 0x04
+#define PSCFG_SLEEPSYN 0x02
+#define PSCFG_AUTOSLEEP 0x01
+
+/* Bits in the PSCTL register */
+#define PSCTL_WAKEDONE 0x20
+#define PSCTL_PS 0x10
+#define PSCTL_GO2DOZE 0x08
+#define PSCTL_LNBCN 0x04
+#define PSCTL_ALBCN 0x02
+#define PSCTL_PSEN 0x01
+
+/* Bits in the PSPWSIG register */
+#define PSSIG_WPE3 0x80
+#define PSSIG_WPE2 0x40
+#define PSSIG_WPE1 0x20
+#define PSSIG_WRADIOPE 0x10
+#define PSSIG_SPE3 0x08
+#define PSSIG_SPE2 0x04
+#define PSSIG_SPE1 0x02
+#define PSSIG_SRADIOPE 0x01
+
+/* Bits in the BBREGCTL register */
+#define BBREGCTL_DONE 0x04
+#define BBREGCTL_REGR 0x02
+#define BBREGCTL_REGW 0x01
+
+/* Bits in the IFREGCTL register */
+#define IFREGCTL_DONE 0x04
+#define IFREGCTL_IFRF 0x02
+#define IFREGCTL_REGW 0x01
+
+/* Bits in the SOFTPWRCTL register */
+#define SOFTPWRCTL_RFLEOPT 0x0800
+#define SOFTPWRCTL_TXPEINV 0x0200
+#define SOFTPWRCTL_SWPECTI 0x0100
+#define SOFTPWRCTL_SWPAPE 0x0020
+#define SOFTPWRCTL_SWCALEN 0x0010
+#define SOFTPWRCTL_SWRADIO_PE 0x0008
+#define SOFTPWRCTL_SWPE2 0x0004
+#define SOFTPWRCTL_SWPE1 0x0002
+#define SOFTPWRCTL_SWPE3 0x0001
+
+/* Bits in the GPIOCTL1 register */
+#define GPIO1_DATA1 0x20
+#define GPIO1_MD1 0x10
+#define GPIO1_DATA0 0x02
+#define GPIO1_MD0 0x01
+
+/* Bits in the DMACTL register */
+#define DMACTL_CLRRUN 0x00080000
+#define DMACTL_RUN 0x00000008
+#define DMACTL_WAKE 0x00000004
+#define DMACTL_DEAD 0x00000002
+#define DMACTL_ACTIVE 0x00000001
+
+/* Bits in the RXDMACTL0 register */
+#define RX_PERPKT 0x00000100
+#define RX_PERPKTCLR 0x01000000
+
+/* Bits in the BCNDMACTL register */
+#define BEACON_READY 0x01
+
+/* Bits in the MISCFFCTL register */
+#define MISCFFCTL_WRITE 0x0001
+
+/* Bits in WAKEUPEN0 */
+#define WAKEUPEN0_DIRPKT 0x10
+#define WAKEUPEN0_LINKOFF 0x08
+#define WAKEUPEN0_ATIMEN 0x04
+#define WAKEUPEN0_TIMEN 0x02
+#define WAKEUPEN0_MAGICEN 0x01
+
+/* Bits in WAKEUPEN1 */
+#define WAKEUPEN1_128_3 0x08
+#define WAKEUPEN1_128_2 0x04
+#define WAKEUPEN1_128_1 0x02
+#define WAKEUPEN1_128_0 0x01
+
+/* Bits in WAKEUPSR0 */
+#define WAKEUPSR0_DIRPKT 0x10
+#define WAKEUPSR0_LINKOFF 0x08
+#define WAKEUPSR0_ATIMEN 0x04
+#define WAKEUPSR0_TIMEN 0x02
+#define WAKEUPSR0_MAGICEN 0x01
+
+/* Bits in WAKEUPSR1 */
+#define WAKEUPSR1_128_3 0x08
+#define WAKEUPSR1_128_2 0x04
+#define WAKEUPSR1_128_1 0x02
+#define WAKEUPSR1_128_0 0x01
+
+/* Bits in the MAC_REG_GPIOCTL register */
+#define GPIO0_MD 0x01
+#define GPIO0_DATA 0x02
+#define GPIO0_INTMD 0x04
+#define GPIO1_MD 0x10
+#define GPIO1_DATA 0x20
+
+/* Bits in the MSRCTL register */
+#define MSRCTL_FINISH 0x80
+#define MSRCTL_READY 0x40
+#define MSRCTL_RADARDETECT 0x20
+#define MSRCTL_EN 0x10
+#define MSRCTL_QUIETTXCHK 0x08
+#define MSRCTL_QUIETRPT 0x04
+#define MSRCTL_QUIETINT 0x02
+#define MSRCTL_QUIETEN 0x01
+
+/* Bits in the MSRCTL1 register */
+#define MSRCTL1_TXPWR 0x08
+#define MSRCTL1_CSAPAREN 0x04
+#define MSRCTL1_TXPAUSE 0x01
+
+/* Loopback mode */
+#define MAC_LB_EXT 0x02
+#define MAC_LB_INTERNAL 0x01
+#define MAC_LB_NONE 0x00
+
+#define DEFAULT_BI 0x200
+
+/* MiscFIFO Offset */
+#define MISCFIFO_KEYETRY0 32
+#define MISCFIFO_KEYENTRYSIZE 22
+#define MISCFIFO_SYNINFO_IDX 10
+#define MISCFIFO_SYNDATA_IDX 11
+#define MISCFIFO_SYNDATASIZE 21
+
+/* enabled mask value of irq */
+#define IMR_MASK_VALUE (IMR_SOFTTIMER1 | \
+ IMR_RXDMA1 | \
+ IMR_RXNOBUF | \
+ IMR_MIBNEARFULL | \
+ IMR_SOFTINT | \
+ IMR_FETALERR | \
+ IMR_WATCHDOG | \
+ IMR_SOFTTIMER | \
+ IMR_GPIO | \
+ IMR_TBTT | \
+ IMR_RXDMA0 | \
+ IMR_BNTX | \
+ IMR_AC0DMA | \
+ IMR_TXDMA0)
+
+/* max time out delay time */
+#define W_MAX_TIMEOUT 0xFFF0U
+
+/* wait time within loop */
+#define CB_DELAY_LOOP_WAIT 10 /* 10ms */
+
+/* revision id */
+#define REV_ID_VT3253_A0 0x00
+#define REV_ID_VT3253_A1 0x01
+#define REV_ID_VT3253_B0 0x08
+#define REV_ID_VT3253_B1 0x09
+
+/*--------------------- Export Types ------------------------------*/
+
+/*--------------------- Export Macros ------------------------------*/
+
+#define VT6655_MAC_SELECT_PAGE0(iobase) iowrite8(0, iobase + MAC_REG_PAGE1SEL)
+
+#define VT6655_MAC_SELECT_PAGE1(iobase) iowrite8(1, iobase + MAC_REG_PAGE1SEL)
+
+#define MAKEWORD(lb, hb) \
+ ((unsigned short)(((unsigned char)(lb)) | (((unsigned short)((unsigned char)(hb))) << 8)))
+
+void vt6655_mac_reg_bits_on(void __iomem *iobase, const u8 reg_offset, const u8 bit_mask);
+void vt6655_mac_word_reg_bits_on(void __iomem *iobase, const u8 reg_offset, const u16 bit_mask);
+void vt6655_mac_reg_bits_off(void __iomem *iobase, const u8 reg_offset, const u8 bit_mask);
+void vt6655_mac_word_reg_bits_off(void __iomem *iobase, const u8 reg_offset, const u16 bit_mask);
+
+void vt6655_mac_set_short_retry_limit(struct vnt_private *priv, unsigned char retry_limit);
+
+void MACvSetLongRetryLimit(struct vnt_private *priv, unsigned char byRetryLimit);
+
+bool MACbSoftwareReset(struct vnt_private *priv);
+bool MACbShutdown(struct vnt_private *priv);
+void MACvInitialize(struct vnt_private *priv);
+void vt6655_mac_set_curr_rx_0_desc_addr(struct vnt_private *priv, u32 curr_desc_addr);
+void vt6655_mac_set_curr_rx_1_desc_addr(struct vnt_private *priv, u32 curr_desc_addr);
+void vt6655_mac_set_curr_tx_desc_addr(int tx_type, struct vnt_private *priv, u32 curr_desc_addr);
+void MACvSetCurrSyncDescAddrEx(struct vnt_private *priv,
+ u32 curr_desc_addr);
+void MACvSetCurrATIMDescAddrEx(struct vnt_private *priv,
+ u32 curr_desc_addr);
+void MACvTimer0MicroSDelay(struct vnt_private *priv, unsigned int uDelay);
+void MACvOneShotTimer1MicroSec(struct vnt_private *priv, unsigned int uDelayTime);
+
+void MACvSetMISCFifo(struct vnt_private *priv, unsigned short wOffset,
+ u32 dwData);
+
+bool MACbPSWakeup(struct vnt_private *priv);
+
+void MACvSetKeyEntry(struct vnt_private *priv, unsigned short wKeyCtl,
+ unsigned int uEntryIdx, unsigned int uKeyIdx,
+ unsigned char *pbyAddr, u32 *pdwKey,
+ unsigned char local_id);
+void MACvDisableKeyEntry(struct vnt_private *priv, unsigned int uEntryIdx);
+
+#endif /* __MAC_H__ */
diff --git a/drivers/staging/vt6655/power.c b/drivers/staging/vt6655/power.c
new file mode 100644
index 0000000000..8527ad3eff
--- /dev/null
+++ b/drivers/staging/vt6655/power.c
@@ -0,0 +1,144 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * Purpose: Handles 802.11 power management functions
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: July 17, 2002
+ *
+ * Functions:
+ * PSvEnablePowerSaving - Enable Power Saving Mode
+ * PSvDiasblePowerSaving - Disable Power Saving Mode
+ * PSbConsiderPowerDown - Decide if we can Power Down
+ * PSvSendPSPOLL - Send PS-POLL packet
+ * PSbSendNullPacket - Send Null packet
+ * PSbIsNextTBTTWakeUp - Decide if we need to wake up at next Beacon
+ *
+ * Revision History:
+ *
+ */
+
+#include "mac.h"
+#include "device.h"
+#include "power.h"
+#include "card.h"
+
+/*--------------------- Static Definitions -------------------------*/
+
+/*--------------------- Static Classes ----------------------------*/
+
+/*--------------------- Static Functions --------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+
+/*--------------------- Export Functions --------------------------*/
+
+/*
+ *
+ * Routine Description:
+ * Enable hw power saving functions
+ *
+ * Return Value:
+ * None.
+ *
+ */
+
+void PSvEnablePowerSaving(struct vnt_private *priv,
+ unsigned short wListenInterval)
+{
+ u16 wAID = priv->current_aid | BIT(14) | BIT(15);
+
+ /* set period of power up before TBTT */
+ iowrite16(C_PWBT, priv->port_offset + MAC_REG_PWBT);
+ if (priv->op_mode != NL80211_IFTYPE_ADHOC) {
+ /* set AID */
+ iowrite16(wAID, priv->port_offset + MAC_REG_AIDATIM);
+ }
+
+ /* Set AutoSleep */
+ vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_PSCFG, PSCFG_AUTOSLEEP);
+
+ /* Set HWUTSF */
+ vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_TFTCTL, TFTCTL_HWUTSF);
+
+ if (wListenInterval >= 2) {
+ /* clear always listen beacon */
+ vt6655_mac_reg_bits_off(priv->port_offset, MAC_REG_PSCTL, PSCTL_ALBCN);
+ /* first time set listen next beacon */
+ vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_PSCTL, PSCTL_LNBCN);
+ } else {
+ /* always listen beacon */
+ vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_PSCTL, PSCTL_ALBCN);
+ }
+
+ /* enable power saving hw function */
+ vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_PSCTL, PSCTL_PSEN);
+ priv->bEnablePSMode = true;
+
+ priv->bPWBitOn = true;
+ pr_debug("PS:Power Saving Mode Enable...\n");
+}
+
+/*
+ *
+ * Routine Description:
+ * Disable hw power saving functions
+ *
+ * Return Value:
+ * None.
+ *
+ */
+
+void PSvDisablePowerSaving(struct vnt_private *priv)
+{
+ /* disable power saving hw function */
+ MACbPSWakeup(priv);
+
+ /* clear AutoSleep */
+ vt6655_mac_reg_bits_off(priv->port_offset, MAC_REG_PSCFG, PSCFG_AUTOSLEEP);
+
+ /* clear HWUTSF */
+ vt6655_mac_reg_bits_off(priv->port_offset, MAC_REG_TFTCTL, TFTCTL_HWUTSF);
+
+ /* set always listen beacon */
+ vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_PSCTL, PSCTL_ALBCN);
+
+ priv->bEnablePSMode = false;
+
+ priv->bPWBitOn = false;
+}
+
+/*
+ *
+ * Routine Description:
+ * Check if Next TBTT must wake up
+ *
+ * Return Value:
+ * None.
+ *
+ */
+
+bool PSbIsNextTBTTWakeUp(struct vnt_private *priv)
+{
+ struct ieee80211_hw *hw = priv->hw;
+ struct ieee80211_conf *conf = &hw->conf;
+ bool wake_up = false;
+
+ if (conf->listen_interval > 1) {
+ if (!priv->wake_up_count)
+ priv->wake_up_count = conf->listen_interval;
+
+ --priv->wake_up_count;
+
+ if (priv->wake_up_count == 1) {
+ /* Turn on wake up to listen next beacon */
+ vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_PSCTL, PSCTL_LNBCN);
+ wake_up = true;
+ }
+ }
+
+ return wake_up;
+}
diff --git a/drivers/staging/vt6655/power.h b/drivers/staging/vt6655/power.h
new file mode 100644
index 0000000000..060516f81f
--- /dev/null
+++ b/drivers/staging/vt6655/power.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * Purpose: Handles 802.11 power management functions
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: July 17, 2002
+ *
+ */
+
+#ifndef __POWER_H__
+#define __POWER_H__
+
+#include "device.h"
+
+#define C_PWBT 1000 /* micro sec. power up before TBTT */
+#define PS_FAST_INTERVAL 1 /* Fast power saving listen interval */
+#define PS_MAX_INTERVAL 4 /* MAX power saving listen interval */
+
+void PSvDisablePowerSaving(struct vnt_private *priv);
+
+void PSvEnablePowerSaving(struct vnt_private *priv, unsigned short wListenInterval);
+
+bool PSbIsNextTBTTWakeUp(struct vnt_private *priv);
+
+#endif /* __POWER_H__ */
diff --git a/drivers/staging/vt6655/rf.c b/drivers/staging/vt6655/rf.c
new file mode 100644
index 0000000000..1fadc2fc44
--- /dev/null
+++ b/drivers/staging/vt6655/rf.c
@@ -0,0 +1,535 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * Purpose: rf function code
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Feb. 19, 2004
+ *
+ * Functions:
+ * IFRFbWriteEmbedded - Embedded write RF register via MAC
+ *
+ * Revision History:
+ * RobertYu 2005
+ * chester 2008
+ *
+ */
+
+#include "mac.h"
+#include "srom.h"
+#include "rf.h"
+#include "baseband.h"
+
+#define BY_AL2230_REG_LEN 23 /* 24bit */
+#define CB_AL2230_INIT_SEQ 15
+#define SWITCH_CHANNEL_DELAY_AL2230 200 /* us */
+#define AL2230_PWR_IDX_LEN 64
+
+#define BY_AL7230_REG_LEN 23 /* 24bit */
+#define CB_AL7230_INIT_SEQ 16
+#define SWITCH_CHANNEL_DELAY_AL7230 200 /* us */
+#define AL7230_PWR_IDX_LEN 64
+
+static const unsigned long al2230_init_table[CB_AL2230_INIT_SEQ] = {
+ 0x03F79000 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x03333100 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x01A00200 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x00FFF300 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x0005A400 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x0F4DC500 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x0805B600 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x0146C700 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x00068800 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x0403B900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x00DBBA00 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x00099B00 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x0BDFFC00 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x00000D00 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x00580F00 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW
+};
+
+static const unsigned long al2230_channel_table0[CB_MAX_CHANNEL] = {
+ 0x03F79000 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 1, Tf = 2412MHz */
+ 0x03F79000 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 2, Tf = 2417MHz */
+ 0x03E79000 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 3, Tf = 2422MHz */
+ 0x03E79000 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 4, Tf = 2427MHz */
+ 0x03F7A000 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 5, Tf = 2432MHz */
+ 0x03F7A000 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 6, Tf = 2437MHz */
+ 0x03E7A000 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 7, Tf = 2442MHz */
+ 0x03E7A000 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 8, Tf = 2447MHz */
+ 0x03F7B000 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 9, Tf = 2452MHz */
+ 0x03F7B000 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 10, Tf = 2457MHz */
+ 0x03E7B000 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 11, Tf = 2462MHz */
+ 0x03E7B000 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 12, Tf = 2467MHz */
+ 0x03F7C000 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 13, Tf = 2472MHz */
+ 0x03E7C000 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW /* channel = 14, Tf = 2412M */
+};
+
+static const unsigned long al2230_channel_table1[CB_MAX_CHANNEL] = {
+ 0x03333100 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 1, Tf = 2412MHz */
+ 0x0B333100 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 2, Tf = 2417MHz */
+ 0x03333100 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 3, Tf = 2422MHz */
+ 0x0B333100 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 4, Tf = 2427MHz */
+ 0x03333100 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 5, Tf = 2432MHz */
+ 0x0B333100 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 6, Tf = 2437MHz */
+ 0x03333100 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 7, Tf = 2442MHz */
+ 0x0B333100 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 8, Tf = 2447MHz */
+ 0x03333100 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 9, Tf = 2452MHz */
+ 0x0B333100 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 10, Tf = 2457MHz */
+ 0x03333100 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 11, Tf = 2462MHz */
+ 0x0B333100 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 12, Tf = 2467MHz */
+ 0x03333100 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 13, Tf = 2472MHz */
+ 0x06666100 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW /* channel = 14, Tf = 2412M */
+};
+
+static unsigned long al2230_power_table[AL2230_PWR_IDX_LEN] = {
+ 0x04040900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x04041900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x04042900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x04043900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x04044900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x04045900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x04046900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x04047900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x04048900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x04049900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x0404A900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x0404B900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x0404C900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x0404D900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x0404E900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x0404F900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x04050900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x04051900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x04052900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x04053900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x04054900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x04055900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x04056900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x04057900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x04058900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x04059900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x0405A900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x0405B900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x0405C900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x0405D900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x0405E900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x0405F900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x04060900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x04061900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x04062900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x04063900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x04064900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x04065900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x04066900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x04067900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x04068900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x04069900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x0406A900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x0406B900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x0406C900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x0406D900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x0406E900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x0406F900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x04070900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x04071900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x04072900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x04073900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x04074900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x04075900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x04076900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x04077900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x04078900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x04079900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x0407A900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x0407B900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x0407C900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x0407D900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x0407E900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
+ 0x0407F900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW
+};
+
+/*
+ * Description: Write to IF/RF, by embedded programming
+ *
+ * Parameters:
+ * In:
+ * iobase - I/O base address
+ * dwData - data to write
+ * Out:
+ * none
+ *
+ * Return Value: true if succeeded; false if failed.
+ *
+ */
+bool IFRFbWriteEmbedded(struct vnt_private *priv, unsigned long dwData)
+{
+ void __iomem *iobase = priv->port_offset;
+ unsigned short ww;
+ unsigned long dwValue;
+
+ iowrite32((u32)dwData, iobase + MAC_REG_IFREGCTL);
+
+ /* W_MAX_TIMEOUT is the timeout period */
+ for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+ dwValue = ioread32(iobase + MAC_REG_IFREGCTL);
+ if (dwValue & IFREGCTL_DONE)
+ break;
+ }
+
+ if (ww == W_MAX_TIMEOUT)
+ return false;
+
+ return true;
+}
+
+/*
+ * Description: AIROHA IFRF chip init function
+ *
+ * Parameters:
+ * In:
+ * iobase - I/O base address
+ * Out:
+ * none
+ *
+ * Return Value: true if succeeded; false if failed.
+ *
+ */
+static bool RFbAL2230Init(struct vnt_private *priv)
+{
+ void __iomem *iobase = priv->port_offset;
+ int ii;
+ bool ret;
+
+ ret = true;
+
+ /* 3-wire control for normal mode */
+ iowrite8(0, iobase + MAC_REG_SOFTPWRCTL);
+
+ vt6655_mac_word_reg_bits_on(iobase, MAC_REG_SOFTPWRCTL,
+ (SOFTPWRCTL_SWPECTI | SOFTPWRCTL_TXPEINV));
+ /* PLL Off */
+ vt6655_mac_word_reg_bits_off(iobase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3);
+
+ /* patch abnormal AL2230 frequency output */
+ IFRFbWriteEmbedded(priv, (0x07168700 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW));
+
+ for (ii = 0; ii < CB_AL2230_INIT_SEQ; ii++)
+ ret &= IFRFbWriteEmbedded(priv, al2230_init_table[ii]);
+ MACvTimer0MicroSDelay(priv, 30); /* delay 30 us */
+
+ /* PLL On */
+ vt6655_mac_word_reg_bits_on(iobase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3);
+
+ MACvTimer0MicroSDelay(priv, 150);/* 150us */
+ ret &= IFRFbWriteEmbedded(priv, (0x00d80f00 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW));
+ MACvTimer0MicroSDelay(priv, 30);/* 30us */
+ ret &= IFRFbWriteEmbedded(priv, (0x00780f00 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW));
+ MACvTimer0MicroSDelay(priv, 30);/* 30us */
+ ret &= IFRFbWriteEmbedded(priv,
+ al2230_init_table[CB_AL2230_INIT_SEQ - 1]);
+
+ vt6655_mac_word_reg_bits_on(iobase, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPE3 |
+ SOFTPWRCTL_SWPE2 |
+ SOFTPWRCTL_SWPECTI |
+ SOFTPWRCTL_TXPEINV));
+
+ /* 3-wire control for power saving mode */
+ iowrite8(PSSIG_WPE3 | PSSIG_WPE2, iobase + MAC_REG_PSPWRSIG);
+
+ return ret;
+}
+
+static bool RFbAL2230SelectChannel(struct vnt_private *priv, unsigned char byChannel)
+{
+ void __iomem *iobase = priv->port_offset;
+ bool ret;
+
+ ret = true;
+
+ ret &= IFRFbWriteEmbedded(priv, al2230_channel_table0[byChannel - 1]);
+ ret &= IFRFbWriteEmbedded(priv, al2230_channel_table1[byChannel - 1]);
+
+ /* Set Channel[7] = 0 to tell H/W channel is changing now. */
+ iowrite8(byChannel & 0x7F, iobase + MAC_REG_CHANNEL);
+ MACvTimer0MicroSDelay(priv, SWITCH_CHANNEL_DELAY_AL2230);
+ /* Set Channel[7] = 1 to tell H/W channel change is done. */
+ iowrite8(byChannel | 0x80, iobase + MAC_REG_CHANNEL);
+
+ return ret;
+}
+
+/*
+ * Description: RF init function
+ *
+ * Parameters:
+ * In:
+ * byBBType
+ * byRFType
+ * Out:
+ * none
+ *
+ * Return Value: true if succeeded; false if failed.
+ *
+ */
+bool RFbInit(struct vnt_private *priv)
+{
+ bool ret = true;
+
+ switch (priv->byRFType) {
+ case RF_AIROHA:
+ case RF_AL2230S:
+ priv->max_pwr_level = AL2230_PWR_IDX_LEN;
+ ret = RFbAL2230Init(priv);
+ break;
+ case RF_NOTHING:
+ ret = true;
+ break;
+ default:
+ ret = false;
+ break;
+ }
+ return ret;
+}
+
+/*
+ * Description: Select channel
+ *
+ * Parameters:
+ * In:
+ * byRFType
+ * byChannel - Channel number
+ * Out:
+ * none
+ *
+ * Return Value: true if succeeded; false if failed.
+ *
+ */
+bool RFbSelectChannel(struct vnt_private *priv, unsigned char byRFType,
+ u16 byChannel)
+{
+ bool ret = true;
+
+ switch (byRFType) {
+ case RF_AIROHA:
+ case RF_AL2230S:
+ ret = RFbAL2230SelectChannel(priv, byChannel);
+ break;
+ /*{{ RobertYu: 20050104 */
+ case RF_NOTHING:
+ ret = true;
+ break;
+ default:
+ ret = false;
+ break;
+ }
+ return ret;
+}
+
+/*
+ * Description: Write WakeProgSyn
+ *
+ * Parameters:
+ * In:
+ * priv - Device Structure
+ * rf_type - RF type
+ * channel - Channel number
+ *
+ * Return Value: true if succeeded; false if failed.
+ *
+ */
+bool rf_write_wake_prog_syn(struct vnt_private *priv, unsigned char rf_type,
+ u16 channel)
+{
+ void __iomem *iobase = priv->port_offset;
+ int i;
+ unsigned char init_count = 0;
+ unsigned char sleep_count = 0;
+ unsigned short idx = MISCFIFO_SYNDATA_IDX;
+
+ iowrite16(0, iobase + MAC_REG_MISCFFNDEX);
+ switch (rf_type) {
+ case RF_AIROHA:
+ case RF_AL2230S:
+
+ if (channel > CB_MAX_CHANNEL_24G)
+ return false;
+
+ /* Init Reg + Channel Reg (2) */
+ init_count = CB_AL2230_INIT_SEQ + 2;
+ sleep_count = 0;
+
+ for (i = 0; i < CB_AL2230_INIT_SEQ; i++)
+ MACvSetMISCFifo(priv, idx++, al2230_init_table[i]);
+
+ MACvSetMISCFifo(priv, idx++, al2230_channel_table0[channel - 1]);
+ MACvSetMISCFifo(priv, idx++, al2230_channel_table1[channel - 1]);
+ break;
+
+ /* Need to check, PLLON need to be low for channel setting */
+
+ case RF_NOTHING:
+ return true;
+
+ default:
+ return false;
+ }
+
+ MACvSetMISCFifo(priv, MISCFIFO_SYNINFO_IDX, (unsigned long)MAKEWORD(sleep_count, init_count));
+
+ return true;
+}
+
+/*
+ * Description: Set Tx power
+ *
+ * Parameters:
+ * In:
+ * iobase - I/O base address
+ * dwRFPowerTable - RF Tx Power Setting
+ * Out:
+ * none
+ *
+ * Return Value: true if succeeded; false if failed.
+ *
+ */
+bool RFbSetPower(struct vnt_private *priv, unsigned int rate, u16 uCH)
+{
+ bool ret;
+ unsigned char byPwr = 0;
+ unsigned char byDec = 0;
+
+ if (priv->dwDiagRefCount != 0)
+ return true;
+
+ if ((uCH < 1) || (uCH > CB_MAX_CHANNEL))
+ return false;
+
+ switch (rate) {
+ case RATE_1M:
+ case RATE_2M:
+ case RATE_5M:
+ case RATE_11M:
+ if (uCH > CB_MAX_CHANNEL_24G)
+ return false;
+
+ byPwr = priv->abyCCKPwrTbl[uCH];
+ break;
+ case RATE_6M:
+ case RATE_9M:
+ case RATE_12M:
+ case RATE_18M:
+ byPwr = priv->abyOFDMPwrTbl[uCH];
+ byDec = byPwr + 10;
+
+ if (byDec >= priv->max_pwr_level)
+ byDec = priv->max_pwr_level - 1;
+
+ byPwr = byDec;
+ break;
+ case RATE_24M:
+ case RATE_36M:
+ case RATE_48M:
+ case RATE_54M:
+ byPwr = priv->abyOFDMPwrTbl[uCH];
+ break;
+ }
+
+ if (priv->byCurPwr == byPwr)
+ return true;
+
+ ret = RFbRawSetPower(priv, byPwr, rate);
+ if (ret)
+ priv->byCurPwr = byPwr;
+
+ return ret;
+}
+
+/*
+ * Description: Set Tx power
+ *
+ * Parameters:
+ * In:
+ * iobase - I/O base address
+ * dwRFPowerTable - RF Tx Power Setting
+ * Out:
+ * none
+ *
+ * Return Value: true if succeeded; false if failed.
+ *
+ */
+
+bool RFbRawSetPower(struct vnt_private *priv, unsigned char byPwr,
+ unsigned int rate)
+{
+ bool ret = true;
+
+ if (byPwr >= priv->max_pwr_level)
+ return false;
+
+ switch (priv->byRFType) {
+ case RF_AIROHA:
+ ret &= IFRFbWriteEmbedded(priv, al2230_power_table[byPwr]);
+ if (rate <= RATE_11M)
+ ret &= IFRFbWriteEmbedded(priv, 0x0001B400 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW);
+ else
+ ret &= IFRFbWriteEmbedded(priv, 0x0005A400 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW);
+
+ break;
+
+ case RF_AL2230S:
+ ret &= IFRFbWriteEmbedded(priv, al2230_power_table[byPwr]);
+ if (rate <= RATE_11M) {
+ ret &= IFRFbWriteEmbedded(priv, 0x040C1400 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW);
+ ret &= IFRFbWriteEmbedded(priv, 0x00299B00 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW);
+ } else {
+ ret &= IFRFbWriteEmbedded(priv, 0x0005A400 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW);
+ ret &= IFRFbWriteEmbedded(priv, 0x00099B00 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW);
+ }
+
+ break;
+
+ default:
+ break;
+ }
+ return ret;
+}
+
+/*
+ *
+ * Routine Description:
+ * Translate RSSI to dBm
+ *
+ * Parameters:
+ * In:
+ * priv - The adapter to be translated
+ * byCurrRSSI - RSSI to be translated
+ * Out:
+ * pdwdbm - Translated dbm number
+ *
+ * Return Value: none
+ *
+ */
+void
+RFvRSSITodBm(struct vnt_private *priv, unsigned char byCurrRSSI, long *pldBm)
+{
+ unsigned char byIdx = (((byCurrRSSI & 0xC0) >> 6) & 0x03);
+ long b = (byCurrRSSI & 0x3F);
+ long a = 0;
+ unsigned char abyAIROHARF[4] = {0, 18, 0, 40};
+
+ switch (priv->byRFType) {
+ case RF_AIROHA:
+ case RF_AL2230S:
+ a = abyAIROHARF[byIdx];
+ break;
+ default:
+ break;
+ }
+
+ *pldBm = -1 * (a + b * 2);
+}
+
diff --git a/drivers/staging/vt6655/rf.h b/drivers/staging/vt6655/rf.h
new file mode 100644
index 0000000000..9fef81846a
--- /dev/null
+++ b/drivers/staging/vt6655/rf.h
@@ -0,0 +1,75 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * Purpose:
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Feb. 19, 2004
+ *
+ */
+
+#ifndef __RF_H__
+#define __RF_H__
+
+#include "device.h"
+
+/*--------------------- Export Definitions -------------------------*/
+/*
+ * Baseband RF pair definition in eeprom (Bits 6..0)
+ */
+#define RF_RFMD2959 0x01
+#define RF_MAXIMAG 0x02
+#define RF_AIROHA 0x03
+
+#define RF_UW2451 0x05
+#define RF_MAXIMG 0x06
+#define RF_MAXIM2829 0x07 /* RobertYu: 20041118 */
+#define RF_UW2452 0x08 /* RobertYu: 20041210 */
+#define RF_AIROHA7230 0x0a /* RobertYu: 20050104 */
+#define RF_UW2453 0x0b
+
+#define RF_VT3226 0x09
+#define RF_AL2230S 0x0e
+
+#define RF_NOTHING 0x7E
+#define RF_EMU 0x80
+#define RF_MASK 0x7F
+
+#define ZONE_FCC 0
+#define ZONE_MKK1 1
+#define ZONE_ETSI 2
+#define ZONE_IC 3
+#define ZONE_SPAIN 4
+#define ZONE_FRANCE 5
+#define ZONE_MKK 6
+#define ZONE_ISRAEL 7
+
+/* [20050104] CB_MAXIM2829_CHANNEL_5G_HIGH, CB_UW2452_CHANNEL_5G_HIGH: 40==>41 */
+#define CB_MAXIM2829_CHANNEL_5G_HIGH 41 /* Index41: channel = 100, Tf = 5500MHz, set the (A3:A0=0101) D6=1 */
+#define CB_UW2452_CHANNEL_5G_HIGH 41 /* [20041210] Index41: channel = 100, Tf = 5500MHz, change VCO2->VCO3 */
+
+/*--------------------- Export Classes ----------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+
+/*--------------------- Export Functions --------------------------*/
+
+bool IFRFbWriteEmbedded(struct vnt_private *priv, unsigned long dwData);
+bool RFbSelectChannel(struct vnt_private *priv, unsigned char byRFType, u16 byChannel);
+bool RFbInit(struct vnt_private *priv);
+bool rf_write_wake_prog_syn(struct vnt_private *priv, unsigned char rf_type, u16 channel);
+bool RFbSetPower(struct vnt_private *priv, unsigned int rate, u16 uCH);
+bool RFbRawSetPower(struct vnt_private *priv, unsigned char byPwr,
+ unsigned int rate);
+
+void RFvRSSITodBm(struct vnt_private *priv, unsigned char byCurrRSSI,
+ long *pldBm);
+
+/* {{ RobertYu: 20050104 */
+bool RFbAL7230SelectChannelPostProcess(struct vnt_private *priv, u16 byOldChannel, u16 byNewChannel);
+/* }} RobertYu */
+
+#endif /* __RF_H__ */
diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c
new file mode 100644
index 0000000000..522d34ca9b
--- /dev/null
+++ b/drivers/staging/vt6655/rxtx.c
@@ -0,0 +1,1462 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * Purpose: handle WMAC/802.3/802.11 rx & tx functions
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: May 20, 2003
+ *
+ * Functions:
+ * s_vGenerateTxParameter - Generate tx dma required parameter.
+ * vGenerateMACHeader - Translate 802.3 to 802.11 header
+ * cbGetFragCount - Calculate fragment number count
+ * csBeacon_xmit - beacon tx function
+ * csMgmt_xmit - management tx function
+ * s_cbFillTxBufHead - fulfill tx dma buffer header
+ * s_uGetDataDuration - get tx data required duration
+ * s_uFillDataHead- fulfill tx data duration header
+ * s_uGetRTSCTSDuration- get rtx/cts required duration
+ * get_rtscts_time- get rts/cts reserved time
+ * s_uGetTxRsvTime- get frame reserved time
+ * s_vFillCTSHead- fulfill CTS ctl header
+ * s_vFillFragParameter- Set fragment ctl parameter.
+ * s_vFillRTSHead- fulfill RTS ctl header
+ * s_vFillTxKey- fulfill tx encrypt key
+ * s_vSWencryption- Software encrypt header
+ * vDMA0_tx_80211- tx 802.11 frame via dma0
+ * vGenerateFIFOHeader- Generate tx FIFO ctl header
+ *
+ * Revision History:
+ *
+ */
+
+#include "device.h"
+#include "rxtx.h"
+#include "card.h"
+#include "mac.h"
+#include "baseband.h"
+#include "rf.h"
+
+/*--------------------- Static Definitions -------------------------*/
+
+/*--------------------- Static Classes ----------------------------*/
+
+/*--------------------- Static Variables --------------------------*/
+
+/*--------------------- Static Functions --------------------------*/
+
+/*--------------------- Static Definitions -------------------------*/
+/* if packet size < 256 -> in-direct send
+ * vpacket size >= 256 -> direct send
+ */
+#define CRITICAL_PACKET_LEN 256
+
+static const unsigned short time_stamp_off[2][MAX_RATE] = {
+ {384, 288, 226, 209, 54, 43, 37, 31, 28, 25, 24, 23}, /* Long Preamble */
+ {384, 192, 130, 113, 54, 43, 37, 31, 28, 25, 24, 23}, /* Short Preamble */
+};
+
+static const unsigned short 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 unsigned short 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 Functions --------------------------*/
+static
+void
+s_vFillRTSHead(
+ struct vnt_private *pDevice,
+ unsigned char byPktType,
+ void *pvRTS,
+ unsigned int cbFrameLength,
+ bool bNeedAck,
+ bool bDisCRC,
+ struct ieee80211_hdr *hdr,
+ unsigned short wCurrentRate,
+ unsigned char byFBOption
+);
+
+static
+void
+s_vGenerateTxParameter(
+ struct vnt_private *pDevice,
+ unsigned char byPktType,
+ struct vnt_tx_fifo_head *,
+ void *pvRrvTime,
+ void *pvRTS,
+ void *pvCTS,
+ unsigned int cbFrameSize,
+ bool bNeedACK,
+ unsigned int uDMAIdx,
+ void *psEthHeader,
+ unsigned short wCurrentRate
+);
+
+static unsigned int
+s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
+ unsigned char *pbyTxBufferAddr,
+ unsigned int uDMAIdx, struct vnt_tx_desc *pHeadTD,
+ unsigned int uNodeIndex);
+
+static
+__le16
+s_uFillDataHead(
+ struct vnt_private *pDevice,
+ unsigned char byPktType,
+ void *pTxDataHead,
+ unsigned int cbFrameLength,
+ unsigned int uDMAIdx,
+ bool bNeedAck,
+ unsigned int uFragIdx,
+ unsigned int cbLastFragmentSize,
+ unsigned int uMACfragNum,
+ unsigned char byFBOption,
+ unsigned short wCurrentRate,
+ bool is_pspoll
+);
+
+/*--------------------- Export Variables --------------------------*/
+
+static __le16 vnt_time_stamp_off(struct vnt_private *priv, u16 rate)
+{
+ return cpu_to_le16(time_stamp_off[priv->preamble_type % 2]
+ [rate % MAX_RATE]);
+}
+
+/* byPktType : PK_TYPE_11A 0
+ * PK_TYPE_11B 1
+ * PK_TYPE_11GB 2
+ * PK_TYPE_11GA 3
+ */
+static
+unsigned int
+s_uGetTxRsvTime(
+ struct vnt_private *pDevice,
+ unsigned char byPktType,
+ unsigned int cbFrameLength,
+ unsigned short wRate,
+ bool bNeedAck
+)
+{
+ unsigned int uDataTime, uAckTime;
+
+ uDataTime = bb_get_frame_time(pDevice->preamble_type, byPktType, cbFrameLength, wRate);
+
+ if (!bNeedAck)
+ return uDataTime;
+
+ /*
+ * CCK mode - 11b
+ * OFDM mode - 11g 2.4G & 11a 5G
+ */
+ uAckTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14,
+ byPktType == PK_TYPE_11B ?
+ pDevice->byTopCCKBasicRate :
+ pDevice->byTopOFDMBasicRate);
+
+ return uDataTime + pDevice->uSIFS + uAckTime;
+}
+
+static __le16 vnt_rxtx_rsvtime_le16(struct vnt_private *priv, u8 pkt_type,
+ u32 frame_length, u16 rate, bool need_ack)
+{
+ return cpu_to_le16((u16)s_uGetTxRsvTime(priv, pkt_type,
+ frame_length, rate, need_ack));
+}
+
+/* byFreqType: 0=>5GHZ 1=>2.4GHZ */
+static __le16 get_rtscts_time(struct vnt_private *priv,
+ unsigned char rts_rsvtype,
+ unsigned char pkt_type,
+ unsigned int frame_length,
+ unsigned short current_rate)
+{
+ unsigned int rrv_time = 0;
+ unsigned int rts_time = 0;
+ unsigned int cts_time = 0;
+ unsigned int ack_time = 0;
+ unsigned int data_time = 0;
+
+ data_time = bb_get_frame_time(priv->preamble_type, pkt_type, frame_length, current_rate);
+ if (rts_rsvtype == 0) { /* RTSTxRrvTime_bb */
+ rts_time = bb_get_frame_time(priv->preamble_type, pkt_type, 20, priv->byTopCCKBasicRate);
+ ack_time = bb_get_frame_time(priv->preamble_type, pkt_type, 14, priv->byTopCCKBasicRate);
+ cts_time = ack_time;
+ } else if (rts_rsvtype == 1) { /* RTSTxRrvTime_ba, only in 2.4GHZ */
+ rts_time = bb_get_frame_time(priv->preamble_type, pkt_type, 20, priv->byTopCCKBasicRate);
+ cts_time = bb_get_frame_time(priv->preamble_type, pkt_type, 14, priv->byTopCCKBasicRate);
+ ack_time = bb_get_frame_time(priv->preamble_type, pkt_type, 14, priv->byTopOFDMBasicRate);
+ } else if (rts_rsvtype == 2) { /* RTSTxRrvTime_aa */
+ rts_time = bb_get_frame_time(priv->preamble_type, pkt_type, 20, priv->byTopOFDMBasicRate);
+ ack_time = bb_get_frame_time(priv->preamble_type, pkt_type, 14, priv->byTopOFDMBasicRate);
+ cts_time = ack_time;
+ } else if (rts_rsvtype == 3) { /* CTSTxRrvTime_ba, only in 2.4GHZ */
+ cts_time = bb_get_frame_time(priv->preamble_type, pkt_type, 14, priv->byTopCCKBasicRate);
+ ack_time = bb_get_frame_time(priv->preamble_type, pkt_type, 14, priv->byTopOFDMBasicRate);
+ rrv_time = cts_time + ack_time + data_time + 2 * priv->uSIFS;
+ return cpu_to_le16((u16)rrv_time);
+ }
+
+ /* RTSRrvTime */
+ rrv_time = rts_time + cts_time + ack_time + data_time + 3 * priv->uSIFS;
+ return cpu_to_le16((u16)rrv_time);
+}
+
+/* byFreqType 0: 5GHz, 1:2.4Ghz */
+static
+unsigned int
+s_uGetDataDuration(
+ struct vnt_private *pDevice,
+ unsigned char byDurType,
+ unsigned int cbFrameLength,
+ unsigned char byPktType,
+ unsigned short wRate,
+ bool bNeedAck,
+ unsigned int uFragIdx,
+ unsigned int cbLastFragmentSize,
+ unsigned int uMACfragNum,
+ unsigned char byFBOption
+)
+{
+ bool bLastFrag = false;
+ unsigned int uAckTime = 0, uNextPktTime = 0, len;
+
+ if (uFragIdx == (uMACfragNum - 1))
+ bLastFrag = true;
+
+ if (uFragIdx == (uMACfragNum - 2))
+ len = cbLastFragmentSize;
+ else
+ len = cbFrameLength;
+
+ switch (byDurType) {
+ case DATADUR_B: /* DATADUR_B */
+ if (bNeedAck) {
+ uAckTime = bb_get_frame_time(pDevice->preamble_type,
+ byPktType, 14,
+ pDevice->byTopCCKBasicRate);
+ }
+ /* Non Frag or Last Frag */
+ if ((uMACfragNum == 1) || bLastFrag) {
+ if (!bNeedAck)
+ return 0;
+ } else {
+ /* First Frag or Mid Frag */
+ uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType,
+ len, wRate, bNeedAck);
+ }
+
+ return pDevice->uSIFS + uAckTime + uNextPktTime;
+
+ case DATADUR_A: /* DATADUR_A */
+ if (bNeedAck) {
+ uAckTime = bb_get_frame_time(pDevice->preamble_type,
+ byPktType, 14,
+ pDevice->byTopOFDMBasicRate);
+ }
+ /* Non Frag or Last Frag */
+ if ((uMACfragNum == 1) || bLastFrag) {
+ if (!bNeedAck)
+ return 0;
+ } else {
+ /* First Frag or Mid Frag */
+ uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType,
+ len, wRate, bNeedAck);
+ }
+
+ return pDevice->uSIFS + uAckTime + uNextPktTime;
+
+ case DATADUR_A_F0: /* DATADUR_A_F0 */
+ case DATADUR_A_F1: /* DATADUR_A_F1 */
+ if (bNeedAck) {
+ uAckTime = bb_get_frame_time(pDevice->preamble_type,
+ byPktType, 14,
+ pDevice->byTopOFDMBasicRate);
+ }
+ /* Non Frag or Last Frag */
+ if ((uMACfragNum == 1) || bLastFrag) {
+ if (!bNeedAck)
+ return 0;
+ } else {
+ /* First Frag or Mid Frag */
+ if (wRate < RATE_18M)
+ wRate = RATE_18M;
+ else if (wRate > RATE_54M)
+ wRate = RATE_54M;
+
+ wRate -= RATE_18M;
+
+ if (byFBOption == AUTO_FB_0)
+ wRate = fb_opt0[FB_RATE0][wRate];
+ else
+ wRate = fb_opt1[FB_RATE0][wRate];
+
+ uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType,
+ len, wRate, bNeedAck);
+ }
+
+ return pDevice->uSIFS + uAckTime + uNextPktTime;
+
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+/* byFreqType: 0=>5GHZ 1=>2.4GHZ */
+static
+__le16
+s_uGetRTSCTSDuration(
+ struct vnt_private *pDevice,
+ unsigned char byDurType,
+ unsigned int cbFrameLength,
+ unsigned char byPktType,
+ unsigned short wRate,
+ bool bNeedAck,
+ unsigned char byFBOption
+)
+{
+ unsigned int uCTSTime = 0, uDurTime = 0;
+
+ switch (byDurType) {
+ case RTSDUR_BB: /* RTSDuration_bb */
+ uCTSTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14, pDevice->byTopCCKBasicRate);
+ uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
+ break;
+
+ case RTSDUR_BA: /* RTSDuration_ba */
+ uCTSTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14, pDevice->byTopCCKBasicRate);
+ uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
+ break;
+
+ case RTSDUR_AA: /* RTSDuration_aa */
+ uCTSTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14, pDevice->byTopOFDMBasicRate);
+ uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
+ break;
+
+ case CTSDUR_BA: /* CTSDuration_ba */
+ uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
+ break;
+
+ case RTSDUR_BA_F0: /* RTSDuration_ba_f0 */
+ uCTSTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14, pDevice->byTopCCKBasicRate);
+ if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
+ uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt0[FB_RATE0][wRate - RATE_18M], bNeedAck);
+ else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
+ uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt1[FB_RATE0][wRate - RATE_18M], bNeedAck);
+
+ break;
+
+ case RTSDUR_AA_F0: /* RTSDuration_aa_f0 */
+ uCTSTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14, pDevice->byTopOFDMBasicRate);
+ if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
+ uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt0[FB_RATE0][wRate - RATE_18M], bNeedAck);
+ else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
+ uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt1[FB_RATE0][wRate - RATE_18M], bNeedAck);
+
+ break;
+
+ case RTSDUR_BA_F1: /* RTSDuration_ba_f1 */
+ uCTSTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14, pDevice->byTopCCKBasicRate);
+ if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
+ uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt0[FB_RATE1][wRate - RATE_18M], bNeedAck);
+ else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
+ uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt1[FB_RATE1][wRate - RATE_18M], bNeedAck);
+
+ break;
+
+ case RTSDUR_AA_F1: /* RTSDuration_aa_f1 */
+ uCTSTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14, pDevice->byTopOFDMBasicRate);
+ if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
+ uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt0[FB_RATE1][wRate - RATE_18M], bNeedAck);
+ else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
+ uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt1[FB_RATE1][wRate - RATE_18M], bNeedAck);
+
+ break;
+
+ case CTSDUR_BA_F0: /* CTSDuration_ba_f0 */
+ if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
+ uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt0[FB_RATE0][wRate - RATE_18M], bNeedAck);
+ else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
+ uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt1[FB_RATE0][wRate - RATE_18M], bNeedAck);
+
+ break;
+
+ case CTSDUR_BA_F1: /* CTSDuration_ba_f1 */
+ if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
+ uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt0[FB_RATE1][wRate - RATE_18M], bNeedAck);
+ else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
+ uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt1[FB_RATE1][wRate - RATE_18M], bNeedAck);
+
+ break;
+
+ default:
+ break;
+ }
+
+ return cpu_to_le16((u16)uDurTime);
+}
+
+static
+__le16
+s_uFillDataHead(
+ struct vnt_private *pDevice,
+ unsigned char byPktType,
+ void *pTxDataHead,
+ unsigned int cbFrameLength,
+ unsigned int uDMAIdx,
+ bool bNeedAck,
+ unsigned int uFragIdx,
+ unsigned int cbLastFragmentSize,
+ unsigned int uMACfragNum,
+ unsigned char byFBOption,
+ unsigned short wCurrentRate,
+ bool is_pspoll
+)
+{
+ struct vnt_tx_datahead_ab *buf = pTxDataHead;
+
+ if (!pTxDataHead)
+ return 0;
+
+ if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
+ /* Auto Fallback */
+ struct vnt_tx_datahead_g_fb *buf = pTxDataHead;
+
+ if (byFBOption == AUTO_FB_NONE) {
+ struct vnt_tx_datahead_g *buf = pTxDataHead;
+ /* Get SignalField, ServiceField & Length */
+ vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
+ byPktType, &buf->a);
+
+ vnt_get_phy_field(pDevice, cbFrameLength,
+ pDevice->byTopCCKBasicRate,
+ PK_TYPE_11B, &buf->b);
+
+ if (is_pspoll) {
+ __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
+
+ buf->duration_a = dur;
+ buf->duration_b = dur;
+ } else {
+ /* Get Duration and TimeStamp */
+ buf->duration_a =
+ cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength,
+ byPktType, wCurrentRate, bNeedAck, uFragIdx,
+ cbLastFragmentSize, uMACfragNum,
+ byFBOption));
+ buf->duration_b =
+ cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength,
+ PK_TYPE_11B, pDevice->byTopCCKBasicRate,
+ bNeedAck, uFragIdx, cbLastFragmentSize,
+ uMACfragNum, byFBOption));
+ }
+
+ buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate);
+ buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate);
+
+ return buf->duration_a;
+ }
+
+ /* Get SignalField, ServiceField & Length */
+ vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
+ byPktType, &buf->a);
+
+ vnt_get_phy_field(pDevice, cbFrameLength,
+ pDevice->byTopCCKBasicRate,
+ PK_TYPE_11B, &buf->b);
+ /* Get Duration and TimeStamp */
+ buf->duration_a = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
+ wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
+ buf->duration_b = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, PK_TYPE_11B,
+ pDevice->byTopCCKBasicRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
+ buf->duration_a_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
+ wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
+ buf->duration_a_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
+ wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
+
+ buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate);
+ buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate);
+
+ return buf->duration_a;
+ /* if (byFBOption == AUTO_FB_NONE) */
+ } else if (byPktType == PK_TYPE_11A) {
+ struct vnt_tx_datahead_ab *buf = pTxDataHead;
+
+ if (byFBOption != AUTO_FB_NONE) {
+ /* Auto Fallback */
+ struct vnt_tx_datahead_a_fb *buf = pTxDataHead;
+ /* Get SignalField, ServiceField & Length */
+ vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
+ byPktType, &buf->a);
+
+ /* Get Duration and TimeStampOff */
+ buf->duration = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
+ wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
+ buf->duration_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
+ wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
+ buf->duration_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
+ wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
+ buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
+ return buf->duration;
+ }
+
+ /* Get SignalField, ServiceField & Length */
+ vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
+ byPktType, &buf->ab);
+
+ if (is_pspoll) {
+ __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
+
+ buf->duration = dur;
+ } else {
+ /* Get Duration and TimeStampOff */
+ buf->duration =
+ cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
+ wCurrentRate, bNeedAck, uFragIdx,
+ cbLastFragmentSize, uMACfragNum,
+ byFBOption));
+ }
+
+ buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
+ return buf->duration;
+ }
+
+ /* Get SignalField, ServiceField & Length */
+ vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
+ byPktType, &buf->ab);
+
+ if (is_pspoll) {
+ __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
+
+ buf->duration = dur;
+ } else {
+ /* Get Duration and TimeStampOff */
+ buf->duration =
+ cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, byPktType,
+ wCurrentRate, bNeedAck, uFragIdx,
+ cbLastFragmentSize, uMACfragNum,
+ byFBOption));
+ }
+
+ buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
+ return buf->duration;
+}
+
+static
+void
+s_vFillRTSHead(
+ struct vnt_private *pDevice,
+ unsigned char byPktType,
+ void *pvRTS,
+ unsigned int cbFrameLength,
+ bool bNeedAck,
+ bool bDisCRC,
+ struct ieee80211_hdr *hdr,
+ unsigned short wCurrentRate,
+ unsigned char byFBOption
+)
+{
+ unsigned int uRTSFrameLen = 20;
+
+ if (!pvRTS)
+ return;
+
+ if (bDisCRC) {
+ /* When CRCDIS bit is on, H/W forgot to generate FCS for
+ * RTS frame, in this case we need to decrease its length by 4.
+ */
+ uRTSFrameLen -= 4;
+ }
+
+ /* Note: So far RTSHead doesn't appear in ATIM & Beacom DMA,
+ * so we don't need to take them into account.
+ * Otherwise, we need to modify codes for them.
+ */
+ if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
+ if (byFBOption == AUTO_FB_NONE) {
+ struct vnt_rts_g *buf = pvRTS;
+ /* Get SignalField, ServiceField & Length */
+ vnt_get_phy_field(pDevice, uRTSFrameLen,
+ pDevice->byTopCCKBasicRate,
+ PK_TYPE_11B, &buf->b);
+
+ vnt_get_phy_field(pDevice, uRTSFrameLen,
+ pDevice->byTopOFDMBasicRate,
+ byPktType, &buf->a);
+ /* Get Duration */
+ buf->duration_bb =
+ s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,
+ cbFrameLength, PK_TYPE_11B,
+ pDevice->byTopCCKBasicRate,
+ bNeedAck, byFBOption);
+ buf->duration_aa =
+ s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
+ cbFrameLength, byPktType,
+ wCurrentRate, bNeedAck,
+ byFBOption);
+ buf->duration_ba =
+ s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,
+ cbFrameLength, byPktType,
+ wCurrentRate, bNeedAck,
+ byFBOption);
+
+ buf->data.duration = buf->duration_aa;
+ /* Get RTS Frame body */
+ buf->data.frame_control =
+ cpu_to_le16(IEEE80211_FTYPE_CTL |
+ IEEE80211_STYPE_RTS);
+
+ ether_addr_copy(buf->data.ra, hdr->addr1);
+ ether_addr_copy(buf->data.ta, hdr->addr2);
+ } else {
+ struct vnt_rts_g_fb *buf = pvRTS;
+ /* Get SignalField, ServiceField & Length */
+ vnt_get_phy_field(pDevice, uRTSFrameLen,
+ pDevice->byTopCCKBasicRate,
+ PK_TYPE_11B, &buf->b);
+
+ vnt_get_phy_field(pDevice, uRTSFrameLen,
+ pDevice->byTopOFDMBasicRate,
+ byPktType, &buf->a);
+ /* Get Duration */
+ buf->duration_bb =
+ s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,
+ cbFrameLength, PK_TYPE_11B,
+ pDevice->byTopCCKBasicRate,
+ bNeedAck, byFBOption);
+ buf->duration_aa =
+ s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
+ cbFrameLength, byPktType,
+ wCurrentRate, bNeedAck,
+ byFBOption);
+ buf->duration_ba =
+ s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,
+ cbFrameLength, byPktType,
+ wCurrentRate, bNeedAck,
+ byFBOption);
+ buf->rts_duration_ba_f0 =
+ s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F0,
+ cbFrameLength, byPktType,
+ wCurrentRate, bNeedAck,
+ byFBOption);
+ buf->rts_duration_aa_f0 =
+ s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0,
+ cbFrameLength, byPktType,
+ wCurrentRate, bNeedAck,
+ byFBOption);
+ buf->rts_duration_ba_f1 =
+ s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F1,
+ cbFrameLength, byPktType,
+ wCurrentRate, bNeedAck,
+ byFBOption);
+ buf->rts_duration_aa_f1 =
+ s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1,
+ cbFrameLength, byPktType,
+ wCurrentRate, bNeedAck,
+ byFBOption);
+ buf->data.duration = buf->duration_aa;
+ /* Get RTS Frame body */
+ buf->data.frame_control =
+ cpu_to_le16(IEEE80211_FTYPE_CTL |
+ IEEE80211_STYPE_RTS);
+
+ ether_addr_copy(buf->data.ra, hdr->addr1);
+ ether_addr_copy(buf->data.ta, hdr->addr2);
+ } /* if (byFBOption == AUTO_FB_NONE) */
+ } else if (byPktType == PK_TYPE_11A) {
+ if (byFBOption == AUTO_FB_NONE) {
+ struct vnt_rts_ab *buf = pvRTS;
+ /* Get SignalField, ServiceField & Length */
+ vnt_get_phy_field(pDevice, uRTSFrameLen,
+ pDevice->byTopOFDMBasicRate,
+ byPktType, &buf->ab);
+ /* Get Duration */
+ buf->duration =
+ s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
+ cbFrameLength, byPktType,
+ wCurrentRate, bNeedAck,
+ byFBOption);
+ buf->data.duration = buf->duration;
+ /* Get RTS Frame body */
+ buf->data.frame_control =
+ cpu_to_le16(IEEE80211_FTYPE_CTL |
+ IEEE80211_STYPE_RTS);
+
+ ether_addr_copy(buf->data.ra, hdr->addr1);
+ ether_addr_copy(buf->data.ta, hdr->addr2);
+ } else {
+ struct vnt_rts_a_fb *buf = pvRTS;
+ /* Get SignalField, ServiceField & Length */
+ vnt_get_phy_field(pDevice, uRTSFrameLen,
+ pDevice->byTopOFDMBasicRate,
+ byPktType, &buf->a);
+ /* Get Duration */
+ buf->duration =
+ s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
+ cbFrameLength, byPktType,
+ wCurrentRate, bNeedAck,
+ byFBOption);
+ buf->rts_duration_f0 =
+ s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0,
+ cbFrameLength, byPktType,
+ wCurrentRate, bNeedAck,
+ byFBOption);
+ buf->rts_duration_f1 =
+ s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1,
+ cbFrameLength, byPktType,
+ wCurrentRate, bNeedAck,
+ byFBOption);
+ buf->data.duration = buf->duration;
+ /* Get RTS Frame body */
+ buf->data.frame_control =
+ cpu_to_le16(IEEE80211_FTYPE_CTL |
+ IEEE80211_STYPE_RTS);
+
+ ether_addr_copy(buf->data.ra, hdr->addr1);
+ ether_addr_copy(buf->data.ta, hdr->addr2);
+ }
+ } else if (byPktType == PK_TYPE_11B) {
+ struct vnt_rts_ab *buf = pvRTS;
+ /* Get SignalField, ServiceField & Length */
+ vnt_get_phy_field(pDevice, uRTSFrameLen,
+ pDevice->byTopCCKBasicRate,
+ PK_TYPE_11B, &buf->ab);
+ /* Get Duration */
+ buf->duration =
+ s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength,
+ byPktType, wCurrentRate, bNeedAck,
+ byFBOption);
+
+ buf->data.duration = buf->duration;
+ /* Get RTS Frame body */
+ buf->data.frame_control =
+ cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);
+
+ ether_addr_copy(buf->data.ra, hdr->addr1);
+ ether_addr_copy(buf->data.ta, hdr->addr2);
+ }
+}
+
+static
+void
+s_vFillCTSHead(
+ struct vnt_private *pDevice,
+ unsigned int uDMAIdx,
+ unsigned char byPktType,
+ void *pvCTS,
+ unsigned int cbFrameLength,
+ bool bNeedAck,
+ bool bDisCRC,
+ unsigned short wCurrentRate,
+ unsigned char byFBOption
+)
+{
+ unsigned int uCTSFrameLen = 14;
+
+ if (!pvCTS)
+ return;
+
+ if (bDisCRC) {
+ /* When CRCDIS bit is on, H/W forgot to generate FCS for
+ * CTS frame, in this case we need to decrease its length by 4.
+ */
+ uCTSFrameLen -= 4;
+ }
+
+ if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
+ if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) {
+ /* Auto Fall back */
+ struct vnt_cts_fb *buf = pvCTS;
+ /* Get SignalField, ServiceField & Length */
+ vnt_get_phy_field(pDevice, uCTSFrameLen,
+ pDevice->byTopCCKBasicRate,
+ PK_TYPE_11B, &buf->b);
+
+ buf->duration_ba =
+ s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,
+ cbFrameLength, byPktType,
+ wCurrentRate, bNeedAck,
+ byFBOption);
+
+ /* Get CTSDuration_ba_f0 */
+ buf->cts_duration_ba_f0 =
+ s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F0,
+ cbFrameLength, byPktType,
+ wCurrentRate, bNeedAck,
+ byFBOption);
+
+ /* Get CTSDuration_ba_f1 */
+ buf->cts_duration_ba_f1 =
+ s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F1,
+ cbFrameLength, byPktType,
+ wCurrentRate, bNeedAck,
+ byFBOption);
+
+ /* Get CTS Frame body */
+ buf->data.duration = buf->duration_ba;
+
+ buf->data.frame_control =
+ cpu_to_le16(IEEE80211_FTYPE_CTL |
+ IEEE80211_STYPE_CTS);
+
+ buf->reserved2 = 0x0;
+
+ ether_addr_copy(buf->data.ra,
+ pDevice->abyCurrentNetAddr);
+ } else { /* if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) */
+ struct vnt_cts *buf = pvCTS;
+ /* Get SignalField, ServiceField & Length */
+ vnt_get_phy_field(pDevice, uCTSFrameLen,
+ pDevice->byTopCCKBasicRate,
+ PK_TYPE_11B, &buf->b);
+
+ /* Get CTSDuration_ba */
+ buf->duration_ba =
+ s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,
+ cbFrameLength, byPktType,
+ wCurrentRate, bNeedAck,
+ byFBOption);
+
+ /* Get CTS Frame body */
+ buf->data.duration = buf->duration_ba;
+
+ buf->data.frame_control =
+ cpu_to_le16(IEEE80211_FTYPE_CTL |
+ IEEE80211_STYPE_CTS);
+
+ buf->reserved2 = 0x0;
+ ether_addr_copy(buf->data.ra,
+ pDevice->abyCurrentNetAddr);
+ }
+ }
+}
+
+/*
+ *
+ * Description:
+ * Generate FIFO control for MAC & Baseband controller
+ *
+ * Parameters:
+ * In:
+ * pDevice - Pointer to adapter
+ * pTxDataHead - Transmit Data Buffer
+ * pTxBufHead - pTxBufHead
+ * pvRrvTime - pvRrvTime
+ * pvRTS - RTS Buffer
+ * pCTS - CTS Buffer
+ * cbFrameSize - Transmit Data Length (Hdr+Payload+FCS)
+ * bNeedACK - If need ACK
+ * uDescIdx - Desc Index
+ * Out:
+ * none
+ *
+ * Return Value: none
+ *
+ -
+ * unsigned int cbFrameSize, Hdr+Payload+FCS
+ */
+static
+void
+s_vGenerateTxParameter(
+ struct vnt_private *pDevice,
+ unsigned char byPktType,
+ struct vnt_tx_fifo_head *tx_buffer_head,
+ void *pvRrvTime,
+ void *pvRTS,
+ void *pvCTS,
+ unsigned int cbFrameSize,
+ bool bNeedACK,
+ unsigned int uDMAIdx,
+ void *psEthHeader,
+ unsigned short wCurrentRate
+)
+{
+ u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl);
+ bool bDisCRC = false;
+ unsigned char byFBOption = AUTO_FB_NONE;
+
+ tx_buffer_head->current_rate = cpu_to_le16(wCurrentRate);
+
+ if (fifo_ctl & FIFOCTL_CRCDIS)
+ bDisCRC = true;
+
+ if (fifo_ctl & FIFOCTL_AUTO_FB_0)
+ byFBOption = AUTO_FB_0;
+ else if (fifo_ctl & FIFOCTL_AUTO_FB_1)
+ byFBOption = AUTO_FB_1;
+
+ if (!pvRrvTime)
+ return;
+
+ if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
+ if (pvRTS) { /* RTS_need */
+ /* Fill RsvTime */
+ struct vnt_rrv_time_rts *buf = pvRrvTime;
+
+ buf->rts_rrv_time_aa = get_rtscts_time(pDevice, 2, byPktType, cbFrameSize, wCurrentRate);
+ buf->rts_rrv_time_ba = get_rtscts_time(pDevice, 1, byPktType, cbFrameSize, wCurrentRate);
+ buf->rts_rrv_time_bb = get_rtscts_time(pDevice, 0, byPktType, cbFrameSize, wCurrentRate);
+ buf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
+ buf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK);
+
+ s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
+ } else {/* RTS_needless, PCF mode */
+ struct vnt_rrv_time_cts *buf = pvRrvTime;
+
+ buf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
+ buf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK);
+ buf->cts_rrv_time_ba = get_rtscts_time(pDevice, 3, byPktType, cbFrameSize, wCurrentRate);
+
+ /* Fill CTS */
+ s_vFillCTSHead(pDevice, uDMAIdx, byPktType, pvCTS, cbFrameSize, bNeedACK, bDisCRC, wCurrentRate, byFBOption);
+ }
+ } else if (byPktType == PK_TYPE_11A) {
+ if (pvRTS) {/* RTS_need, non PCF mode */
+ struct vnt_rrv_time_ab *buf = pvRrvTime;
+
+ buf->rts_rrv_time = get_rtscts_time(pDevice, 2, byPktType, cbFrameSize, wCurrentRate);
+ buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
+
+ /* Fill RTS */
+ s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
+ } else if (!pvRTS) {/* RTS_needless, non PCF mode */
+ struct vnt_rrv_time_ab *buf = pvRrvTime;
+
+ buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11A, cbFrameSize, wCurrentRate, bNeedACK);
+ }
+ } else if (byPktType == PK_TYPE_11B) {
+ if (pvRTS) {/* RTS_need, non PCF mode */
+ struct vnt_rrv_time_ab *buf = pvRrvTime;
+
+ buf->rts_rrv_time = get_rtscts_time(pDevice, 0, byPktType, cbFrameSize, wCurrentRate);
+ buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK);
+
+ /* Fill RTS */
+ s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
+ } else { /* RTS_needless, non PCF mode */
+ struct vnt_rrv_time_ab *buf = pvRrvTime;
+
+ buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK);
+ }
+ }
+}
+
+static unsigned int
+s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
+ unsigned char *pbyTxBufferAddr,
+ unsigned int uDMAIdx, struct vnt_tx_desc *pHeadTD,
+ unsigned int is_pspoll)
+{
+ struct vnt_td_info *td_info = pHeadTD->td_info;
+ struct sk_buff *skb = td_info->skb;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ struct vnt_tx_fifo_head *tx_buffer_head =
+ (struct vnt_tx_fifo_head *)td_info->buf;
+ u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl);
+ unsigned int cbFrameSize;
+ __le16 uDuration;
+ unsigned char *pbyBuffer;
+ unsigned int uLength = 0;
+ unsigned int cbMICHDR = 0;
+ unsigned int uMACfragNum = 1;
+ unsigned int uPadding = 0;
+ unsigned int cbReqCount = 0;
+ bool bNeedACK = (bool)(fifo_ctl & FIFOCTL_NEEDACK);
+ bool bRTS = (bool)(fifo_ctl & FIFOCTL_RTS);
+ struct vnt_tx_desc *ptdCurr;
+ unsigned int cbHeaderLength = 0;
+ void *pvRrvTime = NULL;
+ struct vnt_mic_hdr *pMICHDR = NULL;
+ void *pvRTS = NULL;
+ void *pvCTS = NULL;
+ void *pvTxDataHd = NULL;
+ unsigned short wTxBufSize; /* FFinfo size */
+ unsigned char byFBOption = AUTO_FB_NONE;
+
+ cbFrameSize = skb->len + 4;
+
+ if (info->control.hw_key) {
+ switch (info->control.hw_key->cipher) {
+ case WLAN_CIPHER_SUITE_CCMP:
+ cbMICHDR = sizeof(struct vnt_mic_hdr);
+ break;
+ default:
+ break;
+ }
+
+ cbFrameSize += info->control.hw_key->icv_len;
+
+ if (pDevice->local_id > REV_ID_VT3253_A1) {
+ /* MAC Header should be padding 0 to DW alignment. */
+ uPadding = 4 - (ieee80211_get_hdrlen_from_skb(skb) % 4);
+ uPadding %= 4;
+ }
+ }
+
+ /*
+ * Use for AUTO FALL BACK
+ */
+ if (fifo_ctl & FIFOCTL_AUTO_FB_0)
+ byFBOption = AUTO_FB_0;
+ else if (fifo_ctl & FIFOCTL_AUTO_FB_1)
+ byFBOption = AUTO_FB_1;
+
+ /* Set RrvTime/RTS/CTS Buffer */
+ wTxBufSize = sizeof(struct vnt_tx_fifo_head);
+ if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {/* 802.11g packet */
+
+ if (byFBOption == AUTO_FB_NONE) {
+ if (bRTS) {/* RTS_need */
+ pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
+ pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));
+ pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
+ pvCTS = NULL;
+ pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
+ cbMICHDR + sizeof(struct vnt_rts_g));
+ cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
+ cbMICHDR + sizeof(struct vnt_rts_g) +
+ sizeof(struct vnt_tx_datahead_g);
+ } else { /* RTS_needless */
+ pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
+ pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));
+ pvRTS = NULL;
+ pvCTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
+ pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
+ sizeof(struct vnt_rrv_time_cts) + cbMICHDR + sizeof(struct vnt_cts));
+ cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
+ cbMICHDR + sizeof(struct vnt_cts) + sizeof(struct vnt_tx_datahead_g);
+ }
+ } else {
+ /* Auto Fall Back */
+ if (bRTS) {/* RTS_need */
+ pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
+ pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));
+ pvRTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
+ pvCTS = NULL;
+ pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
+ cbMICHDR + sizeof(struct vnt_rts_g_fb));
+ cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
+ cbMICHDR + sizeof(struct vnt_rts_g_fb) + sizeof(struct vnt_tx_datahead_g_fb);
+ } else { /* RTS_needless */
+ pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
+ pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));
+ pvRTS = NULL;
+ pvCTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
+ pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
+ cbMICHDR + sizeof(struct vnt_cts_fb));
+ cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
+ cbMICHDR + sizeof(struct vnt_cts_fb) + sizeof(struct vnt_tx_datahead_g_fb);
+ }
+ } /* Auto Fall Back */
+ } else {/* 802.11a/b packet */
+
+ if (byFBOption == AUTO_FB_NONE) {
+ if (bRTS) {
+ pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
+ pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
+ pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
+ pvCTS = NULL;
+ pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
+ sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_ab));
+ cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
+ cbMICHDR + sizeof(struct vnt_rts_ab) + sizeof(struct vnt_tx_datahead_ab);
+ } else { /* RTS_needless, need MICHDR */
+ pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
+ pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
+ pvRTS = NULL;
+ pvCTS = NULL;
+ pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
+ cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
+ cbMICHDR + sizeof(struct vnt_tx_datahead_ab);
+ }
+ } else {
+ /* Auto Fall Back */
+ if (bRTS) { /* RTS_need */
+ pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
+ pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
+ pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
+ pvCTS = NULL;
+ pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
+ sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_a_fb));
+ cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
+ cbMICHDR + sizeof(struct vnt_rts_a_fb) + sizeof(struct vnt_tx_datahead_a_fb);
+ } else { /* RTS_needless */
+ pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
+ pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
+ pvRTS = NULL;
+ pvCTS = NULL;
+ pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
+ cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
+ cbMICHDR + sizeof(struct vnt_tx_datahead_a_fb);
+ }
+ } /* Auto Fall Back */
+ }
+
+ td_info->mic_hdr = pMICHDR;
+
+ memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderLength - wTxBufSize));
+
+ /* Fill FIFO,RrvTime,RTS,and CTS */
+ s_vGenerateTxParameter(pDevice, byPktType, tx_buffer_head, pvRrvTime, pvRTS, pvCTS,
+ cbFrameSize, bNeedACK, uDMAIdx, hdr, pDevice->wCurrentRate);
+ /* Fill DataHead */
+ uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK,
+ 0, 0, uMACfragNum, byFBOption, pDevice->wCurrentRate, is_pspoll);
+
+ hdr->duration_id = uDuration;
+
+ cbReqCount = cbHeaderLength + uPadding + skb->len;
+ pbyBuffer = (unsigned char *)pHeadTD->td_info->buf;
+ uLength = cbHeaderLength + uPadding;
+
+ /* Copy the Packet into a tx Buffer */
+ memcpy((pbyBuffer + uLength), skb->data, skb->len);
+
+ ptdCurr = pHeadTD;
+
+ ptdCurr->td_info->req_count = (u16)cbReqCount;
+
+ return cbHeaderLength;
+}
+
+static void vnt_fill_txkey(struct ieee80211_hdr *hdr, u8 *key_buffer,
+ struct ieee80211_key_conf *tx_key,
+ struct sk_buff *skb, u16 payload_len,
+ struct vnt_mic_hdr *mic_hdr)
+{
+ u64 pn64;
+ u8 *iv = ((u8 *)hdr + ieee80211_get_hdrlen_from_skb(skb));
+
+ /* strip header and icv len from payload */
+ payload_len -= ieee80211_get_hdrlen_from_skb(skb);
+ payload_len -= tx_key->icv_len;
+
+ switch (tx_key->cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
+ memcpy(key_buffer, iv, 3);
+ memcpy(key_buffer + 3, tx_key->key, tx_key->keylen);
+
+ if (tx_key->keylen == WLAN_KEY_LEN_WEP40) {
+ memcpy(key_buffer + 8, iv, 3);
+ memcpy(key_buffer + 11,
+ tx_key->key, WLAN_KEY_LEN_WEP40);
+ }
+
+ break;
+ case WLAN_CIPHER_SUITE_TKIP:
+ ieee80211_get_tkip_p2k(tx_key, skb, key_buffer);
+
+ break;
+ case WLAN_CIPHER_SUITE_CCMP:
+
+ if (!mic_hdr)
+ return;
+
+ mic_hdr->id = 0x59;
+ mic_hdr->payload_len = cpu_to_be16(payload_len);
+ ether_addr_copy(mic_hdr->mic_addr2, hdr->addr2);
+
+ pn64 = atomic64_read(&tx_key->tx_pn);
+ mic_hdr->ccmp_pn[5] = pn64;
+ mic_hdr->ccmp_pn[4] = pn64 >> 8;
+ mic_hdr->ccmp_pn[3] = pn64 >> 16;
+ mic_hdr->ccmp_pn[2] = pn64 >> 24;
+ mic_hdr->ccmp_pn[1] = pn64 >> 32;
+ mic_hdr->ccmp_pn[0] = pn64 >> 40;
+
+ if (ieee80211_has_a4(hdr->frame_control))
+ mic_hdr->hlen = cpu_to_be16(28);
+ else
+ mic_hdr->hlen = cpu_to_be16(22);
+
+ ether_addr_copy(mic_hdr->addr1, hdr->addr1);
+ ether_addr_copy(mic_hdr->addr2, hdr->addr2);
+ ether_addr_copy(mic_hdr->addr3, hdr->addr3);
+
+ mic_hdr->frame_control = cpu_to_le16(
+ le16_to_cpu(hdr->frame_control) & 0xc78f);
+ mic_hdr->seq_ctrl = cpu_to_le16(
+ le16_to_cpu(hdr->seq_ctrl) & 0xf);
+
+ if (ieee80211_has_a4(hdr->frame_control))
+ ether_addr_copy(mic_hdr->addr4, hdr->addr4);
+
+ memcpy(key_buffer, tx_key->key, WLAN_KEY_LEN_CCMP);
+
+ break;
+ default:
+ break;
+ }
+}
+
+int vnt_generate_fifo_header(struct vnt_private *priv, u32 dma_idx,
+ struct vnt_tx_desc *head_td, struct sk_buff *skb)
+{
+ struct vnt_td_info *td_info = head_td->td_info;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_tx_rate *tx_rate = &info->control.rates[0];
+ struct ieee80211_rate *rate;
+ struct ieee80211_key_conf *tx_key;
+ struct ieee80211_hdr *hdr;
+ struct vnt_tx_fifo_head *tx_buffer_head =
+ (struct vnt_tx_fifo_head *)td_info->buf;
+ u16 tx_body_size = skb->len, current_rate;
+ u8 pkt_type;
+ bool is_pspoll = false;
+
+ memset(tx_buffer_head, 0, sizeof(*tx_buffer_head));
+
+ hdr = (struct ieee80211_hdr *)(skb->data);
+
+ rate = ieee80211_get_tx_rate(priv->hw, info);
+
+ current_rate = rate->hw_value;
+ if (priv->wCurrentRate != current_rate &&
+ !(priv->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) {
+ priv->wCurrentRate = current_rate;
+
+ RFbSetPower(priv, priv->wCurrentRate,
+ priv->hw->conf.chandef.chan->hw_value);
+ }
+
+ if (current_rate > RATE_11M) {
+ if (info->band == NL80211_BAND_5GHZ) {
+ pkt_type = PK_TYPE_11A;
+ } else {
+ if (tx_rate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
+ pkt_type = PK_TYPE_11GB;
+ else
+ pkt_type = PK_TYPE_11GA;
+ }
+ } else {
+ pkt_type = PK_TYPE_11B;
+ }
+
+ /*Set fifo controls */
+ if (pkt_type == PK_TYPE_11A)
+ tx_buffer_head->fifo_ctl = 0;
+ else if (pkt_type == PK_TYPE_11B)
+ tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11B);
+ else if (pkt_type == PK_TYPE_11GB)
+ tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GB);
+ else if (pkt_type == PK_TYPE_11GA)
+ tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GA);
+
+ /* generate interrupt */
+ tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);
+
+ if (!ieee80211_is_data(hdr->frame_control)) {
+ tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_TMOEN);
+ tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_ISDMA0);
+ tx_buffer_head->time_stamp =
+ cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
+ } else {
+ tx_buffer_head->time_stamp =
+ cpu_to_le16(DEFAULT_MSDU_LIFETIME_RES_64us);
+ }
+
+ if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
+ tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_NEEDACK);
+
+ if (ieee80211_has_retry(hdr->frame_control))
+ tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LRETRY);
+
+ if (tx_rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
+ priv->preamble_type = PREAMBLE_SHORT;
+ else
+ priv->preamble_type = PREAMBLE_LONG;
+
+ if (tx_rate->flags & IEEE80211_TX_RC_USE_RTS_CTS)
+ tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_RTS);
+
+ if (ieee80211_has_a4(hdr->frame_control)) {
+ tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LHEAD);
+ priv->bLongHeader = true;
+ }
+
+ if (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER)
+ is_pspoll = true;
+
+ tx_buffer_head->frag_ctl =
+ cpu_to_le16(ieee80211_get_hdrlen_from_skb(skb) << 10);
+
+ if (info->control.hw_key) {
+ switch (info->control.hw_key->cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
+ tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_LEGACY);
+ break;
+ case WLAN_CIPHER_SUITE_TKIP:
+ tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_TKIP);
+ break;
+ case WLAN_CIPHER_SUITE_CCMP:
+ tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_AES);
+ break;
+ default:
+ break;
+ }
+ }
+
+ tx_buffer_head->current_rate = cpu_to_le16(current_rate);
+
+ /* legacy rates TODO use ieee80211_tx_rate */
+ if (current_rate >= RATE_18M && ieee80211_is_data(hdr->frame_control)) {
+ if (priv->byAutoFBCtrl == AUTO_FB_0)
+ tx_buffer_head->fifo_ctl |=
+ cpu_to_le16(FIFOCTL_AUTO_FB_0);
+ else if (priv->byAutoFBCtrl == AUTO_FB_1)
+ tx_buffer_head->fifo_ctl |=
+ cpu_to_le16(FIFOCTL_AUTO_FB_1);
+ }
+
+ tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_NONFRAG);
+
+ s_cbFillTxBufHead(priv, pkt_type, (u8 *)tx_buffer_head,
+ dma_idx, head_td, is_pspoll);
+
+ if (info->control.hw_key) {
+ tx_key = info->control.hw_key;
+ if (tx_key->keylen > 0)
+ vnt_fill_txkey(hdr, tx_buffer_head->tx_key,
+ tx_key, skb, tx_body_size,
+ td_info->mic_hdr);
+ }
+
+ return 0;
+}
+
+static int vnt_beacon_xmit(struct vnt_private *priv,
+ struct sk_buff *skb)
+{
+ struct vnt_tx_short_buf_head *short_head =
+ (struct vnt_tx_short_buf_head *)priv->tx_beacon_bufs;
+ struct ieee80211_mgmt *mgmt_hdr = (struct ieee80211_mgmt *)
+ (priv->tx_beacon_bufs + sizeof(*short_head));
+ struct ieee80211_tx_info *info;
+ u32 frame_size = skb->len + 4;
+ u16 current_rate;
+
+ memset(priv->tx_beacon_bufs, 0, sizeof(*short_head));
+
+ if (priv->byBBType == BB_TYPE_11A) {
+ current_rate = RATE_6M;
+
+ /* Get SignalField,ServiceField,Length */
+ vnt_get_phy_field(priv, frame_size, current_rate,
+ PK_TYPE_11A, &short_head->ab);
+
+ /* Get Duration and TimeStampOff */
+ short_head->duration =
+ cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B,
+ frame_size, PK_TYPE_11A, current_rate,
+ false, 0, 0, 1, AUTO_FB_NONE));
+
+ short_head->time_stamp_off =
+ vnt_time_stamp_off(priv, current_rate);
+ } else {
+ current_rate = RATE_1M;
+ short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_11B);
+
+ /* Get SignalField,ServiceField,Length */
+ vnt_get_phy_field(priv, frame_size, current_rate,
+ PK_TYPE_11B, &short_head->ab);
+
+ /* Get Duration and TimeStampOff */
+ short_head->duration =
+ cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B,
+ frame_size, PK_TYPE_11B, current_rate,
+ false, 0, 0, 1, AUTO_FB_NONE));
+
+ short_head->time_stamp_off =
+ vnt_time_stamp_off(priv, current_rate);
+ }
+
+ short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);
+
+ /* Copy Beacon */
+ memcpy(mgmt_hdr, skb->data, skb->len);
+
+ /* time stamp always 0 */
+ mgmt_hdr->u.beacon.timestamp = 0;
+
+ info = IEEE80211_SKB_CB(skb);
+ if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)mgmt_hdr;
+
+ hdr->duration_id = 0;
+ hdr->seq_ctrl = cpu_to_le16(priv->wSeqCounter << 4);
+ }
+
+ priv->wSeqCounter++;
+ if (priv->wSeqCounter > 0x0fff)
+ priv->wSeqCounter = 0;
+
+ priv->wBCNBufLen = sizeof(*short_head) + skb->len;
+
+ iowrite32((u32)priv->tx_beacon_dma, priv->port_offset + MAC_REG_BCNDMAPTR);
+
+ iowrite16(priv->wBCNBufLen, priv->port_offset + MAC_REG_BCNDMACTL + 2);
+ /* Set auto Transmit on */
+ vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_TCR, TCR_AUTOBCNTX);
+ /* Poll Transmit the adapter */
+ iowrite8(BEACON_READY, priv->port_offset + MAC_REG_BCNDMACTL);
+
+ return 0;
+}
+
+int vnt_beacon_make(struct vnt_private *priv, struct ieee80211_vif *vif)
+{
+ struct sk_buff *beacon;
+
+ beacon = ieee80211_beacon_get(priv->hw, vif, 0);
+ if (!beacon)
+ return -ENOMEM;
+
+ if (vnt_beacon_xmit(priv, beacon)) {
+ ieee80211_free_txskb(priv->hw, beacon);
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+int vnt_beacon_enable(struct vnt_private *priv, struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *conf)
+{
+ iowrite8(TFTCTL_TSFCNTRST, priv->port_offset + MAC_REG_TFTCTL);
+
+ iowrite8(TFTCTL_TSFCNTREN, priv->port_offset + MAC_REG_TFTCTL);
+
+ CARDvSetFirstNextTBTT(priv, conf->beacon_int);
+
+ CARDbSetBeaconPeriod(priv, conf->beacon_int);
+
+ return vnt_beacon_make(priv, vif);
+}
diff --git a/drivers/staging/vt6655/rxtx.h b/drivers/staging/vt6655/rxtx.h
new file mode 100644
index 0000000000..a67757c9bb
--- /dev/null
+++ b/drivers/staging/vt6655/rxtx.h
@@ -0,0 +1,185 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * Purpose:
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Jun. 27, 2002
+ *
+ */
+
+#ifndef __RXTX_H__
+#define __RXTX_H__
+
+#include "device.h"
+
+#define DEFAULT_MSDU_LIFETIME_RES_64us 8000 /* 64us */
+#define DEFAULT_MGN_LIFETIME_RES_64us 125 /* 64us */
+
+
+/*--------------------- Export Definitions -------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+
+/*--------------------- Export Functions --------------------------*/
+
+/* MIC HDR data header */
+struct vnt_mic_hdr {
+ u8 id;
+ u8 tx_priority;
+ u8 mic_addr2[ETH_ALEN];
+ u8 ccmp_pn[IEEE80211_CCMP_PN_LEN];
+ __be16 payload_len;
+ __be16 hlen;
+ __le16 frame_control;
+ u8 addr1[ETH_ALEN];
+ u8 addr2[ETH_ALEN];
+ u8 addr3[ETH_ALEN];
+ __le16 seq_ctrl;
+ u8 addr4[ETH_ALEN];
+ u16 packing; /* packing to 48 bytes */
+} __packed;
+
+/* RsvTime buffer header */
+struct vnt_rrv_time_rts {
+ __le16 rts_rrv_time_ba;
+ __le16 rts_rrv_time_aa;
+ __le16 rts_rrv_time_bb;
+ u16 reserved;
+ __le16 rrv_time_b;
+ __le16 rrv_time_a;
+} __packed;
+
+struct vnt_rrv_time_cts {
+ __le16 cts_rrv_time_ba;
+ u16 reserved;
+ __le16 rrv_time_b;
+ __le16 rrv_time_a;
+} __packed;
+
+struct vnt_rrv_time_ab {
+ __le16 rts_rrv_time;
+ __le16 rrv_time;
+} __packed;
+
+/* TX data header */
+struct vnt_tx_datahead_g {
+ struct vnt_phy_field b;
+ struct vnt_phy_field a;
+ __le16 duration_b;
+ __le16 duration_a;
+ __le16 time_stamp_off_b;
+ __le16 time_stamp_off_a;
+} __packed;
+
+struct vnt_tx_datahead_g_fb {
+ struct vnt_phy_field b;
+ struct vnt_phy_field a;
+ __le16 duration_b;
+ __le16 duration_a;
+ __le16 duration_a_f0;
+ __le16 duration_a_f1;
+ __le16 time_stamp_off_b;
+ __le16 time_stamp_off_a;
+} __packed;
+
+struct vnt_tx_datahead_ab {
+ struct vnt_phy_field ab;
+ __le16 duration;
+ __le16 time_stamp_off;
+} __packed;
+
+struct vnt_tx_datahead_a_fb {
+ struct vnt_phy_field a;
+ __le16 duration;
+ __le16 time_stamp_off;
+ __le16 duration_f0;
+ __le16 duration_f1;
+} __packed;
+
+/* RTS buffer header */
+struct vnt_rts_g {
+ struct vnt_phy_field b;
+ struct vnt_phy_field a;
+ __le16 duration_ba;
+ __le16 duration_aa;
+ __le16 duration_bb;
+ u16 reserved;
+ struct ieee80211_rts data;
+} __packed __aligned(2);
+
+struct vnt_rts_g_fb {
+ struct vnt_phy_field b;
+ struct vnt_phy_field a;
+ __le16 duration_ba;
+ __le16 duration_aa;
+ __le16 duration_bb;
+ u16 wReserved;
+ __le16 rts_duration_ba_f0;
+ __le16 rts_duration_aa_f0;
+ __le16 rts_duration_ba_f1;
+ __le16 rts_duration_aa_f1;
+ struct ieee80211_rts data;
+} __packed __aligned(2);
+
+struct vnt_rts_ab {
+ struct vnt_phy_field ab;
+ __le16 duration;
+ u16 reserved;
+ struct ieee80211_rts data;
+} __packed __aligned(2);
+
+struct vnt_rts_a_fb {
+ struct vnt_phy_field a;
+ __le16 duration;
+ u16 reserved;
+ __le16 rts_duration_f0;
+ __le16 rts_duration_f1;
+ struct ieee80211_rts data;
+} __packed __aligned(2);
+
+/* CTS buffer header */
+struct vnt_cts {
+ struct vnt_phy_field b;
+ __le16 duration_ba;
+ u16 reserved;
+ struct ieee80211_cts data;
+ u16 reserved2;
+} __packed __aligned(2);
+
+struct vnt_cts_fb {
+ struct vnt_phy_field b;
+ __le16 duration_ba;
+ u16 reserved;
+ __le16 cts_duration_ba_f0;
+ __le16 cts_duration_ba_f1;
+ struct ieee80211_cts data;
+ u16 reserved2;
+} __packed __aligned(2);
+
+struct vnt_tx_fifo_head {
+ u8 tx_key[WLAN_KEY_LEN_CCMP];
+ __le16 fifo_ctl;
+ __le16 time_stamp;
+ __le16 frag_ctl;
+ __le16 current_rate;
+} __packed;
+
+struct vnt_tx_short_buf_head {
+ __le16 fifo_ctl;
+ u16 time_stamp;
+ struct vnt_phy_field ab;
+ __le16 duration;
+ __le16 time_stamp_off;
+} __packed;
+
+int vnt_generate_fifo_header(struct vnt_private *priv, u32 dma_idx,
+ struct vnt_tx_desc *head_td, struct sk_buff *skb);
+int vnt_beacon_make(struct vnt_private *priv, struct ieee80211_vif *vif);
+int vnt_beacon_enable(struct vnt_private *priv, struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *conf);
+
+#endif /* __RXTX_H__ */
diff --git a/drivers/staging/vt6655/srom.c b/drivers/staging/vt6655/srom.c
new file mode 100644
index 0000000000..1b89d401a7
--- /dev/null
+++ b/drivers/staging/vt6655/srom.c
@@ -0,0 +1,140 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * Purpose:Implement functions to access eeprom
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Jan 29, 2003
+ *
+ * Functions:
+ * SROMbyReadEmbedded - Embedded read eeprom via MAC
+ * SROMbWriteEmbedded - Embedded write eeprom via MAC
+ * SROMvRegBitsOn - Set Bits On in eeprom
+ * SROMvRegBitsOff - Clear Bits Off in eeprom
+ * SROMbIsRegBitsOn - Test if Bits On in eeprom
+ * SROMbIsRegBitsOff - Test if Bits Off in eeprom
+ * SROMvReadAllContents - Read all contents in eeprom
+ * SROMvWriteAllContents - Write all contents in eeprom
+ * SROMvReadEtherAddress - Read Ethernet Address in eeprom
+ * SROMvWriteEtherAddress - Write Ethernet Address in eeprom
+ * SROMvReadSubSysVenId - Read Sub_VID and Sub_SysId in eeprom
+ * SROMbAutoLoad - Auto Load eeprom to MAC register
+ *
+ * Revision History:
+ *
+ */
+
+#include "device.h"
+#include "mac.h"
+#include "srom.h"
+
+/*--------------------- Static Definitions -------------------------*/
+
+/*--------------------- Static Classes ----------------------------*/
+
+/*--------------------- Static Variables --------------------------*/
+
+/*--------------------- Static Functions --------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+
+/*--------------------- Export Functions --------------------------*/
+
+/*
+ * Description: Read a byte from EEPROM, by MAC I2C
+ *
+ * Parameters:
+ * In:
+ * iobase - I/O base address
+ * contnt_offset - address of EEPROM
+ * Out:
+ * none
+ *
+ * Return Value: data read
+ *
+ */
+unsigned char SROMbyReadEmbedded(void __iomem *iobase,
+ unsigned char contnt_offset)
+{
+ unsigned short wDelay, wNoACK;
+ unsigned char byWait;
+ unsigned char byData;
+ unsigned char byOrg;
+
+ byData = 0xFF;
+ byOrg = ioread8(iobase + MAC_REG_I2MCFG);
+ /* turn off hardware retry for getting NACK */
+ iowrite8(byOrg & (~I2MCFG_NORETRY), iobase + MAC_REG_I2MCFG);
+ for (wNoACK = 0; wNoACK < W_MAX_I2CRETRY; wNoACK++) {
+ iowrite8(EEP_I2C_DEV_ID, iobase + MAC_REG_I2MTGID);
+ iowrite8(contnt_offset, iobase + MAC_REG_I2MTGAD);
+
+ /* issue read command */
+ iowrite8(I2MCSR_EEMR, iobase + MAC_REG_I2MCSR);
+ /* wait DONE be set */
+ for (wDelay = 0; wDelay < W_MAX_TIMEOUT; wDelay++) {
+ byWait = ioread8(iobase + MAC_REG_I2MCSR);
+ if (byWait & (I2MCSR_DONE | I2MCSR_NACK))
+ break;
+ udelay(CB_DELAY_LOOP_WAIT);
+ }
+ if ((wDelay < W_MAX_TIMEOUT) &&
+ (!(byWait & I2MCSR_NACK))) {
+ break;
+ }
+ }
+ byData = ioread8(iobase + MAC_REG_I2MDIPT);
+ iowrite8(byOrg, iobase + MAC_REG_I2MCFG);
+ return byData;
+}
+
+/*
+ * Description: Read all contents of eeprom to buffer
+ *
+ * Parameters:
+ * In:
+ * iobase - I/O base address
+ * Out:
+ * pbyEepromRegs - EEPROM content Buffer
+ *
+ * Return Value: none
+ *
+ */
+void SROMvReadAllContents(void __iomem *iobase, unsigned char *pbyEepromRegs)
+{
+ int ii;
+
+ /* ii = Rom Address */
+ for (ii = 0; ii < EEP_MAX_CONTEXT_SIZE; ii++) {
+ *pbyEepromRegs = SROMbyReadEmbedded(iobase,
+ (unsigned char)ii);
+ pbyEepromRegs++;
+ }
+}
+
+/*
+ * Description: Read Ethernet Address from eeprom to buffer
+ *
+ * Parameters:
+ * In:
+ * iobase - I/O base address
+ * Out:
+ * pbyEtherAddress - Ethernet Address buffer
+ *
+ * Return Value: none
+ *
+ */
+void SROMvReadEtherAddress(void __iomem *iobase,
+ unsigned char *pbyEtherAddress)
+{
+ unsigned char ii;
+
+ /* ii = Rom Address */
+ for (ii = 0; ii < ETH_ALEN; ii++) {
+ *pbyEtherAddress = SROMbyReadEmbedded(iobase, ii);
+ pbyEtherAddress++;
+ }
+}
diff --git a/drivers/staging/vt6655/srom.h b/drivers/staging/vt6655/srom.h
new file mode 100644
index 0000000000..b03073ffa1
--- /dev/null
+++ b/drivers/staging/vt6655/srom.h
@@ -0,0 +1,85 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
+ * All rights reserved.
+ *
+ * Purpose: Implement functions to access eeprom
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Jan 29, 2003
+ */
+
+#ifndef __SROM_H__
+#define __SROM_H__
+
+/*--------------------- Export Definitions -------------------------*/
+
+#define EEP_MAX_CONTEXT_SIZE 256
+
+#define CB_EEPROM_READBYTE_WAIT 900 /* us */
+
+#define W_MAX_I2CRETRY 0x0fff
+
+/* Contents in the EEPROM */
+#define EEP_OFS_PAR 0x00 /* physical address */
+#define EEP_OFS_ANTENNA 0x16
+#define EEP_OFS_RADIOCTL 0x17
+#define EEP_OFS_RFTYPE 0x1B /* for select RF */
+#define EEP_OFS_MINCHANNEL 0x1C /* Min Channel # */
+#define EEP_OFS_MAXCHANNEL 0x1D /* Max Channel # */
+#define EEP_OFS_SIGNATURE 0x1E
+#define EEP_OFS_ZONETYPE 0x1F
+#define EEP_OFS_RFTABLE 0x20 /* RF POWER TABLE */
+#define EEP_OFS_PWR_CCK 0x20
+#define EEP_OFS_SETPT_CCK 0x21
+#define EEP_OFS_PWR_OFDMG 0x23
+#define EEP_OFS_SETPT_OFDMG 0x24
+#define EEP_OFS_PWR_FORMULA_OST 0x26
+#define EEP_OFS_MAJOR_VER 0x2E
+#define EEP_OFS_MINOR_VER 0x2F
+#define EEP_OFS_CCK_PWR_TBL 0x30
+#define EEP_OFS_CCK_PWR_dBm 0x3F
+#define EEP_OFS_OFDM_PWR_TBL 0x40
+#define EEP_OFS_OFDM_PWR_dBm 0x4F
+/*{{ RobertYu: 20041124 */
+#define EEP_OFS_SETPT_OFDMA 0x4E
+#define EEP_OFS_OFDMA_PWR_TBL 0x50
+/*}}*/
+#define EEP_OFS_OFDMA_PWR_dBm 0xD2
+
+/*----------need to remove --------------------*/
+#define EEP_OFS_BBTAB_LEN 0x70 /* BB Table Length */
+#define EEP_OFS_BBTAB_ADR 0x71 /* BB Table Offset */
+#define EEP_OFS_CHECKSUM 0xFF /* reserved area for baseband 28h~78h */
+
+#define EEP_I2C_DEV_ID 0x50 /* EEPROM device address on I2C bus */
+
+/* Bits in EEP_OFS_ANTENNA */
+#define EEP_ANTENNA_MAIN 0x01
+#define EEP_ANTENNA_AUX 0x02
+#define EEP_ANTINV 0x04
+
+/* Bits in EEP_OFS_RADIOCTL */
+#define EEP_RADIOCTL_ENABLE 0x80
+#define EEP_RADIOCTL_INV 0x01
+
+/*--------------------- Export Types ------------------------------*/
+
+/*--------------------- Export Macros ------------------------------*/
+
+/*--------------------- Export Classes ----------------------------*/
+
+/*--------------------- Export Variables --------------------------*/
+
+/*--------------------- Export Functions --------------------------*/
+
+unsigned char SROMbyReadEmbedded(void __iomem *iobase,
+ unsigned char byContntOffset);
+
+void SROMvReadAllContents(void __iomem *iobase, unsigned char *pbyEepromRegs);
+
+void SROMvReadEtherAddress(void __iomem *iobase,
+ unsigned char *pbyEtherAddress);
+
+#endif /* __EEPROM_H__*/
diff --git a/drivers/staging/vt6655/test b/drivers/staging/vt6655/test
new file mode 100644
index 0000000000..ba6dec7744
--- /dev/null
+++ b/drivers/staging/vt6655/test
@@ -0,0 +1,9 @@
+KSP := /lib/modules/$(shell uname -r)/build \
+ /usr/src/linux-$(shell uname -r) \
+ /usr/src/linux-$(shell uname -r | sed 's/-.*//') \
+# /usr/src/kernel-headers-$(shell uname -r) \
+# /usr/src/kernel-source-$(shell uname -r) \
+# /usr/src/linux-$(shell uname -r | sed 's/\([0-9]*\.[0-9]*\)\..*/\1/') \
+# /usr/src/linux /home/plice
+test_dir = $(shell [ -e $(dir)/include/linux ] && echo $(dir))
+KSP := $(foreach dir, $(KSP), $(test_dir))