diff options
Diffstat (limited to 'drivers/staging/vt6656')
-rw-r--r-- | drivers/staging/vt6656/Makefile | 6 | ||||
-rw-r--r-- | drivers/staging/vt6656/baseband.c | 620 | ||||
-rw-r--r-- | drivers/staging/vt6656/baseband.h | 17 | ||||
-rw-r--r-- | drivers/staging/vt6656/card.c | 570 | ||||
-rw-r--r-- | drivers/staging/vt6656/card.h | 20 | ||||
-rw-r--r-- | drivers/staging/vt6656/device.h | 20 | ||||
-rw-r--r-- | drivers/staging/vt6656/firmware.c | 106 | ||||
-rw-r--r-- | drivers/staging/vt6656/firmware.h | 25 | ||||
-rw-r--r-- | drivers/staging/vt6656/key.c | 47 | ||||
-rw-r--r-- | drivers/staging/vt6656/key.h | 13 | ||||
-rw-r--r-- | drivers/staging/vt6656/mac.c | 128 | ||||
-rw-r--r-- | drivers/staging/vt6656/mac.h | 28 | ||||
-rw-r--r-- | drivers/staging/vt6656/main_usb.c | 181 | ||||
-rw-r--r-- | drivers/staging/vt6656/power.c | 34 | ||||
-rw-r--r-- | drivers/staging/vt6656/power.h | 2 | ||||
-rw-r--r-- | drivers/staging/vt6656/rf.c | 463 | ||||
-rw-r--r-- | drivers/staging/vt6656/rf.h | 3 | ||||
-rw-r--r-- | drivers/staging/vt6656/rxtx.c | 674 | ||||
-rw-r--r-- | drivers/staging/vt6656/rxtx.h | 20 | ||||
-rw-r--r-- | drivers/staging/vt6656/usbpipe.c | 70 | ||||
-rw-r--r-- | drivers/staging/vt6656/usbpipe.h | 11 | ||||
-rw-r--r-- | drivers/staging/vt6656/wcmd.c | 3 |
22 files changed, 1018 insertions, 2043 deletions
diff --git a/drivers/staging/vt6656/Makefile b/drivers/staging/vt6656/Makefile index 375f54e9f58b..f696a9d7a143 100644 --- a/drivers/staging/vt6656/Makefile +++ b/drivers/staging/vt6656/Makefile @@ -1,7 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 -# TODO: all of these should be removed -ccflags-y := -DLINUX -D__KERNEL__ -DEXPORT_SYMTAB -D__NO_VERSION__ -ccflags-y += -DHOSTAP vt6656_stage-y += main_usb.o \ card.o \ @@ -13,7 +10,6 @@ vt6656_stage-y += main_usb.o \ key.o \ rf.o \ usbpipe.o \ - channel.o \ - firmware.o + channel.o obj-$(CONFIG_VT6656) += vt6656_stage.o diff --git a/drivers/staging/vt6656/baseband.c b/drivers/staging/vt6656/baseband.c index a19a563d8bcc..41ae779ec61f 100644 --- a/drivers/staging/vt6656/baseband.c +++ b/drivers/staging/vt6656/baseband.c @@ -23,13 +23,15 @@ */ #include <linux/bits.h> +#include <linux/errno.h> #include <linux/kernel.h> +#include "device.h" #include "mac.h" #include "baseband.h" #include "rf.h" #include "usbpipe.h" -static u8 vnt_vt3184_agc[] = { +static const u8 vnt_vt3184_agc[] = { 0x00, 0x00, 0x02, 0x02, 0x04, 0x04, 0x06, 0x06, 0x08, 0x08, 0x0a, 0x0a, 0x0c, 0x0c, 0x0e, 0x0e, /* 0x0f */ 0x10, 0x10, 0x12, 0x12, 0x14, 0x14, 0x16, 0x16, @@ -76,7 +78,7 @@ static u8 vnt_vt3184_al2230[] = { }; /* {{RobertYu:20060515, new BB setting for VT3226D0 */ -static u8 vnt_vt3184_vt3226d0[] = { +static const u8 vnt_vt3184_vt3226d0[] = { 0x31, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x70, 0x45, 0x2a, 0x76, 0x00, 0x00, 0x80, 0x00, /* 0x0f */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -111,198 +113,85 @@ static u8 vnt_vt3184_vt3226d0[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* 0xff */ }; -static const u16 vnt_frame_time[MAX_RATE] = { - 10, 20, 55, 110, 24, 36, 48, 72, 96, 144, 192, 216 +struct vnt_threshold { + u8 bb_pre_ed_rssi; + u8 cr_201; + u8 cr_206; }; -/* - * Description: Calculate data frame transmitting time - * - * Parameters: - * In: - * preamble_type - Preamble Type - * pkt_type - PK_TYPE_11A, PK_TYPE_11B, PK_TYPE_11GB, PK_TYPE_11GA - * frame_length - Baseband Type - * tx_rate - Tx Rate - * Out: - * - * Return Value: FrameTime - * - */ -unsigned int vnt_get_frame_time(u8 preamble_type, u8 pkt_type, - unsigned int frame_length, u16 tx_rate) -{ - unsigned int frame_time; - unsigned int preamble; - unsigned int rate = 0; - - if (tx_rate > RATE_54M) - return 0; - - rate = (unsigned int)vnt_frame_time[tx_rate]; - - if (tx_rate <= 3) { - if (preamble_type == 1) - preamble = 96; - else - preamble = 192; - - frame_time = DIV_ROUND_UP(frame_length * 80, rate); - return preamble + frame_time; - } - - frame_time = DIV_ROUND_UP(frame_length * 8 + 22, rate); - frame_time = frame_time * 4; - - if (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 == 1) - phy->signal = 0x09; - else - phy->signal = 0x01; - - break; - case RATE_5M: - count = DIV_ROUND_UP(bit_count * 10, 55); - - if (preamble_type == 1) - 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 == 1) - 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; +static const struct vnt_threshold al2230_vnt_threshold[] = { + {0, 0x00, 0x30}, /* Max sensitivity */ + {68, 0x00, 0x36}, + {67, 0x00, 0x43}, + {66, 0x00, 0x51}, + {65, 0x00, 0x62}, + {64, 0x00, 0x79}, + {63, 0x00, 0x93}, + {62, 0x00, 0xb9}, + {61, 0x00, 0xe3}, + {60, 0x01, 0x18}, + {59, 0x01, 0x54}, + {58, 0x01, 0xa0}, + {57, 0x02, 0x20}, + {56, 0x02, 0xa0}, + {55, 0x03, 0x00}, + {53, 0x06, 0x00}, + {51, 0x09, 0x00}, + {49, 0x0e, 0x00}, + {47, 0x15, 0x00}, + {46, 0x1a, 0x00}, + {45, 0xff, 0x00} +}; - 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; - } +static const struct vnt_threshold vt3226_vnt_threshold[] = { + {0, 0x00, 0x24}, /* Max sensitivity */ + {68, 0x00, 0x2d}, + {67, 0x00, 0x36}, + {66, 0x00, 0x43}, + {65, 0x00, 0x52}, + {64, 0x00, 0x68}, + {63, 0x00, 0x80}, + {62, 0x00, 0x9c}, + {61, 0x00, 0xc0}, + {60, 0x00, 0xea}, + {59, 0x01, 0x30}, + {58, 0x01, 0x70}, + {57, 0x01, 0xb0}, + {56, 0x02, 0x30}, + {55, 0x02, 0xc0}, + {53, 0x04, 0x00}, + {51, 0x07, 0x00}, + {49, 0x0a, 0x00}, + {47, 0x11, 0x00}, + {45, 0x18, 0x00}, + {43, 0x26, 0x00}, + {42, 0x36, 0x00}, + {41, 0xff, 0x00} +}; - 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); - } -} +static const struct vnt_threshold vt3342_vnt_threshold[] = { + {0, 0x00, 0x38}, /* Max sensitivity */ + {66, 0x00, 0x43}, + {65, 0x00, 0x52}, + {64, 0x00, 0x68}, + {63, 0x00, 0x80}, + {62, 0x00, 0x9c}, + {61, 0x00, 0xc0}, + {60, 0x00, 0xea}, + {59, 0x01, 0x30}, + {58, 0x01, 0x70}, + {57, 0x01, 0xb0}, + {56, 0x02, 0x30}, + {55, 0x02, 0xc0}, + {53, 0x04, 0x00}, + {51, 0x07, 0x00}, + {49, 0x0a, 0x00}, + {47, 0x11, 0x00}, + {45, 0x18, 0x00}, + {43, 0x26, 0x00}, + {42, 0x36, 0x00}, + {41, 0xff, 0x00} +}; /* * Description: Set Antenna mode @@ -352,9 +241,10 @@ int vnt_set_antenna_mode(struct vnt_private *priv, u8 antenna_mode) int vnt_vt3184_init(struct vnt_private *priv) { - int ret = 0; + int ret; u16 length; - u8 *addr; + u8 *addr = NULL; + const u8 *c_addr; u8 data; ret = vnt_control_in(priv, MESSAGE_TYPE_READ, 0, MESSAGE_REQUEST_EEPROM, @@ -366,23 +256,15 @@ int vnt_vt3184_init(struct vnt_private *priv) dev_dbg(&priv->usb->dev, "RF Type %d\n", priv->rf_type); - if (priv->rf_type == RF_AL2230 || - priv->rf_type == RF_AL2230S) { + if ((priv->rf_type == RF_AL2230) || + (priv->rf_type == RF_AL2230S) || + (priv->rf_type == RF_AIROHA7230)) { priv->bb_rx_conf = vnt_vt3184_al2230[10]; length = sizeof(vnt_vt3184_al2230); addr = vnt_vt3184_al2230; - priv->bb_vga[0] = 0x1C; - priv->bb_vga[1] = 0x10; - priv->bb_vga[2] = 0x0; - priv->bb_vga[3] = 0x0; - - } else if (priv->rf_type == RF_AIROHA7230) { - priv->bb_rx_conf = vnt_vt3184_al2230[10]; - length = sizeof(vnt_vt3184_al2230); - addr = vnt_vt3184_al2230; - - addr[0xd7] = 0x06; + if (priv->rf_type == RF_AIROHA7230) + addr[0xd7] = 0x06; priv->bb_vga[0] = 0x1c; priv->bb_vga[1] = 0x10; @@ -390,25 +272,11 @@ int vnt_vt3184_init(struct vnt_private *priv) priv->bb_vga[3] = 0x0; } else if ((priv->rf_type == RF_VT3226) || - (priv->rf_type == RF_VT3226D0)) { + (priv->rf_type == RF_VT3226D0) || + (priv->rf_type == RF_VT3342A0)) { priv->bb_rx_conf = vnt_vt3184_vt3226d0[10]; length = sizeof(vnt_vt3184_vt3226d0); - addr = vnt_vt3184_vt3226d0; - - priv->bb_vga[0] = 0x20; - priv->bb_vga[1] = 0x10; - priv->bb_vga[2] = 0x0; - priv->bb_vga[3] = 0x0; - - /* Fix VT3226 DFC system timing issue */ - ret = vnt_mac_reg_bits_on(priv, MAC_REG_SOFTPWRCTL2, - SOFTPWRCTL_RFLEOPT); - if (ret) - goto end; - } else if (priv->rf_type == RF_VT3342A0) { - priv->bb_rx_conf = vnt_vt3184_vt3226d0[10]; - length = sizeof(vnt_vt3184_vt3226d0); - addr = vnt_vt3184_vt3226d0; + c_addr = vnt_vt3184_vt3226d0; priv->bb_vga[0] = 0x20; priv->bb_vga[1] = 0x10; @@ -424,8 +292,11 @@ int vnt_vt3184_init(struct vnt_private *priv) goto end; } + if (addr) + c_addr = addr; + ret = vnt_control_out_blocks(priv, VNT_REG_BLOCK_SIZE, - MESSAGE_REQUEST_BBREG, length, addr); + MESSAGE_REQUEST_BBREG, length, c_addr); if (ret) goto end; @@ -435,19 +306,13 @@ int vnt_vt3184_init(struct vnt_private *priv) if (ret) goto end; - if (priv->rf_type == RF_VT3226 || - priv->rf_type == RF_VT3342A0) { - ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_MACREG, - MAC_REG_ITRTMSET, 0x23); - if (ret) - goto end; + if ((priv->rf_type == RF_VT3226) || + (priv->rf_type == RF_VT3342A0) || + (priv->rf_type == RF_VT3226D0)) { + data = (priv->rf_type == RF_VT3226D0) ? 0x11 : 0x23; - ret = vnt_mac_reg_bits_on(priv, MAC_REG_PAPEDELAY, BIT(0)); - if (ret) - goto end; - } else if (priv->rf_type == RF_VT3226D0) { ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_MACREG, - MAC_REG_ITRTMSET, 0x11); + MAC_REG_ITRTMSET, data); if (ret) goto end; @@ -507,21 +372,22 @@ int vnt_set_short_slot_time(struct vnt_private *priv) ret = vnt_control_in_u8(priv, MESSAGE_REQUEST_BBREG, 0xe7, &bb_vga); if (ret) - goto end; + return ret; if (bb_vga == priv->bb_vga[0]) priv->bb_rx_conf |= 0x20; - ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0a, - priv->bb_rx_conf); - -end: - return ret; + return vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0a, + priv->bb_rx_conf); } -void vnt_set_vga_gain_offset(struct vnt_private *priv, u8 data) +int vnt_set_vga_gain_offset(struct vnt_private *priv, u8 data) { - vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0xE7, data); + int ret; + + ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0xE7, data); + if (ret) + return ret; /* patch for 3253B0 Baseband with Cardbus module */ if (priv->short_slot_time) @@ -529,7 +395,8 @@ void vnt_set_vga_gain_offset(struct vnt_private *priv, u8 data) else priv->bb_rx_conf |= 0x20; /* 0010 0000 */ - vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0a, priv->bb_rx_conf); + return vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0a, + priv->bb_rx_conf); } /* @@ -570,268 +437,57 @@ int vnt_exit_deep_sleep(struct vnt_private *priv) return vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0d, 0x01); } -void vnt_update_pre_ed_threshold(struct vnt_private *priv, int scanning) +int vnt_update_pre_ed_threshold(struct vnt_private *priv, int scanning) { - u8 cr_201 = 0x0, cr_206 = 0x0; - u8 ed_inx = priv->bb_pre_ed_index; + const struct vnt_threshold *threshold = NULL; + u8 length; + u8 cr_201, cr_206; + u8 ed_inx; + int ret; switch (priv->rf_type) { case RF_AL2230: case RF_AL2230S: case RF_AIROHA7230: - if (scanning) { /* Max sensitivity */ - ed_inx = 0; - cr_206 = 0x30; - break; - } - - if (priv->bb_pre_ed_rssi <= 45) { - ed_inx = 20; - cr_201 = 0xff; - } else if (priv->bb_pre_ed_rssi <= 46) { - ed_inx = 19; - cr_201 = 0x1a; - } else if (priv->bb_pre_ed_rssi <= 47) { - ed_inx = 18; - cr_201 = 0x15; - } else if (priv->bb_pre_ed_rssi <= 49) { - ed_inx = 17; - cr_201 = 0xe; - } else if (priv->bb_pre_ed_rssi <= 51) { - ed_inx = 16; - cr_201 = 0x9; - } else if (priv->bb_pre_ed_rssi <= 53) { - ed_inx = 15; - cr_201 = 0x6; - } else if (priv->bb_pre_ed_rssi <= 55) { - ed_inx = 14; - cr_201 = 0x3; - } else if (priv->bb_pre_ed_rssi <= 56) { - ed_inx = 13; - cr_201 = 0x2; - cr_206 = 0xa0; - } else if (priv->bb_pre_ed_rssi <= 57) { - ed_inx = 12; - cr_201 = 0x2; - cr_206 = 0x20; - } else if (priv->bb_pre_ed_rssi <= 58) { - ed_inx = 11; - cr_201 = 0x1; - cr_206 = 0xa0; - } else if (priv->bb_pre_ed_rssi <= 59) { - ed_inx = 10; - cr_201 = 0x1; - cr_206 = 0x54; - } else if (priv->bb_pre_ed_rssi <= 60) { - ed_inx = 9; - cr_201 = 0x1; - cr_206 = 0x18; - } else if (priv->bb_pre_ed_rssi <= 61) { - ed_inx = 8; - cr_206 = 0xe3; - } else if (priv->bb_pre_ed_rssi <= 62) { - ed_inx = 7; - cr_206 = 0xb9; - } else if (priv->bb_pre_ed_rssi <= 63) { - ed_inx = 6; - cr_206 = 0x93; - } else if (priv->bb_pre_ed_rssi <= 64) { - ed_inx = 5; - cr_206 = 0x79; - } else if (priv->bb_pre_ed_rssi <= 65) { - ed_inx = 4; - cr_206 = 0x62; - } else if (priv->bb_pre_ed_rssi <= 66) { - ed_inx = 3; - cr_206 = 0x51; - } else if (priv->bb_pre_ed_rssi <= 67) { - ed_inx = 2; - cr_206 = 0x43; - } else if (priv->bb_pre_ed_rssi <= 68) { - ed_inx = 1; - cr_206 = 0x36; - } else { - ed_inx = 0; - cr_206 = 0x30; - } + threshold = al2230_vnt_threshold; + length = ARRAY_SIZE(al2230_vnt_threshold); break; case RF_VT3226: case RF_VT3226D0: - if (scanning) { /* Max sensitivity */ - ed_inx = 0; - cr_206 = 0x24; - break; - } - - if (priv->bb_pre_ed_rssi <= 41) { - ed_inx = 22; - cr_201 = 0xff; - } else if (priv->bb_pre_ed_rssi <= 42) { - ed_inx = 21; - cr_201 = 0x36; - } else if (priv->bb_pre_ed_rssi <= 43) { - ed_inx = 20; - cr_201 = 0x26; - } else if (priv->bb_pre_ed_rssi <= 45) { - ed_inx = 19; - cr_201 = 0x18; - } else if (priv->bb_pre_ed_rssi <= 47) { - ed_inx = 18; - cr_201 = 0x11; - } else if (priv->bb_pre_ed_rssi <= 49) { - ed_inx = 17; - cr_201 = 0xa; - } else if (priv->bb_pre_ed_rssi <= 51) { - ed_inx = 16; - cr_201 = 0x7; - } else if (priv->bb_pre_ed_rssi <= 53) { - ed_inx = 15; - cr_201 = 0x4; - } else if (priv->bb_pre_ed_rssi <= 55) { - ed_inx = 14; - cr_201 = 0x2; - cr_206 = 0xc0; - } else if (priv->bb_pre_ed_rssi <= 56) { - ed_inx = 13; - cr_201 = 0x2; - cr_206 = 0x30; - } else if (priv->bb_pre_ed_rssi <= 57) { - ed_inx = 12; - cr_201 = 0x1; - cr_206 = 0xb0; - } else if (priv->bb_pre_ed_rssi <= 58) { - ed_inx = 11; - cr_201 = 0x1; - cr_206 = 0x70; - } else if (priv->bb_pre_ed_rssi <= 59) { - ed_inx = 10; - cr_201 = 0x1; - cr_206 = 0x30; - } else if (priv->bb_pre_ed_rssi <= 60) { - ed_inx = 9; - cr_206 = 0xea; - } else if (priv->bb_pre_ed_rssi <= 61) { - ed_inx = 8; - cr_206 = 0xc0; - } else if (priv->bb_pre_ed_rssi <= 62) { - ed_inx = 7; - cr_206 = 0x9c; - } else if (priv->bb_pre_ed_rssi <= 63) { - ed_inx = 6; - cr_206 = 0x80; - } else if (priv->bb_pre_ed_rssi <= 64) { - ed_inx = 5; - cr_206 = 0x68; - } else if (priv->bb_pre_ed_rssi <= 65) { - ed_inx = 4; - cr_206 = 0x52; - } else if (priv->bb_pre_ed_rssi <= 66) { - ed_inx = 3; - cr_206 = 0x43; - } else if (priv->bb_pre_ed_rssi <= 67) { - ed_inx = 2; - cr_206 = 0x36; - } else if (priv->bb_pre_ed_rssi <= 68) { - ed_inx = 1; - cr_206 = 0x2d; - } else { - ed_inx = 0; - cr_206 = 0x24; - } + threshold = vt3226_vnt_threshold; + length = ARRAY_SIZE(vt3226_vnt_threshold); break; case RF_VT3342A0: - if (scanning) { /* need Max sensitivity */ - ed_inx = 0; - cr_206 = 0x38; - break; - } - - if (priv->bb_pre_ed_rssi <= 41) { - ed_inx = 20; - cr_201 = 0xff; - } else if (priv->bb_pre_ed_rssi <= 42) { - ed_inx = 19; - cr_201 = 0x36; - } else if (priv->bb_pre_ed_rssi <= 43) { - ed_inx = 18; - cr_201 = 0x26; - } else if (priv->bb_pre_ed_rssi <= 45) { - ed_inx = 17; - cr_201 = 0x18; - } else if (priv->bb_pre_ed_rssi <= 47) { - ed_inx = 16; - cr_201 = 0x11; - } else if (priv->bb_pre_ed_rssi <= 49) { - ed_inx = 15; - cr_201 = 0xa; - } else if (priv->bb_pre_ed_rssi <= 51) { - ed_inx = 14; - cr_201 = 0x7; - } else if (priv->bb_pre_ed_rssi <= 53) { - ed_inx = 13; - cr_201 = 0x4; - } else if (priv->bb_pre_ed_rssi <= 55) { - ed_inx = 12; - cr_201 = 0x2; - cr_206 = 0xc0; - } else if (priv->bb_pre_ed_rssi <= 56) { - ed_inx = 11; - cr_201 = 0x2; - cr_206 = 0x30; - } else if (priv->bb_pre_ed_rssi <= 57) { - ed_inx = 10; - cr_201 = 0x1; - cr_206 = 0xb0; - } else if (priv->bb_pre_ed_rssi <= 58) { - ed_inx = 9; - cr_201 = 0x1; - cr_206 = 0x70; - } else if (priv->bb_pre_ed_rssi <= 59) { - ed_inx = 8; - cr_201 = 0x1; - cr_206 = 0x30; - } else if (priv->bb_pre_ed_rssi <= 60) { - ed_inx = 7; - cr_206 = 0xea; - } else if (priv->bb_pre_ed_rssi <= 61) { - ed_inx = 6; - cr_206 = 0xc0; - } else if (priv->bb_pre_ed_rssi <= 62) { - ed_inx = 5; - cr_206 = 0x9c; - } else if (priv->bb_pre_ed_rssi <= 63) { - ed_inx = 4; - cr_206 = 0x80; - } else if (priv->bb_pre_ed_rssi <= 64) { - ed_inx = 3; - cr_206 = 0x68; - } else if (priv->bb_pre_ed_rssi <= 65) { - ed_inx = 2; - cr_206 = 0x52; - } else if (priv->bb_pre_ed_rssi <= 66) { - ed_inx = 1; - cr_206 = 0x43; - } else { - ed_inx = 0; - cr_206 = 0x38; - } + threshold = vt3342_vnt_threshold; + length = ARRAY_SIZE(vt3342_vnt_threshold); break; } + if (!threshold) + return -EINVAL; + + for (ed_inx = scanning ? 0 : length - 1; ed_inx > 0; ed_inx--) { + if (priv->bb_pre_ed_rssi <= threshold[ed_inx].bb_pre_ed_rssi) + break; + } + + cr_201 = threshold[ed_inx].cr_201; + cr_206 = threshold[ed_inx].cr_206; + if (ed_inx == priv->bb_pre_ed_index && !scanning) - return; + return 0; priv->bb_pre_ed_index = ed_inx; dev_dbg(&priv->usb->dev, "%s bb_pre_ed_rssi %d\n", __func__, priv->bb_pre_ed_rssi); - if (!cr_201 && !cr_206) - return; + ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0xc9, cr_201); + if (ret) + return ret; - vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0xc9, cr_201); - vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0xce, cr_206); + return vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0xce, cr_206); } diff --git a/drivers/staging/vt6656/baseband.h b/drivers/staging/vt6656/baseband.h index dc42aa6ae1d9..12456ebc23ec 100644 --- a/drivers/staging/vt6656/baseband.h +++ b/drivers/staging/vt6656/baseband.h @@ -66,25 +66,12 @@ #define TOP_RATE_2M 0x00200000 #define TOP_RATE_1M 0x00100000 -/* Length, Service, and Signal fields of Phy for Tx */ -struct vnt_phy_field { - u8 signal; - u8 service; - __le16 len; -} __packed; - -unsigned int vnt_get_frame_time(u8 preamble_type, u8 pkt_type, - unsigned int frame_length, u16 tx_rate); - -void vnt_get_phy_field(struct vnt_private *priv, u32 frame_length, - u16 tx_rate, u8 pkt_type, struct vnt_phy_field *phy); - int vnt_set_short_slot_time(struct vnt_private *priv); -void vnt_set_vga_gain_offset(struct vnt_private *priv, u8 data); +int vnt_set_vga_gain_offset(struct vnt_private *priv, u8 data); int vnt_set_antenna_mode(struct vnt_private *priv, u8 antenna_mode); int vnt_vt3184_init(struct vnt_private *priv); int vnt_set_deep_sleep(struct vnt_private *priv); int vnt_exit_deep_sleep(struct vnt_private *priv); -void vnt_update_pre_ed_threshold(struct vnt_private *priv, int scanning); +int vnt_update_pre_ed_threshold(struct vnt_private *priv, int scanning); #endif /* __BASEBAND_H__ */ diff --git a/drivers/staging/vt6656/card.c b/drivers/staging/vt6656/card.c index dc3ab10eb630..10f3dfda83b5 100644 --- a/drivers/staging/vt6656/card.c +++ b/drivers/staging/vt6656/card.c @@ -26,7 +26,8 @@ * */ -#include <linux/bits.h> +#include <linux/bitops.h> +#include <linux/errno.h> #include "device.h" #include "card.h" #include "baseband.h" @@ -45,20 +46,12 @@ static const u16 cw_rxbcntsf_off[MAX_RATE] = { 192, 96, 34, 17, 34, 23, 17, 11, 8, 5, 4, 3 }; -/* - * Description: Set NIC media channel - * - * Parameters: - * In: - * pDevice - The adapter to be set - * connection_channel - Channel to be set - * Out: - * none - */ -void vnt_set_channel(struct vnt_private *priv, u32 connection_channel) +int vnt_set_channel(struct vnt_private *priv, u32 connection_channel) { + int ret; + if (connection_channel > CB_MAX_CHANNEL || !connection_channel) - return; + return -EINVAL; /* clear NAV */ vnt_mac_reg_bits_on(priv, MAC_REG_MACCR, MACCR_CLRNAV); @@ -67,284 +60,73 @@ void vnt_set_channel(struct vnt_private *priv, u32 connection_channel) vnt_mac_reg_bits_off(priv, MAC_REG_CHANNEL, (BIT(7) | BIT(5) | BIT(4))); - vnt_control_out(priv, MESSAGE_TYPE_SELECT_CHANNEL, - connection_channel, 0, 0, NULL); - - vnt_control_out_u8(priv, MESSAGE_REQUEST_MACREG, MAC_REG_CHANNEL, - (u8)(connection_channel | 0x80)); -} - -/* - * Description: Get CCK mode basic rate - * - * Parameters: - * In: - * priv - The adapter to be set - * rate_idx - Receiving data rate - * Out: - * none - * - * Return Value: response Control frame rate - * - */ -static u16 vnt_get_cck_rate(struct vnt_private *priv, u16 rate_idx) -{ - u16 ui = rate_idx; - - while (ui > RATE_1M) { - if (priv->basic_rates & (1 << ui)) - return ui; - ui--; - } + ret = vnt_control_out(priv, MESSAGE_TYPE_SELECT_CHANNEL, + connection_channel, 0, 0, NULL); + if (ret) + return ret; - return RATE_1M; + return vnt_control_out_u8(priv, MESSAGE_REQUEST_MACREG, MAC_REG_CHANNEL, + (u8)(connection_channel | 0x80)); } -/* - * Description: Get OFDM mode basic rate - * - * Parameters: - * In: - * priv - The adapter to be set - * rate_idx - Receiving data rate - * Out: - * none - * - * Return Value: response Control frame rate - * - */ -static u16 vnt_get_ofdm_rate(struct vnt_private *priv, u16 rate_idx) -{ - u16 ui = rate_idx; - - dev_dbg(&priv->usb->dev, "%s basic rate: %d\n", - __func__, priv->basic_rates); - - if (!vnt_ofdm_min_rate(priv)) { - dev_dbg(&priv->usb->dev, "%s (NO OFDM) %d\n", - __func__, rate_idx); - if (rate_idx > RATE_24M) - rate_idx = RATE_24M; - return rate_idx; - } - - while (ui > RATE_11M) { - if (priv->basic_rates & (1 << ui)) { - dev_dbg(&priv->usb->dev, "%s rate: %d\n", - __func__, ui); - return ui; - } - ui--; - } - - dev_dbg(&priv->usb->dev, "%s basic rate: 24M\n", __func__); +static const u8 vnt_rspinf_b_short_table[] = { + 0x70, 0x00, 0x00, 0x00, 0x38, 0x00, 0x09, 0x00, + 0x15, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x0b, 0x80 +}; - return RATE_24M; -} +static const u8 vnt_rspinf_b_long_table[] = { + 0x70, 0x00, 0x00, 0x00, 0x38, 0x00, 0x01, 0x00, + 0x15, 0x00, 0x02, 0x00, 0x0b, 0x00, 0x03, 0x80 +}; -/* - * Description: Calculate TxRate and RsvTime fields for RSPINF in OFDM mode. - * - * Parameters: - * In: - * rate - Tx Rate - * bb_type - Tx Packet type - * Out: - * tx_rate - pointer to RSPINF TxRate field - * rsv_time- pointer to RSPINF RsvTime field - * - * Return Value: none - * - */ -static void vnt_calculate_ofdm_rate(u16 rate, u8 bb_type, - u8 *tx_rate, u8 *rsv_time) -{ - switch (rate) { - case RATE_6M: - if (bb_type == BB_TYPE_11A) { - *tx_rate = 0x9b; - *rsv_time = 24; - } else { - *tx_rate = 0x8b; - *rsv_time = 30; - } - break; - case RATE_9M: - if (bb_type == BB_TYPE_11A) { - *tx_rate = 0x9f; - *rsv_time = 16; - } else { - *tx_rate = 0x8f; - *rsv_time = 22; - } - break; - case RATE_12M: - if (bb_type == BB_TYPE_11A) { - *tx_rate = 0x9a; - *rsv_time = 12; - } else { - *tx_rate = 0x8a; - *rsv_time = 18; - } - break; - case RATE_18M: - if (bb_type == BB_TYPE_11A) { - *tx_rate = 0x9e; - *rsv_time = 8; - } else { - *tx_rate = 0x8e; - *rsv_time = 14; - } - break; - case RATE_36M: - if (bb_type == BB_TYPE_11A) { - *tx_rate = 0x9d; - *rsv_time = 4; - } else { - *tx_rate = 0x8d; - *rsv_time = 10; - } - break; - case RATE_48M: - if (bb_type == BB_TYPE_11A) { - *tx_rate = 0x98; - *rsv_time = 4; - } else { - *tx_rate = 0x88; - *rsv_time = 10; - } - break; - case RATE_54M: - if (bb_type == BB_TYPE_11A) { - *tx_rate = 0x9c; - *rsv_time = 4; - } else { - *tx_rate = 0x8c; - *rsv_time = 10; - } - break; - case RATE_24M: - default: - if (bb_type == BB_TYPE_11A) { - *tx_rate = 0x99; - *rsv_time = 8; - } else { - *tx_rate = 0x89; - *rsv_time = 14; - } - break; - } -} +static const u8 vnt_rspinf_a_table[] = { + 0x9b, 0x18, 0x9f, 0x10, 0x9a, 0x0a, 0x9e, 0x08, 0x99, + 0x08, 0x9d, 0x04, 0x98, 0x04, 0x9c, 0x04, 0x9c, 0x04 +}; -/* - * Description: Set RSPINF - * - * Parameters: - * In: - * pDevice - The adapter to be set - * Out: - * none - * - * Return Value: None. - * - */ +static const u8 vnt_rspinf_gb_table[] = { + 0x8b, 0x1e, 0x8f, 0x16, 0x8a, 0x12, 0x8e, 0x0e, 0x89, + 0x0e, 0x8d, 0x0a, 0x88, 0x0a, 0x8c, 0x0a, 0x8c, 0x0a +}; -void vnt_set_rspinf(struct vnt_private *priv, u8 bb_type) +int vnt_set_rspinf(struct vnt_private *priv, u8 bb_type) { - struct vnt_phy_field phy[4]; - u8 tx_rate[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; /* For OFDM */ - u8 rsv_time[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; - u8 data[34]; - int i; - - /*RSPINF_b_1*/ - vnt_get_phy_field(priv, 14, vnt_get_cck_rate(priv, RATE_1M), - PK_TYPE_11B, &phy[0]); - - /*RSPINF_b_2*/ - vnt_get_phy_field(priv, 14, vnt_get_cck_rate(priv, RATE_2M), - PK_TYPE_11B, &phy[1]); - - /*RSPINF_b_5*/ - vnt_get_phy_field(priv, 14, vnt_get_cck_rate(priv, RATE_5M), - PK_TYPE_11B, &phy[2]); - - /*RSPINF_b_11*/ - vnt_get_phy_field(priv, 14, vnt_get_cck_rate(priv, RATE_11M), - PK_TYPE_11B, &phy[3]); - - /*RSPINF_a_6*/ - vnt_calculate_ofdm_rate(RATE_6M, bb_type, &tx_rate[0], &rsv_time[0]); - - /*RSPINF_a_9*/ - vnt_calculate_ofdm_rate(RATE_9M, bb_type, &tx_rate[1], &rsv_time[1]); + const u8 *data; + u16 len; + int ret; - /*RSPINF_a_12*/ - vnt_calculate_ofdm_rate(RATE_12M, bb_type, &tx_rate[2], &rsv_time[2]); - - /*RSPINF_a_18*/ - vnt_calculate_ofdm_rate(RATE_18M, bb_type, &tx_rate[3], &rsv_time[3]); - - /*RSPINF_a_24*/ - vnt_calculate_ofdm_rate(RATE_24M, bb_type, &tx_rate[4], &rsv_time[4]); - - /*RSPINF_a_36*/ - vnt_calculate_ofdm_rate(vnt_get_ofdm_rate(priv, RATE_36M), - bb_type, &tx_rate[5], &rsv_time[5]); - - /*RSPINF_a_48*/ - vnt_calculate_ofdm_rate(vnt_get_ofdm_rate(priv, RATE_48M), - bb_type, &tx_rate[6], &rsv_time[6]); - - /*RSPINF_a_54*/ - vnt_calculate_ofdm_rate(vnt_get_ofdm_rate(priv, RATE_54M), - bb_type, &tx_rate[7], &rsv_time[7]); - - /*RSPINF_a_72*/ - vnt_calculate_ofdm_rate(vnt_get_ofdm_rate(priv, RATE_54M), - bb_type, &tx_rate[8], &rsv_time[8]); - - put_unaligned(phy[0].len, (u16 *)&data[0]); - data[2] = phy[0].signal; - data[3] = phy[0].service; - - put_unaligned(phy[1].len, (u16 *)&data[4]); - data[6] = phy[1].signal; - data[7] = phy[1].service; - - put_unaligned(phy[2].len, (u16 *)&data[8]); - data[10] = phy[2].signal; - data[11] = phy[2].service; + if (priv->preamble_type) { + data = vnt_rspinf_b_short_table; + len = ARRAY_SIZE(vnt_rspinf_b_short_table); + } else { + data = vnt_rspinf_b_long_table; + len = ARRAY_SIZE(vnt_rspinf_b_long_table); + } - put_unaligned(phy[3].len, (u16 *)&data[12]); - data[14] = phy[3].signal; - data[15] = phy[3].service; + /* RSPINF_b_1 to RSPINF_b_11 */ + ret = vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_RSPINF_B_1, + MESSAGE_REQUEST_MACREG, len, data); + if (ret) + return ret; - for (i = 0; i < 9; i++) { - data[16 + i * 2] = tx_rate[i]; - data[16 + i * 2 + 1] = rsv_time[i]; + if (bb_type == BB_TYPE_11A) { + data = vnt_rspinf_a_table; + len = ARRAY_SIZE(vnt_rspinf_a_table); + } else { + data = vnt_rspinf_gb_table; + len = ARRAY_SIZE(vnt_rspinf_gb_table); } - vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_RSPINF_B_1, - MESSAGE_REQUEST_MACREG, 34, &data[0]); + /* RSPINF_a_6 to RSPINF_a_72 */ + return vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_RSPINF_A_6, + MESSAGE_REQUEST_MACREG, len, data); } -/* - * Description: Update IFS - * - * Parameters: - * In: - * priv - The adapter to be set - * Out: - * none - * - * Return Value: None. - * - */ -void vnt_update_ifs(struct vnt_private *priv) +int vnt_update_ifs(struct vnt_private *priv) { u8 max_min = 0; u8 data[4]; + int ret; if (priv->packet_type == PK_TYPE_11A) { priv->slot = C_SLOT_SHORT; @@ -367,89 +149,36 @@ void vnt_update_ifs(struct vnt_private *priv) priv->eifs = C_EIFS; - switch (priv->rf_type) { - case RF_VT3226D0: - if (priv->bb_type != BB_TYPE_11B) { - priv->sifs -= 1; - priv->difs -= 1; - break; - } - /* fall through */ - case RF_AIROHA7230: - case RF_AL2230: - case RF_AL2230S: - if (priv->bb_type != BB_TYPE_11B) - break; - /* fall through */ - case RF_RFMD2959: - case RF_VT3226: - case RF_VT3342A0: - priv->sifs -= 3; - priv->difs -= 3; - break; - case RF_MAXIM2829: - if (priv->bb_type == BB_TYPE_11A) { - priv->sifs -= 5; - priv->difs -= 5; - } else { - priv->sifs -= 2; - priv->difs -= 2; - } - - break; - } - data[0] = (u8)priv->sifs; data[1] = (u8)priv->difs; data[2] = (u8)priv->eifs; data[3] = (u8)priv->slot; - vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_SIFS, - MESSAGE_REQUEST_MACREG, 4, &data[0]); + ret = vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_SIFS, + MESSAGE_REQUEST_MACREG, 4, &data[0]); + if (ret) + return ret; max_min |= 0xa0; - vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_CWMAXMIN0, - MESSAGE_REQUEST_MACREG, 1, &max_min); + return vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_CWMAXMIN0, + MESSAGE_REQUEST_MACREG, 1, &max_min); } void vnt_update_top_rates(struct vnt_private *priv) { - u8 top_ofdm = RATE_24M, top_cck = RATE_1M; - u8 i; - - /*Determines the highest basic rate.*/ - for (i = RATE_54M; i >= RATE_6M; i--) { - if (priv->basic_rates & (u16)(1 << i)) { - top_ofdm = i; - break; - } - } - - priv->top_ofdm_basic_rate = top_ofdm; + int pos; - for (i = RATE_11M;; i--) { - if (priv->basic_rates & (u16)(1 << i)) { - top_cck = i; - break; - } - if (i == RATE_1M) - break; - } + pos = fls(priv->basic_rates & GENMASK(RATE_54M, RATE_6M)); + priv->top_ofdm_basic_rate = pos ? (pos - 1) : RATE_24M; - priv->top_cck_basic_rate = top_cck; + pos = fls(priv->basic_rates & GENMASK(RATE_11M, RATE_1M)); + priv->top_cck_basic_rate = pos ? (pos - 1) : RATE_1M; } -int vnt_ofdm_min_rate(struct vnt_private *priv) +bool vnt_ofdm_min_rate(struct vnt_private *priv) { - int ii; - - for (ii = RATE_54M; ii >= RATE_6M; ii--) { - if ((priv->basic_rates) & ((u16)BIT(ii))) - return true; - } - - return false; + return priv->basic_rates & GENMASK(RATE_54M, RATE_6M) ? true : false; } u8 vnt_get_pkt_type(struct vnt_private *priv) @@ -481,23 +210,8 @@ u64 vnt_get_tsf_offset(u8 rx_rate, u64 tsf1, u64 tsf2) return tsf1 - tsf2 - (u64)cw_rxbcntsf_off[rx_rate % MAX_RATE]; } -/* - * Description: Sync. TSF counter to BSS - * Get TSF offset and write to HW - * - * Parameters: - * In: - * priv - The adapter to be sync. - * time_stamp - Rx BCN's TSF - * local_tsf - Local TSF - * Out: - * none - * - * Return Value: none - * - */ -void vnt_adjust_tsf(struct vnt_private *priv, u8 rx_rate, - u64 time_stamp, u64 local_tsf) +int vnt_adjust_tsf(struct vnt_private *priv, u8 rx_rate, + u64 time_stamp, u64 local_tsf) { u64 tsf_offset = 0; u8 data[8]; @@ -513,8 +227,8 @@ void vnt_adjust_tsf(struct vnt_private *priv, u8 rx_rate, data[6] = (u8)(tsf_offset >> 48); data[7] = (u8)(tsf_offset >> 56); - vnt_control_out(priv, MESSAGE_TYPE_SET_TSFTBTT, - MESSAGE_REQUEST_TSF, 0, 8, data); + return vnt_control_out(priv, MESSAGE_TYPE_SET_TSFTBTT, + MESSAGE_REQUEST_TSF, 0, 8, data); } /* @@ -589,21 +303,7 @@ u64 vnt_get_next_tbtt(u64 tsf, u16 beacon_interval) return tsf; } -/* - * Description: Set NIC TSF counter for first Beacon time - * Get NEXTTBTT from adjusted TSF and Beacon Interval - * - * Parameters: - * In: - * dwIoBase - IO Base - * beacon_interval - Beacon Interval - * Out: - * none - * - * Return Value: none - * - */ -void vnt_reset_next_tbtt(struct vnt_private *priv, u16 beacon_interval) +int vnt_reset_next_tbtt(struct vnt_private *priv, u16 beacon_interval) { u64 next_tbtt = 0; u8 data[8]; @@ -621,29 +321,15 @@ void vnt_reset_next_tbtt(struct vnt_private *priv, u16 beacon_interval) data[6] = (u8)(next_tbtt >> 48); data[7] = (u8)(next_tbtt >> 56); - vnt_control_out(priv, MESSAGE_TYPE_SET_TSFTBTT, - MESSAGE_REQUEST_TBTT, 0, 8, data); + return vnt_control_out(priv, MESSAGE_TYPE_SET_TSFTBTT, + MESSAGE_REQUEST_TBTT, 0, 8, data); } -/* - * Description: Sync NIC TSF counter for Beacon time - * Get NEXTTBTT and write to HW - * - * Parameters: - * In: - * priv - The adapter to be set - * tsf - Current TSF counter - * beacon_interval - Beacon Interval - * Out: - * none - * - * Return Value: none - * - */ -void vnt_update_next_tbtt(struct vnt_private *priv, u64 tsf, - u16 beacon_interval) +int vnt_update_next_tbtt(struct vnt_private *priv, u64 tsf, + u16 beacon_interval) { u8 data[8]; + int ret; tsf = vnt_get_next_tbtt(tsf, beacon_interval); @@ -656,10 +342,13 @@ void vnt_update_next_tbtt(struct vnt_private *priv, u64 tsf, data[6] = (u8)(tsf >> 48); data[7] = (u8)(tsf >> 56); - vnt_control_out(priv, MESSAGE_TYPE_SET_TSFTBTT, - MESSAGE_REQUEST_TBTT, 0, 8, data); + ret = vnt_control_out(priv, MESSAGE_TYPE_SET_TSFTBTT, + MESSAGE_REQUEST_TBTT, 0, 8, data); + if (ret) + return ret; dev_dbg(&priv->usb->dev, "%s TBTT: %8llx\n", __func__, tsf); + return 0; } /* @@ -723,9 +412,13 @@ int vnt_radio_power_on(struct vnt_private *priv) { int ret = 0; - vnt_exit_deep_sleep(priv); + ret = vnt_exit_deep_sleep(priv); + if (ret) + return ret; - vnt_mac_reg_bits_on(priv, MAC_REG_HOSTCR, HOSTCR_RXON); + ret = vnt_mac_reg_bits_on(priv, MAC_REG_HOSTCR, HOSTCR_RXON); + if (ret) + return ret; switch (priv->rf_type) { case RF_AL2230: @@ -734,56 +427,69 @@ int vnt_radio_power_on(struct vnt_private *priv) case RF_VT3226: case RF_VT3226D0: case RF_VT3342A0: - vnt_mac_reg_bits_on(priv, MAC_REG_SOFTPWRCTL, - (SOFTPWRCTL_SWPE2 | SOFTPWRCTL_SWPE3)); - break; + ret = vnt_mac_reg_bits_on(priv, MAC_REG_SOFTPWRCTL, + (SOFTPWRCTL_SWPE2 | + SOFTPWRCTL_SWPE3)); + if (ret) + return ret; } - vnt_mac_reg_bits_off(priv, MAC_REG_GPIOCTL1, GPIO3_INTMD); - - return ret; + return vnt_mac_reg_bits_off(priv, MAC_REG_GPIOCTL1, GPIO3_INTMD); } -void vnt_set_bss_mode(struct vnt_private *priv) +int vnt_set_bss_mode(struct vnt_private *priv) { - if (priv->rf_type == RF_AIROHA7230 && priv->bb_type == BB_TYPE_11A) - vnt_mac_set_bb_type(priv, BB_TYPE_11G); - else - vnt_mac_set_bb_type(priv, priv->bb_type); + int ret; + unsigned char type = priv->bb_type; + unsigned char data = 0; + unsigned char bb_vga_0 = 0x1c; + unsigned char bb_vga_2_3 = 0x00; - priv->packet_type = vnt_get_pkt_type(priv); + if (priv->rf_type == RF_AIROHA7230 && priv->bb_type == BB_TYPE_11A) + type = BB_TYPE_11G; - if (priv->bb_type == BB_TYPE_11A) - vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x88, 0x03); - else if (priv->bb_type == BB_TYPE_11B) - vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x88, 0x02); - else if (priv->bb_type == BB_TYPE_11G) - vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x88, 0x08); + ret = vnt_mac_set_bb_type(priv, type); + if (ret) + return ret; - vnt_update_ifs(priv); - vnt_set_rspinf(priv, (u8)priv->bb_type); + priv->packet_type = vnt_get_pkt_type(priv); if (priv->bb_type == BB_TYPE_11A) { - if (priv->rf_type == RF_AIROHA7230) { - priv->bb_vga[0] = 0x20; + data = 0x03; + bb_vga_0 = 0x20; + bb_vga_2_3 = 0x10; + } else if (priv->bb_type == BB_TYPE_11B) { + data = 0x02; + } else if (priv->bb_type == BB_TYPE_11G) { + data = 0x08; + } - vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, - 0xe7, priv->bb_vga[0]); - } + if (data) { + ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, + 0x88, data); + if (ret) + return ret; + } - priv->bb_vga[2] = 0x10; - priv->bb_vga[3] = 0x10; - } else { - if (priv->rf_type == RF_AIROHA7230) { - priv->bb_vga[0] = 0x1c; + ret = vnt_update_ifs(priv); + if (ret) + return ret; - vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, - 0xe7, priv->bb_vga[0]); - } + ret = vnt_set_rspinf(priv, priv->bb_type); + if (ret) + return ret; - priv->bb_vga[2] = 0x0; - priv->bb_vga[3] = 0x0; + if (priv->rf_type == RF_AIROHA7230) { + priv->bb_vga[0] = bb_vga_0; + + ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, + 0xe7, priv->bb_vga[0]); + if (ret) + return ret; } - vnt_set_vga_gain_offset(priv, priv->bb_vga[0]); + priv->bb_vga[2] = bb_vga_2_3; + priv->bb_vga[3] = bb_vga_2_3; + + return vnt_set_vga_gain_offset(priv, priv->bb_vga[0]); } diff --git a/drivers/staging/vt6656/card.h b/drivers/staging/vt6656/card.h index 75cd340c0cce..a524fdc60ae3 100644 --- a/drivers/staging/vt6656/card.h +++ b/drivers/staging/vt6656/card.h @@ -25,23 +25,23 @@ struct vnt_private; -void vnt_set_channel(struct vnt_private *priv, u32 connection_channel); -void vnt_set_rspinf(struct vnt_private *priv, u8 bb_type); -void vnt_update_ifs(struct vnt_private *priv); +int vnt_set_channel(struct vnt_private *priv, u32 connection_channel); +int vnt_set_rspinf(struct vnt_private *priv, u8 bb_type); +int vnt_update_ifs(struct vnt_private *priv); void vnt_update_top_rates(struct vnt_private *priv); -int vnt_ofdm_min_rate(struct vnt_private *priv); -void vnt_adjust_tsf(struct vnt_private *priv, u8 rx_rate, - u64 time_stamp, u64 local_tsf); +bool vnt_ofdm_min_rate(struct vnt_private *priv); +int vnt_adjust_tsf(struct vnt_private *priv, u8 rx_rate, + u64 time_stamp, u64 local_tsf); bool vnt_get_current_tsf(struct vnt_private *priv, u64 *current_tsf); bool vnt_clear_current_tsf(struct vnt_private *priv); -void vnt_reset_next_tbtt(struct vnt_private *priv, u16 beacon_interval); -void vnt_update_next_tbtt(struct vnt_private *priv, u64 tsf, - u16 beacon_interval); +int vnt_reset_next_tbtt(struct vnt_private *priv, u16 beacon_interval); +int vnt_update_next_tbtt(struct vnt_private *priv, u64 tsf, + u16 beacon_interval); u64 vnt_get_next_tbtt(u64 tsf, u16 beacon_interval); u64 vnt_get_tsf_offset(u8 rx_rate, u64 tsf1, u64 tsf2); int vnt_radio_power_off(struct vnt_private *priv); int vnt_radio_power_on(struct vnt_private *priv); u8 vnt_get_pkt_type(struct vnt_private *priv); -void vnt_set_bss_mode(struct vnt_private *priv); +int vnt_set_bss_mode(struct vnt_private *priv); #endif /* __CARD_H__ */ diff --git a/drivers/staging/vt6656/device.h b/drivers/staging/vt6656/device.h index e6ee9411f080..947530fefe94 100644 --- a/drivers/staging/vt6656/device.h +++ b/drivers/staging/vt6656/device.h @@ -73,6 +73,10 @@ #define DEVICE_VERSION "mac80211" +#define FIRMWARE_VERSION 0x133 /* version 1.51 */ +#define FIRMWARE_NAME "vntwusb.fw" +#define FIRMWARE_CHUNK_SIZE 0x400 + #define CONFIG_PATH "/etc/vntconfiguration.dat" #define MAX_UINTS 8 @@ -202,8 +206,7 @@ struct vnt_rsp_card_init { * Enum of context types for SendPacket */ enum { - CONTEXT_DATA_PACKET = 1, - CONTEXT_MGMT_PACKET, + CONTEXT_DATA_PACKET = 0, CONTEXT_BEACON_PACKET }; @@ -234,18 +237,14 @@ struct vnt_rcb { struct vnt_usb_send_context { void *priv; struct sk_buff *skb; - struct urb *urb; - struct ieee80211_hdr *hdr; - unsigned int buf_len; + void *tx_buffer; u32 frame_len; u16 tx_hdr_size; u16 tx_rate; u8 type; u8 pkt_no; u8 pkt_type; - u8 need_ack; bool in_use; - unsigned char data[MAX_TOTAL_SIZE_WITH_ALL_HEADERS]; }; /* @@ -288,6 +287,7 @@ struct vnt_private { /* Variables to track resources for the BULK Out Pipe */ struct vnt_usb_send_context *tx_context[CB_MAX_TX_DESC]; + struct usb_anchor tx_submitted; u32 num_tx_context; /* Variables to track resources for the Interrupt In Pipe */ @@ -344,13 +344,9 @@ struct vnt_private { u8 ofdm_pwr_tbl[14]; u8 ofdm_a_pwr_tbl[42]; - u16 current_rate; u16 tx_rate_fb0; u16 tx_rate_fb1; - u8 short_retry_limit; - u8 long_retry_limit; - enum nl80211_iftype op_mode; int short_slot_time; @@ -383,8 +379,6 @@ struct vnt_private { u8 bb_pre_ed_rssi; u8 bb_pre_ed_index; - u16 wake_up_count; - /* command timer */ struct delayed_work run_command_work; diff --git a/drivers/staging/vt6656/firmware.c b/drivers/staging/vt6656/firmware.c deleted file mode 100644 index 70358d427211..000000000000 --- a/drivers/staging/vt6656/firmware.c +++ /dev/null @@ -1,106 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * File: baseband.c - * - * Purpose: Implement functions to access baseband - * - * Author: Yiching Chen - * - * Date: May 20, 2004 - * - * Functions: - * - * Revision History: - * - */ - -#include <linux/compiler.h> -#include "firmware.h" -#include "usbpipe.h" - -#define FIRMWARE_VERSION 0x133 /* version 1.51 */ -#define FIRMWARE_NAME "vntwusb.fw" - -#define FIRMWARE_CHUNK_SIZE 0x400 - -int vnt_download_firmware(struct vnt_private *priv) -{ - struct device *dev = &priv->usb->dev; - const struct firmware *fw; - u16 length; - int ii; - int ret = 0; - - dev_dbg(dev, "---->Download firmware\n"); - - ret = request_firmware(&fw, FIRMWARE_NAME, dev); - if (ret) { - dev_err(dev, "firmware file %s request failed (%d)\n", - FIRMWARE_NAME, ret); - goto end; - } - - for (ii = 0; ii < fw->size; ii += FIRMWARE_CHUNK_SIZE) { - length = min_t(int, fw->size - ii, FIRMWARE_CHUNK_SIZE); - - ret = vnt_control_out(priv, 0, 0x1200 + ii, 0x0000, length, - fw->data + ii); - if (ret) - goto free_fw; - - dev_dbg(dev, "Download firmware...%d %zu\n", ii, fw->size); - } - -free_fw: - release_firmware(fw); -end: - return ret; -} -MODULE_FIRMWARE(FIRMWARE_NAME); - -int vnt_firmware_branch_to_sram(struct vnt_private *priv) -{ - dev_dbg(&priv->usb->dev, "---->Branch to Sram\n"); - - return vnt_control_out(priv, 1, 0x1200, 0x0000, 0, NULL); -} - -int vnt_check_firmware_version(struct vnt_private *priv) -{ - int ret = 0; - - ret = vnt_control_in(priv, MESSAGE_TYPE_READ, 0, - MESSAGE_REQUEST_VERSION, 2, - (u8 *)&priv->firmware_version); - if (ret) { - dev_dbg(&priv->usb->dev, - "Could not get firmware version: %d.\n", ret); - goto end; - } - - dev_dbg(&priv->usb->dev, "Firmware Version [%04x]\n", - priv->firmware_version); - - if (priv->firmware_version == 0xFFFF) { - dev_dbg(&priv->usb->dev, "In Loader.\n"); - ret = -EINVAL; - goto end; - } - - if (priv->firmware_version < FIRMWARE_VERSION) { - /* branch to loader for download new firmware */ - ret = vnt_firmware_branch_to_sram(priv); - if (ret) { - dev_dbg(&priv->usb->dev, - "Could not branch to SRAM: %d.\n", ret); - } else { - ret = -EINVAL; - } - } - -end: - return ret; -} diff --git a/drivers/staging/vt6656/firmware.h b/drivers/staging/vt6656/firmware.h deleted file mode 100644 index 161126faf396..000000000000 --- a/drivers/staging/vt6656/firmware.h +++ /dev/null @@ -1,25 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * File: firmware.h - * - * Purpose: Version and Release Information - * - * Author: Yiching Chen - * - * Date: May 20, 2004 - * - */ - -#ifndef __FIRMWARE_H__ -#define __FIRMWARE_H__ - -#include "device.h" - -int vnt_download_firmware(struct vnt_private *priv); -int vnt_firmware_branch_to_sram(struct vnt_private *priv); -int vnt_check_firmware_version(struct vnt_private *priv); - -#endif /* __FIRMWARE_H__ */ diff --git a/drivers/staging/vt6656/key.c b/drivers/staging/vt6656/key.c index ac3b188984d0..c66cb53cfc09 100644 --- a/drivers/staging/vt6656/key.c +++ b/drivers/staging/vt6656/key.c @@ -35,7 +35,7 @@ int vnt_key_init_table(struct vnt_private *priv) 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) + u32 mode) { struct vnt_private *priv = hw->priv; u8 broadcast[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; @@ -68,17 +68,11 @@ static int vnt_set_keymode(struct ieee80211_hw *hw, u8 *mac_addr, entry = MAX_KEY_TABLE - 1; key->hw_key_idx = entry; /* fall through */ - case VNT_KEY_ALLGROUP: - key_mode |= VNT_KEY_ALLGROUP; - if (onfly_latch) - key_mode |= VNT_KEY_ONFLY_ALL; - /* fall through */ case VNT_KEY_GROUP_ADDRESS: - key_mode |= mode; - /* fall through */ + key_mode = mode | (mode << 4); + break; case VNT_KEY_GROUP: - key_mode |= (mode << 4); - key_mode |= VNT_KEY_GROUP; + key_mode = mode << 4; break; case VNT_KEY_PAIRWISE: key_mode |= mode; @@ -88,8 +82,7 @@ static int vnt_set_keymode(struct ieee80211_hw *hw, u8 *mac_addr, return -EINVAL; } - if (onfly_latch) - key_mode |= VNT_KEY_ONFLY; + key_mode |= key_type; if (mode == KEY_CTL_WEP) { if (key->keylen == WLAN_KEY_LEN_WEP40) @@ -98,9 +91,8 @@ static int vnt_set_keymode(struct ieee80211_hw *hw, u8 *mac_addr, key->key[15] |= 0x80; } - vnt_mac_set_keyentry(priv, key_mode, entry, key_inx, bssid, key->key); - - return 0; + return vnt_mac_set_keyentry(priv, key_mode, entry, + key_inx, bssid, key->key); } int vnt_set_keys(struct ieee80211_hw *hw, struct ieee80211_sta *sta, @@ -109,28 +101,21 @@ int vnt_set_keys(struct ieee80211_hw *hw, struct ieee80211_sta *sta, struct vnt_private *priv = hw->priv; u8 *mac_addr = NULL; u8 key_dec_mode = 0; - int ret = 0, u; if (sta) mac_addr = &sta->addr[0]; switch (key->cipher) { - case 0: - for (u = 0 ; u < MAX_KEY_TABLE; u++) - vnt_mac_disable_keyentry(priv, u); - return ret; - case WLAN_CIPHER_SUITE_WEP40: case WLAN_CIPHER_SUITE_WEP104: - for (u = 0; u < MAX_KEY_TABLE; u++) - vnt_mac_disable_keyentry(priv, u); - vnt_set_keymode(hw, mac_addr, key, VNT_KEY_DEFAULTKEY, - KEY_CTL_WEP, true); + KEY_CTL_WEP); key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; - return ret; + return vnt_set_keymode(hw, mac_addr, key, VNT_KEY_DEFAULTKEY, + KEY_CTL_WEP); + case WLAN_CIPHER_SUITE_TKIP: key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; @@ -151,11 +136,9 @@ int vnt_set_keys(struct ieee80211_hw *hw, struct ieee80211_sta *sta, } 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_GROUP_ADDRESS, - key_dec_mode, true); + return vnt_set_keymode(hw, mac_addr, key, VNT_KEY_PAIRWISE, + key_dec_mode); - return 0; + return vnt_set_keymode(hw, mac_addr, key, + VNT_KEY_GROUP_ADDRESS, key_dec_mode); } diff --git a/drivers/staging/vt6656/key.h b/drivers/staging/vt6656/key.h index 918c07cf86cd..1f3449e66143 100644 --- a/drivers/staging/vt6656/key.h +++ b/drivers/staging/vt6656/key.h @@ -25,13 +25,14 @@ #define KEY_CTL_TKIP 0x02 #define KEY_CTL_CCMP 0x03 -#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 +#define VNT_KEY_ONFLY 0x8000 +#define VNT_KEY_ALLGROUP 0x04 +#define VNT_KEY_GROUP 0x40 +#define VNT_KEY_PAIRWISE VNT_KEY_ONFLY +#define VNT_KEY_GROUP_ADDRESS (VNT_KEY_ALLGROUP | VNT_KEY_GROUP) +#define VNT_KEY_DEFAULTKEY (VNT_KEY_GROUP_ADDRESS | VNT_KEY_ONFLY |\ + VNT_KEY_ONFLY_ALL) int vnt_key_init_table(struct vnt_private *priv); diff --git a/drivers/staging/vt6656/mac.c b/drivers/staging/vt6656/mac.c index 5cacf6e60e90..da7067c34643 100644 --- a/drivers/staging/vt6656/mac.c +++ b/drivers/staging/vt6656/mac.c @@ -22,90 +22,40 @@ #include "mac.h" #include "usbpipe.h" -/* - * Description: - * Write MAC Multicast Address Mask - * - * Parameters: - * In: - * mc_filter (mac filter) - * Out: - * none - * - * Return Value: none - * - */ -void vnt_mac_set_filter(struct vnt_private *priv, u64 mc_filter) +int vnt_mac_set_filter(struct vnt_private *priv, u64 mc_filter) { __le64 le_mc = cpu_to_le64(mc_filter); - vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_MAR0, - MESSAGE_REQUEST_MACREG, sizeof(le_mc), (u8 *)&le_mc); + return vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_MAR0, + MESSAGE_REQUEST_MACREG, sizeof(le_mc), + (u8 *)&le_mc); } -/* - * Description: - * Shut Down MAC - * - * Parameters: - * In: - * Out: - * none - * - * - */ -void vnt_mac_shutdown(struct vnt_private *priv) +int vnt_mac_shutdown(struct vnt_private *priv) { - vnt_control_out(priv, MESSAGE_TYPE_MACSHUTDOWN, 0, 0, 0, NULL); + return vnt_control_out(priv, MESSAGE_TYPE_MACSHUTDOWN, 0, 0, 0, NULL); } -void vnt_mac_set_bb_type(struct vnt_private *priv, u8 type) +int vnt_mac_set_bb_type(struct vnt_private *priv, u8 type) { u8 data[2]; data[0] = type; data[1] = EnCFG_BBType_MASK; - vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, MAC_REG_ENCFG0, - MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); + return vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, MAC_REG_ENCFG0, + MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), + data); } -/* - * Description: - * Disable the Key Entry by MISCFIFO - * - * Parameters: - * In: - * dwIoBase - Base Address for MAC - * - * Out: - * none - * - * Return Value: none - * - */ -void vnt_mac_disable_keyentry(struct vnt_private *priv, u8 entry_idx) +int vnt_mac_disable_keyentry(struct vnt_private *priv, u8 entry_idx) { - vnt_control_out(priv, MESSAGE_TYPE_CLRKEYENTRY, 0, 0, - sizeof(entry_idx), &entry_idx); + return vnt_control_out(priv, MESSAGE_TYPE_CLRKEYENTRY, 0, 0, + sizeof(entry_idx), &entry_idx); } -/* - * Description: - * Set the Key by MISCFIFO - * - * Parameters: - * In: - * dwIoBase - Base Address for MAC - * - * Out: - * none - * - * Return Value: none - * - */ -void vnt_mac_set_keyentry(struct vnt_private *priv, u16 key_ctl, u32 entry_idx, - u32 key_idx, u8 *addr, u8 *key) +int vnt_mac_set_keyentry(struct vnt_private *priv, u16 key_ctl, u32 entry_idx, + u32 key_idx, u8 *addr, u8 *key) { struct vnt_mac_set_key set_key; u16 offset; @@ -124,9 +74,9 @@ void vnt_mac_set_keyentry(struct vnt_private *priv, u16 key_ctl, u32 entry_idx, dev_dbg(&priv->usb->dev, "offset %d key ctl %d set key %24ph\n", offset, key_ctl, (u8 *)&set_key); - vnt_control_out(priv, MESSAGE_TYPE_SETKEY, offset, - (u16)key_idx, sizeof(struct vnt_mac_set_key), - (u8 *)&set_key); + return vnt_control_out(priv, MESSAGE_TYPE_SETKEY, offset, + (u16)key_idx, sizeof(struct vnt_mac_set_key), + (u8 *)&set_key); } int vnt_mac_reg_bits_off(struct vnt_private *priv, u8 reg_ofs, u8 bits) @@ -151,76 +101,76 @@ int vnt_mac_reg_bits_on(struct vnt_private *priv, u8 reg_ofs, u8 bits) MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); } -void vnt_mac_write_word(struct vnt_private *priv, u8 reg_ofs, u16 word) +int vnt_mac_write_word(struct vnt_private *priv, u8 reg_ofs, u16 word) { u8 data[2]; data[0] = (u8)(word & 0xff); data[1] = (u8)(word >> 8); - vnt_control_out(priv, MESSAGE_TYPE_WRITE, reg_ofs, - MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); + return vnt_control_out(priv, MESSAGE_TYPE_WRITE, reg_ofs, + MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); } -void vnt_mac_set_bssid_addr(struct vnt_private *priv, u8 *addr) +int vnt_mac_set_bssid_addr(struct vnt_private *priv, u8 *addr) { - vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_BSSID0, - MESSAGE_REQUEST_MACREG, ETH_ALEN, addr); + return vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_BSSID0, + MESSAGE_REQUEST_MACREG, ETH_ALEN, addr); } -void vnt_mac_enable_protect_mode(struct vnt_private *priv) +int vnt_mac_enable_protect_mode(struct vnt_private *priv) { u8 data[2]; data[0] = EnCFG_ProtectMd; data[1] = EnCFG_ProtectMd; - vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, MAC_REG_ENCFG0, - MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); + return vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, MAC_REG_ENCFG0, + MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); } -void vnt_mac_disable_protect_mode(struct vnt_private *priv) +int vnt_mac_disable_protect_mode(struct vnt_private *priv) { u8 data[2]; data[0] = 0; data[1] = EnCFG_ProtectMd; - vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, MAC_REG_ENCFG0, - MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); + return vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, MAC_REG_ENCFG0, + MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); } -void vnt_mac_enable_barker_preamble_mode(struct vnt_private *priv) +int vnt_mac_enable_barker_preamble_mode(struct vnt_private *priv) { u8 data[2]; data[0] = EnCFG_BarkerPream; data[1] = EnCFG_BarkerPream; - vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, MAC_REG_ENCFG2, - MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); + return vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, MAC_REG_ENCFG2, + MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); } -void vnt_mac_disable_barker_preamble_mode(struct vnt_private *priv) +int vnt_mac_disable_barker_preamble_mode(struct vnt_private *priv) { u8 data[2]; data[0] = 0; data[1] = EnCFG_BarkerPream; - vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, MAC_REG_ENCFG2, - MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); + return vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, MAC_REG_ENCFG2, + MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); } -void vnt_mac_set_beacon_interval(struct vnt_private *priv, u16 interval) +int vnt_mac_set_beacon_interval(struct vnt_private *priv, u16 interval) { u8 data[2]; data[0] = (u8)(interval & 0xff); data[1] = (u8)(interval >> 8); - vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_BI, - MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); + return vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_BI, + MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data); } int vnt_mac_set_led(struct vnt_private *priv, u8 state, u8 led) diff --git a/drivers/staging/vt6656/mac.h b/drivers/staging/vt6656/mac.h index c532b27de37f..dae70b5c7634 100644 --- a/drivers/staging/vt6656/mac.h +++ b/drivers/staging/vt6656/mac.h @@ -177,7 +177,7 @@ #define EnCFG_BBType_a 0x00 #define EnCFG_BBType_b BIT(0) #define EnCFG_BBType_g BIT(1) -#define EnCFG_BBType_MASK (BIT(0) | BIT(1)) +#define EnCFG_BBType_MASK (EnCFG_BBType_b | EnCFG_BBType_g) #define EnCFG_ProtectMd BIT(5) /* Bits in the EnhanceCFG_1 register */ @@ -355,21 +355,21 @@ struct vnt_mac_set_key { u8 key[WLAN_KEY_LEN_CCMP]; } __packed; -void vnt_mac_set_filter(struct vnt_private *priv, u64 mc_filter); -void vnt_mac_shutdown(struct vnt_private *priv); -void vnt_mac_set_bb_type(struct vnt_private *priv, u8 type); -void vnt_mac_disable_keyentry(struct vnt_private *priv, u8 entry_idx); -void vnt_mac_set_keyentry(struct vnt_private *priv, u16 key_ctl, u32 entry_idx, - u32 key_idx, u8 *addr, u8 *key); +int vnt_mac_set_filter(struct vnt_private *priv, u64 mc_filter); +int vnt_mac_shutdown(struct vnt_private *priv); +int vnt_mac_set_bb_type(struct vnt_private *priv, u8 type); +int vnt_mac_disable_keyentry(struct vnt_private *priv, u8 entry_idx); +int vnt_mac_set_keyentry(struct vnt_private *priv, u16 key_ctl, u32 entry_idx, + u32 key_idx, u8 *addr, u8 *key); int vnt_mac_reg_bits_off(struct vnt_private *priv, u8 reg_ofs, u8 bits); int vnt_mac_reg_bits_on(struct vnt_private *priv, u8 reg_ofs, u8 bits); -void vnt_mac_write_word(struct vnt_private *priv, u8 reg_ofs, u16 word); -void vnt_mac_set_bssid_addr(struct vnt_private *priv, u8 *addr); -void vnt_mac_enable_protect_mode(struct vnt_private *priv); -void vnt_mac_disable_protect_mode(struct vnt_private *priv); -void vnt_mac_enable_barker_preamble_mode(struct vnt_private *priv); -void vnt_mac_disable_barker_preamble_mode(struct vnt_private *priv); -void vnt_mac_set_beacon_interval(struct vnt_private *priv, u16 interval); +int vnt_mac_write_word(struct vnt_private *priv, u8 reg_ofs, u16 word); +int vnt_mac_set_bssid_addr(struct vnt_private *priv, u8 *addr); +int vnt_mac_enable_protect_mode(struct vnt_private *priv); +int vnt_mac_disable_protect_mode(struct vnt_private *priv); +int vnt_mac_enable_barker_preamble_mode(struct vnt_private *priv); +int vnt_mac_disable_barker_preamble_mode(struct vnt_private *priv); +int vnt_mac_set_beacon_interval(struct vnt_private *priv, u16 interval); int vnt_mac_set_led(struct vnt_private *privpriv, u8 state, u8 led); #endif /* __MAC_H__ */ diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index 5f78cad3b647..8bf851c53f4e 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -33,7 +33,6 @@ #include "wcmd.h" #include "rxtx.h" #include "rf.h" -#include "firmware.h" #include "usbpipe.h" #include "channel.h" @@ -60,8 +59,6 @@ MODULE_PARM_DESC(tx_buffers, "Number of receive usb tx buffers"); #define RTS_THRESH_DEF 2347 #define FRAG_THRESH_DEF 2346 -#define SHORT_RETRY_DEF 8 -#define LONG_RETRY_DEF 4 /* BasebandType[] baseband type selected * 0: indicate 802.11a type @@ -94,15 +91,91 @@ static void vnt_set_options(struct vnt_private *priv) else priv->num_rcb = vnt_rx_buffers; - priv->short_retry_limit = SHORT_RETRY_DEF; - priv->long_retry_limit = LONG_RETRY_DEF; priv->op_mode = NL80211_IFTYPE_UNSPECIFIED; priv->bb_type = BBP_TYPE_DEF; priv->packet_type = priv->bb_type; - priv->preamble_type = 0; + priv->preamble_type = PREAMBLE_LONG; priv->exist_sw_net_addr = false; } +static int vnt_download_firmware(struct vnt_private *priv) +{ + struct device *dev = &priv->usb->dev; + const struct firmware *fw; + u16 length; + int ii; + int ret = 0; + + dev_dbg(dev, "---->Download firmware\n"); + + ret = request_firmware(&fw, FIRMWARE_NAME, dev); + if (ret) { + dev_err(dev, "firmware file %s request failed (%d)\n", + FIRMWARE_NAME, ret); + goto end; + } + + for (ii = 0; ii < fw->size; ii += FIRMWARE_CHUNK_SIZE) { + length = min_t(int, fw->size - ii, FIRMWARE_CHUNK_SIZE); + + ret = vnt_control_out(priv, 0, 0x1200 + ii, 0x0000, length, + fw->data + ii); + if (ret) + goto free_fw; + + dev_dbg(dev, "Download firmware...%d %zu\n", ii, fw->size); + } + +free_fw: + release_firmware(fw); +end: + return ret; +} + +static int vnt_firmware_branch_to_sram(struct vnt_private *priv) +{ + dev_dbg(&priv->usb->dev, "---->Branch to Sram\n"); + + return vnt_control_out(priv, 1, 0x1200, 0x0000, 0, NULL); +} + +static int vnt_check_firmware_version(struct vnt_private *priv) +{ + int ret = 0; + + ret = vnt_control_in(priv, MESSAGE_TYPE_READ, 0, + MESSAGE_REQUEST_VERSION, 2, + (u8 *)&priv->firmware_version); + if (ret) { + dev_dbg(&priv->usb->dev, + "Could not get firmware version: %d.\n", ret); + goto end; + } + + dev_dbg(&priv->usb->dev, "Firmware Version [%04x]\n", + priv->firmware_version); + + if (priv->firmware_version == 0xFFFF) { + dev_dbg(&priv->usb->dev, "In Loader.\n"); + ret = -EINVAL; + goto end; + } + + if (priv->firmware_version < FIRMWARE_VERSION) { + /* branch to loader for download new firmware */ + ret = vnt_firmware_branch_to_sram(priv); + if (ret) { + dev_dbg(&priv->usb->dev, + "Could not branch to SRAM: %d.\n", ret); + } else { + ret = -EINVAL; + } + } + +end: + return ret; +} + /* * initialization of MAC & BBP registers */ @@ -146,8 +219,8 @@ static int vnt_init_registers(struct vnt_private *priv) init_cmd->exist_sw_net_addr = priv->exist_sw_net_addr; for (ii = 0; ii < ARRAY_SIZE(init_cmd->sw_net_addr); ii++) init_cmd->sw_net_addr[ii] = priv->current_net_addr[ii]; - init_cmd->short_retry_limit = priv->short_retry_limit; - init_cmd->long_retry_limit = priv->long_retry_limit; + init_cmd->short_retry_limit = priv->hw->wiphy->retry_short; + init_cmd->long_retry_limit = priv->hw->wiphy->retry_long; /* issue card_init command to device */ ret = vnt_control_out(priv, MESSAGE_TYPE_CARDINIT, 0, 0, @@ -324,19 +397,6 @@ static int vnt_init_registers(struct vnt_private *priv) dev_dbg(&priv->usb->dev, "Network address = %pM\n", priv->current_net_addr); - /* - * set BB and packet type at the same time - * set Short Slot Time, xIFS, and RSPINF - */ - if (priv->bb_type == BB_TYPE_11A) - priv->short_slot_time = true; - else - priv->short_slot_time = false; - - ret = vnt_set_short_slot_time(priv); - if (ret) - goto end; - priv->radio_ctl = priv->eeprom[EEP_OFS_RADIOCTL]; if ((priv->radio_ctl & EEP_RADIOCTL_ENABLE) != 0) { @@ -385,17 +445,13 @@ static void vnt_free_tx_bufs(struct vnt_private *priv) struct vnt_usb_send_context *tx_context; int ii; + usb_kill_anchored_urbs(&priv->tx_submitted); + for (ii = 0; ii < priv->num_tx_context; ii++) { tx_context = priv->tx_context[ii]; if (!tx_context) continue; - /* deallocate URBs */ - if (tx_context->urb) { - usb_kill_urb(tx_context->urb); - usb_free_urb(tx_context->urb); - } - kfree(tx_context); } } @@ -436,6 +492,8 @@ static int vnt_alloc_bufs(struct vnt_private *priv) struct vnt_rcb *rcb; int ii; + init_usb_anchor(&priv->tx_submitted); + for (ii = 0; ii < priv->num_tx_context; ii++) { tx_context = kmalloc(sizeof(*tx_context), GFP_KERNEL); if (!tx_context) { @@ -446,14 +504,6 @@ static int vnt_alloc_bufs(struct vnt_private *priv) priv->tx_context[ii] = tx_context; tx_context->priv = priv; tx_context->pkt_no = ii; - - /* allocate URBs */ - tx_context->urb = usb_alloc_urb(0, GFP_KERNEL); - if (!tx_context->urb) { - ret = -ENOMEM; - goto free_tx; - } - tx_context->in_use = false; } @@ -683,15 +733,14 @@ static int vnt_config(struct ieee80211_hw *hw, u32 changed) priv->bb_type = BB_TYPE_11G; } - if (changed & IEEE80211_CONF_CHANGE_POWER) { - if (priv->bb_type == BB_TYPE_11B) - priv->current_rate = RATE_1M; - else - priv->current_rate = RATE_54M; + if (changed & IEEE80211_CONF_CHANGE_POWER) + vnt_rf_setpower(priv, conf->chandef.chan); - vnt_rf_setpower(priv, priv->current_rate, - conf->chandef.chan->hw_value); - } + if (conf->flags & (IEEE80211_CONF_OFFCHANNEL | IEEE80211_CONF_IDLE)) + /* Set max sensitivity*/ + vnt_update_pre_ed_threshold(priv, true); + else + vnt_update_pre_ed_threshold(priv, false); return 0; } @@ -718,10 +767,10 @@ static void vnt_bss_info_changed(struct ieee80211_hw *hw, if (changed & BSS_CHANGED_ERP_PREAMBLE) { if (conf->use_short_preamble) { vnt_mac_enable_barker_preamble_mode(priv); - priv->preamble_type = true; + priv->preamble_type = PREAMBLE_SHORT; } else { vnt_mac_disable_barker_preamble_mode(priv); - priv->preamble_type = false; + priv->preamble_type = PREAMBLE_LONG; } } @@ -740,16 +789,14 @@ static void vnt_bss_info_changed(struct ieee80211_hw *hw, vnt_set_short_slot_time(priv); vnt_set_vga_gain_offset(priv, priv->bb_vga[0]); - vnt_update_pre_ed_threshold(priv, false); } if (changed & (BSS_CHANGED_BASIC_RATES | BSS_CHANGED_ERP_PREAMBLE | BSS_CHANGED_ERP_SLOT)) vnt_set_bss_mode(priv); - if (changed & BSS_CHANGED_TXPOWER) - vnt_rf_setpower(priv, priv->current_rate, - conf->chandef.chan->hw_value); + if (changed & (BSS_CHANGED_TXPOWER | BSS_CHANGED_BANDWIDTH)) + vnt_rf_setpower(priv, conf->chandef.chan); if (changed & BSS_CHANGED_BEACON_ENABLED) { dev_dbg(&priv->usb->dev, @@ -767,10 +814,17 @@ static void vnt_bss_info_changed(struct ieee80211_hw *hw, if (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_BEACON_INFO) && priv->op_mode != NL80211_IFTYPE_AP) { if (conf->assoc && conf->beacon_rate) { + u16 ps_beacon_int = conf->beacon_int; + + if (conf->dtim_period) + ps_beacon_int *= conf->dtim_period; + else if (hw->conf.listen_interval) + ps_beacon_int *= hw->conf.listen_interval; + vnt_mac_reg_bits_on(priv, MAC_REG_TFTCTL, TFTCTL_TSFCNTREN); - vnt_mac_set_beacon_interval(priv, conf->beacon_int); + vnt_mac_set_beacon_interval(priv, ps_beacon_int); vnt_reset_next_tbtt(priv, conf->beacon_int); @@ -778,7 +832,7 @@ static void vnt_bss_info_changed(struct ieee80211_hw *hw, conf->sync_tsf, priv->current_tsf); vnt_update_next_tbtt(priv, - conf->sync_tsf, conf->beacon_int); + conf->sync_tsf, ps_beacon_int); } else { vnt_clear_current_tsf(priv); @@ -868,25 +922,6 @@ static int vnt_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, return 0; } -static void vnt_sw_scan_start(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - const u8 *addr) -{ - struct vnt_private *priv = hw->priv; - - /* Set max sensitivity*/ - vnt_update_pre_ed_threshold(priv, true); -} - -static void vnt_sw_scan_complete(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) -{ - struct vnt_private *priv = hw->priv; - - /* Return sensitivity to channel level*/ - vnt_update_pre_ed_threshold(priv, false); -} - static int vnt_get_stats(struct ieee80211_hw *hw, struct ieee80211_low_level_stats *stats) { @@ -932,8 +967,6 @@ static const struct ieee80211_ops vnt_mac_ops = { .prepare_multicast = vnt_prepare_multicast, .configure_filter = vnt_configure, .set_key = vnt_set_key, - .sw_scan_start = vnt_sw_scan_start, - .sw_scan_complete = vnt_sw_scan_complete, .get_stats = vnt_get_stats, .get_tsf = vnt_get_tsf, .set_tsf = vnt_set_tsf, @@ -1010,6 +1043,8 @@ vt6656_probe(struct usb_interface *intf, const struct usb_device_id *id) ieee80211_hw_set(priv->hw, SUPPORTS_PS); ieee80211_hw_set(priv->hw, PS_NULLFUNC_STACK); + priv->hw->extra_tx_headroom = + sizeof(struct vnt_tx_buffer) + sizeof(struct vnt_tx_usb_header); priv->hw->max_signal = 100; SET_IEEE80211_DEV(priv->hw, &intf->dev); @@ -1078,3 +1113,5 @@ static struct usb_driver vt6656_driver = { }; module_usb_driver(vt6656_driver); + +MODULE_FIRMWARE(FIRMWARE_NAME); diff --git a/drivers/staging/vt6656/power.c b/drivers/staging/vt6656/power.c index 7a086c72d5a8..2f49c870272a 100644 --- a/drivers/staging/vt6656/power.c +++ b/drivers/staging/vt6656/power.c @@ -63,41 +63,29 @@ void vnt_enable_power_saving(struct vnt_private *priv, u16 listen_interval) */ vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_GO2DOZE); - if (listen_interval >= 2) { - /* clear always listen beacon */ - vnt_mac_reg_bits_off(priv, MAC_REG_PSCTL, PSCTL_ALBCN); - - /* first time set listen next beacon */ - vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_LNBCN); - } else { - /* always listen beacon */ - vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_ALBCN); - } + /* always listen beacon */ + vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_ALBCN); dev_dbg(&priv->usb->dev, "PS:Power Saving Mode Enable...\n"); } -/* - * - * Routine Description: - * Disable hw power saving functions - * - * Return Value: - * None. - * - */ - -void vnt_disable_power_saving(struct vnt_private *priv) +int vnt_disable_power_saving(struct vnt_private *priv) { + int ret; + /* disable power saving hw function */ - vnt_control_out(priv, MESSAGE_TYPE_DISABLE_PS, 0, - 0, 0, NULL); + ret = vnt_control_out(priv, MESSAGE_TYPE_DISABLE_PS, 0, + 0, 0, NULL); + if (ret) + return ret; /* clear AutoSleep */ vnt_mac_reg_bits_off(priv, MAC_REG_PSCFG, PSCFG_AUTOSLEEP); /* set always listen beacon */ vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_ALBCN); + + return 0; } /* diff --git a/drivers/staging/vt6656/power.h b/drivers/staging/vt6656/power.h index 58755ae16e5a..160872026db3 100644 --- a/drivers/staging/vt6656/power.h +++ b/drivers/staging/vt6656/power.h @@ -18,7 +18,7 @@ #define C_PWBT 1000 /* micro sec. power up before TBTT */ -void vnt_disable_power_saving(struct vnt_private *priv); +int vnt_disable_power_saving(struct vnt_private *priv); void vnt_enable_power_saving(struct vnt_private *priv, u16 listen_interval); int vnt_next_tbtt_wakeup(struct vnt_private *priv); diff --git a/drivers/staging/vt6656/rf.c b/drivers/staging/vt6656/rf.c index 43237b7e1dbe..5b8da06e3916 100644 --- a/drivers/staging/vt6656/rf.c +++ b/drivers/staging/vt6656/rf.c @@ -21,22 +21,16 @@ * */ +#include <linux/errno.h> #include "mac.h" #include "rf.h" #include "baseband.h" #include "usbpipe.h" #define CB_AL2230_INIT_SEQ 15 -#define AL2230_PWR_IDX_LEN 64 - #define CB_AL7230_INIT_SEQ 16 -#define AL7230_PWR_IDX_LEN 64 - #define CB_VT3226_INIT_SEQ 11 -#define VT3226_PWR_IDX_LEN 64 - #define CB_VT3342_INIT_SEQ 13 -#define VT3342_PWR_IDX_LEN 64 static u8 al2230_init_table[CB_AL2230_INIT_SEQ][3] = { {0x03, 0xf7, 0x90}, @@ -518,72 +512,45 @@ static u8 vt3342_channel_table1[CB_MAX_CHANNEL][3] = { {0x03, 0x00, 0x04} }; -/* Power Table */ -static const u32 al2230_power_table[AL2230_PWR_IDX_LEN] = { - 0x04040900, - 0x04041900, - 0x04042900, - 0x04043900, - 0x04044900, - 0x04045900, - 0x04046900, - 0x04047900, - 0x04048900, - 0x04049900, - 0x0404a900, - 0x0404b900, - 0x0404c900, - 0x0404d900, - 0x0404e900, - 0x0404f900, - 0x04050900, - 0x04051900, - 0x04052900, - 0x04053900, - 0x04054900, - 0x04055900, - 0x04056900, - 0x04057900, - 0x04058900, - 0x04059900, - 0x0405a900, - 0x0405b900, - 0x0405c900, - 0x0405d900, - 0x0405e900, - 0x0405f900, - 0x04060900, - 0x04061900, - 0x04062900, - 0x04063900, - 0x04064900, - 0x04065900, - 0x04066900, - 0x04067900, - 0x04068900, - 0x04069900, - 0x0406a900, - 0x0406b900, - 0x0406c900, - 0x0406d900, - 0x0406e900, - 0x0406f900, - 0x04070900, - 0x04071900, - 0x04072900, - 0x04073900, - 0x04074900, - 0x04075900, - 0x04076900, - 0x04077900, - 0x04078900, - 0x04079900, - 0x0407a900, - 0x0407b900, - 0x0407c900, - 0x0407d900, - 0x0407e900, - 0x0407f900 +enum { + VNT_TABLE_INIT = 0, + VNT_TABLE_INIT_2 = 0, + VNT_TABLE_0 = 1, + VNT_TABLE_1 = 2, + VNT_TABLE_2 = 1 +}; + +struct vnt_table_info { + u8 *addr; + int length; +}; + +static const struct vnt_table_info vnt_table_seq[][3] = { + { /* RF_AL2230, RF_AL2230S init table, channel table 0 and 1 */ + {&al2230_init_table[0][0], CB_AL2230_INIT_SEQ * 3}, + {&al2230_channel_table0[0][0], CB_MAX_CHANNEL_24G * 3}, + {&al2230_channel_table1[0][0], CB_MAX_CHANNEL_24G * 3} + }, { /* RF_AIROHA7230 init table, channel table 0 and 1 */ + {&al7230_init_table[0][0], CB_AL7230_INIT_SEQ * 3}, + {&al7230_channel_table0[0][0], CB_MAX_CHANNEL * 3}, + {&al7230_channel_table1[0][0], CB_MAX_CHANNEL * 3} + }, { /* RF_VT3226 init table, channel table 0 and 1 */ + {&vt3226_init_table[0][0], CB_VT3226_INIT_SEQ * 3}, + {&vt3226_channel_table0[0][0], CB_MAX_CHANNEL_24G * 3}, + {&vt3226_channel_table1[0][0], CB_MAX_CHANNEL_24G * 3} + }, { /* RF_VT3226D0 init table, channel table 0 and 1 */ + {&vt3226d0_init_table[0][0], CB_VT3226_INIT_SEQ * 3}, + {&vt3226_channel_table0[0][0], CB_MAX_CHANNEL_24G * 3}, + {&vt3226_channel_table1[0][0], CB_MAX_CHANNEL_24G * 3} + }, { /* RF_VT3342A0 init table, channel table 0 and 1 */ + {&vt3342a0_init_table[0][0], CB_VT3342_INIT_SEQ * 3}, + {&vt3342_channel_table0[0][0], CB_MAX_CHANNEL * 3}, + {&vt3342_channel_table1[0][0], CB_MAX_CHANNEL * 3} + }, { /* RF_AIROHA7230 init table 2 and channel table 2 */ + {&al7230_init_table_amode[0][0], CB_AL7230_INIT_SEQ * 3}, + {&al7230_channel_table2[0][0], CB_MAX_CHANNEL * 3}, + {NULL, 0} + } }; /* @@ -600,124 +567,90 @@ int vnt_rf_write_embedded(struct vnt_private *priv, u32 data) reg_data[2] = (u8)(data >> 16); reg_data[3] = (u8)(data >> 24); - vnt_control_out(priv, MESSAGE_TYPE_WRITE_IFRF, - 0, 0, ARRAY_SIZE(reg_data), reg_data); - - return true; -} - -/* Set Tx power by rate and channel number */ -int vnt_rf_setpower(struct vnt_private *priv, u32 rate, u32 channel) -{ - u8 power = priv->cck_pwr; - - if (channel == 0) - return -EINVAL; - - switch (rate) { - case RATE_1M: - case RATE_2M: - case RATE_5M: - case RATE_11M: - channel--; - - if (channel < sizeof(priv->cck_pwr_tbl)) - power = priv->cck_pwr_tbl[channel]; - break; - case RATE_6M: - case RATE_9M: - case RATE_12M: - case RATE_18M: - case RATE_24M: - case RATE_36M: - case RATE_48M: - case RATE_54M: - if (channel > CB_MAX_CHANNEL_24G) - power = priv->ofdm_a_pwr_tbl[channel - 15]; - else - power = priv->ofdm_pwr_tbl[channel - 1]; - break; - } - - return vnt_rf_set_txpower(priv, power, rate); + return vnt_control_out(priv, MESSAGE_TYPE_WRITE_IFRF, 0, 0, + ARRAY_SIZE(reg_data), reg_data); } static u8 vnt_rf_addpower(struct vnt_private *priv) { + int base; s32 rssi = -priv->current_rssi; if (!rssi) return 7; - if (priv->rf_type == RF_VT3226D0) { - if (rssi < -70) - return 9; - else if (rssi < -65) - return 7; - else if (rssi < -60) - return 5; - } else { - if (rssi < -80) - return 9; - else if (rssi < -75) - return 7; - else if (rssi < -70) - return 5; - } + if (priv->rf_type == RF_VT3226D0) + base = -60; + else + base = -70; + + if (rssi < base) + return ((rssi - base + 1) / -5) * 2 + 5; return 0; } /* Set Tx power by power level and rate */ -int vnt_rf_set_txpower(struct vnt_private *priv, u8 power, u32 rate) +static int vnt_rf_set_txpower(struct vnt_private *priv, u8 power, + struct ieee80211_channel *ch) { u32 power_setting = 0; - int ret = true; + int ret = 0; power += vnt_rf_addpower(priv); if (power > VNT_RF_MAX_POWER) power = VNT_RF_MAX_POWER; if (priv->power == power) - return true; + return 0; priv->power = power; switch (priv->rf_type) { case RF_AL2230: - if (power >= AL2230_PWR_IDX_LEN) - return false; + power_setting = 0x0404090 | (power << 12); - ret &= vnt_rf_write_embedded(priv, al2230_power_table[power]); + ret = vnt_rf_write_embedded(priv, power_setting); + if (ret) + return ret; - if (rate <= RATE_11M) - ret &= vnt_rf_write_embedded(priv, 0x0001b400); + if (ch->flags & IEEE80211_CHAN_NO_OFDM) + ret = vnt_rf_write_embedded(priv, 0x0001b400); else - ret &= vnt_rf_write_embedded(priv, 0x0005a400); + ret = vnt_rf_write_embedded(priv, 0x0005a400); + break; case RF_AL2230S: - if (power >= AL2230_PWR_IDX_LEN) - return false; + power_setting = 0x0404090 | (power << 12); - ret &= vnt_rf_write_embedded(priv, al2230_power_table[power]); + ret = vnt_rf_write_embedded(priv, power_setting); + if (ret) + return ret; - if (rate <= RATE_11M) { - ret &= vnt_rf_write_embedded(priv, 0x040c1400); - ret &= vnt_rf_write_embedded(priv, 0x00299b00); + if (ch->flags & IEEE80211_CHAN_NO_OFDM) { + ret = vnt_rf_write_embedded(priv, 0x040c1400); + if (ret) + return ret; + + ret = vnt_rf_write_embedded(priv, 0x00299b00); } else { - ret &= vnt_rf_write_embedded(priv, 0x0005a400); - ret &= vnt_rf_write_embedded(priv, 0x00099b00); + ret = vnt_rf_write_embedded(priv, 0x0005a400); + if (ret) + return ret; + + ret = vnt_rf_write_embedded(priv, 0x00099b00); } + break; case RF_AIROHA7230: - if (rate <= RATE_11M) - ret &= vnt_rf_write_embedded(priv, 0x111bb900); + if (ch->flags & IEEE80211_CHAN_NO_OFDM) + ret = vnt_rf_write_embedded(priv, 0x111bb900); else - ret &= vnt_rf_write_embedded(priv, 0x221bb900); + ret = vnt_rf_write_embedded(priv, 0x221bb900); - if (power >= AL7230_PWR_IDX_LEN) - return false; + if (ret) + return ret; /* * 0x080F1B00 for 3 wire control TxGain(D10) @@ -725,61 +658,68 @@ int vnt_rf_set_txpower(struct vnt_private *priv, u8 power, u32 rate) */ power_setting = 0x080c0b00 | (power << 12); - ret &= vnt_rf_write_embedded(priv, power_setting); - + ret = vnt_rf_write_embedded(priv, power_setting); break; case RF_VT3226: - if (power >= VT3226_PWR_IDX_LEN) - return false; power_setting = ((0x3f - power) << 20) | (0x17 << 8); - ret &= vnt_rf_write_embedded(priv, power_setting); - + ret = vnt_rf_write_embedded(priv, power_setting); break; case RF_VT3226D0: - if (power >= VT3226_PWR_IDX_LEN) - return false; - - if (rate <= RATE_11M) { - u16 hw_value = priv->hw->conf.chandef.chan->hw_value; + if (ch->flags & IEEE80211_CHAN_NO_OFDM) { + u16 hw_value = ch->hw_value; power_setting = ((0x3f - power) << 20) | (0xe07 << 8); - ret &= vnt_rf_write_embedded(priv, power_setting); - ret &= vnt_rf_write_embedded(priv, 0x03c6a200); + ret = vnt_rf_write_embedded(priv, power_setting); + if (ret) + return ret; + + ret = vnt_rf_write_embedded(priv, 0x03c6a200); + if (ret) + return ret; dev_dbg(&priv->usb->dev, "%s 11b channel [%d]\n", __func__, hw_value); hw_value--; - if (hw_value < ARRAY_SIZE(vt3226d0_lo_current_table)) - ret &= vnt_rf_write_embedded(priv, + if (hw_value < ARRAY_SIZE(vt3226d0_lo_current_table)) { + ret = vnt_rf_write_embedded(priv, vt3226d0_lo_current_table[hw_value]); + if (ret) + return ret; + } - ret &= vnt_rf_write_embedded(priv, 0x015C0800); + ret = vnt_rf_write_embedded(priv, 0x015C0800); } else { dev_dbg(&priv->usb->dev, "@@@@ %s> 11G mode\n", __func__); power_setting = ((0x3f - power) << 20) | (0x7 << 8); - ret &= vnt_rf_write_embedded(priv, power_setting); - ret &= vnt_rf_write_embedded(priv, 0x00C6A200); - ret &= vnt_rf_write_embedded(priv, 0x016BC600); - ret &= vnt_rf_write_embedded(priv, 0x00900800); + ret = vnt_rf_write_embedded(priv, power_setting); + if (ret) + return ret; + + ret = vnt_rf_write_embedded(priv, 0x00C6A200); + if (ret) + return ret; + + ret = vnt_rf_write_embedded(priv, 0x016BC600); + if (ret) + return ret; + + ret = vnt_rf_write_embedded(priv, 0x00900800); } + break; case RF_VT3342A0: - if (power >= VT3342_PWR_IDX_LEN) - return false; - power_setting = ((0x3f - power) << 20) | (0x27 << 8); - ret &= vnt_rf_write_embedded(priv, power_setting); - + ret = vnt_rf_write_embedded(priv, power_setting); break; default: break; @@ -787,6 +727,36 @@ int vnt_rf_set_txpower(struct vnt_private *priv, u8 power, u32 rate) return ret; } +/* Set Tx power by channel number type */ +int vnt_rf_setpower(struct vnt_private *priv, + struct ieee80211_channel *ch) +{ + u16 channel; + u8 power = priv->cck_pwr; + + if (!ch) + return -EINVAL; + + /* set channel number to array number */ + channel = ch->hw_value - 1; + + if (ch->flags & IEEE80211_CHAN_NO_OFDM) { + if (channel < ARRAY_SIZE(priv->cck_pwr_tbl)) + power = priv->cck_pwr_tbl[channel]; + } else if (ch->band == NL80211_BAND_5GHZ) { + /* remove 14 channels to array size */ + channel -= 14; + + if (channel < ARRAY_SIZE(priv->ofdm_a_pwr_tbl)) + power = priv->ofdm_a_pwr_tbl[channel]; + } else { + if (channel < ARRAY_SIZE(priv->ofdm_pwr_tbl)) + power = priv->ofdm_pwr_tbl[channel]; + } + + return vnt_rf_set_txpower(priv, power, ch); +} + /* Convert rssi to dbm */ void vnt_rf_rssi_to_dbm(struct vnt_private *priv, u8 rssi, long *dbm) { @@ -813,140 +783,73 @@ void vnt_rf_rssi_to_dbm(struct vnt_private *priv, u8 rssi, long *dbm) int vnt_rf_table_download(struct vnt_private *priv) { - int ret = 0; - u16 length1 = 0, length2 = 0, length3 = 0; - u8 *addr1 = NULL, *addr2 = NULL, *addr3 = NULL; - u16 length, value; - u8 array[256]; + int ret; + int idx = -1; + const struct vnt_table_info *table_seq; switch (priv->rf_type) { case RF_AL2230: case RF_AL2230S: - length1 = CB_AL2230_INIT_SEQ * 3; - length2 = CB_MAX_CHANNEL_24G * 3; - length3 = CB_MAX_CHANNEL_24G * 3; - addr1 = &al2230_init_table[0][0]; - addr2 = &al2230_channel_table0[0][0]; - addr3 = &al2230_channel_table1[0][0]; + idx = 0; break; case RF_AIROHA7230: - length1 = CB_AL7230_INIT_SEQ * 3; - length2 = CB_MAX_CHANNEL * 3; - length3 = CB_MAX_CHANNEL * 3; - addr1 = &al7230_init_table[0][0]; - addr2 = &al7230_channel_table0[0][0]; - addr3 = &al7230_channel_table1[0][0]; + idx = 1; break; case RF_VT3226: - length1 = CB_VT3226_INIT_SEQ * 3; - length2 = CB_MAX_CHANNEL_24G * 3; - length3 = CB_MAX_CHANNEL_24G * 3; - addr1 = &vt3226_init_table[0][0]; - addr2 = &vt3226_channel_table0[0][0]; - addr3 = &vt3226_channel_table1[0][0]; + idx = 2; break; case RF_VT3226D0: - length1 = CB_VT3226_INIT_SEQ * 3; - length2 = CB_MAX_CHANNEL_24G * 3; - length3 = CB_MAX_CHANNEL_24G * 3; - addr1 = &vt3226d0_init_table[0][0]; - addr2 = &vt3226_channel_table0[0][0]; - addr3 = &vt3226_channel_table1[0][0]; + idx = 3; break; case RF_VT3342A0: - length1 = CB_VT3342_INIT_SEQ * 3; - length2 = CB_MAX_CHANNEL * 3; - length3 = CB_MAX_CHANNEL * 3; - addr1 = &vt3342a0_init_table[0][0]; - addr2 = &vt3342_channel_table0[0][0]; - addr3 = &vt3342_channel_table1[0][0]; + idx = 4; break; } - /* Init Table */ - memcpy(array, addr1, length1); + if (idx < 0) + return 0; + table_seq = &vnt_table_seq[idx][0]; + + /* Init Table */ ret = vnt_control_out(priv, MESSAGE_TYPE_WRITE, 0, - MESSAGE_REQUEST_RF_INIT, length1, array); + MESSAGE_REQUEST_RF_INIT, + table_seq[VNT_TABLE_INIT].length, + table_seq[VNT_TABLE_INIT].addr); if (ret) - goto end; + return ret; /* Channel Table 0 */ - value = 0; - while (length2 > 0) { - if (length2 >= 64) - length = 64; - else - length = length2; - - memcpy(array, addr2, length); - - ret = vnt_control_out(priv, MESSAGE_TYPE_WRITE, value, - MESSAGE_REQUEST_RF_CH0, length, array); - if (ret) - goto end; - - length2 -= length; - value += length; - addr2 += length; - } - - /* Channel table 1 */ - value = 0; - while (length3 > 0) { - if (length3 >= 64) - length = 64; - else - length = length3; - - memcpy(array, addr3, length); + ret = vnt_control_out_blocks(priv, VNT_REG_BLOCK_SIZE, + MESSAGE_REQUEST_RF_CH0, + table_seq[VNT_TABLE_0].length, + table_seq[VNT_TABLE_0].addr); + if (ret) + return ret; - ret = vnt_control_out(priv, MESSAGE_TYPE_WRITE, value, - MESSAGE_REQUEST_RF_CH1, length, array); - if (ret) - goto end; - - length3 -= length; - value += length; - addr3 += length; - } + /* Channel Table 1 */ + ret = vnt_control_out_blocks(priv, VNT_REG_BLOCK_SIZE, + MESSAGE_REQUEST_RF_CH1, + table_seq[VNT_TABLE_1].length, + table_seq[VNT_TABLE_1].addr); if (priv->rf_type == RF_AIROHA7230) { - length1 = CB_AL7230_INIT_SEQ * 3; - length2 = CB_MAX_CHANNEL * 3; - addr1 = &al7230_init_table_amode[0][0]; - addr2 = &al7230_channel_table2[0][0]; - - memcpy(array, addr1, length1); + table_seq = &vnt_table_seq[5][0]; /* Init Table 2 */ ret = vnt_control_out(priv, MESSAGE_TYPE_WRITE, 0, - MESSAGE_REQUEST_RF_INIT2, length1, array); + MESSAGE_REQUEST_RF_INIT2, + table_seq[VNT_TABLE_INIT_2].length, + table_seq[VNT_TABLE_INIT_2].addr); if (ret) - goto end; + return ret; - /* Channel Table 0 */ - value = 0; - while (length2 > 0) { - if (length2 >= 64) - length = 64; - else - length = length2; - - memcpy(array, addr2, length); - - ret = vnt_control_out(priv, MESSAGE_TYPE_WRITE, value, - MESSAGE_REQUEST_RF_CH2, length, - array); - if (ret) - goto end; - - length2 -= length; - value += length; - addr2 += length; - } + /* Channel Table 2 */ + ret = vnt_control_out_blocks(priv, VNT_REG_BLOCK_SIZE, + MESSAGE_REQUEST_RF_CH2, + table_seq[VNT_TABLE_2].length, + table_seq[VNT_TABLE_2].addr); } -end: return ret; } diff --git a/drivers/staging/vt6656/rf.h b/drivers/staging/vt6656/rf.h index 7494546d71b8..493faaf4e2b5 100644 --- a/drivers/staging/vt6656/rf.h +++ b/drivers/staging/vt6656/rf.h @@ -41,8 +41,7 @@ #define VNT_RF_REG_LEN 0x17 /* 24 bit length */ int vnt_rf_write_embedded(struct vnt_private *priv, u32 data); -int vnt_rf_setpower(struct vnt_private *priv, u32 rate, u32 channel); -int vnt_rf_set_txpower(struct vnt_private *priv, u8 power, u32 rate); +int vnt_rf_setpower(struct vnt_private *priv, struct ieee80211_channel *ch); void vnt_rf_rssi_to_dbm(struct vnt_private *priv, u8 rssi, long *dbm); int vnt_rf_table_download(struct vnt_private *priv); diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c index 9439d190f431..5dd6b4d2bf20 100644 --- a/drivers/staging/vt6656/rxtx.c +++ b/drivers/staging/vt6656/rxtx.c @@ -13,8 +13,6 @@ * * Functions: * vnt_generate_tx_parameter - Generate tx dma required parameter. - * vnt_get_rtscts_duration_le- get rtx/cts required duration - * vnt_get_rtscts_rsvtime_le- get rts/cts reserved time * vnt_get_rsvtime- get frame reserved time * vnt_fill_cts_head- fulfill CTS ctl header * @@ -38,13 +36,24 @@ static const u16 vnt_time_stampoff[2][MAX_RATE] = { {384, 192, 130, 113, 54, 43, 37, 31, 28, 25, 24, 23}, }; -#define RTSDUR_BB 0 -#define RTSDUR_BA 1 -#define RTSDUR_AA 2 -#define CTSDUR_BA 3 #define DATADUR_B 10 #define DATADUR_A 11 +static const u8 vnt_phy_signal[] = { + 0x00, /* RATE_1M */ + 0x01, /* RATE_2M */ + 0x02, /* RATE_5M */ + 0x03, /* RATE_11M */ + 0x8b, /* RATE_6M */ + 0x8f, /* RATE_9M */ + 0x8a, /* RATE_12M */ + 0x8e, /* RATE_18M */ + 0x89, /* RATE_24M */ + 0x8d, /* RATE_36M */ + 0x88, /* RATE_48M */ + 0x8c /* RATE_54M */ +}; + static struct vnt_usb_send_context *vnt_get_free_context(struct vnt_private *priv) { @@ -60,11 +69,6 @@ static struct vnt_usb_send_context context = priv->tx_context[ii]; if (!context->in_use) { context->in_use = true; - memset(context->data, 0, - MAX_TOTAL_SIZE_WITH_ALL_HEADERS); - - context->hdr = NULL; - return context; } } @@ -78,146 +82,105 @@ static struct vnt_usb_send_context return NULL; } -static __le16 vnt_time_stamp_off(struct vnt_private *priv, u16 rate) +/* Get Length, Service, and Signal fields of Phy for Tx */ +static void vnt_get_phy_field(struct vnt_private *priv, u32 frame_length, + u16 tx_rate, u8 pkt_type, + struct vnt_phy_field *phy) { - return cpu_to_le16(vnt_time_stampoff[priv->preamble_type % 2] - [rate % MAX_RATE]); -} + u32 bit_count; + u32 count = 0; + u32 tmp; + int ext_bit; + int i; + u8 mask = 0; + u8 preamble_type = priv->preamble_type; + + bit_count = frame_length * 8; + ext_bit = false; + + switch (tx_rate) { + case RATE_1M: + count = bit_count; + break; + case RATE_2M: + count = bit_count / 2; + break; + case RATE_5M: + count = DIV_ROUND_UP(bit_count * 10, 55); + break; + case RATE_11M: + count = bit_count / 11; + tmp = count * 11; -static u32 vnt_get_rsvtime(struct vnt_private *priv, u8 pkt_type, - u32 frame_length, u16 rate, int need_ack) -{ - u32 data_time, ack_time; + if (tmp != bit_count) { + count++; - data_time = vnt_get_frame_time(priv->preamble_type, pkt_type, - frame_length, rate); + if ((bit_count - tmp) <= 3) + ext_bit = true; + } + + break; + } - if (pkt_type == PK_TYPE_11B) - ack_time = vnt_get_frame_time(priv->preamble_type, pkt_type, 14, - (u16)priv->top_cck_basic_rate); - else - ack_time = vnt_get_frame_time(priv->preamble_type, pkt_type, 14, - (u16)priv->top_ofdm_basic_rate); + if (tx_rate > RATE_11M) { + if (pkt_type == PK_TYPE_11A) + mask = BIT(4); + } else if (tx_rate > RATE_1M) { + if (preamble_type == PREAMBLE_SHORT) + mask = BIT(3); + } - if (need_ack) - return data_time + priv->sifs + ack_time; + i = tx_rate > RATE_54M ? RATE_54M : tx_rate; + phy->signal = vnt_phy_signal[i] | mask; + phy->service = 0x00; - return data_time; + if (pkt_type == PK_TYPE_11B) { + if (ext_bit) + phy->service |= 0x80; + phy->len = cpu_to_le16((u16)count); + } else { + phy->len = cpu_to_le16((u16)frame_length); + } } -static __le16 vnt_rxtx_rsvtime_le16(struct vnt_private *priv, u8 pkt_type, - u32 frame_length, u16 rate, int need_ack) +static __le16 vnt_time_stamp_off(struct vnt_private *priv, u16 rate) { - return cpu_to_le16((u16)vnt_get_rsvtime(priv, pkt_type, - frame_length, rate, need_ack)); + return cpu_to_le16(vnt_time_stampoff[priv->preamble_type % 2] + [rate % MAX_RATE]); } -static __le16 vnt_get_rtscts_rsvtime_le(struct vnt_private *priv, u8 rsv_type, - u8 pkt_type, u32 frame_length, - u16 current_rate) +static __le16 vnt_rxtx_rsvtime_le16(struct vnt_usb_send_context *context) { - u32 rrv_time, rts_time, cts_time, ack_time, data_time; - - rrv_time = 0; - rts_time = 0; - cts_time = 0; - ack_time = 0; - - data_time = vnt_get_frame_time(priv->preamble_type, pkt_type, - frame_length, current_rate); - - if (rsv_type == 0) { - rts_time = vnt_get_frame_time(priv->preamble_type, pkt_type, - 20, priv->top_cck_basic_rate); - ack_time = vnt_get_frame_time(priv->preamble_type, - pkt_type, 14, - priv->top_cck_basic_rate); - cts_time = ack_time; - - } else if (rsv_type == 1) { - rts_time = vnt_get_frame_time(priv->preamble_type, pkt_type, - 20, priv->top_cck_basic_rate); - cts_time = vnt_get_frame_time(priv->preamble_type, pkt_type, - 14, priv->top_cck_basic_rate); - ack_time = vnt_get_frame_time(priv->preamble_type, pkt_type, - 14, priv->top_ofdm_basic_rate); - } else if (rsv_type == 2) { - rts_time = vnt_get_frame_time(priv->preamble_type, pkt_type, - 20, priv->top_ofdm_basic_rate); - ack_time = vnt_get_frame_time(priv->preamble_type, - pkt_type, 14, - priv->top_ofdm_basic_rate); - cts_time = ack_time; - - } else if (rsv_type == 3) { - cts_time = vnt_get_frame_time(priv->preamble_type, pkt_type, - 14, priv->top_cck_basic_rate); - ack_time = vnt_get_frame_time(priv->preamble_type, pkt_type, - 14, priv->top_ofdm_basic_rate); - - rrv_time = cts_time + ack_time + data_time + 2 * priv->sifs; - - return cpu_to_le16((u16)rrv_time); - } - - rrv_time = rts_time + cts_time + ack_time + data_time + 3 * priv->sifs; + struct vnt_private *priv = context->priv; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(context->skb); + struct ieee80211_rate *rate = ieee80211_get_tx_rate(priv->hw, info); - return cpu_to_le16((u16)rrv_time); + return ieee80211_generic_frame_duration(priv->hw, + info->control.vif, info->band, + context->frame_len, + rate); } -static __le16 vnt_get_rtscts_duration_le(struct vnt_usb_send_context *context, - u8 dur_type, u8 pkt_type, u16 rate) +static __le16 vnt_get_rts_duration(struct vnt_usb_send_context *context) { struct vnt_private *priv = context->priv; - u32 cts_time = 0, dur_time = 0; - u32 frame_length = context->frame_len; - u8 need_ack = context->need_ack; - - switch (dur_type) { - case RTSDUR_BB: - case RTSDUR_BA: - cts_time = vnt_get_frame_time(priv->preamble_type, pkt_type, - 14, priv->top_cck_basic_rate); - dur_time = cts_time + 2 * priv->sifs + - vnt_get_rsvtime(priv, pkt_type, - frame_length, rate, need_ack); - break; - - case RTSDUR_AA: - cts_time = vnt_get_frame_time(priv->preamble_type, pkt_type, - 14, priv->top_ofdm_basic_rate); - dur_time = cts_time + 2 * priv->sifs + - vnt_get_rsvtime(priv, pkt_type, - frame_length, rate, need_ack); - break; - - case CTSDUR_BA: - dur_time = priv->sifs + vnt_get_rsvtime(priv, - pkt_type, frame_length, rate, need_ack); - break; - - default: - break; - } + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(context->skb); - return cpu_to_le16((u16)dur_time); + return ieee80211_rts_duration(priv->hw, priv->vif, + context->frame_len, info); } -static u16 vnt_mac_hdr_pos(struct vnt_usb_send_context *tx_context, - struct ieee80211_hdr *hdr) +static __le16 vnt_get_cts_duration(struct vnt_usb_send_context *context) { - u8 *head = tx_context->data + offsetof(struct vnt_tx_buffer, fifo_head); - u8 *hdr_pos = (u8 *)hdr; - - tx_context->hdr = hdr; - if (!tx_context->hdr) - return 0; + struct vnt_private *priv = context->priv; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(context->skb); - return (u16)(hdr_pos - head); + return ieee80211_ctstoself_duration(priv->hw, priv->vif, + context->frame_len, info); } -static u16 vnt_rxtx_datahead_g(struct vnt_usb_send_context *tx_context, - struct vnt_tx_datahead_g *buf) +static void vnt_rxtx_datahead_g(struct vnt_usb_send_context *tx_context, + struct vnt_tx_datahead_g *buf) { struct vnt_private *priv = tx_context->priv; struct ieee80211_hdr *hdr = @@ -236,14 +199,10 @@ static u16 vnt_rxtx_datahead_g(struct vnt_usb_send_context *tx_context, buf->time_stamp_off_a = vnt_time_stamp_off(priv, rate); buf->time_stamp_off_b = vnt_time_stamp_off(priv, priv->top_cck_basic_rate); - - tx_context->tx_hdr_size = vnt_mac_hdr_pos(tx_context, &buf->hdr); - - return le16_to_cpu(buf->duration_a); } -static u16 vnt_rxtx_datahead_ab(struct vnt_usb_send_context *tx_context, - struct vnt_tx_datahead_ab *buf) +static void vnt_rxtx_datahead_ab(struct vnt_usb_send_context *tx_context, + struct vnt_tx_datahead_ab *buf) { struct vnt_private *priv = tx_context->priv; struct ieee80211_hdr *hdr = @@ -258,14 +217,10 @@ static u16 vnt_rxtx_datahead_ab(struct vnt_usb_send_context *tx_context, /* Get Duration and TimeStampOff */ buf->duration = hdr->duration_id; buf->time_stamp_off = vnt_time_stamp_off(priv, rate); - - tx_context->tx_hdr_size = vnt_mac_hdr_pos(tx_context, &buf->hdr); - - return le16_to_cpu(buf->duration); } -static int vnt_fill_ieee80211_rts(struct vnt_usb_send_context *tx_context, - struct ieee80211_rts *rts, __le16 duration) +static void vnt_fill_ieee80211_rts(struct vnt_usb_send_context *tx_context, + struct ieee80211_rts *rts, __le16 duration) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx_context->skb->data; @@ -276,72 +231,56 @@ static int vnt_fill_ieee80211_rts(struct vnt_usb_send_context *tx_context, ether_addr_copy(rts->ra, hdr->addr1); ether_addr_copy(rts->ta, hdr->addr2); - - return 0; } -static u16 vnt_rxtx_rts_g_head(struct vnt_usb_send_context *tx_context, - struct vnt_rts_g *buf) +static void vnt_rxtx_rts_g_head(struct vnt_usb_send_context *tx_context, + struct vnt_rts_g *buf) { struct vnt_private *priv = tx_context->priv; u16 rts_frame_len = 20; - u16 current_rate = tx_context->tx_rate; vnt_get_phy_field(priv, rts_frame_len, priv->top_cck_basic_rate, PK_TYPE_11B, &buf->b); vnt_get_phy_field(priv, rts_frame_len, priv->top_ofdm_basic_rate, tx_context->pkt_type, &buf->a); - buf->duration_bb = vnt_get_rtscts_duration_le(tx_context, RTSDUR_BB, - PK_TYPE_11B, - priv->top_cck_basic_rate); - buf->duration_aa = vnt_get_rtscts_duration_le(tx_context, RTSDUR_AA, - tx_context->pkt_type, - current_rate); - buf->duration_ba = vnt_get_rtscts_duration_le(tx_context, RTSDUR_BA, - tx_context->pkt_type, - current_rate); + buf->duration_bb = vnt_get_rts_duration(tx_context); + buf->duration_aa = buf->duration_bb; + buf->duration_ba = buf->duration_bb; vnt_fill_ieee80211_rts(tx_context, &buf->data, buf->duration_aa); - return vnt_rxtx_datahead_g(tx_context, &buf->data_head); + vnt_rxtx_datahead_g(tx_context, &buf->data_head); } -static u16 vnt_rxtx_rts_ab_head(struct vnt_usb_send_context *tx_context, - struct vnt_rts_ab *buf) +static void vnt_rxtx_rts_ab_head(struct vnt_usb_send_context *tx_context, + struct vnt_rts_ab *buf) { struct vnt_private *priv = tx_context->priv; - u16 current_rate = tx_context->tx_rate; u16 rts_frame_len = 20; vnt_get_phy_field(priv, rts_frame_len, priv->top_ofdm_basic_rate, tx_context->pkt_type, &buf->ab); - buf->duration = vnt_get_rtscts_duration_le(tx_context, RTSDUR_AA, - tx_context->pkt_type, - current_rate); + buf->duration = vnt_get_rts_duration(tx_context); vnt_fill_ieee80211_rts(tx_context, &buf->data, buf->duration); - return vnt_rxtx_datahead_ab(tx_context, &buf->data_head); + vnt_rxtx_datahead_ab(tx_context, &buf->data_head); } -static u16 vnt_fill_cts_head(struct vnt_usb_send_context *tx_context, - union vnt_tx_data_head *head) +static void vnt_fill_cts_head(struct vnt_usb_send_context *tx_context, + union vnt_tx_data_head *head) { struct vnt_private *priv = tx_context->priv; struct vnt_cts *buf = &head->cts_g; u32 cts_frame_len = 14; - u16 current_rate = tx_context->tx_rate; /* Get SignalField,ServiceField,Length */ vnt_get_phy_field(priv, cts_frame_len, priv->top_cck_basic_rate, PK_TYPE_11B, &buf->b); /* Get CTSDuration_ba */ - buf->duration_ba = - vnt_get_rtscts_duration_le(tx_context, CTSDUR_BA, - tx_context->pkt_type, - current_rate); + buf->duration_ba = vnt_get_cts_duration(tx_context); /*Get CTS Frame body*/ buf->data.duration = buf->duration_ba; buf->data.frame_control = @@ -349,127 +288,19 @@ static u16 vnt_fill_cts_head(struct vnt_usb_send_context *tx_context, ether_addr_copy(buf->data.ra, priv->current_net_addr); - return vnt_rxtx_datahead_g(tx_context, &buf->data_head); + vnt_rxtx_datahead_g(tx_context, &buf->data_head); } -static u16 vnt_rxtx_rts(struct vnt_usb_send_context *tx_context, - union vnt_tx_head *tx_head, bool need_mic) +/* returns true if mic_hdr is needed */ +static bool vnt_fill_txkey(struct vnt_tx_buffer *tx_buffer, struct sk_buff *skb) { - struct vnt_private *priv = tx_context->priv; - struct vnt_rrv_time_rts *buf = &tx_head->tx_rts.rts; - union vnt_tx_data_head *head = &tx_head->tx_rts.tx.head; - u32 frame_len = tx_context->frame_len; - u16 current_rate = tx_context->tx_rate; - u8 need_ack = tx_context->need_ack; - - buf->rts_rrv_time_aa = vnt_get_rtscts_rsvtime_le(priv, 2, - tx_context->pkt_type, frame_len, current_rate); - buf->rts_rrv_time_ba = vnt_get_rtscts_rsvtime_le(priv, 1, - tx_context->pkt_type, frame_len, current_rate); - buf->rts_rrv_time_bb = vnt_get_rtscts_rsvtime_le(priv, 0, - tx_context->pkt_type, frame_len, current_rate); - - buf->rrv_time_a = vnt_rxtx_rsvtime_le16(priv, tx_context->pkt_type, - frame_len, current_rate, - need_ack); - buf->rrv_time_b = vnt_rxtx_rsvtime_le16(priv, PK_TYPE_11B, frame_len, - priv->top_cck_basic_rate, need_ack); - - if (need_mic) - head = &tx_head->tx_rts.tx.mic.head; - - return vnt_rxtx_rts_g_head(tx_context, &head->rts_g); -} - -static u16 vnt_rxtx_cts(struct vnt_usb_send_context *tx_context, - union vnt_tx_head *tx_head, bool need_mic) -{ - struct vnt_private *priv = tx_context->priv; - struct vnt_rrv_time_cts *buf = &tx_head->tx_cts.cts; - union vnt_tx_data_head *head = &tx_head->tx_cts.tx.head; - u32 frame_len = tx_context->frame_len; - u16 current_rate = tx_context->tx_rate; - u8 need_ack = tx_context->need_ack; - - buf->rrv_time_a = vnt_rxtx_rsvtime_le16(priv, tx_context->pkt_type, - frame_len, current_rate, need_ack); - buf->rrv_time_b = vnt_rxtx_rsvtime_le16(priv, PK_TYPE_11B, - frame_len, priv->top_cck_basic_rate, need_ack); - - buf->cts_rrv_time_ba = vnt_get_rtscts_rsvtime_le(priv, 3, - tx_context->pkt_type, frame_len, current_rate); - - if (need_mic) - head = &tx_head->tx_cts.tx.mic.head; - - return vnt_fill_cts_head(tx_context, head); -} - -static u16 vnt_rxtx_ab(struct vnt_usb_send_context *tx_context, - union vnt_tx_head *tx_head, bool need_rts, bool need_mic) -{ - struct vnt_private *priv = tx_context->priv; - struct vnt_rrv_time_ab *buf = &tx_head->tx_ab.ab; - union vnt_tx_data_head *head = &tx_head->tx_ab.tx.head; - u32 frame_len = tx_context->frame_len; - u16 current_rate = tx_context->tx_rate; - u8 need_ack = tx_context->need_ack; - - buf->rrv_time = vnt_rxtx_rsvtime_le16(priv, tx_context->pkt_type, - frame_len, current_rate, need_ack); - - if (need_mic) - head = &tx_head->tx_ab.tx.mic.head; - - if (need_rts) { - if (tx_context->pkt_type == PK_TYPE_11B) - buf->rts_rrv_time = vnt_get_rtscts_rsvtime_le(priv, 0, - tx_context->pkt_type, frame_len, current_rate); - else /* PK_TYPE_11A */ - buf->rts_rrv_time = vnt_get_rtscts_rsvtime_le(priv, 2, - tx_context->pkt_type, frame_len, current_rate); - - return vnt_rxtx_rts_ab_head(tx_context, &head->rts_ab); - } - - return vnt_rxtx_datahead_ab(tx_context, &head->data_head_ab); -} - -static u16 vnt_generate_tx_parameter(struct vnt_usb_send_context *tx_context, - struct vnt_tx_buffer *tx_buffer, - struct vnt_mic_hdr **mic_hdr, u32 need_mic, - bool need_rts) -{ - if (tx_context->pkt_type == PK_TYPE_11GB || - tx_context->pkt_type == PK_TYPE_11GA) { - if (need_rts) { - if (need_mic) - *mic_hdr = - &tx_buffer->tx_head.tx_rts.tx.mic.hdr; - - return vnt_rxtx_rts(tx_context, &tx_buffer->tx_head, - need_mic); - } - - if (need_mic) - *mic_hdr = &tx_buffer->tx_head.tx_cts.tx.mic.hdr; - - return vnt_rxtx_cts(tx_context, &tx_buffer->tx_head, need_mic); - } - - if (need_mic) - *mic_hdr = &tx_buffer->tx_head.tx_ab.tx.mic.hdr; - - return vnt_rxtx_ab(tx_context, &tx_buffer->tx_head, need_rts, need_mic); -} - -static void vnt_fill_txkey(struct vnt_usb_send_context *tx_context, - u8 *key_buffer, struct ieee80211_key_conf *tx_key, - struct sk_buff *skb, u16 payload_len, - struct vnt_mic_hdr *mic_hdr) -{ - struct ieee80211_hdr *hdr = tx_context->hdr; + struct vnt_tx_fifo_head *fifo = &tx_buffer->fifo_head; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_key_conf *tx_key = info->control.hw_key; + struct vnt_mic_hdr *mic_hdr; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; u64 pn64; + u16 payload_len = skb->len; u8 *iv = ((u8 *)hdr + ieee80211_get_hdrlen_from_skb(skb)); /* strip header and icv len from payload */ @@ -479,24 +310,31 @@ static void vnt_fill_txkey(struct vnt_usb_send_context *tx_context, 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); + memcpy(fifo->tx_key, iv, 3); + memcpy(fifo->tx_key + 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, + memcpy(fifo->tx_key + 8, iv, 3); + memcpy(fifo->tx_key + 11, tx_key->key, WLAN_KEY_LEN_WEP40); } + fifo->frag_ctl |= cpu_to_le16(FRAGCTL_LEGACY); break; case WLAN_CIPHER_SUITE_TKIP: - ieee80211_get_tkip_p2k(tx_key, skb, key_buffer); + ieee80211_get_tkip_p2k(tx_key, skb, fifo->tx_key); + fifo->frag_ctl |= cpu_to_le16(FRAGCTL_TKIP); break; case WLAN_CIPHER_SUITE_CCMP: - - if (!mic_hdr) - return; + if (info->control.use_cts_prot) { + if (info->control.use_rts) + mic_hdr = &tx_buffer->tx_head.tx_rts.tx.mic.hdr; + else + mic_hdr = &tx_buffer->tx_head.tx_cts.tx.mic.hdr; + } else { + mic_hdr = &tx_buffer->tx_head.tx_ab.tx.mic.hdr; + } mic_hdr->id = 0x59; mic_hdr->payload_len = cpu_to_be16(payload_len); @@ -527,12 +365,137 @@ static void vnt_fill_txkey(struct vnt_usb_send_context *tx_context, 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); + memcpy(fifo->tx_key, tx_key->key, WLAN_KEY_LEN_CCMP); - break; + fifo->frag_ctl |= cpu_to_le16(FRAGCTL_AES); + return true; default: break; } + + return false; +} + +static void vnt_rxtx_rts(struct vnt_usb_send_context *tx_context) +{ + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_context->skb); + struct vnt_tx_buffer *tx_buffer = tx_context->tx_buffer; + union vnt_tx_head *tx_head = &tx_buffer->tx_head; + struct vnt_rrv_time_rts *buf = &tx_head->tx_rts.rts; + union vnt_tx_data_head *head = &tx_head->tx_rts.tx.head; + + buf->rts_rrv_time_aa = vnt_get_rts_duration(tx_context); + buf->rts_rrv_time_ba = buf->rts_rrv_time_aa; + buf->rts_rrv_time_bb = buf->rts_rrv_time_aa; + + buf->rrv_time_a = vnt_rxtx_rsvtime_le16(tx_context); + buf->rrv_time_b = buf->rrv_time_a; + + if (info->control.hw_key) { + if (vnt_fill_txkey(tx_buffer, tx_context->skb)) + head = &tx_head->tx_rts.tx.mic.head; + } + + vnt_rxtx_rts_g_head(tx_context, &head->rts_g); +} + +static void vnt_rxtx_cts(struct vnt_usb_send_context *tx_context) +{ + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_context->skb); + struct vnt_tx_buffer *tx_buffer = tx_context->tx_buffer; + union vnt_tx_head *tx_head = &tx_buffer->tx_head; + struct vnt_rrv_time_cts *buf = &tx_head->tx_cts.cts; + union vnt_tx_data_head *head = &tx_head->tx_cts.tx.head; + + buf->rrv_time_a = vnt_rxtx_rsvtime_le16(tx_context); + buf->rrv_time_b = buf->rrv_time_a; + + buf->cts_rrv_time_ba = vnt_get_cts_duration(tx_context); + + if (info->control.hw_key) { + if (vnt_fill_txkey(tx_buffer, tx_context->skb)) + head = &tx_head->tx_cts.tx.mic.head; + } + + vnt_fill_cts_head(tx_context, head); +} + +static void vnt_rxtx_ab(struct vnt_usb_send_context *tx_context) +{ + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_context->skb); + struct vnt_tx_buffer *tx_buffer = tx_context->tx_buffer; + union vnt_tx_head *tx_head = &tx_buffer->tx_head; + struct vnt_rrv_time_ab *buf = &tx_head->tx_ab.ab; + union vnt_tx_data_head *head = &tx_head->tx_ab.tx.head; + + buf->rrv_time = vnt_rxtx_rsvtime_le16(tx_context); + + if (info->control.hw_key) { + if (vnt_fill_txkey(tx_buffer, tx_context->skb)) + head = &tx_head->tx_ab.tx.mic.head; + } + + if (info->control.use_rts) { + buf->rts_rrv_time = vnt_get_rts_duration(tx_context); + + vnt_rxtx_rts_ab_head(tx_context, &head->rts_ab); + + return; + } + + vnt_rxtx_datahead_ab(tx_context, &head->data_head_ab); +} + +static void vnt_generate_tx_parameter(struct vnt_usb_send_context *tx_context) +{ + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_context->skb); + + if (info->control.use_cts_prot) { + if (info->control.use_rts) { + vnt_rxtx_rts(tx_context); + + return; + } + + vnt_rxtx_cts(tx_context); + + return; + } + + vnt_rxtx_ab(tx_context); +} + +static u16 vnt_get_hdr_size(struct ieee80211_tx_info *info) +{ + u16 size = sizeof(struct vnt_tx_datahead_ab); + + if (info->control.use_cts_prot) { + if (info->control.use_rts) + size = sizeof(struct vnt_rts_g); + else + size = sizeof(struct vnt_cts); + } else if (info->control.use_rts) { + size = sizeof(struct vnt_rts_ab); + } + + if (info->control.hw_key) { + if (info->control.hw_key->cipher == WLAN_CIPHER_SUITE_CCMP) + size += sizeof(struct vnt_mic_hdr); + } + + /* Get rrv_time header */ + if (info->control.use_cts_prot) { + if (info->control.use_rts) + size += sizeof(struct vnt_rrv_time_rts); + else + size += sizeof(struct vnt_rrv_time_cts); + } else { + size += sizeof(struct vnt_rrv_time_ab); + } + + size += sizeof(struct vnt_tx_fifo_head); + + return size; } int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb) @@ -540,30 +503,18 @@ int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb) 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_mic_hdr *mic_hdr = NULL; struct vnt_tx_buffer *tx_buffer; struct vnt_tx_fifo_head *tx_buffer_head; struct vnt_usb_send_context *tx_context; unsigned long flags; - u16 tx_bytes, tx_header_size, tx_body_size, current_rate, duration_id; u8 pkt_type; - bool need_rts = false; - bool need_mic = false; hdr = (struct ieee80211_hdr *)(skb->data); rate = ieee80211_get_tx_rate(priv->hw, info); - current_rate = rate->hw_value; - if (priv->current_rate != current_rate && - !(priv->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) { - priv->current_rate = current_rate; - vnt_schedule_command(priv, WLAN_CMD_SETPOWER); - } - - if (current_rate > RATE_11M) { + if (rate->hw_value > RATE_11M) { if (info->band == NL80211_BAND_5GHZ) { pkt_type = PK_TYPE_11A; } else { @@ -589,17 +540,23 @@ int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb) return -ENOMEM; } - tx_context->skb = skb; tx_context->pkt_type = pkt_type; - tx_context->need_ack = false; tx_context->frame_len = skb->len + 4; - tx_context->tx_rate = current_rate; + tx_context->tx_rate = rate->hw_value; spin_unlock_irqrestore(&priv->lock, flags); - tx_buffer = (struct vnt_tx_buffer *)tx_context->data; + tx_context->skb = skb_clone(skb, GFP_ATOMIC); + if (!tx_context->skb) { + tx_context->in_use = false; + return -ENOMEM; + } + + tx_buffer = skb_push(skb, vnt_get_hdr_size(info)); + tx_context->tx_buffer = tx_buffer; tx_buffer_head = &tx_buffer->fifo_head; - tx_body_size = skb->len; + + tx_context->type = CONTEXT_DATA_PACKET; /*Set fifo controls */ if (pkt_type == PK_TYPE_11A) @@ -623,92 +580,43 @@ int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb) cpu_to_le16(DEFAULT_MSDU_LIFETIME_RES_64us); } - if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) { + if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_NEEDACK); - tx_context->need_ack = true; - } 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) { - need_rts = true; + if (info->control.use_rts) 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); tx_buffer_head->frag_ctl = - cpu_to_le16(ieee80211_get_hdrlen_from_skb(skb) << 10); + cpu_to_le16(ieee80211_hdrlen(hdr->frame_control) << 10); - if (info->control.hw_key) { - tx_key = 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); - need_mic = true; - default: - break; - } - tx_context->frame_len += tx_key->icv_len; - } + if (info->control.hw_key) + tx_context->frame_len += info->control.hw_key->icv_len; - tx_buffer_head->current_rate = cpu_to_le16(current_rate); + tx_buffer_head->current_rate = cpu_to_le16(rate->hw_value); - duration_id = vnt_generate_tx_parameter(tx_context, tx_buffer, &mic_hdr, - need_mic, need_rts); - - tx_header_size = tx_context->tx_hdr_size; - if (!tx_header_size) { - tx_context->in_use = false; - return -ENOMEM; - } + vnt_generate_tx_parameter(tx_context); tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_NONFRAG); - tx_bytes = tx_header_size + tx_body_size; - - memcpy(tx_context->hdr, skb->data, tx_body_size); - - if (info->control.hw_key) { - tx_key = info->control.hw_key; - if (tx_key->keylen > 0) - vnt_fill_txkey(tx_context, tx_buffer_head->tx_key, - tx_key, skb, tx_body_size, mic_hdr); - } - priv->seq_counter = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; - tx_buffer->tx_byte_count = cpu_to_le16(tx_bytes); - tx_buffer->pkt_no = tx_context->pkt_no; - tx_buffer->type = 0x00; - - tx_bytes += 4; - - tx_context->type = CONTEXT_DATA_PACKET; - tx_context->buf_len = tx_bytes; - spin_lock_irqsave(&priv->lock, flags); - if (vnt_tx_context(priv, tx_context)) { + if (vnt_tx_context(priv, tx_context, skb)) { + dev_kfree_skb(tx_context->skb); spin_unlock_irqrestore(&priv->lock, flags); return -EIO; } + dev_kfree_skb(skb); + spin_unlock_irqrestore(&priv->lock, flags); return 0; @@ -716,14 +624,13 @@ int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb) static int vnt_beacon_xmit(struct vnt_private *priv, struct sk_buff *skb) { - struct vnt_beacon_buffer *beacon_buffer; struct vnt_tx_short_buf_head *short_head; struct ieee80211_tx_info *info; struct vnt_usb_send_context *context; struct ieee80211_mgmt *mgmt_hdr; unsigned long flags; u32 frame_size = skb->len + 4; - u16 current_rate, count; + u16 current_rate; spin_lock_irqsave(&priv->lock, flags); @@ -738,8 +645,8 @@ static int vnt_beacon_xmit(struct vnt_private *priv, struct sk_buff *skb) spin_unlock_irqrestore(&priv->lock, flags); - beacon_buffer = (struct vnt_beacon_buffer *)&context->data[0]; - short_head = &beacon_buffer->short_head; + mgmt_hdr = (struct ieee80211_mgmt *)skb->data; + short_head = skb_push(skb, sizeof(*short_head)); if (priv->bb_type == BB_TYPE_11A) { current_rate = RATE_6M; @@ -764,10 +671,6 @@ static int vnt_beacon_xmit(struct vnt_private *priv, struct sk_buff *skb) vnt_time_stamp_off(priv, current_rate); } - /* Generate Beacon Header */ - mgmt_hdr = &beacon_buffer->mgmt_hdr; - memcpy(mgmt_hdr, skb->data, skb->len); - /* Get Duration */ short_head->duration = mgmt_hdr->duration; @@ -786,18 +689,11 @@ static int vnt_beacon_xmit(struct vnt_private *priv, struct sk_buff *skb) if (priv->seq_counter > 0x0fff) priv->seq_counter = 0; - count = sizeof(struct vnt_tx_short_buf_head) + skb->len; - - beacon_buffer->tx_byte_count = cpu_to_le16(count); - beacon_buffer->pkt_no = context->pkt_no; - beacon_buffer->type = 0x01; - context->type = CONTEXT_BEACON_PACKET; - context->buf_len = count + 4; /* USB header */ spin_lock_irqsave(&priv->lock, flags); - if (vnt_tx_context(priv, context)) + if (vnt_tx_context(priv, context, skb)) ieee80211_free_txskb(priv->hw, context->skb); spin_unlock_irqrestore(&priv->lock, flags); diff --git a/drivers/staging/vt6656/rxtx.h b/drivers/staging/vt6656/rxtx.h index 0e6226af7d41..6ca2ca32d036 100644 --- a/drivers/staging/vt6656/rxtx.h +++ b/drivers/staging/vt6656/rxtx.h @@ -23,6 +23,13 @@ #define DEFAULT_MGN_LIFETIME_RES_64us 125 /* 64us */ #define DEFAULT_MSDU_LIFETIME_RES_64us 8000 +/* Length, Service, and Signal fields of Phy for Tx */ +struct vnt_phy_field { + u8 signal; + u8 service; + __le16 len; +} __packed; + /* MIC HDR data header */ struct vnt_mic_hdr { u8 id; @@ -70,14 +77,12 @@ struct vnt_tx_datahead_g { __le16 duration_a; __le16 time_stamp_off_b; __le16 time_stamp_off_a; - struct ieee80211_hdr hdr; } __packed; struct vnt_tx_datahead_ab { struct vnt_phy_field ab; __le16 duration; __le16 time_stamp_off; - struct ieee80211_hdr hdr; } __packed; /* RTS buffer header */ @@ -155,9 +160,6 @@ struct vnt_tx_fifo_head { } __packed; struct vnt_tx_buffer { - u8 type; - u8 pkt_no; - __le16 tx_byte_count; struct vnt_tx_fifo_head fifo_head; union vnt_tx_head tx_head; } __packed; @@ -170,14 +172,6 @@ struct vnt_tx_short_buf_head { __le16 time_stamp_off; } __packed; -struct vnt_beacon_buffer { - u8 type; - u8 pkt_no; - __le16 tx_byte_count; - struct vnt_tx_short_buf_head short_head; - struct ieee80211_mgmt mgmt_hdr; -} __packed; - int vnt_tx_packet(struct vnt_private *priv, 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, diff --git a/drivers/staging/vt6656/usbpipe.c b/drivers/staging/vt6656/usbpipe.c index 91b62c3dff7b..82b774be6485 100644 --- a/drivers/staging/vt6656/usbpipe.c +++ b/drivers/staging/vt6656/usbpipe.c @@ -77,7 +77,7 @@ int vnt_control_out_u8(struct vnt_private *priv, u8 reg, u8 reg_off, u8 data) } int vnt_control_out_blocks(struct vnt_private *priv, - u16 block, u8 reg, u16 length, u8 *data) + u16 block, u8 reg, u16 length, const u8 *data) { int ret = 0, i; @@ -196,32 +196,18 @@ static void vnt_int_process_data(struct vnt_private *priv) if (int_data->tsr3 & TSR_VALID) vnt_int_report_rate(priv, int_data->pkt3, int_data->tsr3); - if (int_data->isr0 != 0) { - if (int_data->isr0 & ISR_BNTX && - priv->op_mode == NL80211_IFTYPE_AP) - vnt_schedule_command(priv, WLAN_CMD_BECON_SEND); - - if (int_data->isr0 & ISR_TBTT && - priv->hw->conf.flags & IEEE80211_CONF_PS) { - if (!priv->wake_up_count) - priv->wake_up_count = - priv->hw->conf.listen_interval; + if (!int_data->isr0) + return; - if (priv->wake_up_count) - --priv->wake_up_count; + if (int_data->isr0 & ISR_BNTX && priv->op_mode == NL80211_IFTYPE_AP) + vnt_schedule_command(priv, WLAN_CMD_BECON_SEND); - /* Turn on wake up to listen next beacon */ - if (priv->wake_up_count == 1) - vnt_schedule_command(priv, - WLAN_CMD_TBTT_WAKEUP); - } - priv->current_tsf = le64_to_cpu(int_data->tsf); + priv->current_tsf = le64_to_cpu(int_data->tsf); - low_stats->dot11RTSSuccessCount += int_data->rts_success; - low_stats->dot11RTSFailureCount += int_data->rts_fail; - low_stats->dot11ACKFailureCount += int_data->ack_fail; - low_stats->dot11FCSErrorCount += int_data->fcs_err; - } + low_stats->dot11RTSSuccessCount += int_data->rts_success; + low_stats->dot11RTSFailureCount += int_data->rts_fail; + low_stats->dot11ACKFailureCount += int_data->ack_fail; + low_stats->dot11FCSErrorCount += int_data->fcs_err; } static void vnt_start_interrupt_urb_complete(struct urb *urb) @@ -442,7 +428,8 @@ static void vnt_tx_context_complete(struct urb *urb) switch (urb->status) { case 0: - dev_dbg(&priv->usb->dev, "Write %d bytes\n", context->buf_len); + dev_dbg(&priv->usb->dev, + "Write %d bytes\n", urb->actual_length); break; case -ECONNRESET: case -ENOENT: @@ -467,30 +454,53 @@ static void vnt_tx_context_complete(struct urb *urb) } int vnt_tx_context(struct vnt_private *priv, - struct vnt_usb_send_context *context) + struct vnt_usb_send_context *context, + struct sk_buff *skb) { + struct vnt_tx_usb_header *usb; + struct urb *urb; int status; - struct urb *urb = context->urb; + u16 count = skb->len; + + usb = skb_push(skb, sizeof(*usb)); + usb->tx_byte_count = cpu_to_le16(count); + usb->pkt_no = context->pkt_no; + usb->type = context->type; if (test_bit(DEVICE_FLAGS_DISCONNECTED, &priv->flags)) { context->in_use = false; return -ENODEV; } + if (skb->len > MAX_TOTAL_SIZE_WITH_ALL_HEADERS) { + context->in_use = false; + return -E2BIG; + } + + urb = usb_alloc_urb(0, GFP_ATOMIC); + if (!urb) { + context->in_use = false; + return -ENOMEM; + } + usb_fill_bulk_urb(urb, priv->usb, usb_sndbulkpipe(priv->usb, 3), - context->data, - context->buf_len, + skb->data, + skb->len, vnt_tx_context_complete, context); + usb_anchor_urb(urb, &priv->tx_submitted); + status = usb_submit_urb(urb, GFP_ATOMIC); if (status) { dev_dbg(&priv->usb->dev, "Submit Tx URB failed %d\n", status); - + usb_unanchor_urb(urb); context->in_use = false; } + usb_free_urb(urb); + return status; } diff --git a/drivers/staging/vt6656/usbpipe.h b/drivers/staging/vt6656/usbpipe.h index 35697b58d748..52c2a928c9c1 100644 --- a/drivers/staging/vt6656/usbpipe.h +++ b/drivers/staging/vt6656/usbpipe.h @@ -41,6 +41,12 @@ struct vnt_interrupt_data { u8 sw[2]; } __packed; +struct vnt_tx_usb_header { + u8 type; + u8 pkt_no; + __le16 tx_byte_count; +} __packed; + #define VNT_REG_BLOCK_SIZE 64 int vnt_control_out(struct vnt_private *priv, u8 request, u16 value, @@ -52,11 +58,12 @@ int vnt_control_out_u8(struct vnt_private *priv, u8 reg, u8 ref_off, u8 data); int vnt_control_in_u8(struct vnt_private *priv, u8 reg, u8 reg_off, u8 *data); int vnt_control_out_blocks(struct vnt_private *priv, - u16 block, u8 reg, u16 len, u8 *data); + u16 block, u8 reg, u16 len, const u8 *data); int vnt_start_interrupt_urb(struct vnt_private *priv); int vnt_submit_rx_urb(struct vnt_private *priv, struct vnt_rcb *rcb); int vnt_tx_context(struct vnt_private *priv, - struct vnt_usb_send_context *context); + struct vnt_usb_send_context *context, + struct sk_buff *skb); #endif /* __USBPIPE_H__ */ diff --git a/drivers/staging/vt6656/wcmd.c b/drivers/staging/vt6656/wcmd.c index 2c5250ca2801..0ccc87da394e 100644 --- a/drivers/staging/vt6656/wcmd.c +++ b/drivers/staging/vt6656/wcmd.c @@ -122,8 +122,7 @@ void vnt_run_command(struct work_struct *work) case WLAN_CMD_SETPOWER_START: - vnt_rf_setpower(priv, priv->current_rate, - priv->hw->conf.chandef.chan->hw_value); + vnt_rf_setpower(priv, priv->hw->conf.chandef.chan); break; |