Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem

This commit is contained in:
John W. Linville 2011-02-22 15:10:22 -05:00
commit 5db5e44cdc
153 changed files with 22694 additions and 6362 deletions

View File

@ -35,6 +35,17 @@ Who: Luis R. Rodriguez <lrodriguez@atheros.com>
---------------------------
What: AR9170USB
When: 2.6.40
Why: This driver is deprecated and the firmware is no longer
maintained. The replacement driver "carl9170" has been
around for a while, so the devices are still supported.
Who: Christian Lamparter <chunkeey@googlemail.com>
---------------------------
What: IRQF_SAMPLE_RANDOM
Check: IRQF_SAMPLE_RANDOM
When: July 2009

View File

@ -1205,7 +1205,7 @@ ATHEROS AR9170 WIRELESS DRIVER
M: Christian Lamparter <chunkeey@web.de>
L: linux-wireless@vger.kernel.org
W: http://wireless.kernel.org/en/users/Drivers/ar9170
S: Maintained
S: Obsolete
F: drivers/net/wireless/ath/ar9170/
CARL9170 LINUX COMMUNITY WIRELESS DRIVER

View File

@ -31,6 +31,30 @@
#define VERSION "1.0"
#define ATH3K_DNLOAD 0x01
#define ATH3K_GETSTATE 0x05
#define ATH3K_SET_NORMAL_MODE 0x07
#define ATH3K_GETVERSION 0x09
#define USB_REG_SWITCH_VID_PID 0x0a
#define ATH3K_MODE_MASK 0x3F
#define ATH3K_NORMAL_MODE 0x0E
#define ATH3K_PATCH_UPDATE 0x80
#define ATH3K_SYSCFG_UPDATE 0x40
#define ATH3K_XTAL_FREQ_26M 0x00
#define ATH3K_XTAL_FREQ_40M 0x01
#define ATH3K_XTAL_FREQ_19P2 0x02
#define ATH3K_NAME_LEN 0xFF
struct ath3k_version {
unsigned int rom_version;
unsigned int build_version;
unsigned int ram_version;
unsigned char ref_clock;
unsigned char reserved[0x07];
};
static struct usb_device_id ath3k_table[] = {
/* Atheros AR3011 */
@ -41,13 +65,32 @@ static struct usb_device_id ath3k_table[] = {
/* Atheros AR9285 Malbec with sflash firmware */
{ USB_DEVICE(0x03F0, 0x311D) },
/* Atheros AR3012 with sflash firmware*/
{ USB_DEVICE(0x0CF3, 0x3004) },
/* Atheros AR5BBU12 with sflash firmware */
{ USB_DEVICE(0x0489, 0xE02C) },
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, ath3k_table);
#define BTUSB_ATH3012 0x80
/* This table is to load patch and sysconfig files
* for AR3012 */
static struct usb_device_id ath3k_blist_tbl[] = {
/* Atheros AR3012 with sflash firmware*/
{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
{ } /* Terminating entry */
};
#define USB_REQ_DFU_DNLOAD 1
#define BULK_SIZE 4096
#define FW_HDR_SIZE 20
static int ath3k_load_firmware(struct usb_device *udev,
const struct firmware *firmware)
@ -103,28 +146,265 @@ error:
return err;
}
static int ath3k_get_state(struct usb_device *udev, unsigned char *state)
{
int pipe = 0;
pipe = usb_rcvctrlpipe(udev, 0);
return usb_control_msg(udev, pipe, ATH3K_GETSTATE,
USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
state, 0x01, USB_CTRL_SET_TIMEOUT);
}
static int ath3k_get_version(struct usb_device *udev,
struct ath3k_version *version)
{
int pipe = 0;
pipe = usb_rcvctrlpipe(udev, 0);
return usb_control_msg(udev, pipe, ATH3K_GETVERSION,
USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, version,
sizeof(struct ath3k_version),
USB_CTRL_SET_TIMEOUT);
}
static int ath3k_load_fwfile(struct usb_device *udev,
const struct firmware *firmware)
{
u8 *send_buf;
int err, pipe, len, size, count, sent = 0;
int ret;
count = firmware->size;
send_buf = kmalloc(BULK_SIZE, GFP_ATOMIC);
if (!send_buf) {
BT_ERR("Can't allocate memory chunk for firmware");
return -ENOMEM;
}
size = min_t(uint, count, FW_HDR_SIZE);
memcpy(send_buf, firmware->data, size);
pipe = usb_sndctrlpipe(udev, 0);
ret = usb_control_msg(udev, pipe, ATH3K_DNLOAD,
USB_TYPE_VENDOR, 0, 0, send_buf,
size, USB_CTRL_SET_TIMEOUT);
if (ret < 0) {
BT_ERR("Can't change to loading configuration err");
kfree(send_buf);
return ret;
}
sent += size;
count -= size;
while (count) {
size = min_t(uint, count, BULK_SIZE);
pipe = usb_sndbulkpipe(udev, 0x02);
memcpy(send_buf, firmware->data + sent, size);
err = usb_bulk_msg(udev, pipe, send_buf, size,
&len, 3000);
if (err || (len != size)) {
BT_ERR("Error in firmware loading err = %d,"
"len = %d, size = %d", err, len, size);
kfree(send_buf);
return err;
}
sent += size;
count -= size;
}
kfree(send_buf);
return 0;
}
static int ath3k_switch_pid(struct usb_device *udev)
{
int pipe = 0;
pipe = usb_sndctrlpipe(udev, 0);
return usb_control_msg(udev, pipe, USB_REG_SWITCH_VID_PID,
USB_TYPE_VENDOR, 0, 0,
NULL, 0, USB_CTRL_SET_TIMEOUT);
}
static int ath3k_set_normal_mode(struct usb_device *udev)
{
unsigned char fw_state;
int pipe = 0, ret;
ret = ath3k_get_state(udev, &fw_state);
if (ret < 0) {
BT_ERR("Can't get state to change to normal mode err");
return ret;
}
if ((fw_state & ATH3K_MODE_MASK) == ATH3K_NORMAL_MODE) {
BT_DBG("firmware was already in normal mode");
return 0;
}
pipe = usb_sndctrlpipe(udev, 0);
return usb_control_msg(udev, pipe, ATH3K_SET_NORMAL_MODE,
USB_TYPE_VENDOR, 0, 0,
NULL, 0, USB_CTRL_SET_TIMEOUT);
}
static int ath3k_load_patch(struct usb_device *udev)
{
unsigned char fw_state;
char filename[ATH3K_NAME_LEN] = {0};
const struct firmware *firmware;
struct ath3k_version fw_version, pt_version;
int ret;
ret = ath3k_get_state(udev, &fw_state);
if (ret < 0) {
BT_ERR("Can't get state to change to load ram patch err");
return ret;
}
if (fw_state & ATH3K_PATCH_UPDATE) {
BT_DBG("Patch was already downloaded");
return 0;
}
ret = ath3k_get_version(udev, &fw_version);
if (ret < 0) {
BT_ERR("Can't get version to change to load ram patch err");
return ret;
}
snprintf(filename, ATH3K_NAME_LEN, "ar3k/AthrBT_0x%08x.dfu",
fw_version.rom_version);
ret = request_firmware(&firmware, filename, &udev->dev);
if (ret < 0) {
BT_ERR("Patch file not found %s", filename);
return ret;
}
pt_version.rom_version = *(int *)(firmware->data + firmware->size - 8);
pt_version.build_version = *(int *)
(firmware->data + firmware->size - 4);
if ((pt_version.rom_version != fw_version.rom_version) ||
(pt_version.build_version <= fw_version.build_version)) {
BT_ERR("Patch file version did not match with firmware");
release_firmware(firmware);
return -EINVAL;
}
ret = ath3k_load_fwfile(udev, firmware);
release_firmware(firmware);
return ret;
}
static int ath3k_load_syscfg(struct usb_device *udev)
{
unsigned char fw_state;
char filename[ATH3K_NAME_LEN] = {0};
const struct firmware *firmware;
struct ath3k_version fw_version;
int clk_value, ret;
ret = ath3k_get_state(udev, &fw_state);
if (ret < 0) {
BT_ERR("Can't get state to change to load configration err");
return -EBUSY;
}
ret = ath3k_get_version(udev, &fw_version);
if (ret < 0) {
BT_ERR("Can't get version to change to load ram patch err");
return ret;
}
switch (fw_version.ref_clock) {
case ATH3K_XTAL_FREQ_26M:
clk_value = 26;
break;
case ATH3K_XTAL_FREQ_40M:
clk_value = 40;
break;
case ATH3K_XTAL_FREQ_19P2:
clk_value = 19;
break;
default:
clk_value = 0;
break;
}
snprintf(filename, ATH3K_NAME_LEN, "ar3k/ramps_0x%08x_%d%s",
fw_version.rom_version, clk_value, ".dfu");
ret = request_firmware(&firmware, filename, &udev->dev);
if (ret < 0) {
BT_ERR("Configuration file not found %s", filename);
return ret;
}
ret = ath3k_load_fwfile(udev, firmware);
release_firmware(firmware);
return ret;
}
static int ath3k_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
const struct firmware *firmware;
struct usb_device *udev = interface_to_usbdev(intf);
int ret;
BT_DBG("intf %p id %p", intf, id);
if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
return -ENODEV;
/* match device ID in ath3k blacklist table */
if (!id->driver_info) {
const struct usb_device_id *match;
match = usb_match_id(intf, ath3k_blist_tbl);
if (match)
id = match;
}
/* load patch and sysconfig files for AR3012 */
if (id->driver_info & BTUSB_ATH3012) {
ret = ath3k_load_patch(udev);
if (ret < 0) {
BT_ERR("Loading patch file failed");
return ret;
}
ret = ath3k_load_syscfg(udev);
if (ret < 0) {
BT_ERR("Loading sysconfig file failed");
return ret;
}
ret = ath3k_set_normal_mode(udev);
if (ret < 0) {
BT_ERR("Set normal mode failed");
return ret;
}
ath3k_switch_pid(udev);
return 0;
}
if (request_firmware(&firmware, "ath3k-1.fw", &udev->dev) < 0) {
BT_ERR("Error loading firmware");
return -EIO;
}
if (ath3k_load_firmware(udev, firmware)) {
release_firmware(firmware);
return -EIO;
}
ret = ath3k_load_firmware(udev, firmware);
release_firmware(firmware);
return 0;
return ret;
}
static void ath3k_disconnect(struct usb_interface *intf)

View File

@ -105,6 +105,12 @@ static struct usb_device_id blacklist_table[] = {
/* Atheros AR9285 Malbec with sflash firmware */
{ USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE },
/* Atheros 3012 with sflash firmware */
{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_IGNORE },
/* Atheros AR5BBU12 with sflash firmware */
{ USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },
/* Broadcom BCM2035 */
{ USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU },
{ USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_WRONG_SCO_MTU },
@ -711,15 +717,11 @@ static int btusb_send_frame(struct sk_buff *skb)
pipe = usb_sndisocpipe(data->udev,
data->isoc_tx_ep->bEndpointAddress);
urb->dev = data->udev;
urb->pipe = pipe;
urb->context = skb;
urb->complete = btusb_isoc_tx_complete;
urb->interval = data->isoc_tx_ep->bInterval;
usb_fill_int_urb(urb, data->udev, pipe,
skb->data, skb->len, btusb_isoc_tx_complete,
skb, data->isoc_tx_ep->bInterval);
urb->transfer_flags = URB_ISO_ASAP;
urb->transfer_buffer = skb->data;
urb->transfer_buffer_length = skb->len;
__fill_isoc_descriptor(urb, skb->len,
le16_to_cpu(data->isoc_tx_ep->wMaxPacketSize));
@ -829,7 +831,7 @@ static void btusb_work(struct work_struct *work)
if (hdev->conn_hash.sco_num > 0) {
if (!test_bit(BTUSB_DID_ISO_RESUME, &data->flags)) {
err = usb_autopm_get_interface(data->isoc);
err = usb_autopm_get_interface(data->isoc ? data->isoc : data->intf);
if (err < 0) {
clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
usb_kill_anchored_urbs(&data->isoc_anchor);
@ -858,7 +860,7 @@ static void btusb_work(struct work_struct *work)
__set_isoc_interface(hdev, 0);
if (test_and_clear_bit(BTUSB_DID_ISO_RESUME, &data->flags))
usb_autopm_put_interface(data->isoc);
usb_autopm_put_interface(data->isoc ? data->isoc : data->intf);
}
}

View File

@ -398,6 +398,7 @@ static int hci_uart_register_dev(struct hci_uart *hu)
hdev->flush = hci_uart_flush;
hdev->send = hci_uart_send_frame;
hdev->destruct = hci_uart_destruct;
hdev->parent = hu->tty->dev;
hdev->owner = THIS_MODULE;

View File

@ -1,8 +1,10 @@
config AR9170_USB
tristate "Atheros AR9170 802.11n USB support"
tristate "Atheros AR9170 802.11n USB support (OBSOLETE)"
depends on USB && MAC80211
select FW_LOADER
help
This driver is going to get replaced by carl9170.
This is a driver for the Atheros "otus" 802.11n USB devices.
These devices require additional firmware (2 files).

View File

@ -1158,6 +1158,26 @@ void ath5k_hw_deinit(struct ath5k_hw *ah);
int ath5k_sysfs_register(struct ath5k_softc *sc);
void ath5k_sysfs_unregister(struct ath5k_softc *sc);
/* base.c */
struct ath5k_buf;
struct ath5k_txq;
void set_beacon_filter(struct ieee80211_hw *hw, bool enable);
bool ath_any_vif_assoc(struct ath5k_softc *sc);
int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
struct ath5k_txq *txq);
int ath5k_init_hw(struct ath5k_softc *sc);
int ath5k_stop_hw(struct ath5k_softc *sc);
void ath5k_mode_setup(struct ath5k_softc *sc, struct ieee80211_vif *vif);
void ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc,
struct ieee80211_vif *vif);
int ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan);
void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf);
int ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
void ath5k_beacon_config(struct ath5k_softc *sc);
void ath5k_txbuf_free_skb(struct ath5k_softc *sc, struct ath5k_buf *bf);
void ath5k_rxbuf_free_skb(struct ath5k_softc *sc, struct ath5k_buf *bf);
/*Chip id helper functions */
const char *ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val);
int ath5k_hw_read_srev(struct ath5k_hw *ah);

View File

@ -220,7 +220,8 @@ int ath5k_hw_init(struct ath5k_softc *sc)
ah->ah_radio = AR5K_RF5112;
ah->ah_single_chip = false;
ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_5112B;
} else if (ah->ah_mac_version == (AR5K_SREV_AR2415 >> 4)) {
} else if (ah->ah_mac_version == (AR5K_SREV_AR2415 >> 4) ||
ah->ah_mac_version == (AR5K_SREV_AR2315_R6 >> 4)) {
ah->ah_radio = AR5K_RF2316;
ah->ah_single_chip = true;
ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2316;

View File

@ -48,23 +48,6 @@
extern int ath5k_modparam_nohwcrypt;
/* functions used from base.c */
void set_beacon_filter(struct ieee80211_hw *hw, bool enable);
bool ath_any_vif_assoc(struct ath5k_softc *sc);
int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
struct ath5k_txq *txq);
int ath5k_init_hw(struct ath5k_softc *sc);
int ath5k_stop_hw(struct ath5k_softc *sc);
void ath5k_mode_setup(struct ath5k_softc *sc, struct ieee80211_vif *vif);
void ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc,
struct ieee80211_vif *vif);
int ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan);
void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf);
int ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
void ath5k_beacon_config(struct ath5k_softc *sc);
void ath5k_txbuf_free_skb(struct ath5k_softc *sc, struct ath5k_buf *bf);
void ath5k_rxbuf_free_skb(struct ath5k_softc *sc, struct ath5k_buf *bf);
/********************\
* Mac80211 functions *
\********************/

View File

@ -1281,6 +1281,7 @@ static int ath5k_hw_channel(struct ath5k_hw *ah,
case AR5K_RF5111:
ret = ath5k_hw_rf5111_channel(ah, channel);
break;
case AR5K_RF2317:
case AR5K_RF2425:
ret = ath5k_hw_rf2425_channel(ah, channel);
break;

View File

@ -28,7 +28,67 @@
*/
static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
{
if (AR_SREV_9485(ah)) {
if (AR_SREV_9485_11(ah)) {
/* mac */
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
ar9485_1_1_mac_core,
ARRAY_SIZE(ar9485_1_1_mac_core), 2);
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
ar9485_1_1_mac_postamble,
ARRAY_SIZE(ar9485_1_1_mac_postamble), 5);
/* bb */
INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], ar9485_1_1,
ARRAY_SIZE(ar9485_1_1), 2);
INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
ar9485_1_1_baseband_core,
ARRAY_SIZE(ar9485_1_1_baseband_core), 2);
INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
ar9485_1_1_baseband_postamble,
ARRAY_SIZE(ar9485_1_1_baseband_postamble), 5);
/* radio */
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
ar9485_1_1_radio_core,
ARRAY_SIZE(ar9485_1_1_radio_core), 2);
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
ar9485_1_1_radio_postamble,
ARRAY_SIZE(ar9485_1_1_radio_postamble), 2);
/* soc */
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
ar9485_1_1_soc_preamble,
ARRAY_SIZE(ar9485_1_1_soc_preamble), 2);
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], NULL, 0, 0);
/* rx/tx gain */
INIT_INI_ARRAY(&ah->iniModesRxGain,
ar9485_common_rx_gain_1_1,
ARRAY_SIZE(ar9485_common_rx_gain_1_1), 2);
INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9485_modes_lowest_ob_db_tx_gain_1_1,
ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1),
5);
/* Load PCIE SERDES settings from INI */
/* Awake Setting */
INIT_INI_ARRAY(&ah->iniPcieSerdes,
ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1,
ARRAY_SIZE(ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1),
2);
/* Sleep Setting */
INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1,
ARRAY_SIZE(ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1),
2);
} else if (AR_SREV_9485(ah)) {
/* mac */
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
@ -85,8 +145,8 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
/* Sleep Setting */
INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
ar9485_1_0_pcie_phy_pll_on_clkreq_enable_L1,
ARRAY_SIZE(ar9485_1_0_pcie_phy_pll_on_clkreq_enable_L1),
ar9485_1_0_pcie_phy_pll_on_clkreq_disable_L1,
ARRAY_SIZE(ar9485_1_0_pcie_phy_pll_on_clkreq_disable_L1),
2);
} else {
/* mac */
@ -163,7 +223,12 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
switch (ar9003_hw_get_tx_gain_idx(ah)) {
case 0:
default:
if (AR_SREV_9485(ah))
if (AR_SREV_9485_11(ah))
INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9485_modes_lowest_ob_db_tx_gain_1_1,
ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1),
5);
else if (AR_SREV_9485(ah))
INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9485Modes_lowest_ob_db_tx_gain_1_0,
ARRAY_SIZE(ar9485Modes_lowest_ob_db_tx_gain_1_0),
@ -175,10 +240,15 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
5);
break;
case 1:
if (AR_SREV_9485(ah))
if (AR_SREV_9485_11(ah))
INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9485Modes_high_ob_db_tx_gain_1_1,
ARRAY_SIZE(ar9485Modes_high_ob_db_tx_gain_1_1),
5);
else if (AR_SREV_9485(ah))
INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9485Modes_high_ob_db_tx_gain_1_0,
ARRAY_SIZE(ar9485Modes_lowest_ob_db_tx_gain_1_0),
ARRAY_SIZE(ar9485Modes_high_ob_db_tx_gain_1_0),
5);
else
INIT_INI_ARRAY(&ah->iniModesTxGain,
@ -187,10 +257,15 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
5);
break;
case 2:
if (AR_SREV_9485(ah))
if (AR_SREV_9485_11(ah))
INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9485Modes_low_ob_db_tx_gain_1_1,
ARRAY_SIZE(ar9485Modes_low_ob_db_tx_gain_1_1),
5);
else if (AR_SREV_9485(ah))
INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9485Modes_low_ob_db_tx_gain_1_0,
ARRAY_SIZE(ar9485Modes_lowest_ob_db_tx_gain_1_0),
ARRAY_SIZE(ar9485Modes_low_ob_db_tx_gain_1_0),
5);
else
INIT_INI_ARRAY(&ah->iniModesTxGain,
@ -199,7 +274,12 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
5);
break;
case 3:
if (AR_SREV_9485(ah))
if (AR_SREV_9485_11(ah))
INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9485Modes_high_power_tx_gain_1_1,
ARRAY_SIZE(ar9485Modes_high_power_tx_gain_1_1),
5);
else if (AR_SREV_9485(ah))
INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9485Modes_high_power_tx_gain_1_0,
ARRAY_SIZE(ar9485Modes_high_power_tx_gain_1_0),
@ -218,7 +298,12 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah)
switch (ar9003_hw_get_rx_gain_idx(ah)) {
case 0:
default:
if (AR_SREV_9485(ah))
if (AR_SREV_9485_11(ah))
INIT_INI_ARRAY(&ah->iniModesRxGain,
ar9485_common_rx_gain_1_1,
ARRAY_SIZE(ar9485_common_rx_gain_1_1),
2);
else if (AR_SREV_9485(ah))
INIT_INI_ARRAY(&ah->iniModesRxGain,
ar9485Common_rx_gain_1_0,
ARRAY_SIZE(ar9485Common_rx_gain_1_0),
@ -230,7 +315,12 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah)
2);
break;
case 1:
if (AR_SREV_9485(ah))
if (AR_SREV_9485_11(ah))
INIT_INI_ARRAY(&ah->iniModesRxGain,
ar9485Common_wo_xlna_rx_gain_1_1,
ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1),
2);
else if (AR_SREV_9485(ah))
INIT_INI_ARRAY(&ah->iniModesRxGain,
ar9485Common_wo_xlna_rx_gain_1_0,
ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_0),

File diff suppressed because it is too large Load Diff

View File

@ -21,7 +21,6 @@
#include <linux/device.h>
#include <linux/leds.h>
#include <linux/completion.h>
#include <linux/pm_qos_params.h>
#include "debug.h"
#include "common.h"
@ -57,8 +56,6 @@ struct ath_node;
#define A_MAX(a, b) ((a) > (b) ? (a) : (b))
#define ATH9K_PM_QOS_DEFAULT_VALUE 55
#define TSF_TO_TU(_h,_l) \
((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))
@ -192,6 +189,7 @@ struct ath_txq {
u32 axq_ampdu_depth;
bool stopped;
bool axq_tx_inprogress;
bool txq_flush_inprogress;
struct list_head axq_acq;
struct list_head txq_fifo[ATH_TXFIFO_DEPTH];
struct list_head txq_fifo_pending;
@ -349,6 +347,7 @@ void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid
struct ath_vif {
int av_bslot;
bool is_bslot_active;
__le64 tsf_adjust; /* TSF adjustment for staggered beacons */
enum nl80211_iftype av_opmode;
struct ath_buf *av_bcbuf;
@ -371,7 +370,7 @@ struct ath_vif {
#define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024)
struct ath_beacon_config {
u16 beacon_interval;
int beacon_interval;
u16 listen_interval;
u16 dtim_period;
u16 bmiss_timeout;
@ -403,6 +402,7 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif);
int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif);
void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp);
int ath_beaconq_config(struct ath_softc *sc);
void ath9k_set_beaconing_status(struct ath_softc *sc, bool status);
/*******/
/* ANI */
@ -633,8 +633,6 @@ struct ath_softc {
struct ath9k_hw_cal_data caldata;
int last_rssi;
int beacon_interval;
#ifdef CONFIG_ATH9K_DEBUGFS
struct ath9k_debug debug;
spinlock_t nodes_lock;
@ -649,8 +647,6 @@ struct ath_softc {
struct ath_descdma txsdma;
struct ath_ant_comb ant_comb;
struct pm_qos_request_list pm_qos_req;
};
void ath9k_tasklet(unsigned long data);
@ -665,7 +661,6 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz)
extern struct ieee80211_ops ath9k_ops;
extern int ath9k_modparam_nohwcrypt;
extern int led_blink;
extern int ath9k_pm_qos_value;
extern bool is_ath9k_unloaded;
irqreturn_t ath_isr(int irq, void *dev);

View File

@ -143,7 +143,7 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw,
avp = (void *)vif->drv_priv;
cabq = sc->beacon.cabq;
if (avp->av_bcbuf == NULL)
if ((avp->av_bcbuf == NULL) || !avp->is_bslot_active)
return NULL;
/* Release the old beacon first */
@ -226,6 +226,7 @@ int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif)
struct ath_vif *avp;
struct ath_buf *bf;
struct sk_buff *skb;
struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
__le64 tstamp;
avp = (void *)vif->drv_priv;
@ -248,6 +249,7 @@ int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif)
for (slot = 0; slot < ATH_BCBUF; slot++)
if (sc->beacon.bslot[slot] == NULL) {
avp->av_bslot = slot;
avp->is_bslot_active = false;
/* NB: keep looking for a double slot */
if (slot == 0 || !sc->beacon.bslot[slot-1])
@ -282,7 +284,7 @@ int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif)
u64 tsfadjust;
int intval;
intval = sc->beacon_interval ? : ATH_DEFAULT_BINTVAL;
intval = cur_conf->beacon_interval ? : ATH_DEFAULT_BINTVAL;
/*
* Calculate the TSF offset for this beacon slot, i.e., the
@ -314,6 +316,7 @@ int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif)
ath_err(common, "dma_mapping_error on beacon alloc\n");
return -ENOMEM;
}
avp->is_bslot_active = true;
return 0;
}
@ -346,6 +349,7 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp)
void ath_beacon_tasklet(unsigned long data)
{
struct ath_softc *sc = (struct ath_softc *)data;
struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
struct ath_buf *bf = NULL;
@ -393,7 +397,7 @@ void ath_beacon_tasklet(unsigned long data)
* on the tsf to safeguard against missing an swba.
*/
intval = sc->beacon_interval ? : ATH_DEFAULT_BINTVAL;
intval = cur_conf->beacon_interval ? : ATH_DEFAULT_BINTVAL;
tsf = ath9k_hw_gettsf64(ah);
tsftu = TSF_TO_TU(tsf>>32, tsf);
@ -747,3 +751,36 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)
sc->sc_flags |= SC_OP_BEACONS;
}
void ath9k_set_beaconing_status(struct ath_softc *sc, bool status)
{
struct ath_hw *ah = sc->sc_ah;
struct ath_vif *avp;
int slot;
bool found = false;
ath9k_ps_wakeup(sc);
if (status) {
for (slot = 0; slot < ATH_BCBUF; slot++) {
if (sc->beacon.bslot[slot]) {
avp = (void *)sc->beacon.bslot[slot]->drv_priv;
if (avp->is_bslot_active) {
found = true;
break;
}
}
}
if (found) {
/* Re-enable beaconing */
ah->imask |= ATH9K_INT_SWBA;
ath9k_hw_set_interrupts(ah, ah->imask);
}
} else {
/* Disable SWBA interrupt */
ah->imask &= ~ATH9K_INT_SWBA;
ath9k_hw_set_interrupts(ah, ah->imask);
tasklet_kill(&sc->bcon_tasklet);
ath9k_hw_stoptxdma(ah, sc->beacon.beaconq);
}
ath9k_ps_restore(sc);
}

View File

@ -169,7 +169,7 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
struct ieee80211_conf *conf = &common->hw->conf;
bool fastcc;
struct ieee80211_channel *channel = hw->conf.channel;
struct ath9k_hw_cal_data *caldata;
struct ath9k_hw_cal_data *caldata = NULL;
enum htc_phymode mode;
__be16 htc_mode;
u8 cmd_rsp;

View File

@ -1100,7 +1100,6 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah)
REG_WRITE(ah, AR_RC, AR_RC_AHB);
REG_WRITE(ah, AR_RTC_RESET, 0);
udelay(2);
REGWRITE_BUFFER_FLUSH(ah);

View File

@ -41,10 +41,6 @@ static int ath9k_btcoex_enable;
module_param_named(btcoex_enable, ath9k_btcoex_enable, int, 0444);
MODULE_PARM_DESC(btcoex_enable, "Enable wifi-BT coexistence");
int ath9k_pm_qos_value = ATH9K_PM_QOS_DEFAULT_VALUE;
module_param_named(pmqos, ath9k_pm_qos_value, int, S_IRUSR | S_IRGRP | S_IROTH);
MODULE_PARM_DESC(pmqos, "User specified PM-QOS value");
bool is_ath9k_unloaded;
/* We use the hw_value as an index into our private channel structure */
@ -760,9 +756,6 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
ath_init_leds(sc);
ath_start_rfkill_poll(sc);
pm_qos_add_request(&sc->pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
PM_QOS_DEFAULT_VALUE);
return 0;
error_world:
@ -819,7 +812,6 @@ void ath9k_deinit_device(struct ath_softc *sc)
ath9k_ps_restore(sc);
ieee80211_unregister_hw(hw);
pm_qos_remove_request(&sc->pm_qos_req);
ath_rx_cleanup(sc);
ath_tx_cleanup(sc);
ath9k_deinit_softc(sc);

View File

@ -15,6 +15,7 @@
*/
#include <linux/nl80211.h>
#include <linux/delay.h>
#include "ath9k.h"
#include "btcoex.h"
@ -53,6 +54,21 @@ static u8 parse_mpdudensity(u8 mpdudensity)
}
}
static bool ath9k_has_pending_frames(struct ath_softc *sc, struct ath_txq *txq)
{
bool pending = false;
spin_lock_bh(&txq->axq_lock);
if (txq->axq_depth || !list_empty(&txq->axq_acq))
pending = true;
else if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
pending = !list_empty(&txq->txq_fifo_pending);
spin_unlock_bh(&txq->axq_lock);
return pending;
}
bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode)
{
unsigned long flags;
@ -1117,12 +1133,6 @@ static int ath9k_start(struct ieee80211_hw *hw)
ath9k_btcoex_timer_resume(sc);
}
/* User has the option to provide pm-qos value as a module
* parameter rather than using the default value of
* 'ATH9K_PM_QOS_DEFAULT_VALUE'.
*/
pm_qos_update_request(&sc->pm_qos_req, ath9k_pm_qos_value);
if (ah->caps.pcie_lcr_extsync_en && common->bus_ops->extn_synch_en)
common->bus_ops->extn_synch_en(common);
@ -1267,8 +1277,6 @@ static void ath9k_stop(struct ieee80211_hw *hw)
sc->sc_flags |= SC_OP_INVALID;
pm_qos_update_request(&sc->pm_qos_req, PM_QOS_DEFAULT_VALUE);
mutex_unlock(&sc->mutex);
ath_dbg(common, ATH_DBG_CONFIG, "Driver halt\n");
@ -1291,24 +1299,10 @@ static void ath9k_reclaim_beacon(struct ath_softc *sc,
{
struct ath_vif *avp = (void *)vif->drv_priv;
/* Disable SWBA interrupt */
sc->sc_ah->imask &= ~ATH9K_INT_SWBA;
ath9k_ps_wakeup(sc);
ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask);
ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
tasklet_kill(&sc->bcon_tasklet);
ath9k_ps_restore(sc);
ath9k_set_beaconing_status(sc, false);
ath_beacon_return(sc, avp);
ath9k_set_beaconing_status(sc, true);
sc->sc_flags &= ~SC_OP_BEACONS;
if (sc->nbcnvifs > 0) {
/* Re-enable beaconing */
sc->sc_ah->imask |= ATH9K_INT_SWBA;
ath9k_ps_wakeup(sc);
ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask);
ath9k_ps_restore(sc);
}
}
static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
@ -1436,16 +1430,17 @@ static void ath9k_do_vif_add_setup(struct ieee80211_hw *hw,
if (ath9k_uses_beacons(vif->type)) {
int error;
ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
/* This may fail because upper levels do not have beacons
* properly configured yet. That's OK, we assume it
* will be properly configured and then we will be notified
* in the info_changed method and set up beacons properly
* there.
*/
ath9k_set_beaconing_status(sc, false);
error = ath_beacon_alloc(sc, vif);
if (!error)
ath_beacon_config(sc, vif);
ath9k_set_beaconing_status(sc, true);
}
}
@ -1676,8 +1671,9 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
else
sc->sc_flags &= ~SC_OP_OFFCHANNEL;
ath_dbg(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n",
curchan->center_freq);
ath_dbg(common, ATH_DBG_CONFIG,
"Set channel: %d MHz type: %d\n",
curchan->center_freq, conf->channel_type);
ath9k_cmn_update_ichannel(&sc->sc_ah->channels[pos],
curchan, conf->channel_type);
@ -1723,6 +1719,8 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
}
if (changed & IEEE80211_CONF_CHANGE_POWER) {
ath_dbg(common, ATH_DBG_CONFIG,
"Set power: %d\n", conf->power_level);
sc->config.txpowlimit = 2 * conf->power_level;
ath9k_ps_wakeup(sc);
ath9k_cmn_update_txpow(ah, sc->curtxpow,
@ -1886,6 +1884,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
u32 changed)
{
struct ath_softc *sc = hw->priv;
struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
struct ath_vif *avp = (void *)vif->drv_priv;
@ -1914,10 +1913,11 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
/* Enable transmission of beacons (AP, IBSS, MESH) */
if ((changed & BSS_CHANGED_BEACON) ||
((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon)) {
ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
ath9k_set_beaconing_status(sc, false);
error = ath_beacon_alloc(sc, vif);
if (!error)
ath_beacon_config(sc, vif);
ath9k_set_beaconing_status(sc, true);
}
if (changed & BSS_CHANGED_ERP_SLOT) {
@ -1940,21 +1940,26 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
}
/* Disable transmission of beacons */
if ((changed & BSS_CHANGED_BEACON_ENABLED) && !bss_conf->enable_beacon)
ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
if ((changed & BSS_CHANGED_BEACON_ENABLED) &&
!bss_conf->enable_beacon) {
ath9k_set_beaconing_status(sc, false);
avp->is_bslot_active = false;
ath9k_set_beaconing_status(sc, true);
}
if (changed & BSS_CHANGED_BEACON_INT) {
sc->beacon_interval = bss_conf->beacon_int;
cur_conf->beacon_interval = bss_conf->beacon_int;
/*
* In case of AP mode, the HW TSF has to be reset
* when the beacon interval changes.
*/
if (vif->type == NL80211_IFTYPE_AP) {
sc->sc_flags |= SC_OP_TSF_RESET;
ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
ath9k_set_beaconing_status(sc, false);
error = ath_beacon_alloc(sc, vif);
if (!error)
ath_beacon_config(sc, vif);
ath9k_set_beaconing_status(sc, true);
} else {
ath_beacon_config(sc, vif);
}
@ -2122,6 +2127,60 @@ static void ath9k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class)
mutex_unlock(&sc->mutex);
}
static void ath9k_flush(struct ieee80211_hw *hw, bool drop)
{
#define ATH_FLUSH_TIMEOUT 60 /* ms */
struct ath_softc *sc = hw->priv;
struct ath_txq *txq;
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
int i, j, npend = 0;
mutex_lock(&sc->mutex);
cancel_delayed_work_sync(&sc->tx_complete_work);
for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
if (!ATH_TXQ_SETUP(sc, i))
continue;
txq = &sc->tx.txq[i];
if (!drop) {
for (j = 0; j < ATH_FLUSH_TIMEOUT; j++) {
if (!ath9k_has_pending_frames(sc, txq))
break;
usleep_range(1000, 2000);
}
}
if (drop || ath9k_has_pending_frames(sc, txq)) {
ath_dbg(common, ATH_DBG_QUEUE, "Drop frames from hw queue:%d\n",
txq->axq_qnum);
spin_lock_bh(&txq->axq_lock);
txq->txq_flush_inprogress = true;
spin_unlock_bh(&txq->axq_lock);
ath9k_ps_wakeup(sc);
ath9k_hw_stoptxdma(ah, txq->axq_qnum);
npend = ath9k_hw_numtxpending(ah, txq->axq_qnum);
ath9k_ps_restore(sc);
if (npend)
break;
ath_draintxq(sc, txq, false);
txq->txq_flush_inprogress = false;
}
}
if (npend) {
ath_reset(sc, false);
txq->txq_flush_inprogress = false;
}
ieee80211_queue_delayed_work(hw, &sc->tx_complete_work, 0);
mutex_unlock(&sc->mutex);
}
struct ieee80211_ops ath9k_ops = {
.tx = ath9k_tx,
.start = ath9k_start,
@ -2143,4 +2202,5 @@ struct ieee80211_ops ath9k_ops = {
.get_survey = ath9k_get_survey,
.rfkill_poll = ath9k_rfkill_poll_state,
.set_coverage_class = ath9k_set_coverage_class,
.flush = ath9k_flush,
};

View File

@ -789,6 +789,7 @@
#define AR_SREV_REVISION_9300_20 2 /* 2.0 and 2.1 */
#define AR_SREV_VERSION_9485 0x240
#define AR_SREV_REVISION_9485_10 0
#define AR_SREV_REVISION_9485_11 1
#define AR_SREV_5416(_ah) \
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \
@ -866,6 +867,9 @@
#define AR_SREV_9485_10(_ah) \
(AR_SREV_9485(_ah) && \
((_ah)->hw_version.macRev == AR_SREV_REVISION_9485_10))
#define AR_SREV_9485_11(_ah) \
(AR_SREV_9485(_ah) && \
((_ah)->hw_version.macRev == AR_SREV_REVISION_9485_11))
#define AR_SREV_9285E_20(_ah) \
(AR_SREV_9285_12_OR_LATER(_ah) && \

View File

@ -1055,6 +1055,7 @@ int ath_txq_update(struct ath_softc *sc, int qnum,
int ath_cabq_update(struct ath_softc *sc)
{
struct ath9k_tx_queue_info qi;
struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
int qnum = sc->beacon.cabq->axq_qnum;
ath9k_hw_get_txq_props(sc->sc_ah, qnum, &qi);
@ -1066,7 +1067,7 @@ int ath_cabq_update(struct ath_softc *sc)
else if (sc->config.cabqReadytime > ATH9K_READY_TIME_HI_BOUND)
sc->config.cabqReadytime = ATH9K_READY_TIME_HI_BOUND;
qi.tqi_readyTime = (sc->beacon_interval *
qi.tqi_readyTime = (cur_conf->beacon_interval *
sc->config.cabqReadytime) / 100;
ath_txq_update(sc, qnum, &qi);
@ -2013,7 +2014,8 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
spin_lock_bh(&txq->axq_lock);
if (list_empty(&txq->axq_q)) {
txq->axq_link = NULL;
if (sc->sc_flags & SC_OP_TXAGGR)
if (sc->sc_flags & SC_OP_TXAGGR &&
!txq->txq_flush_inprogress)
ath_txq_schedule(sc, txq);
spin_unlock_bh(&txq->axq_lock);
break;
@ -2070,6 +2072,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
if (bf_is_ampdu_not_probing(bf))
txq->axq_ampdu_depth--;
spin_unlock_bh(&txq->axq_lock);
if (bf_held)
@ -2093,7 +2096,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
spin_lock_bh(&txq->axq_lock);
if (sc->sc_flags & SC_OP_TXAGGR)
if (sc->sc_flags & SC_OP_TXAGGR && !txq->txq_flush_inprogress)
ath_txq_schedule(sc, txq);
spin_unlock_bh(&txq->axq_lock);
}
@ -2264,15 +2267,18 @@ void ath_tx_edma_tasklet(struct ath_softc *sc)
spin_lock_bh(&txq->axq_lock);
if (!list_empty(&txq->txq_fifo_pending)) {
INIT_LIST_HEAD(&bf_head);
bf = list_first_entry(&txq->txq_fifo_pending,
struct ath_buf, list);
list_cut_position(&bf_head, &txq->txq_fifo_pending,
&bf->bf_lastbf->list);
ath_tx_txqaddbuf(sc, txq, &bf_head);
} else if (sc->sc_flags & SC_OP_TXAGGR)
ath_txq_schedule(sc, txq);
if (!txq->txq_flush_inprogress) {
if (!list_empty(&txq->txq_fifo_pending)) {
INIT_LIST_HEAD(&bf_head);
bf = list_first_entry(&txq->txq_fifo_pending,
struct ath_buf, list);
list_cut_position(&bf_head,
&txq->txq_fifo_pending,
&bf->bf_lastbf->list);
ath_tx_txqaddbuf(sc, txq, &bf_head);
} else if (sc->sc_flags & SC_OP_TXAGGR)
ath_txq_schedule(sc, txq);
}
spin_unlock_bh(&txq->axq_lock);
}
}

View File

@ -265,7 +265,8 @@ static struct iwl_lib_ops iwl2000_lib = {
.txq_free_tfd = iwl_hw_txq_free_tfd,
.txq_init = iwl_hw_tx_queue_init,
.rx_handler_setup = iwlagn_rx_handler_setup,
.setup_deferred_work = iwlagn_setup_deferred_work,
.setup_deferred_work = iwlagn_bt_setup_deferred_work,
.cancel_deferred_work = iwlagn_bt_cancel_deferred_work,
.is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
.load_ucode = iwlagn_load_ucode,
.dump_nic_event_log = iwl_dump_nic_event_log,

View File

@ -1832,7 +1832,7 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv)
* IBSS mode (no proper uCode support for coex then).
*/
if (!bt_coex_active || priv->iw_mode == NL80211_IFTYPE_ADHOC) {
bt_cmd.flags = 0;
bt_cmd.flags = IWLAGN_BT_FLAG_COEX_MODE_DISABLED;
} else {
bt_cmd.flags = IWLAGN_BT_FLAG_COEX_MODE_3W <<
IWLAGN_BT_FLAG_COEX_MODE_SHIFT;
@ -1869,6 +1869,11 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work)
struct iwl_rxon_context *ctx;
int smps_request = -1;
if (priv->bt_enable_flag == IWLAGN_BT_FLAG_COEX_MODE_DISABLED) {
/* bt coex disabled */
return;
}
/*
* Note: bt_traffic_load can be overridden by scan complete and
* coex profile notifications. Ignore that since only bad consequence
@ -2022,6 +2027,11 @@ void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
struct iwl_bt_coex_profile_notif *coex = &pkt->u.bt_coex_profile_notif;
struct iwl_bt_uart_msg *uart_msg = &coex->last_bt_uart_msg;
if (priv->bt_enable_flag == IWLAGN_BT_FLAG_COEX_MODE_DISABLED) {
/* bt coex disabled */
return;
}
IWL_DEBUG_NOTIF(priv, "BT Coex notification:\n");
IWL_DEBUG_NOTIF(priv, " status: %d\n", coex->bt_status);
IWL_DEBUG_NOTIF(priv, " traffic load: %d\n", coex->bt_traffic_load);

View File

@ -1413,34 +1413,42 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
/**
* iwl_good_ack_health - checks for ACK count ratios, BA timeout retries.
*
* When the ACK count ratio is 0 and aggregated BA timeout retries exceeding
* When the ACK count ratio is low and aggregated BA timeout retries exceeding
* the BA_TIMEOUT_MAX, reload firmware and bring system back to normal
* operation state.
*/
bool iwl_good_ack_health(struct iwl_priv *priv,
struct iwl_rx_packet *pkt)
bool iwl_good_ack_health(struct iwl_priv *priv, struct iwl_rx_packet *pkt)
{
bool rc = true;
int actual_ack_cnt_delta, expected_ack_cnt_delta;
int ba_timeout_delta;
int actual_delta, expected_delta, ba_timeout_delta;
struct statistics_tx *cur, *old;
actual_ack_cnt_delta =
le32_to_cpu(pkt->u.stats.tx.actual_ack_cnt) -
le32_to_cpu(priv->_agn.statistics.tx.actual_ack_cnt);
expected_ack_cnt_delta =
le32_to_cpu(pkt->u.stats.tx.expected_ack_cnt) -
le32_to_cpu(priv->_agn.statistics.tx.expected_ack_cnt);
ba_timeout_delta =
le32_to_cpu(pkt->u.stats.tx.agg.ba_timeout) -
le32_to_cpu(priv->_agn.statistics.tx.agg.ba_timeout);
if ((priv->_agn.agg_tids_count > 0) &&
(expected_ack_cnt_delta > 0) &&
(((actual_ack_cnt_delta * 100) / expected_ack_cnt_delta)
< ACK_CNT_RATIO) &&
(ba_timeout_delta > BA_TIMEOUT_CNT)) {
IWL_DEBUG_RADIO(priv, "actual_ack_cnt delta = %d,"
" expected_ack_cnt = %d\n",
actual_ack_cnt_delta, expected_ack_cnt_delta);
if (priv->_agn.agg_tids_count)
return true;
if (iwl_bt_statistics(priv)) {
cur = &pkt->u.stats_bt.tx;
old = &priv->_agn.statistics_bt.tx;
} else {
cur = &pkt->u.stats.tx;
old = &priv->_agn.statistics.tx;
}
actual_delta = le32_to_cpu(cur->actual_ack_cnt) -
le32_to_cpu(old->actual_ack_cnt);
expected_delta = le32_to_cpu(cur->expected_ack_cnt) -
le32_to_cpu(old->expected_ack_cnt);
/* Values should not be negative, but we do not trust the firmware */
if (actual_delta <= 0 || expected_delta <= 0)
return true;
ba_timeout_delta = le32_to_cpu(cur->agg.ba_timeout) -
le32_to_cpu(old->agg.ba_timeout);
if ((actual_delta * 100 / expected_delta) < ACK_CNT_RATIO &&
ba_timeout_delta > BA_TIMEOUT_CNT) {
IWL_DEBUG_RADIO(priv, "deltas: actual %d expected %d ba_timeout %d\n",
actual_delta, expected_delta, ba_timeout_delta);
#ifdef CONFIG_IWLWIFI_DEBUGFS
/*
@ -1448,20 +1456,18 @@ bool iwl_good_ack_health(struct iwl_priv *priv,
* statistics aren't available. If DEBUGFS is set but
* DEBUG is not, these will just compile out.
*/
IWL_DEBUG_RADIO(priv, "rx_detected_cnt delta = %d\n",
IWL_DEBUG_RADIO(priv, "rx_detected_cnt delta %d\n",
priv->_agn.delta_statistics.tx.rx_detected_cnt);
IWL_DEBUG_RADIO(priv,
"ack_or_ba_timeout_collision delta = %d\n",
priv->_agn.delta_statistics.tx.
ack_or_ba_timeout_collision);
"ack_or_ba_timeout_collision delta %d\n",
priv->_agn.delta_statistics.tx.ack_or_ba_timeout_collision);
#endif
IWL_DEBUG_RADIO(priv, "agg ba_timeout delta = %d\n",
ba_timeout_delta);
if (!actual_ack_cnt_delta &&
(ba_timeout_delta >= BA_TIMEOUT_MAX))
rc = false;
if (ba_timeout_delta >= BA_TIMEOUT_MAX)
return false;
}
return rc;
return true;
}

View File

@ -234,33 +234,20 @@ EXPORT_SYMBOL(iwl_rx_spectrum_measure_notif);
void iwl_recover_from_statistics(struct iwl_priv *priv,
struct iwl_rx_packet *pkt)
{
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
!iwl_is_any_associated(priv))
return;
if (iwl_is_any_associated(priv)) {
if (priv->cfg->ops->lib->check_ack_health) {
if (!priv->cfg->ops->lib->check_ack_health(
priv, pkt)) {
/*
* low ack count detected
* restart Firmware
*/
IWL_ERR(priv, "low ack count detected, "
"restart firmware\n");
if (!iwl_force_reset(priv, IWL_FW_RESET, false))
return;
}
}
if (priv->cfg->ops->lib->check_plcp_health) {
if (!priv->cfg->ops->lib->check_plcp_health(
priv, pkt)) {
/*
* high plcp error detected
* reset Radio
*/
iwl_force_reset(priv, IWL_RF_RESET, false);
}
}
if (priv->cfg->ops->lib->check_ack_health &&
!priv->cfg->ops->lib->check_ack_health(priv, pkt)) {
IWL_ERR(priv, "low ack count detected, restart firmware\n");
if (!iwl_force_reset(priv, IWL_FW_RESET, false))
return;
}
if (priv->cfg->ops->lib->check_plcp_health &&
!priv->cfg->ops->lib->check_plcp_health(priv, pkt))
iwl_force_reset(priv, IWL_RF_RESET, false);
}
EXPORT_SYMBOL(iwl_recover_from_statistics);

View File

@ -55,6 +55,17 @@ static struct ieee80211_rate p54_arates[] = {
{ .bitrate = 540, .hw_value = 11, },
};
static struct p54_rssi_db_entry p54_rssi_default = {
/*
* The defaults are taken from usb-logs of the
* vendor driver. So, they should be safe to
* use in case we can't get a match from the
* rssi <-> dBm conversion database.
*/
.mul = 130,
.add = -398,
};
#define CHAN_HAS_CAL BIT(0)
#define CHAN_HAS_LIMIT BIT(1)
#define CHAN_HAS_CURVE BIT(2)
@ -87,13 +98,27 @@ static int p54_get_band_from_freq(u16 freq)
return -1;
}
static int same_band(u16 freq, u16 freq2)
{
return p54_get_band_from_freq(freq) == p54_get_band_from_freq(freq2);
}
static int p54_compare_channels(const void *_a,
const void *_b)
{
const struct p54_channel_entry *a = _a;
const struct p54_channel_entry *b = _b;
return a->index - b->index;
return a->freq - b->freq;
}
static int p54_compare_rssichan(const void *_a,
const void *_b)
{
const struct p54_rssi_db_entry *a = _a;
const struct p54_rssi_db_entry *b = _b;
return a->freq - b->freq;
}
static int p54_fill_band_bitrates(struct ieee80211_hw *dev,
@ -145,25 +170,26 @@ static int p54_generate_band(struct ieee80211_hw *dev,
for (i = 0, j = 0; (j < list->band_channel_num[band]) &&
(i < list->entries); i++) {
struct p54_channel_entry *chan = &list->channels[i];
if (list->channels[i].band != band)
if (chan->band != band)
continue;
if (list->channels[i].data != CHAN_HAS_ALL) {
wiphy_err(dev->wiphy,
"%s%s%s is/are missing for channel:%d [%d MHz].\n",
(list->channels[i].data & CHAN_HAS_CAL ? "" :
if (chan->data != CHAN_HAS_ALL) {
wiphy_err(dev->wiphy, "%s%s%s is/are missing for "
"channel:%d [%d MHz].\n",
(chan->data & CHAN_HAS_CAL ? "" :
" [iqauto calibration data]"),
(list->channels[i].data & CHAN_HAS_LIMIT ? "" :
(chan->data & CHAN_HAS_LIMIT ? "" :
" [output power limits]"),
(list->channels[i].data & CHAN_HAS_CURVE ? "" :
(chan->data & CHAN_HAS_CURVE ? "" :
" [curve data]"),
list->channels[i].index, list->channels[i].freq);
chan->index, chan->freq);
continue;
}
tmp->channels[j].band = list->channels[i].band;
tmp->channels[j].center_freq = list->channels[i].freq;
tmp->channels[j].band = chan->band;
tmp->channels[j].center_freq = chan->freq;
j++;
}
@ -291,7 +317,7 @@ static int p54_generate_channel_lists(struct ieee80211_hw *dev)
}
}
/* sort the list by the channel index */
/* sort the channel list by frequency */
sort(list->channels, list->entries, sizeof(struct p54_channel_entry),
p54_compare_channels, NULL);
@ -410,33 +436,118 @@ static int p54_convert_rev1(struct ieee80211_hw *dev,
static const char *p54_rf_chips[] = { "INVALID-0", "Duette3", "Duette2",
"Frisbee", "Xbow", "Longbow", "INVALID-6", "INVALID-7" };
static void p54_parse_rssical(struct ieee80211_hw *dev, void *data, int len,
u16 type)
static int p54_parse_rssical(struct ieee80211_hw *dev,
u8 *data, int len, u16 type)
{
struct p54_common *priv = dev->priv;
int offset = (type == PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED) ? 2 : 0;
int entry_size = sizeof(struct pda_rssi_cal_entry) + offset;
int num_entries = (type == PDR_RSSI_LINEAR_APPROXIMATION) ? 1 : 2;
int i;
struct p54_rssi_db_entry *entry;
size_t db_len, entries;
int offset = 0, i;
if (len != (entry_size * num_entries)) {
wiphy_err(dev->wiphy,
"unknown rssi calibration data packing type:(%x) len:%d.\n",
type, len);
if (type != PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED) {
entries = (type == PDR_RSSI_LINEAR_APPROXIMATION) ? 1 : 2;
if (len != sizeof(struct pda_rssi_cal_entry) * entries) {
wiphy_err(dev->wiphy, "rssical size mismatch.\n");
goto err_data;
}
} else {
/*
* Some devices (Dell 1450 USB, Xbow 5GHz card, etc...)
* have an empty two byte header.
*/
if (*((__le16 *)&data[offset]) == cpu_to_le16(0))
offset += 2;
print_hex_dump_bytes("rssical:", DUMP_PREFIX_NONE,
data, len);
entries = (len - offset) /
sizeof(struct pda_rssi_cal_ext_entry);
wiphy_err(dev->wiphy, "please report this issue.\n");
return;
if ((len - offset) % sizeof(struct pda_rssi_cal_ext_entry) ||
entries <= 0) {
wiphy_err(dev->wiphy, "invalid rssi database.\n");
goto err_data;
}
}
for (i = 0; i < num_entries; i++) {
struct pda_rssi_cal_entry *cal = data +
(offset + i * entry_size);
priv->rssical_db[i].mul = (s16) le16_to_cpu(cal->mul);
priv->rssical_db[i].add = (s16) le16_to_cpu(cal->add);
db_len = sizeof(*entry) * entries;
priv->rssi_db = kzalloc(db_len + sizeof(*priv->rssi_db), GFP_KERNEL);
if (!priv->rssi_db)
return -ENOMEM;
priv->rssi_db->offset = 0;
priv->rssi_db->entries = entries;
priv->rssi_db->entry_size = sizeof(*entry);
priv->rssi_db->len = db_len;
entry = (void *)((unsigned long)priv->rssi_db->data + priv->rssi_db->offset);
if (type == PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED) {
struct pda_rssi_cal_ext_entry *cal = (void *) &data[offset];
for (i = 0; i < entries; i++) {
entry[i].freq = le16_to_cpu(cal[i].freq);
entry[i].mul = (s16) le16_to_cpu(cal[i].mul);
entry[i].add = (s16) le16_to_cpu(cal[i].add);
}
} else {
struct pda_rssi_cal_entry *cal = (void *) &data[offset];
for (i = 0; i < entries; i++) {
u16 freq;
switch (i) {
case IEEE80211_BAND_2GHZ:
freq = 2437;
break;
case IEEE80211_BAND_5GHZ:
freq = 5240;
break;
}
entry[i].freq = freq;
entry[i].mul = (s16) le16_to_cpu(cal[i].mul);
entry[i].add = (s16) le16_to_cpu(cal[i].add);
}
}
/* sort the list by channel frequency */
sort(entry, entries, sizeof(*entry), p54_compare_rssichan, NULL);
return 0;
err_data:
wiphy_err(dev->wiphy,
"rssi calibration data packing type:(%x) len:%d.\n",
type, len);
print_hex_dump_bytes("rssical:", DUMP_PREFIX_NONE, data, len);
wiphy_err(dev->wiphy, "please report this issue.\n");
return -EINVAL;
}
struct p54_rssi_db_entry *p54_rssi_find(struct p54_common *priv, const u16 freq)
{
struct p54_rssi_db_entry *entry = (void *)(priv->rssi_db->data +
priv->rssi_db->offset);
int i, found = -1;
for (i = 0; i < priv->rssi_db->entries; i++) {
if (!same_band(freq, entry[i].freq))
continue;
if (found == -1) {
found = i;
continue;
}
/* nearest match */
if (abs(freq - entry[i].freq) <
abs(freq - entry[found].freq)) {
found = i;
continue;
} else {
break;
}
}
return found < 0 ? &p54_rssi_default : &entry[found];
}
static void p54_parse_default_country(struct ieee80211_hw *dev,
@ -627,21 +738,30 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
case PDR_RSSI_LINEAR_APPROXIMATION:
case PDR_RSSI_LINEAR_APPROXIMATION_DUAL_BAND:
case PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED:
p54_parse_rssical(dev, entry->data, data_len,
le16_to_cpu(entry->code));
err = p54_parse_rssical(dev, entry->data, data_len,
le16_to_cpu(entry->code));
if (err)
goto err;
break;
case PDR_RSSI_LINEAR_APPROXIMATION_CUSTOM: {
__le16 *src = (void *) entry->data;
s16 *dst = (void *) &priv->rssical_db;
case PDR_RSSI_LINEAR_APPROXIMATION_CUSTOMV2: {
struct pda_custom_wrapper *pda = (void *) entry->data;
__le16 *src;
u16 *dst;
int i;
if (data_len != sizeof(priv->rssical_db)) {
err = -EINVAL;
goto err;
}
for (i = 0; i < sizeof(priv->rssical_db) /
sizeof(*src); i++)
if (priv->rssi_db || data_len < sizeof(*pda))
break;
priv->rssi_db = p54_convert_db(pda, data_len);
if (!priv->rssi_db)
break;
src = (void *) priv->rssi_db->data;
dst = (void *) priv->rssi_db->data;
for (i = 0; i < priv->rssi_db->entries; i++)
*(dst++) = (s16) le16_to_cpu(*(src++));
}
break;
case PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS_CUSTOM: {
@ -717,6 +837,8 @@ good_eeprom:
SET_IEEE80211_PERM_ADDR(dev, perm_addr);
}
priv->cur_rssi = &p54_rssi_default;
wiphy_info(dev->wiphy, "hwaddr %pM, MAC:isl38%02x RF:%s\n",
dev->wiphy->perm_addr, priv->version,
p54_rf_chips[priv->rxhw]);
@ -727,9 +849,11 @@ err:
kfree(priv->iq_autocal);
kfree(priv->output_limit);
kfree(priv->curve_data);
kfree(priv->rssi_db);
priv->iq_autocal = NULL;
priv->output_limit = NULL;
priv->curve_data = NULL;
priv->rssi_db = NULL;
wiphy_err(dev->wiphy, "eeprom parse failed!\n");
return err;

View File

@ -81,6 +81,12 @@ struct pda_pa_curve_data {
u8 data[0];
} __packed;
struct pda_rssi_cal_ext_entry {
__le16 freq;
__le16 mul;
__le16 add;
} __packed;
struct pda_rssi_cal_entry {
__le16 mul;
__le16 add;
@ -179,6 +185,7 @@ struct pda_custom_wrapper {
/* used by our modificated eeprom image */
#define PDR_RSSI_LINEAR_APPROXIMATION_CUSTOM 0xDEAD
#define PDR_RSSI_LINEAR_APPROXIMATION_CUSTOMV2 0xCAFF
#define PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS_CUSTOM 0xBEEF
#define PDR_PRISM_PA_CAL_CURVE_DATA_CUSTOM 0xB05D

View File

@ -397,9 +397,9 @@ int p54_scan(struct p54_common *priv, u16 mode, u16 dwell)
union p54_scan_body_union *body;
struct p54_scan_tail_rate *rate;
struct pda_rssi_cal_entry *rssi;
struct p54_rssi_db_entry *rssi_data;
unsigned int i;
void *entry;
int band = priv->hw->conf.channel->band;
__le16 freq = cpu_to_le16(priv->hw->conf.channel->center_freq);
skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*head) +
@ -503,13 +503,14 @@ int p54_scan(struct p54_common *priv, u16 mode, u16 dwell)
}
rssi = (struct pda_rssi_cal_entry *) skb_put(skb, sizeof(*rssi));
rssi->mul = cpu_to_le16(priv->rssical_db[band].mul);
rssi->add = cpu_to_le16(priv->rssical_db[band].add);
rssi_data = p54_rssi_find(priv, le16_to_cpu(freq));
rssi->mul = cpu_to_le16(rssi_data->mul);
rssi->add = cpu_to_le16(rssi_data->add);
if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) {
/* Longbow frontend needs ever more */
rssi = (void *) skb_put(skb, sizeof(*rssi));
rssi->mul = cpu_to_le16(priv->rssical_db[band].longbow_unkn);
rssi->add = cpu_to_le16(priv->rssical_db[band].longbow_unk2);
rssi->mul = cpu_to_le16(rssi_data->longbow_unkn);
rssi->add = cpu_to_le16(rssi_data->longbow_unk2);
}
if (priv->fw_var >= 0x509) {
@ -523,6 +524,7 @@ int p54_scan(struct p54_common *priv, u16 mode, u16 dwell)
hdr->len = cpu_to_le16(skb->len - sizeof(*hdr));
p54_tx(priv, skb);
priv->cur_rssi = rssi_data;
return 0;
err:

View File

@ -551,6 +551,7 @@ int p54_upload_key(struct p54_common *priv, u8 algo, int slot,
/* eeprom */
int p54_download_eeprom(struct p54_common *priv, void *buf,
u16 offset, u16 len);
struct p54_rssi_db_entry *p54_rssi_find(struct p54_common *p, const u16 freq);
/* utility */
u8 *p54_find_ie(struct sk_buff *skb, u8 ie);

View File

@ -524,6 +524,48 @@ static int p54_get_survey(struct ieee80211_hw *dev, int idx,
return 0;
}
static unsigned int p54_flush_count(struct p54_common *priv)
{
unsigned int total = 0, i;
BUILD_BUG_ON(P54_QUEUE_NUM > ARRAY_SIZE(priv->tx_stats));
/*
* Because the firmware has the sole control over any frames
* in the P54_QUEUE_BEACON or P54_QUEUE_SCAN queues, they
* don't really count as pending or active.
*/
for (i = P54_QUEUE_MGMT; i < P54_QUEUE_NUM; i++)
total += priv->tx_stats[i].len;
return total;
}
static void p54_flush(struct ieee80211_hw *dev, bool drop)
{
struct p54_common *priv = dev->priv;
unsigned int total, i;
/*
* Currently, it wouldn't really matter if we wait for one second
* or 15 minutes. But once someone gets around and completes the
* TODOs [ancel stuck frames / reset device] in p54_work, it will
* suddenly make sense to wait that long.
*/
i = P54_STATISTICS_UPDATE * 2 / 20;
/*
* In this case no locking is required because as we speak the
* queues have already been stopped and no new frames can sneak
* up from behind.
*/
while ((total = p54_flush_count(priv) && i--)) {
/* waste time */
msleep(20);
}
WARN(total, "tx flush timeout, unresponsive firmware");
}
static const struct ieee80211_ops p54_ops = {
.tx = p54_tx_80211,
.start = p54_start,
@ -536,6 +578,7 @@ static const struct ieee80211_ops p54_ops = {
.sta_remove = p54_sta_add_remove,
.set_key = p54_set_key,
.config = p54_config,
.flush = p54_flush,
.bss_info_changed = p54_bss_info_changed,
.configure_filter = p54_configure_filter,
.conf_tx = p54_conf_tx,
@ -611,7 +654,7 @@ EXPORT_SYMBOL_GPL(p54_init_common);
int p54_register_common(struct ieee80211_hw *dev, struct device *pdev)
{
struct p54_common *priv = dev->priv;
struct p54_common __maybe_unused *priv = dev->priv;
int err;
err = ieee80211_register_hw(dev);
@ -642,10 +685,12 @@ void p54_free_common(struct ieee80211_hw *dev)
kfree(priv->iq_autocal);
kfree(priv->output_limit);
kfree(priv->curve_data);
kfree(priv->rssi_db);
kfree(priv->used_rxkeys);
priv->iq_autocal = NULL;
priv->output_limit = NULL;
priv->curve_data = NULL;
priv->rssi_db = NULL;
priv->used_rxkeys = NULL;
ieee80211_free_hw(dev);
}

View File

@ -116,7 +116,8 @@ struct p54_edcf_queue_param {
__le16 txop;
} __packed;
struct p54_rssi_linear_approximation {
struct p54_rssi_db_entry {
u16 freq;
s16 mul;
s16 add;
s16 longbow_unkn;
@ -197,13 +198,14 @@ struct p54_common {
u8 rx_diversity_mask;
u8 tx_diversity_mask;
unsigned int output_power;
struct p54_rssi_db_entry *cur_rssi;
int noise;
/* calibration, output power limit and rssi<->dBm conversation data */
struct pda_iq_autocal_entry *iq_autocal;
unsigned int iq_autocal_len;
struct p54_cal_database *curve_data;
struct p54_cal_database *output_limit;
struct p54_rssi_linear_approximation rssical_db[IEEE80211_NUM_BANDS];
struct p54_cal_database *rssi_db;
struct ieee80211_supported_band *band_table[IEEE80211_NUM_BANDS];
/* BBP/MAC state */

View File

@ -65,9 +65,10 @@ static unsigned char p54spi_eeprom[] = {
0x03, 0x00, 0x00, 0x11, /* PDR_ANTENNA_GAIN */
0x08, 0x08, 0x08, 0x08,
0x09, 0x00, 0xad, 0xde, /* PDR_RSSI_LINEAR_APPROXIMATION_CUSTOM */
0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0a, 0x00, 0xff, 0xca, /* PDR_RSSI_LINEAR_APPROXIMATION_CUSTOMV2 */
0x01, 0x00, 0x0a, 0x00,
0x00, 0x00, 0x0a, 0x00,
0x85, 0x09, 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00,
/* struct pda_custom_wrapper */
0x10, 0x06, 0x5d, 0xb0, /* PDR_PRISM_PA_CAL_CURVE_DATA_CUSTOM */
@ -671,7 +672,7 @@ static unsigned char p54spi_eeprom[] = {
0xa8, 0x09, 0x25, 0x00, 0xf5, 0xff, 0xf9, 0xff, 0x00, 0x01,
0x02, 0x00, 0x00, 0x00, /* PDR_END */
0x67, 0x99,
0xb6, 0x04,
};
#endif /* P54SPI_EEPROM_H */

View File

@ -273,11 +273,9 @@ void p54_tx(struct p54_common *priv, struct sk_buff *skb)
static int p54_rssi_to_dbm(struct p54_common *priv, int rssi)
{
int band = priv->hw->conf.channel->band;
if (priv->rxhw != 5) {
return ((rssi * priv->rssical_db[band].mul) / 64 +
priv->rssical_db[band].add) / 4;
return ((rssi * priv->cur_rssi->mul) / 64 +
priv->cur_rssi->add) / 4;
} else {
/*
* TODO: find the correct formula

View File

@ -97,6 +97,18 @@ config RT2800PCI_RT35XX
Support for these devices is non-functional at the moment and is
intended for testers and developers.
config RT2800PCI_RT53XX
bool "rt2800-pci - Include support for rt53xx devices (EXPERIMENTAL)"
depends on EXPERIMENTAL
default n
---help---
This adds support for rt53xx wireless chipset family to the
rt2800pci driver.
Supported chips: RT5390
Support for these devices is non-functional at the moment and is
intended for testers and developers.
endif
config RT2500USB

View File

@ -51,6 +51,7 @@
* RF3320 2.4G 1T1R(RT3350/RT3370/RT3390)
* RF3322 2.4G 2T2R(RT3352/RT3371/RT3372/RT3391/RT3392)
* RF3853 2.4G/5G 3T3R(RT3883/RT3563/RT3573/RT3593/RT3662)
* RF5390 2.4G 1T1R
*/
#define RF2820 0x0001
#define RF2850 0x0002
@ -65,6 +66,7 @@
#define RF3320 0x000b
#define RF3322 0x000c
#define RF3853 0x000d
#define RF5390 0x5390
/*
* Chipset revisions.
@ -77,6 +79,7 @@
#define REV_RT3071E 0x0211
#define REV_RT3090E 0x0211
#define REV_RT3390E 0x0211
#define REV_RT5390F 0x0502
/*
* Signal information.
@ -120,6 +123,13 @@
#define E2PROM_CSR_LOAD_STATUS FIELD32(0x00000040)
#define E2PROM_CSR_RELOAD FIELD32(0x00000080)
/*
* AUX_CTRL: Aux/PCI-E related configuration
*/
#define AUX_CTRL 0x10c
#define AUX_CTRL_WAKE_PCIE_EN FIELD32(0x00000002)
#define AUX_CTRL_FORCE_PCIE_CLK FIELD32(0x00000400)
/*
* OPT_14: Unknown register used by rt3xxx devices.
*/
@ -270,6 +280,7 @@
/*
* GPIO_CTRL_CFG:
* GPIOD: GPIO direction, 0: Output, 1: Input
*/
#define GPIO_CTRL_CFG 0x0228
#define GPIO_CTRL_CFG_BIT0 FIELD32(0x00000001)
@ -280,7 +291,14 @@
#define GPIO_CTRL_CFG_BIT5 FIELD32(0x00000020)
#define GPIO_CTRL_CFG_BIT6 FIELD32(0x00000040)
#define GPIO_CTRL_CFG_BIT7 FIELD32(0x00000080)
#define GPIO_CTRL_CFG_BIT8 FIELD32(0x00000100)
#define GPIO_CTRL_CFG_GPIOD_BIT0 FIELD32(0x00000100)
#define GPIO_CTRL_CFG_GPIOD_BIT1 FIELD32(0x00000200)
#define GPIO_CTRL_CFG_GPIOD_BIT2 FIELD32(0x00000400)
#define GPIO_CTRL_CFG_GPIOD_BIT3 FIELD32(0x00000800)
#define GPIO_CTRL_CFG_GPIOD_BIT4 FIELD32(0x00001000)
#define GPIO_CTRL_CFG_GPIOD_BIT5 FIELD32(0x00002000)
#define GPIO_CTRL_CFG_GPIOD_BIT6 FIELD32(0x00004000)
#define GPIO_CTRL_CFG_GPIOD_BIT7 FIELD32(0x00008000)
/*
* MCU_CMD_CFG
@ -446,7 +464,7 @@
*/
#define RF_CSR_CFG 0x0500
#define RF_CSR_CFG_DATA FIELD32(0x000000ff)
#define RF_CSR_CFG_REGNUM FIELD32(0x00001f00)
#define RF_CSR_CFG_REGNUM FIELD32(0x00003f00)
#define RF_CSR_CFG_WRITE FIELD32(0x00010000)
#define RF_CSR_CFG_BUSY FIELD32(0x00020000)
@ -1136,8 +1154,8 @@
* PROTECT_RATE: Protection control frame rate for CCK TX(RTS/CTS/CFEnd)
* PROTECT_CTRL: Protection control frame type for CCK TX
* 0:none, 1:RTS/CTS, 2:CTS-to-self
* PROTECT_NAV: TXOP protection type for CCK TX
* 0:none, 1:ShortNAVprotect, 2:LongNAVProtect
* PROTECT_NAV_SHORT: TXOP protection type for CCK TX with short NAV
* PROTECT_NAV_LONG: TXOP protection type for CCK TX with long NAV
* TX_OP_ALLOW_CCK: CCK TXOP allowance, 0:disallow
* TX_OP_ALLOW_OFDM: CCK TXOP allowance, 0:disallow
* TX_OP_ALLOW_MM20: CCK TXOP allowance, 0:disallow
@ -1149,7 +1167,8 @@
#define CCK_PROT_CFG 0x1364
#define CCK_PROT_CFG_PROTECT_RATE FIELD32(0x0000ffff)
#define CCK_PROT_CFG_PROTECT_CTRL FIELD32(0x00030000)
#define CCK_PROT_CFG_PROTECT_NAV FIELD32(0x000c0000)
#define CCK_PROT_CFG_PROTECT_NAV_SHORT FIELD32(0x00040000)
#define CCK_PROT_CFG_PROTECT_NAV_LONG FIELD32(0x00080000)
#define CCK_PROT_CFG_TX_OP_ALLOW_CCK FIELD32(0x00100000)
#define CCK_PROT_CFG_TX_OP_ALLOW_OFDM FIELD32(0x00200000)
#define CCK_PROT_CFG_TX_OP_ALLOW_MM20 FIELD32(0x00400000)
@ -1164,7 +1183,8 @@
#define OFDM_PROT_CFG 0x1368
#define OFDM_PROT_CFG_PROTECT_RATE FIELD32(0x0000ffff)
#define OFDM_PROT_CFG_PROTECT_CTRL FIELD32(0x00030000)
#define OFDM_PROT_CFG_PROTECT_NAV FIELD32(0x000c0000)
#define OFDM_PROT_CFG_PROTECT_NAV_SHORT FIELD32(0x00040000)
#define OFDM_PROT_CFG_PROTECT_NAV_LONG FIELD32(0x00080000)
#define OFDM_PROT_CFG_TX_OP_ALLOW_CCK FIELD32(0x00100000)
#define OFDM_PROT_CFG_TX_OP_ALLOW_OFDM FIELD32(0x00200000)
#define OFDM_PROT_CFG_TX_OP_ALLOW_MM20 FIELD32(0x00400000)
@ -1179,7 +1199,8 @@
#define MM20_PROT_CFG 0x136c
#define MM20_PROT_CFG_PROTECT_RATE FIELD32(0x0000ffff)
#define MM20_PROT_CFG_PROTECT_CTRL FIELD32(0x00030000)
#define MM20_PROT_CFG_PROTECT_NAV FIELD32(0x000c0000)
#define MM20_PROT_CFG_PROTECT_NAV_SHORT FIELD32(0x00040000)
#define MM20_PROT_CFG_PROTECT_NAV_LONG FIELD32(0x00080000)
#define MM20_PROT_CFG_TX_OP_ALLOW_CCK FIELD32(0x00100000)
#define MM20_PROT_CFG_TX_OP_ALLOW_OFDM FIELD32(0x00200000)
#define MM20_PROT_CFG_TX_OP_ALLOW_MM20 FIELD32(0x00400000)
@ -1194,7 +1215,8 @@
#define MM40_PROT_CFG 0x1370
#define MM40_PROT_CFG_PROTECT_RATE FIELD32(0x0000ffff)
#define MM40_PROT_CFG_PROTECT_CTRL FIELD32(0x00030000)
#define MM40_PROT_CFG_PROTECT_NAV FIELD32(0x000c0000)
#define MM40_PROT_CFG_PROTECT_NAV_SHORT FIELD32(0x00040000)
#define MM40_PROT_CFG_PROTECT_NAV_LONG FIELD32(0x00080000)
#define MM40_PROT_CFG_TX_OP_ALLOW_CCK FIELD32(0x00100000)
#define MM40_PROT_CFG_TX_OP_ALLOW_OFDM FIELD32(0x00200000)
#define MM40_PROT_CFG_TX_OP_ALLOW_MM20 FIELD32(0x00400000)
@ -1209,7 +1231,8 @@
#define GF20_PROT_CFG 0x1374
#define GF20_PROT_CFG_PROTECT_RATE FIELD32(0x0000ffff)
#define GF20_PROT_CFG_PROTECT_CTRL FIELD32(0x00030000)
#define GF20_PROT_CFG_PROTECT_NAV FIELD32(0x000c0000)
#define GF20_PROT_CFG_PROTECT_NAV_SHORT FIELD32(0x00040000)
#define GF20_PROT_CFG_PROTECT_NAV_LONG FIELD32(0x00080000)
#define GF20_PROT_CFG_TX_OP_ALLOW_CCK FIELD32(0x00100000)
#define GF20_PROT_CFG_TX_OP_ALLOW_OFDM FIELD32(0x00200000)
#define GF20_PROT_CFG_TX_OP_ALLOW_MM20 FIELD32(0x00400000)
@ -1224,7 +1247,8 @@
#define GF40_PROT_CFG 0x1378
#define GF40_PROT_CFG_PROTECT_RATE FIELD32(0x0000ffff)
#define GF40_PROT_CFG_PROTECT_CTRL FIELD32(0x00030000)
#define GF40_PROT_CFG_PROTECT_NAV FIELD32(0x000c0000)
#define GF40_PROT_CFG_PROTECT_NAV_SHORT FIELD32(0x00040000)
#define GF40_PROT_CFG_PROTECT_NAV_LONG FIELD32(0x00080000)
#define GF40_PROT_CFG_TX_OP_ALLOW_CCK FIELD32(0x00100000)
#define GF40_PROT_CFG_TX_OP_ALLOW_OFDM FIELD32(0x00200000)
#define GF40_PROT_CFG_TX_OP_ALLOW_MM20 FIELD32(0x00400000)
@ -1701,11 +1725,14 @@ struct mac_iveiv_entry {
*/
/*
* BBP 1: TX Antenna & Power
* POWER: 0 - normal, 1 - drop tx power by 6dBm, 2 - drop tx power by 12dBm,
* 3 - increase tx power by 6dBm
* BBP 1: TX Antenna & Power Control
* POWER_CTRL:
* 0 - normal,
* 1 - drop tx power by 6dBm,
* 2 - drop tx power by 12dBm,
* 3 - increase tx power by 6dBm
*/
#define BBP1_TX_POWER FIELD8(0x07)
#define BBP1_TX_POWER_CTRL FIELD8(0x07)
#define BBP1_TX_ANTENNA FIELD8(0x18)
/*
@ -1719,6 +1746,13 @@ struct mac_iveiv_entry {
*/
#define BBP4_TX_BF FIELD8(0x01)
#define BBP4_BANDWIDTH FIELD8(0x18)
#define BBP4_MAC_IF_CTRL FIELD8(0x40)
/*
* BBP 109
*/
#define BBP109_TX0_POWER FIELD8(0x0f)
#define BBP109_TX1_POWER FIELD8(0xf0)
/*
* BBP 138: Unknown
@ -1728,6 +1762,11 @@ struct mac_iveiv_entry {
#define BBP138_TX_DAC1 FIELD8(0x20)
#define BBP138_TX_DAC2 FIELD8(0x40)
/*
* BBP 152: Rx Ant
*/
#define BBP152_RX_DEFAULT_ANT FIELD8(0x80)
/*
* RFCSR registers
* The wordsize of the RFCSR is 8 bits.
@ -1737,11 +1776,17 @@ struct mac_iveiv_entry {
* RFCSR 1:
*/
#define RFCSR1_RF_BLOCK_EN FIELD8(0x01)
#define RFCSR1_PLL_PD FIELD8(0x02)
#define RFCSR1_RX0_PD FIELD8(0x04)
#define RFCSR1_TX0_PD FIELD8(0x08)
#define RFCSR1_RX1_PD FIELD8(0x10)
#define RFCSR1_TX1_PD FIELD8(0x20)
/*
* RFCSR 2:
*/
#define RFCSR2_RESCAL_EN FIELD8(0x80)
/*
* RFCSR 6:
*/
@ -1753,6 +1798,11 @@ struct mac_iveiv_entry {
*/
#define RFCSR7_RF_TUNING FIELD8(0x01)
/*
* RFCSR 11:
*/
#define RFCSR11_R FIELD8(0x03)
/*
* RFCSR 12:
*/
@ -1774,6 +1824,7 @@ struct mac_iveiv_entry {
#define RFCSR17_TXMIXER_GAIN FIELD8(0x07)
#define RFCSR17_TX_LO1_EN FIELD8(0x08)
#define RFCSR17_R FIELD8(0x20)
#define RFCSR17_CODE FIELD8(0x7f)
/*
* RFCSR 20:
@ -1806,6 +1857,9 @@ struct mac_iveiv_entry {
/*
* RFCSR 30:
*/
#define RFCSR30_TX_H20M FIELD8(0x02)
#define RFCSR30_RX_H20M FIELD8(0x04)
#define RFCSR30_RX_VCM FIELD8(0x18)
#define RFCSR30_RF_CALIBRATION FIELD8(0x80)
/*
@ -1814,6 +1868,21 @@ struct mac_iveiv_entry {
#define RFCSR31_RX_AGC_FC FIELD8(0x1f)
#define RFCSR31_RX_H20M FIELD8(0x20)
/*
* RFCSR 38:
*/
#define RFCSR38_RX_LO1_EN FIELD8(0x20)
/*
* RFCSR 39:
*/
#define RFCSR39_RX_LO2_EN FIELD8(0x80)
/*
* RFCSR 49:
*/
#define RFCSR49_TX FIELD8(0x3f)
/*
* RF registers
*/
@ -1846,6 +1915,11 @@ struct mac_iveiv_entry {
* The wordsize of the EEPROM is 16 bits.
*/
/*
* Chip ID
*/
#define EEPROM_CHIP_ID 0x0000
/*
* EEPROM Version
*/
@ -1999,23 +2073,26 @@ struct mac_iveiv_entry {
#define EEPROM_RSSI_A2_LNA_A2 FIELD16(0xff00)
/*
* EEPROM Maximum TX power values
* EEPROM EIRP Maximum TX power values(unit: dbm)
*/
#define EEPROM_MAX_TX_POWER 0x0027
#define EEPROM_MAX_TX_POWER_24GHZ FIELD16(0x00ff)
#define EEPROM_MAX_TX_POWER_5GHZ FIELD16(0xff00)
#define EEPROM_EIRP_MAX_TX_POWER 0x0027
#define EEPROM_EIRP_MAX_TX_POWER_2GHZ FIELD16(0x00ff)
#define EEPROM_EIRP_MAX_TX_POWER_5GHZ FIELD16(0xff00)
/*
* EEPROM TXpower delta: 20MHZ AND 40 MHZ use different power.
* This is delta in 40MHZ.
* VALUE: Tx Power dalta value (MAX=4)
* VALUE: Tx Power dalta value, MAX=4(unit: dbm)
* TYPE: 1: Plus the delta value, 0: minus the delta value
* TXPOWER: Enable:
* ENABLE: enable tx power compensation for 40BW
*/
#define EEPROM_TXPOWER_DELTA 0x0028
#define EEPROM_TXPOWER_DELTA_VALUE FIELD16(0x003f)
#define EEPROM_TXPOWER_DELTA_TYPE FIELD16(0x0040)
#define EEPROM_TXPOWER_DELTA_TXPOWER FIELD16(0x0080)
#define EEPROM_TXPOWER_DELTA_VALUE_2G FIELD16(0x003f)
#define EEPROM_TXPOWER_DELTA_TYPE_2G FIELD16(0x0040)
#define EEPROM_TXPOWER_DELTA_ENABLE_2G FIELD16(0x0080)
#define EEPROM_TXPOWER_DELTA_VALUE_5G FIELD16(0x3f00)
#define EEPROM_TXPOWER_DELTA_TYPE_5G FIELD16(0x4000)
#define EEPROM_TXPOWER_DELTA_ENABLE_5G FIELD16(0x8000)
/*
* EEPROM TXPOWER 802.11BG
@ -2068,6 +2145,7 @@ struct mac_iveiv_entry {
#define MCU_LED_LED_POLARITY 0x54
#define MCU_RADAR 0x60
#define MCU_BOOT_SIGNAL 0x72
#define MCU_ANT_SELECT 0X73
#define MCU_BBP_SIGNAL 0x80
#define MCU_POWER_SAVE 0x83
@ -2212,4 +2290,9 @@ struct mac_iveiv_entry {
#define TXPOWER_A_TO_DEV(__txpower) \
clamp_t(char, __txpower, MIN_A_TXPOWER, MAX_A_TXPOWER)
/*
* Board's maximun TX power limitation
*/
#define EIRP_MAX_TX_POWER_LIMIT 0x50
#endif /* RT2800_H */

File diff suppressed because it is too large Load Diff

View File

@ -493,6 +493,13 @@ static int rt2800pci_init_registers(struct rt2x00_dev *rt2x00dev)
rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f);
rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00);
if (rt2x00_rt(rt2x00dev, RT5390)) {
rt2800_register_read(rt2x00dev, AUX_CTRL, &reg);
rt2x00_set_field32(&reg, AUX_CTRL_FORCE_PCIE_CLK, 1);
rt2x00_set_field32(&reg, AUX_CTRL_WAKE_PCIE_EN, 1);
rt2800_register_write(rt2x00dev, AUX_CTRL, reg);
}
rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003);
rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
@ -1119,11 +1126,16 @@ static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = {
{ PCI_DEVICE(0x1814, 0x3390), PCI_DEVICE_DATA(&rt2800pci_ops) },
#endif
#ifdef CONFIG_RT2800PCI_RT35XX
{ PCI_DEVICE(0x1432, 0x7711), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1432, 0x7722), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1814, 0x3060), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1814, 0x3062), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1814, 0x3562), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1814, 0x3592), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1814, 0x3593), PCI_DEVICE_DATA(&rt2800pci_ops) },
#endif
#ifdef CONFIG_RT2800PCI_RT53XX
{ PCI_DEVICE(0x1814, 0x5390), PCI_DEVICE_DATA(&rt2800pci_ops) },
#endif
{ 0, }
};

View File

@ -189,6 +189,7 @@ struct rt2x00_chip {
#define RT3572 0x3572
#define RT3593 0x3593 /* PCIe */
#define RT3883 0x3883 /* WSOC */
#define RT5390 0x5390 /* 2.4GHz */
u16 rf;
u16 rev;
@ -225,6 +226,8 @@ struct channel_info {
struct antenna_setup {
enum antenna rx;
enum antenna tx;
u8 rx_chain_num;
u8 tx_chain_num;
};
/*
@ -665,6 +668,7 @@ enum rt2x00_flags {
*/
CONFIG_SUPPORT_HW_BUTTON,
CONFIG_SUPPORT_HW_CRYPTO,
CONFIG_SUPPORT_POWER_LIMIT,
DRIVER_SUPPORT_CONTROL_FILTERS,
DRIVER_SUPPORT_CONTROL_FILTER_PSPOLL,
DRIVER_SUPPORT_PRE_TBTT_INTERRUPT,

View File

@ -69,7 +69,6 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
txdesc->mcs |= 0x08;
}
/*
* This frame is eligible for an AMPDU, however, don't aggregate
* frames that are intended to probe a specific tx rate.

View File

@ -139,9 +139,9 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
* either RTS or CTS-to-self frame and handles everything
* inside the hardware.
*/
if ((tx_info->control.rates[0].flags & (IEEE80211_TX_RC_USE_RTS_CTS |
IEEE80211_TX_RC_USE_CTS_PROTECT)) &&
!rt2x00dev->ops->hw->set_rts_threshold) {
if (!rt2x00dev->ops->hw->set_rts_threshold &&
(tx_info->control.rates[0].flags & (IEEE80211_TX_RC_USE_RTS_CTS |
IEEE80211_TX_RC_USE_CTS_PROTECT))) {
if (rt2x00queue_available(queue) <= 1)
goto exit_fail;

View File

@ -365,13 +365,10 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
/*
* Beacons and probe responses require the tsf timestamp
* to be inserted into the frame, except for a frame that has been injected
* through a monitor interface. This latter is needed for testing a
* monitor interface.
* to be inserted into the frame.
*/
if ((ieee80211_is_beacon(hdr->frame_control) ||
ieee80211_is_probe_resp(hdr->frame_control)) &&
(!(tx_info->flags & IEEE80211_TX_CTL_INJECTED)))
if (ieee80211_is_beacon(hdr->frame_control) ||
ieee80211_is_probe_resp(hdr->frame_control))
__set_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags);
/*

View File

@ -1978,13 +1978,14 @@ static void rt61pci_write_beacon(struct queue_entry *entry,
struct queue_entry_priv_pci *entry_priv = entry->priv_data;
unsigned int beacon_base;
unsigned int padding_len;
u32 reg;
u32 orig_reg, reg;
/*
* Disable beaconing while we are reloading the beacon data,
* otherwise we might be sending out invalid data.
*/
rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, &reg);
orig_reg = reg;
rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0);
rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
@ -2002,7 +2003,14 @@ static void rt61pci_write_beacon(struct queue_entry *entry,
* Write entire beacon with descriptor and padding to register.
*/
padding_len = roundup(entry->skb->len, 4) - entry->skb->len;
skb_pad(entry->skb, padding_len);
if (padding_len && skb_pad(entry->skb, padding_len)) {
ERROR(rt2x00dev, "Failure padding beacon, aborting\n");
/* skb freed by skb_pad() on failure */
entry->skb = NULL;
rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, orig_reg);
return;
}
beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
rt2x00pci_register_multiwrite(rt2x00dev, beacon_base,
entry_priv->desc, TXINFO_SIZE);

View File

@ -1533,13 +1533,14 @@ static void rt73usb_write_beacon(struct queue_entry *entry,
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
unsigned int beacon_base;
unsigned int padding_len;
u32 reg;
u32 orig_reg, reg;
/*
* Disable beaconing while we are reloading the beacon data,
* otherwise we might be sending out invalid data.
*/
rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
orig_reg = reg;
rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0);
rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
@ -1563,7 +1564,14 @@ static void rt73usb_write_beacon(struct queue_entry *entry,
* Write entire beacon with descriptor and padding to register.
*/
padding_len = roundup(entry->skb->len, 4) - entry->skb->len;
skb_pad(entry->skb, padding_len);
if (padding_len && skb_pad(entry->skb, padding_len)) {
ERROR(rt2x00dev, "Failure padding beacon, aborting\n");
/* skb freed by skb_pad() on failure */
entry->skb = NULL;
rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, orig_reg);
return;
}
beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
rt2x00usb_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data,
entry->skb->len + padding_len);

View File

@ -1,6 +1,6 @@
config RTL8192CE
tristate "Realtek RTL8192CE/RTL8188SE Wireless Network Adapter"
depends on MAC80211 && EXPERIMENTAL
tristate "Realtek RTL8192CE/RTL8188CE Wireless Network Adapter"
depends on MAC80211 && PCI && EXPERIMENTAL
select FW_LOADER
select RTLWIFI
---help---
@ -9,7 +9,18 @@ config RTL8192CE
If you choose to build it as a module, it will be called rtl8192ce
config RTL8192CU
tristate "Realtek RTL8192CU/RTL8188CU USB Wireless Network Adapter"
depends on MAC80211 && USB && EXPERIMENTAL
select FW_LOADER
select RTLWIFI
---help---
This is the driver for Realtek RTL8192CU/RTL8188CU 802.11n USB
wireless network adapters.
If you choose to build it as a module, it will be called rtl8192cu
config RTLWIFI
tristate
depends on RTL8192CE
depends on RTL8192CE || RTL8192CU
default m

View File

@ -8,6 +8,10 @@ rtlwifi-objs := \
pci.o \
ps.o \
rc.o \
regd.o
regd.o \
usb.o
obj-$(CONFIG_RTL8192CE) += rtl8192ce/
obj-$(CONFIG_RTL8192CU) += rtl8192cu/
ccflags-y += -D__CHECK_ENDIAN__

View File

@ -144,7 +144,7 @@ static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw,
ht_cap->mcs.rx_mask[1] = 0xFF;
ht_cap->mcs.rx_mask[4] = 0x01;
ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS15;
ht_cap->mcs.rx_highest = cpu_to_le16(MAX_BIT_RATE_40MHZ_MCS15);
} else if (get_rf_type(rtlphy) == RF_1T1R) {
RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("1T1R\n"));
@ -153,7 +153,7 @@ static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw,
ht_cap->mcs.rx_mask[1] = 0x00;
ht_cap->mcs.rx_mask[4] = 0x01;
ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS7;
ht_cap->mcs.rx_highest = cpu_to_le16(MAX_BIT_RATE_40MHZ_MCS7);
}
}
@ -399,21 +399,21 @@ static void _rtl_query_protection_mode(struct ieee80211_hw *hw,
u8 rate_flag = info->control.rates[0].flags;
/* Common Settings */
tcb_desc->b_rts_stbc = false;
tcb_desc->b_cts_enable = false;
tcb_desc->rts_stbc = false;
tcb_desc->cts_enable = false;
tcb_desc->rts_sc = 0;
tcb_desc->b_rts_bw = false;
tcb_desc->b_rts_use_shortpreamble = false;
tcb_desc->b_rts_use_shortgi = false;
tcb_desc->rts_bw = false;
tcb_desc->rts_use_shortpreamble = false;
tcb_desc->rts_use_shortgi = false;
if (rate_flag & IEEE80211_TX_RC_USE_CTS_PROTECT) {
/* Use CTS-to-SELF in protection mode. */
tcb_desc->b_rts_enable = true;
tcb_desc->b_cts_enable = true;
tcb_desc->rts_enable = true;
tcb_desc->cts_enable = true;
tcb_desc->rts_rate = rtlpriv->cfg->maps[RTL_RC_OFDM_RATE24M];
} else if (rate_flag & IEEE80211_TX_RC_USE_RTS_CTS) {
/* Use RTS-CTS in protection mode. */
tcb_desc->b_rts_enable = true;
tcb_desc->rts_enable = true;
tcb_desc->rts_rate = rtlpriv->cfg->maps[RTL_RC_OFDM_RATE24M];
}
@ -429,7 +429,7 @@ static void _rtl_txrate_selectmode(struct ieee80211_hw *hw,
if (mac->opmode == NL80211_IFTYPE_STATION)
tcb_desc->ratr_index = 0;
else if (mac->opmode == NL80211_IFTYPE_ADHOC) {
if (tcb_desc->b_multicast || tcb_desc->b_broadcast) {
if (tcb_desc->multicast || tcb_desc->broadcast) {
tcb_desc->hw_rate =
rtlpriv->cfg->maps[RTL_RC_CCK_RATE2M];
tcb_desc->use_driver_rate = 1;
@ -439,7 +439,7 @@ static void _rtl_txrate_selectmode(struct ieee80211_hw *hw,
}
}
if (rtlpriv->dm.b_useramask) {
if (rtlpriv->dm.useramask) {
/* TODO we will differentiate adhoc and station futrue */
tcb_desc->mac_id = 0;
@ -461,19 +461,19 @@ static void _rtl_query_bandwidth_mode(struct ieee80211_hw *hw,
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
tcb_desc->b_packet_bw = false;
tcb_desc->packet_bw = false;
if (!mac->bw_40 || !mac->ht_enable)
return;
if (tcb_desc->b_multicast || tcb_desc->b_broadcast)
if (tcb_desc->multicast || tcb_desc->broadcast)
return;
/*use legency rate, shall use 20MHz */
if (tcb_desc->hw_rate <= rtlpriv->cfg->maps[RTL_RC_OFDM_RATE54M])
return;
tcb_desc->b_packet_bw = true;
tcb_desc->packet_bw = true;
}
static u8 _rtl_get_highest_n_rate(struct ieee80211_hw *hw)
@ -498,7 +498,7 @@ void rtl_get_tcb_desc(struct ieee80211_hw *hw,
struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw));
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
struct ieee80211_rate *txrate;
u16 fc = le16_to_cpu(hdr->frame_control);
__le16 fc = hdr->frame_control;
memset(tcb_desc, 0, sizeof(struct rtl_tcb_desc));
@ -545,9 +545,9 @@ void rtl_get_tcb_desc(struct ieee80211_hw *hw,
}
if (is_multicast_ether_addr(ieee80211_get_DA(hdr)))
tcb_desc->b_multicast = 1;
tcb_desc->multicast = 1;
else if (is_broadcast_ether_addr(ieee80211_get_DA(hdr)))
tcb_desc->b_broadcast = 1;
tcb_desc->broadcast = 1;
_rtl_txrate_selectmode(hw, tcb_desc);
_rtl_query_bandwidth_mode(hw, tcb_desc);
@ -570,7 +570,7 @@ bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb)
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
u16 fc = le16_to_cpu(hdr->frame_control);
__le16 fc = hdr->frame_control;
if (ieee80211_is_auth(fc)) {
RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, ("MAC80211_LINKING\n"));
@ -587,7 +587,7 @@ bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
struct rtl_priv *rtlpriv = rtl_priv(hw);
u16 fc = le16_to_cpu(hdr->frame_control);
__le16 fc = hdr->frame_control;
u8 *act = (u8 *) (((u8 *) skb->data + MAC80211_3ADDR_LEN));
u8 category;
@ -632,7 +632,7 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
u16 fc = le16_to_cpu(hdr->frame_control);
__le16 fc = hdr->frame_control;
u16 ether_type;
u8 mac_hdr_len = ieee80211_get_hdrlen_from_skb(skb);
const struct iphdr *ip;
@ -646,7 +646,6 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
ip = (struct iphdr *)((u8 *) skb->data + mac_hdr_len +
SNAP_SIZE + PROTOC_TYPE_SIZE);
ether_type = *(u16 *) ((u8 *) skb->data + mac_hdr_len + SNAP_SIZE);
ether_type = ntohs(ether_type);
if (ETH_P_IP == ether_type) {
if (IPPROTO_UDP == ip->protocol) {
@ -690,7 +689,8 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
}
return true;
} else if (0x86DD == ether_type) {
} else if (ETH_P_IPV6 == ether_type) {
/* IPv6 */
return true;
}
@ -777,10 +777,10 @@ void rtl_watchdog_wq_callback(void *data)
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
bool b_busytraffic = false;
bool b_higher_busytraffic = false;
bool b_higher_busyrxtraffic = false;
bool b_higher_busytxtraffic = false;
bool busytraffic = false;
bool higher_busytraffic = false;
bool higher_busyrxtraffic = false;
bool higher_busytxtraffic = false;
u8 idx = 0;
u32 rx_cnt_inp4eriod = 0;
@ -788,7 +788,7 @@ void rtl_watchdog_wq_callback(void *data)
u32 aver_rx_cnt_inperiod = 0;
u32 aver_tx_cnt_inperiod = 0;
bool benter_ps = false;
bool enter_ps = false;
if (is_hal_stop(rtlhal))
return;
@ -832,29 +832,29 @@ void rtl_watchdog_wq_callback(void *data)
/* (2) check traffic busy */
if (aver_rx_cnt_inperiod > 100 || aver_tx_cnt_inperiod > 100)
b_busytraffic = true;
busytraffic = true;
/* Higher Tx/Rx data. */
if (aver_rx_cnt_inperiod > 4000 ||
aver_tx_cnt_inperiod > 4000) {
b_higher_busytraffic = true;
higher_busytraffic = true;
/* Extremely high Rx data. */
if (aver_rx_cnt_inperiod > 5000)
b_higher_busyrxtraffic = true;
higher_busyrxtraffic = true;
else
b_higher_busytxtraffic = false;
higher_busytxtraffic = false;
}
if (((rtlpriv->link_info.num_rx_inperiod +
rtlpriv->link_info.num_tx_inperiod) > 8) ||
(rtlpriv->link_info.num_rx_inperiod > 2))
benter_ps = false;
enter_ps = false;
else
benter_ps = true;
enter_ps = true;
/* LeisurePS only work in infra mode. */
if (benter_ps)
if (enter_ps)
rtl_lps_enter(hw);
else
rtl_lps_leave(hw);
@ -863,9 +863,9 @@ void rtl_watchdog_wq_callback(void *data)
rtlpriv->link_info.num_rx_inperiod = 0;
rtlpriv->link_info.num_tx_inperiod = 0;
rtlpriv->link_info.b_busytraffic = b_busytraffic;
rtlpriv->link_info.b_higher_busytraffic = b_higher_busytraffic;
rtlpriv->link_info.b_higher_busyrxtraffic = b_higher_busyrxtraffic;
rtlpriv->link_info.busytraffic = busytraffic;
rtlpriv->link_info.higher_busytraffic = higher_busytraffic;
rtlpriv->link_info.higher_busyrxtraffic = higher_busyrxtraffic;
}

View File

@ -30,6 +30,7 @@
#define __RTL_BASE_H__
#define RTL_DUMMY_OFFSET 0
#define RTL_RX_DESC_SIZE 24
#define RTL_DUMMY_UNIT 8
#define RTL_TX_DUMMY_SIZE (RTL_DUMMY_OFFSET * RTL_DUMMY_UNIT)
#define RTL_TX_DESC_SIZE 32
@ -52,46 +53,22 @@
#define FRAME_OFFSET_SEQUENCE 22
#define FRAME_OFFSET_ADDRESS4 24
#define SET_80211_HDR_FRAME_CONTROL(_hdr, _val) \
WRITEEF2BYTE(_hdr, _val)
#define SET_80211_HDR_TYPE_AND_SUBTYPE(_hdr, _val) \
WRITEEF1BYTE(_hdr, _val)
#define SET_80211_HDR_PWR_MGNT(_hdr, _val) \
SET_BITS_TO_LE_2BYTE(_hdr, 12, 1, _val)
#define SET_80211_HDR_TO_DS(_hdr, _val) \
SET_BITS_TO_LE_2BYTE(_hdr, 8, 1, _val)
#define SET_80211_PS_POLL_AID(_hdr, _val) \
WRITEEF2BYTE(((u8 *)(_hdr)) + 2, _val)
(*(u16 *)((u8 *)(_hdr) + 2) = le16_to_cpu(_val))
#define SET_80211_PS_POLL_BSSID(_hdr, _val) \
CP_MACADDR(((u8 *)(_hdr)) + 4, (u8 *)(_val))
memcpy(((u8 *)(_hdr)) + 4, (u8 *)(_val), ETH_ALEN)
#define SET_80211_PS_POLL_TA(_hdr, _val) \
CP_MACADDR(((u8 *)(_hdr)) + 10, (u8 *)(_val))
memcpy(((u8 *)(_hdr)) + 10, (u8 *)(_val), ETH_ALEN)
#define SET_80211_HDR_DURATION(_hdr, _val) \
WRITEEF2BYTE((u8 *)(_hdr)+FRAME_OFFSET_DURATION, _val)
(*(u16 *)((u8 *)(_hdr) + FRAME_OFFSET_DURATION) = le16_to_cpu(_val))
#define SET_80211_HDR_ADDRESS1(_hdr, _val) \
CP_MACADDR((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS1, (u8*)(_val))
memcpy((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS1, (u8*)(_val), ETH_ALEN)
#define SET_80211_HDR_ADDRESS2(_hdr, _val) \
CP_MACADDR((u8 *)(_hdr) + FRAME_OFFSET_ADDRESS2, (u8 *)(_val))
memcpy((u8 *)(_hdr) + FRAME_OFFSET_ADDRESS2, (u8 *)(_val), ETH_ALEN)
#define SET_80211_HDR_ADDRESS3(_hdr, _val) \
CP_MACADDR((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS3, (u8 *)(_val))
#define SET_80211_HDR_FRAGMENT_SEQUENCE(_hdr, _val) \
WRITEEF2BYTE((u8 *)(_hdr)+FRAME_OFFSET_SEQUENCE, _val)
#define SET_BEACON_PROBE_RSP_TIME_STAMP_LOW(__phdr, __val) \
WRITEEF4BYTE(((u8 *)(__phdr)) + 24, __val)
#define SET_BEACON_PROBE_RSP_TIME_STAMP_HIGH(__phdr, __val) \
WRITEEF4BYTE(((u8 *)(__phdr)) + 28, __val)
#define SET_BEACON_PROBE_RSP_BEACON_INTERVAL(__phdr, __val) \
WRITEEF2BYTE(((u8 *)(__phdr)) + 32, __val)
#define GET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr) \
READEF2BYTE(((u8 *)(__phdr)) + 34)
#define SET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, __val) \
WRITEEF2BYTE(((u8 *)(__phdr)) + 34, __val)
#define MASK_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, __val) \
SET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, \
(GET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr) & (~(__val))))
memcpy((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS3, (u8 *)(_val), ETH_ALEN)
int rtl_init_core(struct ieee80211_hw *hw);
void rtl_deinit_core(struct ieee80211_hw *hw);

View File

@ -434,9 +434,9 @@ static int rtl_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
aci = _rtl_get_hal_qnum(queue);
mac->ac[aci].aifs = param->aifs;
mac->ac[aci].cw_min = param->cw_min;
mac->ac[aci].cw_max = param->cw_max;
mac->ac[aci].tx_op = param->txop;
mac->ac[aci].cw_min = cpu_to_le16(param->cw_min);
mac->ac[aci].cw_max = cpu_to_le16(param->cw_max);
mac->ac[aci].tx_op = cpu_to_le16(param->txop);
memcpy(&mac->edca_param[aci], param, sizeof(*param));
rtlpriv->cfg->ops->set_qos(hw, aci);
return 0;
@ -666,7 +666,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
(u8 *) (&basic_rates));
if (rtlpriv->dm.b_useramask)
if (rtlpriv->dm.useramask)
rtlpriv->cfg->ops->update_rate_mask(hw, 0);
else
rtlpriv->cfg->ops->update_rate_table(hw);
@ -681,7 +681,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
*/
if (changed & BSS_CHANGED_ASSOC) {
if (bss_conf->assoc) {
if (ppsc->b_fwctrl_lps) {
if (ppsc->fwctrl_lps) {
u8 mstatus = RT_MEDIA_CONNECT;
rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_H2C_FW_JOINBSSRPT,
@ -689,7 +689,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
ppsc->report_linked = true;
}
} else {
if (ppsc->b_fwctrl_lps) {
if (ppsc->fwctrl_lps) {
u8 mstatus = RT_MEDIA_DISCONNECT;
rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_H2C_FW_JOINBSSRPT,
@ -818,7 +818,7 @@ static void rtl_op_sw_scan_complete(struct ieee80211_hw *hw)
/* fix fwlps issue */
rtlpriv->cfg->ops->set_network_type(hw, mac->opmode);
if (rtlpriv->dm.b_useramask)
if (rtlpriv->dm.useramask)
rtlpriv->cfg->ops->update_rate_mask(hw, 0);
else
rtlpriv->cfg->ops->update_rate_table(hw);

View File

@ -105,6 +105,7 @@
#define COMP_MAC80211 BIT(26)
#define COMP_REGD BIT(27)
#define COMP_CHAN BIT(28)
#define COMP_USB BIT(29)
/*--------------------------------------------------------------
Define the rt_print components

View File

@ -50,7 +50,7 @@ static void _rtl_pci_update_default_setting(struct ieee80211_hw *hw)
u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor;
ppsc->reg_rfps_level = 0;
ppsc->b_support_aspm = 0;
ppsc->support_aspm = 0;
/*Update PCI ASPM setting */
ppsc->const_amdpci_aspm = rtlpci->const_amdpci_aspm;
@ -115,29 +115,29 @@ static void _rtl_pci_update_default_setting(struct ieee80211_hw *hw)
switch (rtlpci->const_support_pciaspm) {
case 0:{
/*Not support ASPM. */
bool b_support_aspm = false;
ppsc->b_support_aspm = b_support_aspm;
bool support_aspm = false;
ppsc->support_aspm = support_aspm;
break;
}
case 1:{
/*Support ASPM. */
bool b_support_aspm = true;
bool b_support_backdoor = true;
ppsc->b_support_aspm = b_support_aspm;
bool support_aspm = true;
bool support_backdoor = true;
ppsc->support_aspm = support_aspm;
/*if(priv->oem_id == RT_CID_TOSHIBA &&
!priv->ndis_adapter.amd_l1_patch)
b_support_backdoor = false; */
support_backdoor = false; */
ppsc->b_support_backdoor = b_support_backdoor;
ppsc->support_backdoor = support_backdoor;
break;
}
case 2:
/*ASPM value set by chipset. */
if (pcibridge_vendor == PCI_BRIDGE_VENDOR_INTEL) {
bool b_support_aspm = true;
ppsc->b_support_aspm = b_support_aspm;
bool support_aspm = true;
ppsc->support_aspm = support_aspm;
}
break;
default:
@ -476,9 +476,9 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio)
skb = __skb_dequeue(&ring->queue);
pci_unmap_single(rtlpci->pdev,
le32_to_cpu(rtlpriv->cfg->ops->
rtlpriv->cfg->ops->
get_desc((u8 *) entry, true,
HW_DESC_TXBUFF_ADDR)),
HW_DESC_TXBUFF_ADDR),
skb->len, PCI_DMA_TODEVICE);
RT_TRACE(rtlpriv, (COMP_INTR | COMP_SEND), DBG_TRACE,
@ -557,7 +557,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
return;
} else {
struct ieee80211_hdr *hdr;
u16 fc;
__le16 fc;
struct sk_buff *new_skb = NULL;
rtlpriv->cfg->ops->query_rx_desc(hw, &stats,
@ -583,9 +583,9 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
*/
hdr = (struct ieee80211_hdr *)(skb->data);
fc = le16_to_cpu(hdr->frame_control);
fc = hdr->frame_control;
if (!stats.b_crc) {
if (!stats.crc) {
memcpy(IEEE80211_SKB_RXCB(skb), &rx_status,
sizeof(rx_status));
@ -666,7 +666,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
}
done:
bufferaddress = cpu_to_le32(*((dma_addr_t *) skb->cb));
bufferaddress = (u32)(*((dma_addr_t *) skb->cb));
tmp_one = 1;
rtlpriv->cfg->ops->set_desc((u8 *) pdesc, false,
HW_DESC_RXBUFF_ADDR,
@ -690,75 +690,6 @@ done:
}
void _rtl_pci_tx_interrupt(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
int prio;
for (prio = 0; prio < RTL_PCI_MAX_TX_QUEUE_COUNT; prio++) {
struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[prio];
while (skb_queue_len(&ring->queue)) {
struct rtl_tx_desc *entry = &ring->desc[ring->idx];
struct sk_buff *skb;
struct ieee80211_tx_info *info;
u8 own;
/*
*beacon packet will only use the first
*descriptor defautly, and the own may not
*be cleared by the hardware, and
*beacon will free in prepare beacon
*/
if (prio == BEACON_QUEUE || prio == TXCMD_QUEUE ||
prio == HCCA_QUEUE)
break;
own = (u8)rtlpriv->cfg->ops->get_desc((u8 *)entry,
true,
HW_DESC_OWN);
if (own)
break;
skb = __skb_dequeue(&ring->queue);
pci_unmap_single(rtlpci->pdev,
le32_to_cpu(rtlpriv->cfg->ops->
get_desc((u8 *) entry,
true,
HW_DESC_TXBUFF_ADDR)),
skb->len, PCI_DMA_TODEVICE);
ring->idx = (ring->idx + 1) % ring->entries;
info = IEEE80211_SKB_CB(skb);
ieee80211_tx_info_clear_status(info);
info->flags |= IEEE80211_TX_STAT_ACK;
/*info->status.rates[0].count = 1; */
ieee80211_tx_status_irqsafe(hw, skb);
if ((ring->entries - skb_queue_len(&ring->queue))
== 2 && prio != BEACON_QUEUE) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
("more desc left, wake "
"skb_queue@%d,ring->idx = %d,"
"skb_queue_len = 0x%d\n",
prio, ring->idx,
skb_queue_len(&ring->queue)));
ieee80211_wake_queue(hw,
skb_get_queue_mapping
(skb));
}
skb = NULL;
}
}
}
static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id)
{
struct ieee80211_hw *hw = dev_id;
@ -959,17 +890,17 @@ static void _rtl_pci_init_struct(struct ieee80211_hw *hw,
rtlhal->hw = hw;
rtlpci->pdev = pdev;
ppsc->b_inactiveps = false;
ppsc->b_leisure_ps = true;
ppsc->b_fwctrl_lps = true;
ppsc->b_reg_fwctrl_lps = 3;
ppsc->inactiveps = false;
ppsc->leisure_ps = true;
ppsc->fwctrl_lps = true;
ppsc->reg_fwctrl_lps = 3;
ppsc->reg_max_lps_awakeintvl = 5;
if (ppsc->b_reg_fwctrl_lps == 1)
if (ppsc->reg_fwctrl_lps == 1)
ppsc->fwctrl_psmode = FW_PS_MIN_MODE;
else if (ppsc->b_reg_fwctrl_lps == 2)
else if (ppsc->reg_fwctrl_lps == 2)
ppsc->fwctrl_psmode = FW_PS_MAX_MODE;
else if (ppsc->b_reg_fwctrl_lps == 3)
else if (ppsc->reg_fwctrl_lps == 3)
ppsc->fwctrl_psmode = FW_PS_DTIM_MODE;
/*Tx/Rx related var */
@ -1024,9 +955,8 @@ static int _rtl_pci_init_tx_ring(struct ieee80211_hw *hw,
("queue:%d, ring_addr:%p\n", prio, ring));
for (i = 0; i < entries; i++) {
nextdescaddress = cpu_to_le32((u32) dma +
((i + 1) % entries) *
sizeof(*ring));
nextdescaddress = (u32) dma + ((i + 1) % entries) *
sizeof(*ring);
rtlpriv->cfg->ops->set_desc((u8 *)&(ring[i]),
true, HW_DESC_TX_NEXTDESC_ADDR,
@ -1090,7 +1020,7 @@ static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw)
rtlpci->rxbuffersize,
PCI_DMA_FROMDEVICE);
bufferaddress = cpu_to_le32(*((dma_addr_t *)skb->cb));
bufferaddress = (u32)(*((dma_addr_t *)skb->cb));
rtlpriv->cfg->ops->set_desc((u8 *)entry, false,
HW_DESC_RXBUFF_ADDR,
(u8 *)&bufferaddress);
@ -1121,9 +1051,9 @@ static void _rtl_pci_free_tx_ring(struct ieee80211_hw *hw,
struct sk_buff *skb = __skb_dequeue(&ring->queue);
pci_unmap_single(rtlpci->pdev,
le32_to_cpu(rtlpriv->cfg->
rtlpriv->cfg->
ops->get_desc((u8 *) entry, true,
HW_DESC_TXBUFF_ADDR)),
HW_DESC_TXBUFF_ADDR),
skb->len, PCI_DMA_TODEVICE);
kfree_skb(skb);
ring->idx = (ring->idx + 1) % ring->entries;
@ -1255,11 +1185,11 @@ int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw)
__skb_dequeue(&ring->queue);
pci_unmap_single(rtlpci->pdev,
le32_to_cpu(rtlpriv->cfg->ops->
rtlpriv->cfg->ops->
get_desc((u8 *)
entry,
true,
HW_DESC_TXBUFF_ADDR)),
HW_DESC_TXBUFF_ADDR),
skb->len, PCI_DMA_TODEVICE);
kfree_skb(skb);
ring->idx = (ring->idx + 1) % ring->entries;
@ -1273,7 +1203,7 @@ int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw)
return 0;
}
unsigned int _rtl_mac_to_hwqueue(u16 fc,
static unsigned int _rtl_mac_to_hwqueue(__le16 fc,
unsigned int mac80211_queue_index)
{
unsigned int hw_queue_index;
@ -1312,7 +1242,7 @@ out:
return hw_queue_index;
}
int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
static int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
@ -1323,7 +1253,7 @@ int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
unsigned int queue_index, hw_queue;
unsigned long flags;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
u16 fc = le16_to_cpu(hdr->frame_control);
__le16 fc = hdr->frame_control;
u8 *pda_addr = hdr->addr1;
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
/*ssn */
@ -1429,7 +1359,7 @@ int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
return 0;
}
void rtl_pci_deinit(struct ieee80211_hw *hw)
static void rtl_pci_deinit(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
@ -1444,7 +1374,7 @@ void rtl_pci_deinit(struct ieee80211_hw *hw)
}
int rtl_pci_init(struct ieee80211_hw *hw, struct pci_dev *pdev)
static int rtl_pci_init(struct ieee80211_hw *hw, struct pci_dev *pdev)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
int err;
@ -1461,7 +1391,7 @@ int rtl_pci_init(struct ieee80211_hw *hw, struct pci_dev *pdev)
return 1;
}
int rtl_pci_start(struct ieee80211_hw *hw)
static int rtl_pci_start(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
@ -1496,7 +1426,7 @@ int rtl_pci_start(struct ieee80211_hw *hw)
return 0;
}
void rtl_pci_stop(struct ieee80211_hw *hw)
static void rtl_pci_stop(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
@ -1838,7 +1768,7 @@ fail3:
ieee80211_free_hw(hw);
if (rtlpriv->io.pci_mem_start != 0)
pci_iounmap(pdev, (void *)rtlpriv->io.pci_mem_start);
pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start);
fail2:
pci_release_regions(pdev);
@ -1888,7 +1818,7 @@ void rtl_pci_disconnect(struct pci_dev *pdev)
}
if (rtlpriv->io.pci_mem_start != 0) {
pci_iounmap(pdev, (void *)rtlpriv->io.pci_mem_start);
pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start);
pci_release_regions(pdev);
}

View File

@ -244,34 +244,34 @@ int rtl_pci_resume(struct pci_dev *pdev);
static inline u8 pci_read8_sync(struct rtl_priv *rtlpriv, u32 addr)
{
return 0xff & readb((u8 *) rtlpriv->io.pci_mem_start + addr);
return readb((u8 __iomem *) rtlpriv->io.pci_mem_start + addr);
}
static inline u16 pci_read16_sync(struct rtl_priv *rtlpriv, u32 addr)
{
return readw((u8 *) rtlpriv->io.pci_mem_start + addr);
return readw((u8 __iomem *) rtlpriv->io.pci_mem_start + addr);
}
static inline u32 pci_read32_sync(struct rtl_priv *rtlpriv, u32 addr)
{
return readl((u8 *) rtlpriv->io.pci_mem_start + addr);
return readl((u8 __iomem *) rtlpriv->io.pci_mem_start + addr);
}
static inline void pci_write8_async(struct rtl_priv *rtlpriv, u32 addr, u8 val)
{
writeb(val, (u8 *) rtlpriv->io.pci_mem_start + addr);
writeb(val, (u8 __iomem *) rtlpriv->io.pci_mem_start + addr);
}
static inline void pci_write16_async(struct rtl_priv *rtlpriv,
u32 addr, u16 val)
{
writew(val, (u8 *) rtlpriv->io.pci_mem_start + addr);
writew(val, (u8 __iomem *) rtlpriv->io.pci_mem_start + addr);
}
static inline void pci_write32_async(struct rtl_priv *rtlpriv,
u32 addr, u32 val)
{
writel(val, (u8 *) rtlpriv->io.pci_mem_start + addr);
writel(val, (u8 __iomem *) rtlpriv->io.pci_mem_start + addr);
}
static inline void rtl_pci_raw_write_port_ulong(u32 port, u32 val)

View File

@ -86,7 +86,7 @@ bool rtl_ps_set_rf_state(struct ieee80211_hw *hw,
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
enum rf_pwrstate rtstate;
bool b_actionallowed = false;
bool actionallowed = false;
u16 rfwait_cnt = 0;
unsigned long flag;
@ -139,13 +139,13 @@ no_protect:
ppsc->rfoff_reason &= (~changesource);
if ((changesource == RF_CHANGE_BY_HW) &&
(ppsc->b_hwradiooff == true)) {
ppsc->b_hwradiooff = false;
(ppsc->hwradiooff == true)) {
ppsc->hwradiooff = false;
}
if (!ppsc->rfoff_reason) {
ppsc->rfoff_reason = 0;
b_actionallowed = true;
actionallowed = true;
}
break;
@ -153,17 +153,17 @@ no_protect:
case ERFOFF:
if ((changesource == RF_CHANGE_BY_HW)
&& (ppsc->b_hwradiooff == false)) {
ppsc->b_hwradiooff = true;
&& (ppsc->hwradiooff == false)) {
ppsc->hwradiooff = true;
}
ppsc->rfoff_reason |= changesource;
b_actionallowed = true;
actionallowed = true;
break;
case ERFSLEEP:
ppsc->rfoff_reason |= changesource;
b_actionallowed = true;
actionallowed = true;
break;
default:
@ -172,7 +172,7 @@ no_protect:
break;
}
if (b_actionallowed)
if (actionallowed)
rtlpriv->cfg->ops->set_rf_power_state(hw, state_toset);
if (!protect_or_not) {
@ -181,7 +181,7 @@ no_protect:
spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
}
return b_actionallowed;
return actionallowed;
}
EXPORT_SYMBOL(rtl_ps_set_rf_state);
@ -191,7 +191,7 @@ static void _rtl_ps_inactive_ps(struct ieee80211_hw *hw)
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
ppsc->b_swrf_processing = true;
ppsc->swrf_processing = true;
if (ppsc->inactive_pwrstate == ERFON && rtlhal->interface == INTF_PCI) {
if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) &&
@ -213,7 +213,7 @@ static void _rtl_ps_inactive_ps(struct ieee80211_hw *hw)
}
}
ppsc->b_swrf_processing = false;
ppsc->swrf_processing = false;
}
void rtl_ips_nic_off_wq_callback(void *data)
@ -239,13 +239,13 @@ void rtl_ips_nic_off_wq_callback(void *data)
if (rtlpriv->sec.being_setkey)
return;
if (ppsc->b_inactiveps) {
if (ppsc->inactiveps) {
rtstate = ppsc->rfpwr_state;
/*
*Do not enter IPS in the following conditions:
*(1) RF is already OFF or Sleep
*(2) b_swrf_processing (indicates the IPS is still under going)
*(2) swrf_processing (indicates the IPS is still under going)
*(3) Connectted (only disconnected can trigger IPS)
*(4) IBSS (send Beacon)
*(5) AP mode (send Beacon)
@ -253,14 +253,14 @@ void rtl_ips_nic_off_wq_callback(void *data)
*/
if (rtstate == ERFON &&
!ppsc->b_swrf_processing &&
!ppsc->swrf_processing &&
(mac->link_state == MAC80211_NOLINK) &&
!mac->act_scanning) {
RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
("IPSEnter(): Turn off RF.\n"));
ppsc->inactive_pwrstate = ERFOFF;
ppsc->b_in_powersavemode = true;
ppsc->in_powersavemode = true;
/*rtl_pci_reset_trx_ring(hw); */
_rtl_ps_inactive_ps(hw);
@ -290,15 +290,15 @@ void rtl_ips_nic_on(struct ieee80211_hw *hw)
spin_lock_irqsave(&rtlpriv->locks.ips_lock, flags);
if (ppsc->b_inactiveps) {
if (ppsc->inactiveps) {
rtstate = ppsc->rfpwr_state;
if (rtstate != ERFON &&
!ppsc->b_swrf_processing &&
!ppsc->swrf_processing &&
ppsc->rfoff_reason <= RF_CHANGE_BY_IPS) {
ppsc->inactive_pwrstate = ERFON;
ppsc->b_in_powersavemode = false;
ppsc->in_powersavemode = false;
_rtl_ps_inactive_ps(hw);
}
@ -370,9 +370,9 @@ static void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode)
* mode and set RPWM to turn RF on.
*/
if ((ppsc->b_fwctrl_lps) && (ppsc->b_leisure_ps) &&
if ((ppsc->fwctrl_lps) && (ppsc->leisure_ps) &&
ppsc->report_linked) {
bool b_fw_current_inps;
bool fw_current_inps;
if (ppsc->dot11_psmode == EACTIVE) {
RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
("FW LPS leave ps_mode:%x\n",
@ -385,11 +385,11 @@ static void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode)
rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_H2C_FW_PWRMODE,
(u8 *) (&fw_pwrmode));
b_fw_current_inps = false;
fw_current_inps = false;
rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_FW_PSMODE_STATUS,
(u8 *) (&b_fw_current_inps));
(u8 *) (&fw_current_inps));
} else {
if (rtl_get_fwlps_doze(hw)) {
@ -398,10 +398,10 @@ static void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode)
ppsc->fwctrl_psmode));
rpwm_val = 0x02; /* RF off */
b_fw_current_inps = true;
fw_current_inps = true;
rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_FW_PSMODE_STATUS,
(u8 *) (&b_fw_current_inps));
(u8 *) (&fw_current_inps));
rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_H2C_FW_PWRMODE,
(u8 *) (&ppsc->fwctrl_psmode));
@ -425,13 +425,13 @@ void rtl_lps_enter(struct ieee80211_hw *hw)
struct rtl_priv *rtlpriv = rtl_priv(hw);
unsigned long flag;
if (!(ppsc->b_fwctrl_lps && ppsc->b_leisure_ps))
if (!(ppsc->fwctrl_lps && ppsc->leisure_ps))
return;
if (rtlpriv->sec.being_setkey)
return;
if (rtlpriv->link_info.b_busytraffic)
if (rtlpriv->link_info.busytraffic)
return;
/*sleep after linked 10s, to let DHCP and 4-way handshake ok enough!! */
@ -446,7 +446,7 @@ void rtl_lps_enter(struct ieee80211_hw *hw)
spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag);
if (ppsc->b_leisure_ps) {
if (ppsc->leisure_ps) {
/* Idle for a while if we connect to AP a while ago. */
if (mac->cnt_after_linked >= 2) {
if (ppsc->dot11_psmode == EACTIVE) {
@ -470,7 +470,7 @@ void rtl_lps_leave(struct ieee80211_hw *hw)
spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag);
if (ppsc->b_fwctrl_lps && ppsc->b_leisure_ps) {
if (ppsc->fwctrl_lps && ppsc->leisure_ps) {
if (ppsc->dot11_psmode != EACTIVE) {
/*FIX ME */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -10,3 +10,5 @@ rtl8192ce-objs := \
trx.o
obj-$(CONFIG_RTL8192CE) += rtl8192ce.o
ccflags-y += -D__CHECK_ENDIAN__

View File

@ -121,11 +121,37 @@
#define CHIP_92C 0x01
#define CHIP_88C 0x00
/* Add vendor information into chip version definition.
* Add UMC B-Cut and RTL8723 chip info definition.
*
* BIT 7 Reserved
* BIT 6 UMC BCut
* BIT 5 Manufacturer(TSMC/UMC)
* BIT 4 TEST/NORMAL
* BIT 3 8723 Version
* BIT 2 8723?
* BIT 1 1T2R?
* BIT 0 88C/92C
*/
enum version_8192c {
VERSION_A_CHIP_92C = 0x01,
VERSION_A_CHIP_88C = 0x00,
VERSION_B_CHIP_92C = 0x11,
VERSION_B_CHIP_88C = 0x10,
VERSION_TEST_CHIP_88C = 0x00,
VERSION_TEST_CHIP_92C = 0x01,
VERSION_NORMAL_TSMC_CHIP_88C = 0x10,
VERSION_NORMAL_TSMC_CHIP_92C = 0x11,
VERSION_NORMAL_TSMC_CHIP_92C_1T2R = 0x13,
VERSION_NORMAL_UMC_CHIP_88C_A_CUT = 0x30,
VERSION_NORMAL_UMC_CHIP_92C_A_CUT = 0x31,
VERSION_NORMAL_UMC_CHIP_92C_1T2R_A_CUT = 0x33,
VERSION_NORMA_UMC_CHIP_8723_1T1R_A_CUT = 0x34,
VERSION_NORMA_UMC_CHIP_8723_1T1R_B_CUT = 0x3c,
VERSION_NORMAL_UMC_CHIP_88C_B_CUT = 0x70,
VERSION_NORMAL_UMC_CHIP_92C_B_CUT = 0x71,
VERSION_NORMAL_UMC_CHIP_92C_1T2R_B_CUT = 0x73,
VERSION_UNKNOWN = 0x88,
};
@ -254,4 +280,122 @@ struct h2c_cmd_8192c {
u8 *p_cmdbuffer;
};
static inline u8 _rtl92c_get_chnl_group(u8 chnl)
{
u8 group = 0;
if (chnl < 3)
group = 0;
else if (chnl < 9)
group = 1;
else
group = 2;
return group;
}
/* NOTE: reference to rtl8192c_rates struct */
static inline int _rtl92c_rate_mapping(struct ieee80211_hw *hw, bool isHT,
u8 desc_rate, bool first_ampdu)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
int rate_idx = 0;
if (first_ampdu) {
if (false == isHT) {
switch (desc_rate) {
case DESC92C_RATE1M:
rate_idx = 0;
break;
case DESC92C_RATE2M:
rate_idx = 1;
break;
case DESC92C_RATE5_5M:
rate_idx = 2;
break;
case DESC92C_RATE11M:
rate_idx = 3;
break;
case DESC92C_RATE6M:
rate_idx = 4;
break;
case DESC92C_RATE9M:
rate_idx = 5;
break;
case DESC92C_RATE12M:
rate_idx = 6;
break;
case DESC92C_RATE18M:
rate_idx = 7;
break;
case DESC92C_RATE24M:
rate_idx = 8;
break;
case DESC92C_RATE36M:
rate_idx = 9;
break;
case DESC92C_RATE48M:
rate_idx = 10;
break;
case DESC92C_RATE54M:
rate_idx = 11;
break;
default:
RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG,
("Rate %d is not support, set to "
"1M rate.\n", desc_rate));
rate_idx = 0;
break;
}
} else {
rate_idx = 11;
}
return rate_idx;
}
switch (desc_rate) {
case DESC92C_RATE1M:
rate_idx = 0;
break;
case DESC92C_RATE2M:
rate_idx = 1;
break;
case DESC92C_RATE5_5M:
rate_idx = 2;
break;
case DESC92C_RATE11M:
rate_idx = 3;
break;
case DESC92C_RATE6M:
rate_idx = 4;
break;
case DESC92C_RATE9M:
rate_idx = 5;
break;
case DESC92C_RATE12M:
rate_idx = 6;
break;
case DESC92C_RATE18M:
rate_idx = 7;
break;
case DESC92C_RATE24M:
rate_idx = 8;
break;
case DESC92C_RATE36M:
rate_idx = 9;
break;
case DESC92C_RATE48M:
rate_idx = 10;
break;
case DESC92C_RATE54M:
rate_idx = 11;
break;
/* TODO: How to mapping MCS rate? */
/* NOTE: referenc to __ieee80211_rx */
default:
rate_idx = 11;
break;
}
return rate_idx;
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -192,5 +192,6 @@ void rtl92c_dm_init_edca_turbo(struct ieee80211_hw *hw);
void rtl92c_dm_check_txpower_tracking(struct ieee80211_hw *hw);
void rtl92c_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw);
void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal);
void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw);
#endif

View File

@ -133,17 +133,15 @@ static void _rtl92c_write_fw(struct ieee80211_hw *hw,
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
bool is_version_b;
u8 *bufferPtr = (u8 *) buffer;
RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, ("FW size is %d bytes,\n", size));
is_version_b = IS_CHIP_VER_B(version);
if (is_version_b) {
if (IS_CHIP_VER_B(version)) {
u32 pageNums, remainSize;
u32 page, offset;
if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CE)
if (IS_HARDWARE_TYPE_8192CE(rtlhal))
_rtl92c_fill_dummy(bufferPtr, &size);
pageNums = size / FW_8192C_PAGE_SIZE;
@ -231,14 +229,14 @@ int rtl92c_download_fw(struct ieee80211_hw *hw)
u32 fwsize;
int err;
enum version_8192c version = rtlhal->version;
const struct firmware *firmware;
const struct firmware *firmware = NULL;
printk(KERN_INFO "rtl8192cu: Loading firmware file %s\n",
rtlpriv->cfg->fw_name);
err = request_firmware(&firmware, rtlpriv->cfg->fw_name,
rtlpriv->io.dev);
if (err) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
("Failed to request firmware!\n"));
printk(KERN_ERR "rtl8192cu: Firmware loading failed\n");
return 1;
}
@ -318,12 +316,12 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
while (true) {
spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
if (rtlhal->b_h2c_setinprogress) {
if (rtlhal->h2c_setinprogress) {
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
("H2C set in progress! Wait to set.."
"element_id(%d).\n", element_id));
while (rtlhal->b_h2c_setinprogress) {
while (rtlhal->h2c_setinprogress) {
spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
flag);
h2c_waitcounter++;
@ -339,7 +337,7 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
}
spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
} else {
rtlhal->b_h2c_setinprogress = true;
rtlhal->h2c_setinprogress = true;
spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
break;
}
@ -495,7 +493,7 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
}
spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
rtlhal->b_h2c_setinprogress = false;
rtlhal->h2c_setinprogress = false;
spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("go out\n"));
@ -507,7 +505,7 @@ void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw,
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
u32 tmp_cmdbuf[2];
if (rtlhal->bfw_ready == false) {
if (rtlhal->fw_ready == false) {
RT_ASSERT(false, ("return H2C cmd because of Fw "
"download fail!!!\n"));
return;
@ -560,39 +558,6 @@ void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
}
static bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw,
struct sk_buff *skb)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
struct rtl8192_tx_ring *ring;
struct rtl_tx_desc *pdesc;
u8 own;
unsigned long flags;
struct sk_buff *pskb = NULL;
ring = &rtlpci->tx_ring[BEACON_QUEUE];
pskb = __skb_dequeue(&ring->queue);
if (pskb)
kfree_skb(pskb);
spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
pdesc = &ring->desc[0];
own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, true, HW_DESC_OWN);
rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb);
__skb_queue_tail(&ring->queue, skb);
spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE);
return true;
}
#define BEACON_PG 0 /*->1*/
#define PSPOLL_PG 2
#define NULL_PG 3
@ -776,7 +741,7 @@ void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
memcpy((u8 *) skb_put(skb, totalpacketlen),
&reserved_page_packet, totalpacketlen);
rtstatus = _rtl92c_cmd_send_packet(hw, skb);
rtstatus = rtlpriv->cfg->ops->cmd_send_packet(hw, skb);
if (rtstatus)
b_dlok = true;

View File

@ -124,7 +124,7 @@ void rtl92ce_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
break;
}
case HW_VAR_FW_PSMODE_STATUS:
*((bool *) (val)) = ppsc->b_fw_current_inpsmode;
*((bool *) (val)) = ppsc->fw_current_inpsmode;
break;
case HW_VAR_CORRECT_TSF:{
u64 tsf;
@ -173,15 +173,15 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
break;
}
case HW_VAR_BASIC_RATE:{
u16 b_rate_cfg = ((u16 *) val)[0];
u16 rate_cfg = ((u16 *) val)[0];
u8 rate_index = 0;
b_rate_cfg = b_rate_cfg & 0x15f;
b_rate_cfg |= 0x01;
rtl_write_byte(rtlpriv, REG_RRSR, b_rate_cfg & 0xff);
rate_cfg &= 0x15f;
rate_cfg |= 0x01;
rtl_write_byte(rtlpriv, REG_RRSR, rate_cfg & 0xff);
rtl_write_byte(rtlpriv, REG_RRSR + 1,
(b_rate_cfg >> 8)&0xff);
while (b_rate_cfg > 0x1) {
b_rate_cfg = (b_rate_cfg >> 1);
(rate_cfg >> 8)&0xff);
while (rate_cfg > 0x1) {
rate_cfg = (rate_cfg >> 1);
rate_index++;
}
rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL,
@ -318,15 +318,17 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
}
case HW_VAR_AC_PARAM:{
u8 e_aci = *((u8 *) val);
u32 u4b_ac_param = 0;
u32 u4b_ac_param;
u16 cw_min = le16_to_cpu(mac->ac[e_aci].cw_min);
u16 cw_max = le16_to_cpu(mac->ac[e_aci].cw_max);
u16 tx_op = le16_to_cpu(mac->ac[e_aci].tx_op);
u4b_ac_param |= (u32) mac->ac[e_aci].aifs;
u4b_ac_param |= ((u32) mac->ac[e_aci].cw_min
u4b_ac_param = (u32) mac->ac[e_aci].aifs;
u4b_ac_param |= ((u32)cw_min
& 0xF) << AC_PARAM_ECW_MIN_OFFSET;
u4b_ac_param |= ((u32) mac->ac[e_aci].cw_max &
u4b_ac_param |= ((u32)cw_max &
0xF) << AC_PARAM_ECW_MAX_OFFSET;
u4b_ac_param |= (u32) mac->ac[e_aci].tx_op
<< AC_PARAM_TXOP_LIMIT_OFFSET;
u4b_ac_param |= (u32)tx_op << AC_PARAM_TXOP_OFFSET;
RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
("queue:%x, ac_param:%x\n", e_aci,
@ -469,12 +471,12 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
break;
}
case HW_VAR_FW_PSMODE_STATUS:
ppsc->b_fw_current_inpsmode = *((bool *) val);
ppsc->fw_current_inpsmode = *((bool *) val);
break;
case HW_VAR_H2C_FW_JOINBSSRPT:{
u8 mstatus = (*(u8 *) val);
u8 tmp_regcr, tmp_reg422;
bool b_recover = false;
bool recover = false;
if (mstatus == RT_MEDIA_CONNECT) {
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AID,
@ -491,7 +493,7 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
rtl_read_byte(rtlpriv,
REG_FWHW_TXQ_CTRL + 2);
if (tmp_reg422 & BIT(6))
b_recover = true;
recover = true;
rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2,
tmp_reg422 & (~BIT(6)));
@ -500,7 +502,7 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
_rtl92ce_set_bcn_ctrl_reg(hw, BIT(3), 0);
_rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(4));
if (b_recover) {
if (recover) {
rtl_write_byte(rtlpriv,
REG_FWHW_TXQ_CTRL + 2,
tmp_reg422);
@ -868,7 +870,7 @@ static void _rtl92ce_enable_aspm_back_door(struct ieee80211_hw *hw)
rtl_write_word(rtlpriv, 0x350, 0x870c);
rtl_write_byte(rtlpriv, 0x352, 0x1);
if (ppsc->b_support_backdoor)
if (ppsc->support_backdoor)
rtl_write_byte(rtlpriv, 0x349, 0x1b);
else
rtl_write_byte(rtlpriv, 0x349, 0x03);
@ -940,10 +942,10 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw)
("Failed to download FW. Init HW "
"without FW now..\n"));
err = 1;
rtlhal->bfw_ready = false;
rtlhal->fw_ready = false;
return err;
} else {
rtlhal->bfw_ready = true;
rtlhal->fw_ready = true;
}
rtlhal->last_hmeboxnum = 0;
@ -1170,21 +1172,20 @@ void rtl92ce_set_qos(struct ieee80211_hw *hw, int aci)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
u32 u4b_ac_param;
u16 cw_min = le16_to_cpu(mac->ac[aci].cw_min);
u16 cw_max = le16_to_cpu(mac->ac[aci].cw_max);
u16 tx_op = le16_to_cpu(mac->ac[aci].tx_op);
rtl92c_dm_init_edca_turbo(hw);
u4b_ac_param = (u32) mac->ac[aci].aifs;
u4b_ac_param |=
((u32) mac->ac[aci].cw_min & 0xF) << AC_PARAM_ECW_MIN_OFFSET;
u4b_ac_param |=
((u32) mac->ac[aci].cw_max & 0xF) << AC_PARAM_ECW_MAX_OFFSET;
u4b_ac_param |= (u32) mac->ac[aci].tx_op << AC_PARAM_TXOP_LIMIT_OFFSET;
u4b_ac_param |= (u32) ((cw_min & 0xF) << AC_PARAM_ECW_MIN_OFFSET);
u4b_ac_param |= (u32) ((cw_max & 0xF) << AC_PARAM_ECW_MAX_OFFSET);
u4b_ac_param |= (u32) (tx_op << AC_PARAM_TXOP_OFFSET);
RT_TRACE(rtlpriv, COMP_QOS, DBG_DMESG,
("queue:%x, ac_param:%x aifs:%x cwmin:%x cwmax:%x txop:%x\n",
aci, u4b_ac_param, mac->ac[aci].aifs, mac->ac[aci].cw_min,
mac->ac[aci].cw_max, mac->ac[aci].tx_op));
aci, u4b_ac_param, mac->ac[aci].aifs, cw_min,
cw_max, tx_op));
switch (aci) {
case AC1_BK:
rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, u4b_ac_param);
@ -1237,7 +1238,7 @@ static void _rtl92ce_poweroff_adapter(struct ieee80211_hw *hw)
rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE0);
if ((rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) && rtlhal->bfw_ready)
if ((rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) && rtlhal->fw_ready)
rtl92c_firmware_selfreset(hw);
rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, 0x51);
rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00);
@ -1335,19 +1336,6 @@ void rtl92ce_update_interrupt_mask(struct ieee80211_hw *hw,
rtl92ce_enable_interrupt(hw);
}
static u8 _rtl92c_get_chnl_group(u8 chnl)
{
u8 group;
if (chnl < 3)
group = 0;
else if (chnl < 9)
group = 1;
else
group = 2;
return group;
}
static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
bool autoload_fail,
u8 *hwinfo)
@ -1568,7 +1556,7 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
rtlefuse->eeprom_thermalmeter = (tempval & 0x1f);
if (rtlefuse->eeprom_thermalmeter == 0x1f || autoload_fail)
rtlefuse->b_apk_thermalmeterignore = true;
rtlefuse->apk_thermalmeterignore = true;
rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter;
RTPRINT(rtlpriv, FINIT, INIT_TxPower,
@ -1625,7 +1613,7 @@ static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw)
rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN];
rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION];
rtlefuse->b_txpwr_fromeprom = true;
rtlefuse->txpwr_fromeprom = true;
rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID];
RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
@ -1668,7 +1656,7 @@ static void _rtl92ce_hal_customized_behavior(struct ieee80211_hw *hw)
switch (rtlhal->oem_id) {
case RT_CID_819x_HP:
pcipriv->ledctl.bled_opendrain = true;
pcipriv->ledctl.led_opendrain = true;
break;
case RT_CID_819x_Lenovo:
case RT_CID_DEFAULT:
@ -1693,10 +1681,10 @@ void rtl92ce_read_eeprom_info(struct ieee80211_hw *hw)
rtlhal->version = _rtl92ce_read_chip_version(hw);
if (get_rf_type(rtlphy) == RF_1T1R)
rtlpriv->dm.brfpath_rxenable[0] = true;
rtlpriv->dm.rfpath_rxenable[0] = true;
else
rtlpriv->dm.brfpath_rxenable[0] =
rtlpriv->dm.brfpath_rxenable[1] = true;
rtlpriv->dm.rfpath_rxenable[0] =
rtlpriv->dm.rfpath_rxenable[1] = true;
RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("VersionID = 0x%4x\n",
rtlhal->version));
tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR);
@ -1725,18 +1713,18 @@ void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw)
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
u32 ratr_value = (u32) mac->basic_rates;
u8 *p_mcsrate = mac->mcs;
u8 *mcsrate = mac->mcs;
u8 ratr_index = 0;
u8 b_nmode = mac->ht_enable;
u8 nmode = mac->ht_enable;
u8 mimo_ps = 1;
u16 shortgi_rate;
u32 tmp_ratr_value;
u8 b_curtxbw_40mhz = mac->bw_40;
u8 b_curshortgi_40mhz = mac->sgi_40;
u8 b_curshortgi_20mhz = mac->sgi_20;
u8 curtxbw_40mhz = mac->bw_40;
u8 curshortgi_40mhz = mac->sgi_40;
u8 curshortgi_20mhz = mac->sgi_20;
enum wireless_mode wirelessmode = mac->mode;
ratr_value |= EF2BYTE((*(u16 *) (p_mcsrate))) << 12;
ratr_value |= ((*(u16 *) (mcsrate))) << 12;
switch (wirelessmode) {
case WIRELESS_MODE_B:
@ -1750,7 +1738,7 @@ void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw)
break;
case WIRELESS_MODE_N_24G:
case WIRELESS_MODE_N_5G:
b_nmode = 1;
nmode = 1;
if (mimo_ps == 0) {
ratr_value &= 0x0007F005;
} else {
@ -1776,9 +1764,8 @@ void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw)
ratr_value &= 0x0FFFFFFF;
if (b_nmode && ((b_curtxbw_40mhz &&
b_curshortgi_40mhz) || (!b_curtxbw_40mhz &&
b_curshortgi_20mhz))) {
if (nmode && ((curtxbw_40mhz && curshortgi_40mhz) || (!curtxbw_40mhz &&
curshortgi_20mhz))) {
ratr_value |= 0x10000000;
tmp_ratr_value = (ratr_value >> 12);
@ -1806,11 +1793,11 @@ void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)
u32 ratr_bitmap = (u32) mac->basic_rates;
u8 *p_mcsrate = mac->mcs;
u8 ratr_index;
u8 b_curtxbw_40mhz = mac->bw_40;
u8 b_curshortgi_40mhz = mac->sgi_40;
u8 b_curshortgi_20mhz = mac->sgi_20;
u8 curtxbw_40mhz = mac->bw_40;
u8 curshortgi_40mhz = mac->sgi_40;
u8 curshortgi_20mhz = mac->sgi_20;
enum wireless_mode wirelessmode = mac->mode;
bool b_shortgi = false;
bool shortgi = false;
u8 rate_mask[5];
u8 macid = 0;
u8 mimops = 1;
@ -1852,7 +1839,7 @@ void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)
} else {
if (rtlphy->rf_type == RF_1T2R ||
rtlphy->rf_type == RF_1T1R) {
if (b_curtxbw_40mhz) {
if (curtxbw_40mhz) {
if (rssi_level == 1)
ratr_bitmap &= 0x000f0000;
else if (rssi_level == 2)
@ -1868,7 +1855,7 @@ void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)
ratr_bitmap &= 0x000ff005;
}
} else {
if (b_curtxbw_40mhz) {
if (curtxbw_40mhz) {
if (rssi_level == 1)
ratr_bitmap &= 0x0f0f0000;
else if (rssi_level == 2)
@ -1886,13 +1873,13 @@ void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)
}
}
if ((b_curtxbw_40mhz && b_curshortgi_40mhz) ||
(!b_curtxbw_40mhz && b_curshortgi_20mhz)) {
if ((curtxbw_40mhz && curshortgi_40mhz) ||
(!curtxbw_40mhz && curshortgi_20mhz)) {
if (macid == 0)
b_shortgi = true;
shortgi = true;
else if (macid == 1)
b_shortgi = false;
shortgi = false;
}
break;
default:
@ -1906,9 +1893,9 @@ void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)
}
RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
("ratr_bitmap :%x\n", ratr_bitmap));
*(u32 *)&rate_mask = EF4BYTE((ratr_bitmap & 0x0fffffff) |
(ratr_index << 28));
rate_mask[4] = macid | (b_shortgi ? 0x20 : 0x00) | 0x80;
*(u32 *)&rate_mask = (ratr_bitmap & 0x0fffffff) |
(ratr_index << 28);
rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80;
RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, ("Rate_index:%x, "
"ratr_val:%x, %x:%x:%x:%x:%x\n",
ratr_index, ratr_bitmap,
@ -1940,13 +1927,13 @@ bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid)
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
enum rf_pwrstate e_rfpowerstate_toset, cur_rfstate;
u8 u1tmp;
bool b_actuallyset = false;
bool actuallyset = false;
unsigned long flag;
if ((rtlpci->up_first_time == 1) || (rtlpci->being_init_adapter))
return false;
if (ppsc->b_swrf_processing)
if (ppsc->swrf_processing)
return false;
spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
@ -1972,24 +1959,24 @@ bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid)
u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL);
e_rfpowerstate_toset = (u1tmp & BIT(3)) ? ERFON : ERFOFF;
if ((ppsc->b_hwradiooff == true) && (e_rfpowerstate_toset == ERFON)) {
if ((ppsc->hwradiooff == true) && (e_rfpowerstate_toset == ERFON)) {
RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
("GPIOChangeRF - HW Radio ON, RF ON\n"));
e_rfpowerstate_toset = ERFON;
ppsc->b_hwradiooff = false;
b_actuallyset = true;
} else if ((ppsc->b_hwradiooff == false)
ppsc->hwradiooff = false;
actuallyset = true;
} else if ((ppsc->hwradiooff == false)
&& (e_rfpowerstate_toset == ERFOFF)) {
RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
("GPIOChangeRF - HW Radio OFF, RF OFF\n"));
e_rfpowerstate_toset = ERFOFF;
ppsc->b_hwradiooff = true;
b_actuallyset = true;
ppsc->hwradiooff = true;
actuallyset = true;
}
if (b_actuallyset) {
if (actuallyset) {
if (e_rfpowerstate_toset == ERFON) {
if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) &&
RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM)) {
@ -2028,7 +2015,7 @@ bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid)
}
*valid = 1;
return !ppsc->b_hwradiooff;
return !ppsc->hwradiooff;
}

View File

@ -57,7 +57,7 @@ void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
("switch case not process\n"));
break;
}
pled->b_ledon = true;
pled->ledon = true;
}
void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
@ -76,7 +76,7 @@ void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
break;
case LED_PIN_LED0:
ledcfg &= 0xf0;
if (pcipriv->ledctl.bled_opendrain == true)
if (pcipriv->ledctl.led_opendrain == true)
rtl_write_byte(rtlpriv, REG_LEDCFG2,
(ledcfg | BIT(1) | BIT(5) | BIT(6)));
else
@ -92,7 +92,7 @@ void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
("switch case not process\n"));
break;
}
pled->b_ledon = false;
pled->ledon = false;
}
void rtl92ce_init_sw_leds(struct ieee80211_hw *hw)

File diff suppressed because it is too large Load Diff

View File

@ -57,8 +57,6 @@
#define IQK_MAC_REG_NUM 4
#define RF90_PATH_MAX 2
#define CHANNEL_MAX_NUMBER 14
#define CHANNEL_GROUP_MAX 3
#define CT_OFFSET_MAC_ADDR 0X16
@ -78,9 +76,7 @@
#define CT_OFFSET_CUSTOMER_ID 0x7F
#define RTL92C_MAX_PATH_NUM 2
#define CHANNEL_MAX_NUMBER 14
#define CHANNEL_GROUP_MAX 3
#define LLT_LAST_ENTRY_OF_TX_PKT_BUFFER 255
enum swchnlcmd_id {
CMDID_END,
CMDID_SET_TXPOWEROWER_LEVEL,
@ -233,5 +229,6 @@ void rtl92c_phy_config_bb_external_pa(struct ieee80211_hw *hw);
void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw);
bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype);
void rtl92c_phy_set_io(struct ieee80211_hw *hw);
void rtl92c_bb_block_on(struct ieee80211_hw *hw);
#endif

View File

@ -63,7 +63,15 @@
#define REG_LEDCFG3 0x004F
#define REG_FSIMR 0x0050
#define REG_FSISR 0x0054
#define REG_HSIMR 0x0058
#define REG_HSISR 0x005c
/* RTL8723 WIFI/BT/GPS Multi-Function GPIO Pin Control. */
#define REG_GPIO_PIN_CTRL_2 0x0060
/* RTL8723 WIFI/BT/GPS Multi-Function GPIO Select. */
#define REG_GPIO_IO_SEL_2 0x0062
/* RTL8723 WIFI/BT/GPS Multi-Function control source. */
#define REG_MULTI_FUNC_CTRL 0x0068
#define REG_MCUFWDL 0x0080
#define REG_HMEBOX_EXT_0 0x0088
@ -79,6 +87,7 @@
#define REG_PCIE_MIO_INTD 0x00E8
#define REG_HPON_FSM 0x00EC
#define REG_SYS_CFG 0x00F0
#define REG_GPIO_OUTSTS 0x00F4 /* For RTL8723 only.*/
#define REG_CR 0x0100
#define REG_PBP 0x0104
@ -209,6 +218,8 @@
#define REG_RDG_PIFS 0x0513
#define REG_SIFS_CTX 0x0514
#define REG_SIFS_TRX 0x0516
#define REG_SIFS_CCK 0x0514
#define REG_SIFS_OFDM 0x0516
#define REG_AGGR_BREAK_TIME 0x051A
#define REG_SLOT 0x051B
#define REG_TX_PTCL_CTRL 0x0520
@ -261,6 +272,10 @@
#define REG_MAC_SPEC_SIFS 0x063A
#define REG_RESP_SIFS_CCK 0x063C
#define REG_RESP_SIFS_OFDM 0x063E
/* [15:8]SIFS_R2T_OFDM, [7:0]SIFS_R2T_CCK */
#define REG_R2T_SIFS 0x063C
/* [15:8]SIFS_T2T_OFDM, [7:0]SIFS_T2T_CCK */
#define REG_T2T_SIFS 0x063E
#define REG_ACKTO 0x0640
#define REG_CTS2TO 0x0641
#define REG_EIFS 0x0642
@ -641,9 +656,10 @@
#define STOPBE BIT(1)
#define STOPBK BIT(0)
#define RCR_APPFCS BIT(31)
#define RCR_APP_FCS BIT(31)
#define RCR_APP_MIC BIT(30)
#define RCR_APP_ICV BIT(29)
#define RCR_APP_PHYSTS BIT(28)
#define RCR_APP_PHYST_RXFF BIT(28)
#define RCR_APP_BA_SSN BIT(27)
#define RCR_ENMBID BIT(24)
@ -759,6 +775,7 @@
#define BOOT_FROM_EEPROM BIT(4)
#define EEPROM_EN BIT(5)
#define EEPROMSEL BOOT_FROM_EEPROM
#define AFE_BGEN BIT(0)
#define AFE_MBEN BIT(1)
@ -876,6 +893,8 @@
#define BD_MAC2 BIT(9)
#define BD_MAC1 BIT(10)
#define IC_MACPHY_MODE BIT(11)
#define BT_FUNC BIT(16)
#define VENDOR_ID BIT(19)
#define PAD_HWPD_IDN BIT(22)
#define TRP_VAUX_EN BIT(23)
#define TRP_BT_EN BIT(24)
@ -883,6 +902,28 @@
#define BD_HCI_SEL BIT(26)
#define TYPE_ID BIT(27)
/* REG_GPIO_OUTSTS (For RTL8723 only) */
#define EFS_HCI_SEL (BIT(0)|BIT(1))
#define PAD_HCI_SEL (BIT(2)|BIT(3))
#define HCI_SEL (BIT(4)|BIT(5))
#define PKG_SEL_HCI BIT(6)
#define FEN_GPS BIT(7)
#define FEN_BT BIT(8)
#define FEN_WL BIT(9)
#define FEN_PCI BIT(10)
#define FEN_USB BIT(11)
#define BTRF_HWPDN_N BIT(12)
#define WLRF_HWPDN_N BIT(13)
#define PDN_BT_N BIT(14)
#define PDN_GPS_N BIT(15)
#define BT_CTL_HWPDN BIT(16)
#define GPS_CTL_HWPDN BIT(17)
#define PPHY_SUSB BIT(20)
#define UPHY_SUSB BIT(21)
#define PCI_SUSEN BIT(22)
#define USB_SUSEN BIT(23)
#define RF_RL_ID (BIT(31) | BIT(30) | BIT(29) | BIT(28))
#define CHIP_VER_RTL_MASK 0xF000
#define CHIP_VER_RTL_SHIFT 12
@ -1035,7 +1076,7 @@
#define _RARF_RC7(x) (((x) & 0x1F) << 16)
#define _RARF_RC8(x) (((x) & 0x1F) << 24)
#define AC_PARAM_TXOP_LIMIT_OFFSET 16
#define AC_PARAM_TXOP_OFFSET 16
#define AC_PARAM_ECW_MAX_OFFSET 12
#define AC_PARAM_ECW_MIN_OFFSET 8
#define AC_PARAM_AIFS_OFFSET 0
@ -1184,6 +1225,30 @@
#define HAL_8192C_HW_GPIO_WPS_BIT BIT(2)
/* REG_MULTI_FUNC_CTRL(For RTL8723 Only) */
/* Enable GPIO[9] as WiFi HW PDn source */
#define WL_HWPDN_EN BIT(0)
/* WiFi HW PDn polarity control */
#define WL_HWPDN_SL BIT(1)
/* WiFi function enable */
#define WL_FUNC_EN BIT(2)
/* Enable GPIO[9] as WiFi RF HW PDn source */
#define WL_HWROF_EN BIT(3)
/* Enable GPIO[11] as BT HW PDn source */
#define BT_HWPDN_EN BIT(16)
/* BT HW PDn polarity control */
#define BT_HWPDN_SL BIT(17)
/* BT function enable */
#define BT_FUNC_EN BIT(18)
/* Enable GPIO[11] as BT/GPS RF HW PDn source */
#define BT_HWROF_EN BIT(19)
/* Enable GPIO[10] as GPS HW PDn source */
#define GPS_HWPDN_EN BIT(20)
/* GPS HW PDn polarity control */
#define GPS_HWPDN_SL BIT(21)
/* GPS function enable */
#define GPS_FUNC_EN BIT(22)
#define RPMAC_RESET 0x100
#define RPMAC_TXSTART 0x104
#define RPMAC_TXLEGACYSIG 0x108
@ -1496,7 +1561,7 @@
#define BTXHTSTBC 0x30
#define BTXHTADVANCECODING 0x40
#define BTXHTSHORTGI 0x80
#define BTXHTNUMBERHT_LT F 0x300
#define BTXHTNUMBERHT_LTF 0x300
#define BTXHTCRC8 0x3fc00
#define BCOUNTERRESET 0x10000
#define BNUMOFOFDMTX 0xffff

View File

@ -46,13 +46,13 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw)
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
rtlpriv->dm.b_dm_initialgain_enable = 1;
rtlpriv->dm.dm_initialgain_enable = 1;
rtlpriv->dm.dm_flag = 0;
rtlpriv->dm.b_disable_framebursting = 0;;
rtlpriv->dm.disable_framebursting = 0;
rtlpriv->dm.thermalvalue = 0;
rtlpci->transmit_config = CFENDFORM | BIT(12) | BIT(13);
rtlpci->receive_config = (RCR_APPFCS |
rtlpci->receive_config = (RCR_APP_FCS |
RCR_AMF |
RCR_ADF |
RCR_APP_MIC |
@ -135,6 +135,7 @@ static struct rtl_hal_ops rtl8192ce_hal_ops = {
.set_bbreg = rtl92c_phy_set_bb_reg,
.get_rfreg = rtl92c_phy_query_rf_reg,
.set_rfreg = rtl92c_phy_set_rf_reg,
.cmd_send_packet = _rtl92c_cmd_send_packet,
};
static struct rtl_mod_params rtl92ce_mod_params = {

View File

@ -33,5 +33,7 @@
int rtl92c_init_sw_vars(struct ieee80211_hw *hw);
void rtl92c_deinit_sw_vars(struct ieee80211_hw *hw);
void rtl92c_init_var_map(struct ieee80211_hw *hw);
bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw,
struct sk_buff *skb);
#endif

View File

@ -36,7 +36,7 @@
#include "trx.h"
#include "led.h"
static enum rtl_desc_qsel _rtl92ce_map_hwqueue_to_fwqueue(u16 fc,
static enum rtl_desc_qsel _rtl92ce_map_hwqueue_to_fwqueue(__le16 fc,
unsigned int
skb_queue)
{
@ -245,9 +245,9 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw,
struct rtl_stats *pstats,
struct rx_desc_92c *pdesc,
struct rx_fwinfo_92c *p_drvinfo,
bool bpacket_match_bssid,
bool bpacket_toself,
bool b_packet_beacon)
bool packet_match_bssid,
bool packet_toself,
bool packet_beacon)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct phy_sts_cck_8192s_t *cck_buf;
@ -258,11 +258,11 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw,
bool is_cck_rate;
is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc);
pstats->b_packet_matchbssid = bpacket_match_bssid;
pstats->b_packet_toself = bpacket_toself;
pstats->b_is_cck = is_cck_rate;
pstats->b_packet_beacon = b_packet_beacon;
pstats->b_is_cck = is_cck_rate;
pstats->packet_matchbssid = packet_match_bssid;
pstats->packet_toself = packet_toself;
pstats->is_cck = is_cck_rate;
pstats->packet_beacon = packet_beacon;
pstats->is_cck = is_cck_rate;
pstats->rx_mimo_signalquality[0] = -1;
pstats->rx_mimo_signalquality[1] = -1;
@ -315,7 +315,7 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw,
pstats->rx_pwdb_all = pwdb_all;
pstats->recvsignalpower = rx_pwr_all;
if (bpacket_match_bssid) {
if (packet_match_bssid) {
u8 sq;
if (pstats->rx_pwdb_all > 40)
sq = 100;
@ -334,10 +334,10 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw,
pstats->rx_mimo_signalquality[1] = -1;
}
} else {
rtlpriv->dm.brfpath_rxenable[0] =
rtlpriv->dm.brfpath_rxenable[1] = true;
rtlpriv->dm.rfpath_rxenable[0] =
rtlpriv->dm.rfpath_rxenable[1] = true;
for (i = RF90_PATH_A; i < RF90_PATH_MAX; i++) {
if (rtlpriv->dm.brfpath_rxenable[i])
if (rtlpriv->dm.rfpath_rxenable[i])
rf_rx_num++;
rx_pwr[i] =
@ -347,7 +347,7 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw,
rtlpriv->stats.rx_snr_db[i] =
(long)(p_drvinfo->rxsnr[i] / 2);
if (bpacket_match_bssid)
if (packet_match_bssid)
pstats->rx_mimo_signalstrength[i] = (u8) rssi;
}
@ -366,7 +366,7 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw,
for (i = 0; i < max_spatial_stream; i++) {
evm = _rtl92c_evm_db_to_percentage(p_drvinfo->rxevm[i]);
if (bpacket_match_bssid) {
if (packet_match_bssid) {
if (i == 0)
pstats->signalquality =
(u8) (evm & 0xff);
@ -393,7 +393,7 @@ static void _rtl92ce_process_ui_rssi(struct ieee80211_hw *hw,
u8 rfpath;
u32 last_rssi, tmpval;
if (pstats->b_packet_toself || pstats->b_packet_beacon) {
if (pstats->packet_toself || pstats->packet_beacon) {
rtlpriv->stats.rssi_calculate_cnt++;
if (rtlpriv->stats.ui_rssi.total_num++ >=
@ -421,7 +421,7 @@ static void _rtl92ce_process_ui_rssi(struct ieee80211_hw *hw,
pstats->rssi = rtlpriv->stats.signal_strength;
}
if (!pstats->b_is_cck && pstats->b_packet_toself) {
if (!pstats->is_cck && pstats->packet_toself) {
for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath;
rfpath++) {
@ -493,7 +493,7 @@ static void _rtl92ce_process_pwdb(struct ieee80211_hw *hw,
rtlpriv->dm.undecorated_smoothed_pwdb;
}
if (pstats->b_packet_toself || pstats->b_packet_beacon) {
if (pstats->packet_toself || pstats->packet_beacon) {
if (undecorated_smoothed_pwdb < 0)
undecorated_smoothed_pwdb = pstats->rx_pwdb_all;
@ -525,7 +525,7 @@ static void _rtl92ce_process_ui_link_quality(struct ieee80211_hw *hw,
u32 last_evm, n_spatialstream, tmpval;
if (pstats->signalquality != 0) {
if (pstats->b_packet_toself || pstats->b_packet_beacon) {
if (pstats->packet_toself || pstats->packet_beacon) {
if (rtlpriv->stats.ui_link_quality.total_num++ >=
PHY_LINKQUALITY_SLID_WIN_MAX) {
@ -595,8 +595,8 @@ static void _rtl92ce_process_phyinfo(struct ieee80211_hw *hw,
struct rtl_stats *pcurrent_stats)
{
if (!pcurrent_stats->b_packet_matchbssid &&
!pcurrent_stats->b_packet_beacon)
if (!pcurrent_stats->packet_matchbssid &&
!pcurrent_stats->packet_beacon)
return;
_rtl92ce_process_ui_rssi(hw, pcurrent_stats);
@ -617,34 +617,36 @@ static void _rtl92ce_translate_rx_signal_stuff(struct ieee80211_hw *hw,
u8 *tmp_buf;
u8 *praddr;
u8 *psaddr;
u16 fc, type;
bool b_packet_matchbssid, b_packet_toself, b_packet_beacon;
__le16 fc;
u16 type, c_fc;
bool packet_matchbssid, packet_toself, packet_beacon;
tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift;
hdr = (struct ieee80211_hdr *)tmp_buf;
fc = le16_to_cpu(hdr->frame_control);
fc = hdr->frame_control;
c_fc = le16_to_cpu(fc);
type = WLAN_FC_GET_TYPE(fc);
praddr = hdr->addr1;
psaddr = hdr->addr2;
b_packet_matchbssid =
packet_matchbssid =
((IEEE80211_FTYPE_CTL != type) &&
(!compare_ether_addr(mac->bssid,
(fc & IEEE80211_FCTL_TODS) ?
hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS) ?
(c_fc & IEEE80211_FCTL_TODS) ?
hdr->addr1 : (c_fc & IEEE80211_FCTL_FROMDS) ?
hdr->addr2 : hdr->addr3)) &&
(!pstats->b_hwerror) && (!pstats->b_crc) && (!pstats->b_icv));
(!pstats->hwerror) && (!pstats->crc) && (!pstats->icv));
b_packet_toself = b_packet_matchbssid &&
packet_toself = packet_matchbssid &&
(!compare_ether_addr(praddr, rtlefuse->dev_addr));
if (ieee80211_is_beacon(fc))
b_packet_beacon = true;
packet_beacon = true;
_rtl92ce_query_rxphystatus(hw, pstats, pdesc, p_drvinfo,
b_packet_matchbssid, b_packet_toself,
b_packet_beacon);
packet_matchbssid, packet_toself,
packet_beacon);
_rtl92ce_process_phyinfo(hw, tmp_buf, pstats);
}
@ -662,14 +664,14 @@ bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw,
stats->rx_drvinfo_size = (u8) GET_RX_DESC_DRV_INFO_SIZE(pdesc) *
RX_DRV_INFO_SIZE_UNIT;
stats->rx_bufshift = (u8) (GET_RX_DESC_SHIFT(pdesc) & 0x03);
stats->b_icv = (u16) GET_RX_DESC_ICV(pdesc);
stats->b_crc = (u16) GET_RX_DESC_CRC32(pdesc);
stats->b_hwerror = (stats->b_crc | stats->b_icv);
stats->icv = (u16) GET_RX_DESC_ICV(pdesc);
stats->crc = (u16) GET_RX_DESC_CRC32(pdesc);
stats->hwerror = (stats->crc | stats->icv);
stats->decrypted = !GET_RX_DESC_SWDEC(pdesc);
stats->rate = (u8) GET_RX_DESC_RXMCS(pdesc);
stats->b_shortpreamble = (u16) GET_RX_DESC_SPLCP(pdesc);
stats->b_isampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1);
stats->b_isampdu = (bool) ((GET_RX_DESC_PAGGR(pdesc) == 1)
stats->shortpreamble = (u16) GET_RX_DESC_SPLCP(pdesc);
stats->isampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1);
stats->isampdu = (bool) ((GET_RX_DESC_PAGGR(pdesc) == 1)
&& (GET_RX_DESC_FAGGR(pdesc) == 1));
stats->timestamp_low = GET_RX_DESC_TSFL(pdesc);
stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc);
@ -727,27 +729,24 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
bool b_defaultadapter = true;
bool defaultadapter = true;
struct ieee80211_sta *sta = ieee80211_find_sta(mac->vif, mac->bssid);
u8 *pdesc = (u8 *) pdesc_tx;
struct rtl_tcb_desc tcb_desc;
u8 *qc = ieee80211_get_qos_ctl(hdr);
u8 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
u16 seq_number;
u16 fc = le16_to_cpu(hdr->frame_control);
__le16 fc = hdr->frame_control;
u8 rate_flag = info->control.rates[0].flags;
enum rtl_desc_qsel fw_qsel =
_rtl92ce_map_hwqueue_to_fwqueue(le16_to_cpu(hdr->frame_control),
queue_index);
_rtl92ce_map_hwqueue_to_fwqueue(fc, queue_index);
bool b_firstseg = ((hdr->seq_ctrl &
cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0);
bool firstseg = ((hdr->seq_ctrl &
cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0);
bool b_lastseg = ((hdr->frame_control &
cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0);
bool lastseg = ((hdr->frame_control &
cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0);
dma_addr_t mapping = pci_map_single(rtlpci->pdev,
skb->data, skb->len,
@ -759,7 +758,7 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,
CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_92c));
if (b_firstseg) {
if (firstseg) {
SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
SET_TX_DESC_TX_RATE(pdesc, tcb_desc.hw_rate);
@ -774,25 +773,25 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,
}
SET_TX_DESC_SEQ(pdesc, seq_number);
SET_TX_DESC_RTS_ENABLE(pdesc, ((tcb_desc.b_rts_enable &&
SET_TX_DESC_RTS_ENABLE(pdesc, ((tcb_desc.rts_enable &&
!tcb_desc.
b_cts_enable) ? 1 : 0));
cts_enable) ? 1 : 0));
SET_TX_DESC_HW_RTS_ENABLE(pdesc,
((tcb_desc.b_rts_enable
|| tcb_desc.b_cts_enable) ? 1 : 0));
SET_TX_DESC_CTS2SELF(pdesc, ((tcb_desc.b_cts_enable) ? 1 : 0));
SET_TX_DESC_RTS_STBC(pdesc, ((tcb_desc.b_rts_stbc) ? 1 : 0));
((tcb_desc.rts_enable
|| tcb_desc.cts_enable) ? 1 : 0));
SET_TX_DESC_CTS2SELF(pdesc, ((tcb_desc.cts_enable) ? 1 : 0));
SET_TX_DESC_RTS_STBC(pdesc, ((tcb_desc.rts_stbc) ? 1 : 0));
SET_TX_DESC_RTS_RATE(pdesc, tcb_desc.rts_rate);
SET_TX_DESC_RTS_BW(pdesc, 0);
SET_TX_DESC_RTS_SC(pdesc, tcb_desc.rts_sc);
SET_TX_DESC_RTS_SHORT(pdesc,
((tcb_desc.rts_rate <= DESC92C_RATE54M) ?
(tcb_desc.b_rts_use_shortpreamble ? 1 : 0)
: (tcb_desc.b_rts_use_shortgi ? 1 : 0)));
(tcb_desc.rts_use_shortpreamble ? 1 : 0)
: (tcb_desc.rts_use_shortgi ? 1 : 0)));
if (mac->bw_40) {
if (tcb_desc.b_packet_bw) {
if (tcb_desc.packet_bw) {
SET_TX_DESC_DATA_BW(pdesc, 1);
SET_TX_DESC_TX_SUB_CARRIER(pdesc, 3);
} else {
@ -854,14 +853,14 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,
}
}
SET_TX_DESC_FIRST_SEG(pdesc, (b_firstseg ? 1 : 0));
SET_TX_DESC_LAST_SEG(pdesc, (b_lastseg ? 1 : 0));
SET_TX_DESC_FIRST_SEG(pdesc, (firstseg ? 1 : 0));
SET_TX_DESC_LAST_SEG(pdesc, (lastseg ? 1 : 0));
SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) skb->len);
SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping));
if (rtlpriv->dm.b_useramask) {
if (rtlpriv->dm.useramask) {
SET_TX_DESC_RATE_ID(pdesc, tcb_desc.ratr_index);
SET_TX_DESC_MACID(pdesc, tcb_desc.mac_id);
} else {
@ -869,16 +868,16 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,
SET_TX_DESC_MACID(pdesc, tcb_desc.ratr_index);
}
if ((!ieee80211_is_data_qos(fc)) && ppsc->b_leisure_ps &&
ppsc->b_fwctrl_lps) {
if ((!ieee80211_is_data_qos(fc)) && ppsc->leisure_ps &&
ppsc->fwctrl_lps) {
SET_TX_DESC_HWSEQ_EN(pdesc, 1);
SET_TX_DESC_PKT_ID(pdesc, 8);
if (!b_defaultadapter)
if (!defaultadapter)
SET_TX_DESC_QOS(pdesc, 1);
}
SET_TX_DESC_MORE_FRAG(pdesc, (b_lastseg ? 0 : 1));
SET_TX_DESC_MORE_FRAG(pdesc, (lastseg ? 0 : 1));
if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) ||
is_broadcast_ether_addr(ieee80211_get_DA(hdr))) {
@ -889,8 +888,8 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,
}
void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw,
u8 *pdesc, bool b_firstseg,
bool b_lastseg, struct sk_buff *skb)
u8 *pdesc, bool firstseg,
bool lastseg, struct sk_buff *skb)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
@ -901,11 +900,11 @@ void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw,
PCI_DMA_TODEVICE);
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
u16 fc = le16_to_cpu(hdr->frame_control);
__le16 fc = hdr->frame_control;
CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE);
if (b_firstseg)
if (firstseg)
SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
SET_TX_DESC_TX_RATE(pdesc, DESC92C_RATE1M);
@ -1029,3 +1028,36 @@ void rtl92ce_tx_polling(struct ieee80211_hw *hw, unsigned int hw_queue)
BIT(0) << (hw_queue));
}
}
bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw,
struct sk_buff *skb)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
struct rtl8192_tx_ring *ring;
struct rtl_tx_desc *pdesc;
u8 own;
unsigned long flags;
struct sk_buff *pskb = NULL;
ring = &rtlpci->tx_ring[BEACON_QUEUE];
spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
pskb = __skb_dequeue(&ring->queue);
if (pskb)
kfree_skb(pskb);
pdesc = &ring->desc[0];
own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, true, HW_DESC_OWN);
rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb);
__skb_queue_tail(&ring->queue, skb);
spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE);
return true;
}

View File

@ -40,470 +40,494 @@
#define USB_HWDESC_HEADER_LEN 32
#define CRCLENGTH 4
/* Define a macro that takes a le32 word, converts it to host ordering,
* right shifts by a specified count, creates a mask of the specified
* bit count, and extracts that number of bits.
*/
#define SHIFT_AND_MASK_LE(__pdesc, __shift, __mask) \
((le32_to_cpu(*(((__le32 *)(__pdesc)))) >> (__shift)) & \
BIT_LEN_MASK_32(__mask))
/* Define a macro that clears a bit field in an le32 word and
* sets the specified value into that bit field. The resulting
* value remains in le32 ordering; however, it is properly converted
* to host ordering for the clear and set operations before conversion
* back to le32.
*/
#define SET_BITS_OFFSET_LE(__pdesc, __shift, __len, __val) \
(*(__le32 *)(__pdesc) = \
(cpu_to_le32((le32_to_cpu(*((__le32 *)(__pdesc))) & \
(~(BIT_OFFSET_LEN_MASK_32((__shift), __len)))) | \
(((u32)(__val) & BIT_LEN_MASK_32(__len)) << (__shift)))));
/* macros to read/write various fields in RX or TX descriptors */
#define SET_TX_DESC_PKT_SIZE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 0, 16, __val)
SET_BITS_OFFSET_LE(__pdesc, 0, 16, __val)
#define SET_TX_DESC_OFFSET(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 16, 8, __val)
SET_BITS_OFFSET_LE(__pdesc, 16, 8, __val)
#define SET_TX_DESC_BMC(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 24, 1, __val)
SET_BITS_OFFSET_LE(__pdesc, 24, 1, __val)
#define SET_TX_DESC_HTC(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 25, 1, __val)
SET_BITS_OFFSET_LE(__pdesc, 25, 1, __val)
#define SET_TX_DESC_LAST_SEG(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 26, 1, __val)
SET_BITS_OFFSET_LE(__pdesc, 26, 1, __val)
#define SET_TX_DESC_FIRST_SEG(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 27, 1, __val)
SET_BITS_OFFSET_LE(__pdesc, 27, 1, __val)
#define SET_TX_DESC_LINIP(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 28, 1, __val)
SET_BITS_OFFSET_LE(__pdesc, 28, 1, __val)
#define SET_TX_DESC_NO_ACM(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 29, 1, __val)
SET_BITS_OFFSET_LE(__pdesc, 29, 1, __val)
#define SET_TX_DESC_GF(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 30, 1, __val)
SET_BITS_OFFSET_LE(__pdesc, 30, 1, __val)
#define SET_TX_DESC_OWN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val)
SET_BITS_OFFSET_LE(__pdesc, 31, 1, __val)
#define GET_TX_DESC_PKT_SIZE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 0, 16)
SHIFT_AND_MASK_LE(__pdesc, 0, 16)
#define GET_TX_DESC_OFFSET(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 16, 8)
SHIFT_AND_MASK_LE(__pdesc, 16, 8)
#define GET_TX_DESC_BMC(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 24, 1)
SHIFT_AND_MASK_LE(__pdesc, 24, 1)
#define GET_TX_DESC_HTC(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 25, 1)
SHIFT_AND_MASK_LE(__pdesc, 25, 1)
#define GET_TX_DESC_LAST_SEG(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 26, 1)
SHIFT_AND_MASK_LE(__pdesc, 26, 1)
#define GET_TX_DESC_FIRST_SEG(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 27, 1)
SHIFT_AND_MASK_LE(__pdesc, 27, 1)
#define GET_TX_DESC_LINIP(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 28, 1)
SHIFT_AND_MASK_LE(__pdesc, 28, 1)
#define GET_TX_DESC_NO_ACM(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 29, 1)
SHIFT_AND_MASK_LE(__pdesc, 29, 1)
#define GET_TX_DESC_GF(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 30, 1)
SHIFT_AND_MASK_LE(__pdesc, 30, 1)
#define GET_TX_DESC_OWN(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 31, 1)
SHIFT_AND_MASK_LE(__pdesc, 31, 1)
#define SET_TX_DESC_MACID(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+4, 0, 5, __val)
SET_BITS_OFFSET_LE(__pdesc+4, 0, 5, __val)
#define SET_TX_DESC_AGG_BREAK(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+4, 5, 1, __val)
SET_BITS_OFFSET_LE(__pdesc+4, 5, 1, __val)
#define SET_TX_DESC_BK(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+4, 6, 1, __val)
SET_BITS_OFFSET_LE(__pdesc+4, 6, 1, __val)
#define SET_TX_DESC_RDG_ENABLE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+4, 7, 1, __val)
SET_BITS_OFFSET_LE(__pdesc+4, 7, 1, __val)
#define SET_TX_DESC_QUEUE_SEL(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+4, 8, 5, __val)
SET_BITS_OFFSET_LE(__pdesc+4, 8, 5, __val)
#define SET_TX_DESC_RDG_NAV_EXT(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+4, 13, 1, __val)
SET_BITS_OFFSET_LE(__pdesc+4, 13, 1, __val)
#define SET_TX_DESC_LSIG_TXOP_EN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+4, 14, 1, __val)
SET_BITS_OFFSET_LE(__pdesc+4, 14, 1, __val)
#define SET_TX_DESC_PIFS(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+4, 15, 1, __val)
SET_BITS_OFFSET_LE(__pdesc+4, 15, 1, __val)
#define SET_TX_DESC_RATE_ID(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+4, 16, 4, __val)
SET_BITS_OFFSET_LE(__pdesc+4, 16, 4, __val)
#define SET_TX_DESC_NAV_USE_HDR(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+4, 20, 1, __val)
SET_BITS_OFFSET_LE(__pdesc+4, 20, 1, __val)
#define SET_TX_DESC_EN_DESC_ID(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+4, 21, 1, __val)
SET_BITS_OFFSET_LE(__pdesc+4, 21, 1, __val)
#define SET_TX_DESC_SEC_TYPE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+4, 22, 2, __val)
SET_BITS_OFFSET_LE(__pdesc+4, 22, 2, __val)
#define SET_TX_DESC_PKT_OFFSET(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+4, 24, 8, __val)
SET_BITS_OFFSET_LE(__pdesc+4, 24, 8, __val)
#define GET_TX_DESC_MACID(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 0, 5)
SHIFT_AND_MASK_LE(__pdesc+4, 0, 5)
#define GET_TX_DESC_AGG_ENABLE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 5, 1)
SHIFT_AND_MASK_LE(__pdesc+4, 5, 1)
#define GET_TX_DESC_AGG_BREAK(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 6, 1)
SHIFT_AND_MASK_LE(__pdesc+4, 6, 1)
#define GET_TX_DESC_RDG_ENABLE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 7, 1)
SHIFT_AND_MASK_LE(__pdesc+4, 7, 1)
#define GET_TX_DESC_QUEUE_SEL(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 8, 5)
SHIFT_AND_MASK_LE(__pdesc+4, 8, 5)
#define GET_TX_DESC_RDG_NAV_EXT(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 13, 1)
SHIFT_AND_MASK_LE(__pdesc+4, 13, 1)
#define GET_TX_DESC_LSIG_TXOP_EN(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 14, 1)
SHIFT_AND_MASK_LE(__pdesc+4, 14, 1)
#define GET_TX_DESC_PIFS(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 15, 1)
SHIFT_AND_MASK_LE(__pdesc+4, 15, 1)
#define GET_TX_DESC_RATE_ID(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 16, 4)
SHIFT_AND_MASK_LE(__pdesc+4, 16, 4)
#define GET_TX_DESC_NAV_USE_HDR(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 20, 1)
SHIFT_AND_MASK_LE(__pdesc+4, 20, 1)
#define GET_TX_DESC_EN_DESC_ID(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 21, 1)
SHIFT_AND_MASK_LE(__pdesc+4, 21, 1)
#define GET_TX_DESC_SEC_TYPE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 22, 2)
SHIFT_AND_MASK_LE(__pdesc+4, 22, 2)
#define GET_TX_DESC_PKT_OFFSET(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 24, 8)
SHIFT_AND_MASK_LE(__pdesc+4, 24, 8)
#define SET_TX_DESC_RTS_RC(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 0, 6, __val)
SET_BITS_OFFSET_LE(__pdesc+8, 0, 6, __val)
#define SET_TX_DESC_DATA_RC(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 6, 6, __val)
SET_BITS_OFFSET_LE(__pdesc+8, 6, 6, __val)
#define SET_TX_DESC_BAR_RTY_TH(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 14, 2, __val)
SET_BITS_OFFSET_LE(__pdesc+8, 14, 2, __val)
#define SET_TX_DESC_MORE_FRAG(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 17, 1, __val)
SET_BITS_OFFSET_LE(__pdesc+8, 17, 1, __val)
#define SET_TX_DESC_RAW(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 18, 1, __val)
SET_BITS_OFFSET_LE(__pdesc+8, 18, 1, __val)
#define SET_TX_DESC_CCX(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 19, 1, __val)
SET_BITS_OFFSET_LE(__pdesc+8, 19, 1, __val)
#define SET_TX_DESC_AMPDU_DENSITY(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 20, 3, __val)
SET_BITS_OFFSET_LE(__pdesc+8, 20, 3, __val)
#define SET_TX_DESC_ANTSEL_A(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 24, 1, __val)
SET_BITS_OFFSET_LE(__pdesc+8, 24, 1, __val)
#define SET_TX_DESC_ANTSEL_B(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 25, 1, __val)
SET_BITS_OFFSET_LE(__pdesc+8, 25, 1, __val)
#define SET_TX_DESC_TX_ANT_CCK(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 26, 2, __val)
SET_BITS_OFFSET_LE(__pdesc+8, 26, 2, __val)
#define SET_TX_DESC_TX_ANTL(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 28, 2, __val)
SET_BITS_OFFSET_LE(__pdesc+8, 28, 2, __val)
#define SET_TX_DESC_TX_ANT_HT(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 30, 2, __val)
SET_BITS_OFFSET_LE(__pdesc+8, 30, 2, __val)
#define GET_TX_DESC_RTS_RC(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 0, 6)
SHIFT_AND_MASK_LE(__pdesc+8, 0, 6)
#define GET_TX_DESC_DATA_RC(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 6, 6)
SHIFT_AND_MASK_LE(__pdesc+8, 6, 6)
#define GET_TX_DESC_BAR_RTY_TH(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 14, 2)
SHIFT_AND_MASK_LE(__pdesc+8, 14, 2)
#define GET_TX_DESC_MORE_FRAG(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 17, 1)
SHIFT_AND_MASK_LE(__pdesc+8, 17, 1)
#define GET_TX_DESC_RAW(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 18, 1)
SHIFT_AND_MASK_LE(__pdesc+8, 18, 1)
#define GET_TX_DESC_CCX(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 19, 1)
SHIFT_AND_MASK_LE(__pdesc+8, 19, 1)
#define GET_TX_DESC_AMPDU_DENSITY(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 20, 3)
SHIFT_AND_MASK_LE(__pdesc+8, 20, 3)
#define GET_TX_DESC_ANTSEL_A(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 24, 1)
SHIFT_AND_MASK_LE(__pdesc+8, 24, 1)
#define GET_TX_DESC_ANTSEL_B(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 25, 1)
SHIFT_AND_MASK_LE(__pdesc+8, 25, 1)
#define GET_TX_DESC_TX_ANT_CCK(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 26, 2)
SHIFT_AND_MASK_LE(__pdesc+8, 26, 2)
#define GET_TX_DESC_TX_ANTL(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 28, 2)
SHIFT_AND_MASK_LE(__pdesc+8, 28, 2)
#define GET_TX_DESC_TX_ANT_HT(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 30, 2)
SHIFT_AND_MASK_LE(__pdesc+8, 30, 2)
#define SET_TX_DESC_NEXT_HEAP_PAGE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+12, 0, 8, __val)
SET_BITS_OFFSET_LE(__pdesc+12, 0, 8, __val)
#define SET_TX_DESC_TAIL_PAGE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+12, 8, 8, __val)
SET_BITS_OFFSET_LE(__pdesc+12, 8, 8, __val)
#define SET_TX_DESC_SEQ(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+12, 16, 12, __val)
SET_BITS_OFFSET_LE(__pdesc+12, 16, 12, __val)
#define SET_TX_DESC_PKT_ID(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+12, 28, 4, __val)
SET_BITS_OFFSET_LE(__pdesc+12, 28, 4, __val)
#define GET_TX_DESC_NEXT_HEAP_PAGE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 0, 8)
SHIFT_AND_MASK_LE(__pdesc+12, 0, 8)
#define GET_TX_DESC_TAIL_PAGE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 8, 8)
SHIFT_AND_MASK_LE(__pdesc+12, 8, 8)
#define GET_TX_DESC_SEQ(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 16, 12)
SHIFT_AND_MASK_LE(__pdesc+12, 16, 12)
#define GET_TX_DESC_PKT_ID(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 28, 4)
SHIFT_AND_MASK_LE(__pdesc+12, 28, 4)
#define SET_TX_DESC_RTS_RATE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 0, 5, __val)
SET_BITS_OFFSET_LE(__pdesc+16, 0, 5, __val)
#define SET_TX_DESC_AP_DCFE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 5, 1, __val)
SET_BITS_OFFSET_LE(__pdesc+16, 5, 1, __val)
#define SET_TX_DESC_QOS(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 6, 1, __val)
SET_BITS_OFFSET_LE(__pdesc+16, 6, 1, __val)
#define SET_TX_DESC_HWSEQ_EN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 7, 1, __val)
SET_BITS_OFFSET_LE(__pdesc+16, 7, 1, __val)
#define SET_TX_DESC_USE_RATE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 8, 1, __val)
SET_BITS_OFFSET_LE(__pdesc+16, 8, 1, __val)
#define SET_TX_DESC_DISABLE_RTS_FB(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 9, 1, __val)
SET_BITS_OFFSET_LE(__pdesc+16, 9, 1, __val)
#define SET_TX_DESC_DISABLE_FB(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 10, 1, __val)
SET_BITS_OFFSET_LE(__pdesc+16, 10, 1, __val)
#define SET_TX_DESC_CTS2SELF(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 11, 1, __val)
SET_BITS_OFFSET_LE(__pdesc+16, 11, 1, __val)
#define SET_TX_DESC_RTS_ENABLE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 12, 1, __val)
SET_BITS_OFFSET_LE(__pdesc+16, 12, 1, __val)
#define SET_TX_DESC_HW_RTS_ENABLE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 13, 1, __val)
SET_BITS_OFFSET_LE(__pdesc+16, 13, 1, __val)
#define SET_TX_DESC_PORT_ID(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 14, 1, __val)
SET_BITS_OFFSET_LE(__pdesc+16, 14, 1, __val)
#define SET_TX_DESC_WAIT_DCTS(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 18, 1, __val)
SET_BITS_OFFSET_LE(__pdesc+16, 18, 1, __val)
#define SET_TX_DESC_CTS2AP_EN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 19, 1, __val)
SET_BITS_OFFSET_LE(__pdesc+16, 19, 1, __val)
#define SET_TX_DESC_TX_SUB_CARRIER(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 20, 2, __val)
SET_BITS_OFFSET_LE(__pdesc+16, 20, 2, __val)
#define SET_TX_DESC_TX_STBC(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 22, 2, __val)
SET_BITS_OFFSET_LE(__pdesc+16, 22, 2, __val)
#define SET_TX_DESC_DATA_SHORT(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 24, 1, __val)
SET_BITS_OFFSET_LE(__pdesc+16, 24, 1, __val)
#define SET_TX_DESC_DATA_BW(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 25, 1, __val)
SET_BITS_OFFSET_LE(__pdesc+16, 25, 1, __val)
#define SET_TX_DESC_RTS_SHORT(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 26, 1, __val)
SET_BITS_OFFSET_LE(__pdesc+16, 26, 1, __val)
#define SET_TX_DESC_RTS_BW(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 27, 1, __val)
SET_BITS_OFFSET_LE(__pdesc+16, 27, 1, __val)
#define SET_TX_DESC_RTS_SC(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 28, 2, __val)
SET_BITS_OFFSET_LE(__pdesc+16, 28, 2, __val)
#define SET_TX_DESC_RTS_STBC(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 30, 2, __val)
SET_BITS_OFFSET_LE(__pdesc+16, 30, 2, __val)
#define GET_TX_DESC_RTS_RATE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 0, 5)
SHIFT_AND_MASK_LE(__pdesc+16, 0, 5)
#define GET_TX_DESC_AP_DCFE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 5, 1)
SHIFT_AND_MASK_LE(__pdesc+16, 5, 1)
#define GET_TX_DESC_QOS(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 6, 1)
SHIFT_AND_MASK_LE(__pdesc+16, 6, 1)
#define GET_TX_DESC_HWSEQ_EN(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 7, 1)
SHIFT_AND_MASK_LE(__pdesc+16, 7, 1)
#define GET_TX_DESC_USE_RATE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 8, 1)
SHIFT_AND_MASK_LE(__pdesc+16, 8, 1)
#define GET_TX_DESC_DISABLE_RTS_FB(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 9, 1)
SHIFT_AND_MASK_LE(__pdesc+16, 9, 1)
#define GET_TX_DESC_DISABLE_FB(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 10, 1)
SHIFT_AND_MASK_LE(__pdesc+16, 10, 1)
#define GET_TX_DESC_CTS2SELF(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 11, 1)
SHIFT_AND_MASK_LE(__pdesc+16, 11, 1)
#define GET_TX_DESC_RTS_ENABLE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 12, 1)
SHIFT_AND_MASK_LE(__pdesc+16, 12, 1)
#define GET_TX_DESC_HW_RTS_ENABLE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 13, 1)
SHIFT_AND_MASK_LE(__pdesc+16, 13, 1)
#define GET_TX_DESC_PORT_ID(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 14, 1)
SHIFT_AND_MASK_LE(__pdesc+16, 14, 1)
#define GET_TX_DESC_WAIT_DCTS(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 18, 1)
SHIFT_AND_MASK_LE(__pdesc+16, 18, 1)
#define GET_TX_DESC_CTS2AP_EN(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 19, 1)
SHIFT_AND_MASK_LE(__pdesc+16, 19, 1)
#define GET_TX_DESC_TX_SUB_CARRIER(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 20, 2)
SHIFT_AND_MASK_LE(__pdesc+16, 20, 2)
#define GET_TX_DESC_TX_STBC(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 22, 2)
SHIFT_AND_MASK_LE(__pdesc+16, 22, 2)
#define GET_TX_DESC_DATA_SHORT(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 24, 1)
SHIFT_AND_MASK_LE(__pdesc+16, 24, 1)
#define GET_TX_DESC_DATA_BW(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 25, 1)
SHIFT_AND_MASK_LE(__pdesc+16, 25, 1)
#define GET_TX_DESC_RTS_SHORT(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 26, 1)
SHIFT_AND_MASK_LE(__pdesc+16, 26, 1)
#define GET_TX_DESC_RTS_BW(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 27, 1)
SHIFT_AND_MASK_LE(__pdesc+16, 27, 1)
#define GET_TX_DESC_RTS_SC(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 28, 2)
SHIFT_AND_MASK_LE(__pdesc+16, 28, 2)
#define GET_TX_DESC_RTS_STBC(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 30, 2)
SHIFT_AND_MASK_LE(__pdesc+16, 30, 2)
#define SET_TX_DESC_TX_RATE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+20, 0, 6, __val)
SET_BITS_OFFSET_LE(__pdesc+20, 0, 6, __val)
#define SET_TX_DESC_DATA_SHORTGI(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+20, 6, 1, __val)
SET_BITS_OFFSET_LE(__pdesc+20, 6, 1, __val)
#define SET_TX_DESC_CCX_TAG(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+20, 7, 1, __val)
SET_BITS_OFFSET_LE(__pdesc+20, 7, 1, __val)
#define SET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+20, 8, 5, __val)
SET_BITS_OFFSET_LE(__pdesc+20, 8, 5, __val)
#define SET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+20, 13, 4, __val)
SET_BITS_OFFSET_LE(__pdesc+20, 13, 4, __val)
#define SET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+20, 17, 1, __val)
SET_BITS_OFFSET_LE(__pdesc+20, 17, 1, __val)
#define SET_TX_DESC_DATA_RETRY_LIMIT(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+20, 18, 6, __val)
SET_BITS_OFFSET_LE(__pdesc+20, 18, 6, __val)
#define SET_TX_DESC_USB_TXAGG_NUM(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+20, 24, 8, __val)
SET_BITS_OFFSET_LE(__pdesc+20, 24, 8, __val)
#define GET_TX_DESC_TX_RATE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+20, 0, 6)
SHIFT_AND_MASK_LE(__pdesc+20, 0, 6)
#define GET_TX_DESC_DATA_SHORTGI(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+20, 6, 1)
SHIFT_AND_MASK_LE(__pdesc+20, 6, 1)
#define GET_TX_DESC_CCX_TAG(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+20, 7, 1)
SHIFT_AND_MASK_LE(__pdesc+20, 7, 1)
#define GET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+20, 8, 5)
SHIFT_AND_MASK_LE(__pdesc+20, 8, 5)
#define GET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+20, 13, 4)
SHIFT_AND_MASK_LE(__pdesc+20, 13, 4)
#define GET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+20, 17, 1)
SHIFT_AND_MASK_LE(__pdesc+20, 17, 1)
#define GET_TX_DESC_DATA_RETRY_LIMIT(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+20, 18, 6)
SHIFT_AND_MASK_LE(__pdesc+20, 18, 6)
#define GET_TX_DESC_USB_TXAGG_NUM(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+20, 24, 8)
SHIFT_AND_MASK_LE(__pdesc+20, 24, 8)
#define SET_TX_DESC_TXAGC_A(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+24, 0, 5, __val)
SET_BITS_OFFSET_LE(__pdesc+24, 0, 5, __val)
#define SET_TX_DESC_TXAGC_B(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+24, 5, 5, __val)
SET_BITS_OFFSET_LE(__pdesc+24, 5, 5, __val)
#define SET_TX_DESC_USE_MAX_LEN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+24, 10, 1, __val)
SET_BITS_OFFSET_LE(__pdesc+24, 10, 1, __val)
#define SET_TX_DESC_MAX_AGG_NUM(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+24, 11, 5, __val)
SET_BITS_OFFSET_LE(__pdesc+24, 11, 5, __val)
#define SET_TX_DESC_MCSG1_MAX_LEN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+24, 16, 4, __val)
SET_BITS_OFFSET_LE(__pdesc+24, 16, 4, __val)
#define SET_TX_DESC_MCSG2_MAX_LEN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+24, 20, 4, __val)
SET_BITS_OFFSET_LE(__pdesc+24, 20, 4, __val)
#define SET_TX_DESC_MCSG3_MAX_LEN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+24, 24, 4, __val)
SET_BITS_OFFSET_LE(__pdesc+24, 24, 4, __val)
#define SET_TX_DESC_MCS7_SGI_MAX_LEN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+24, 28, 4, __val)
SET_BITS_OFFSET_LE(__pdesc+24, 28, 4, __val)
#define GET_TX_DESC_TXAGC_A(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+24, 0, 5)
SHIFT_AND_MASK_LE(__pdesc+24, 0, 5)
#define GET_TX_DESC_TXAGC_B(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+24, 5, 5)
SHIFT_AND_MASK_LE(__pdesc+24, 5, 5)
#define GET_TX_DESC_USE_MAX_LEN(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+24, 10, 1)
SHIFT_AND_MASK_LE(__pdesc+24, 10, 1)
#define GET_TX_DESC_MAX_AGG_NUM(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+24, 11, 5)
SHIFT_AND_MASK_LE(__pdesc+24, 11, 5)
#define GET_TX_DESC_MCSG1_MAX_LEN(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+24, 16, 4)
SHIFT_AND_MASK_LE(__pdesc+24, 16, 4)
#define GET_TX_DESC_MCSG2_MAX_LEN(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+24, 20, 4)
SHIFT_AND_MASK_LE(__pdesc+24, 20, 4)
#define GET_TX_DESC_MCSG3_MAX_LEN(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+24, 24, 4)
SHIFT_AND_MASK_LE(__pdesc+24, 24, 4)
#define GET_TX_DESC_MCS7_SGI_MAX_LEN(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+24, 28, 4)
SHIFT_AND_MASK_LE(__pdesc+24, 28, 4)
#define SET_TX_DESC_TX_BUFFER_SIZE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+28, 0, 16, __val)
SET_BITS_OFFSET_LE(__pdesc+28, 0, 16, __val)
#define SET_TX_DESC_MCSG4_MAX_LEN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+28, 16, 4, __val)
SET_BITS_OFFSET_LE(__pdesc+28, 16, 4, __val)
#define SET_TX_DESC_MCSG5_MAX_LEN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+28, 20, 4, __val)
SET_BITS_OFFSET_LE(__pdesc+28, 20, 4, __val)
#define SET_TX_DESC_MCSG6_MAX_LEN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+28, 24, 4, __val)
SET_BITS_OFFSET_LE(__pdesc+28, 24, 4, __val)
#define SET_TX_DESC_MCS15_SGI_MAX_LEN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+28, 28, 4, __val)
SET_BITS_OFFSET_LE(__pdesc+28, 28, 4, __val)
#define GET_TX_DESC_TX_BUFFER_SIZE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+28, 0, 16)
SHIFT_AND_MASK_LE(__pdesc+28, 0, 16)
#define GET_TX_DESC_MCSG4_MAX_LEN(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+28, 16, 4)
SHIFT_AND_MASK_LE(__pdesc+28, 16, 4)
#define GET_TX_DESC_MCSG5_MAX_LEN(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+28, 20, 4)
SHIFT_AND_MASK_LE(__pdesc+28, 20, 4)
#define GET_TX_DESC_MCSG6_MAX_LEN(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+28, 24, 4)
SHIFT_AND_MASK_LE(__pdesc+28, 24, 4)
#define GET_TX_DESC_MCS15_SGI_MAX_LEN(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+28, 28, 4)
SHIFT_AND_MASK_LE(__pdesc+28, 28, 4)
#define SET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+32, 0, 32, __val)
SET_BITS_OFFSET_LE(__pdesc+32, 0, 32, __val)
#define SET_TX_DESC_TX_BUFFER_ADDRESS64(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+36, 0, 32, __val)
SET_BITS_OFFSET_LE(__pdesc+36, 0, 32, __val)
#define GET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+32, 0, 32)
SHIFT_AND_MASK_LE(__pdesc+32, 0, 32)
#define GET_TX_DESC_TX_BUFFER_ADDRESS64(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+36, 0, 32)
SHIFT_AND_MASK_LE(__pdesc+36, 0, 32)
#define SET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+40, 0, 32, __val)
SET_BITS_OFFSET_LE(__pdesc+40, 0, 32, __val)
#define SET_TX_DESC_NEXT_DESC_ADDRESS64(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+44, 0, 32, __val)
SET_BITS_OFFSET_LE(__pdesc+44, 0, 32, __val)
#define GET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+40, 0, 32)
SHIFT_AND_MASK_LE(__pdesc+40, 0, 32)
#define GET_TX_DESC_NEXT_DESC_ADDRESS64(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+44, 0, 32)
SHIFT_AND_MASK_LE(__pdesc+44, 0, 32)
#define GET_RX_DESC_PKT_LEN(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 0, 14)
SHIFT_AND_MASK_LE(__pdesc, 0, 14)
#define GET_RX_DESC_CRC32(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 14, 1)
SHIFT_AND_MASK_LE(__pdesc, 14, 1)
#define GET_RX_DESC_ICV(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 15, 1)
SHIFT_AND_MASK_LE(__pdesc, 15, 1)
#define GET_RX_DESC_DRV_INFO_SIZE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 16, 4)
SHIFT_AND_MASK_LE(__pdesc, 16, 4)
#define GET_RX_DESC_SECURITY(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 20, 3)
SHIFT_AND_MASK_LE(__pdesc, 20, 3)
#define GET_RX_DESC_QOS(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 23, 1)
SHIFT_AND_MASK_LE(__pdesc, 23, 1)
#define GET_RX_DESC_SHIFT(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 24, 2)
SHIFT_AND_MASK_LE(__pdesc, 24, 2)
#define GET_RX_DESC_PHYST(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 26, 1)
SHIFT_AND_MASK_LE(__pdesc, 26, 1)
#define GET_RX_DESC_SWDEC(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 27, 1)
SHIFT_AND_MASK_LE(__pdesc, 27, 1)
#define GET_RX_DESC_LS(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 28, 1)
SHIFT_AND_MASK_LE(__pdesc, 28, 1)
#define GET_RX_DESC_FS(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 29, 1)
SHIFT_AND_MASK_LE(__pdesc, 29, 1)
#define GET_RX_DESC_EOR(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 30, 1)
SHIFT_AND_MASK_LE(__pdesc, 30, 1)
#define GET_RX_DESC_OWN(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 31, 1)
SHIFT_AND_MASK_LE(__pdesc, 31, 1)
#define SET_RX_DESC_PKT_LEN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 0, 14, __val)
SET_BITS_OFFSET_LE(__pdesc, 0, 14, __val)
#define SET_RX_DESC_EOR(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 30, 1, __val)
SET_BITS_OFFSET_LE(__pdesc, 30, 1, __val)
#define SET_RX_DESC_OWN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val)
SET_BITS_OFFSET_LE(__pdesc, 31, 1, __val)
#define GET_RX_DESC_MACID(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 0, 5)
SHIFT_AND_MASK_LE(__pdesc+4, 0, 5)
#define GET_RX_DESC_TID(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 5, 4)
SHIFT_AND_MASK_LE(__pdesc+4, 5, 4)
#define GET_RX_DESC_HWRSVD(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 9, 5)
SHIFT_AND_MASK_LE(__pdesc+4, 9, 5)
#define GET_RX_DESC_PAGGR(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 14, 1)
SHIFT_AND_MASK_LE(__pdesc+4, 14, 1)
#define GET_RX_DESC_FAGGR(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 15, 1)
SHIFT_AND_MASK_LE(__pdesc+4, 15, 1)
#define GET_RX_DESC_A1_FIT(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 16, 4)
SHIFT_AND_MASK_LE(__pdesc+4, 16, 4)
#define GET_RX_DESC_A2_FIT(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 20, 4)
SHIFT_AND_MASK_LE(__pdesc+4, 20, 4)
#define GET_RX_DESC_PAM(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 24, 1)
SHIFT_AND_MASK_LE(__pdesc+4, 24, 1)
#define GET_RX_DESC_PWR(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 25, 1)
SHIFT_AND_MASK_LE(__pdesc+4, 25, 1)
#define GET_RX_DESC_MD(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 26, 1)
SHIFT_AND_MASK_LE(__pdesc+4, 26, 1)
#define GET_RX_DESC_MF(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 27, 1)
SHIFT_AND_MASK_LE(__pdesc+4, 27, 1)
#define GET_RX_DESC_TYPE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 28, 2)
SHIFT_AND_MASK_LE(__pdesc+4, 28, 2)
#define GET_RX_DESC_MC(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 30, 1)
SHIFT_AND_MASK_LE(__pdesc+4, 30, 1)
#define GET_RX_DESC_BC(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 31, 1)
SHIFT_AND_MASK_LE(__pdesc+4, 31, 1)
#define GET_RX_DESC_SEQ(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 0, 12)
SHIFT_AND_MASK_LE(__pdesc+8, 0, 12)
#define GET_RX_DESC_FRAG(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 12, 4)
SHIFT_AND_MASK_LE(__pdesc+8, 12, 4)
#define GET_RX_DESC_NEXT_PKT_LEN(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 16, 14)
SHIFT_AND_MASK_LE(__pdesc+8, 16, 14)
#define GET_RX_DESC_NEXT_IND(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 30, 1)
SHIFT_AND_MASK_LE(__pdesc+8, 30, 1)
#define GET_RX_DESC_RSVD(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 31, 1)
SHIFT_AND_MASK_LE(__pdesc+8, 31, 1)
#define GET_RX_DESC_RXMCS(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 0, 6)
SHIFT_AND_MASK_LE(__pdesc+12, 0, 6)
#define GET_RX_DESC_RXHT(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 6, 1)
SHIFT_AND_MASK_LE(__pdesc+12, 6, 1)
#define GET_RX_DESC_SPLCP(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 8, 1)
SHIFT_AND_MASK_LE(__pdesc+12, 8, 1)
#define GET_RX_DESC_BW(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 9, 1)
SHIFT_AND_MASK_LE(__pdesc+12, 9, 1)
#define GET_RX_DESC_HTC(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 10, 1)
SHIFT_AND_MASK_LE(__pdesc+12, 10, 1)
#define GET_RX_DESC_HWPC_ERR(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 14, 1)
SHIFT_AND_MASK_LE(__pdesc+12, 14, 1)
#define GET_RX_DESC_HWPC_IND(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 15, 1)
SHIFT_AND_MASK_LE(__pdesc+12, 15, 1)
#define GET_RX_DESC_IV0(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 16, 16)
SHIFT_AND_MASK_LE(__pdesc+12, 16, 16)
#define GET_RX_DESC_IV1(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 0, 32)
SHIFT_AND_MASK_LE(__pdesc+16, 0, 32)
#define GET_RX_DESC_TSFL(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+20, 0, 32)
SHIFT_AND_MASK_LE(__pdesc+20, 0, 32)
#define GET_RX_DESC_BUFF_ADDR(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+24, 0, 32)
SHIFT_AND_MASK_LE(__pdesc+24, 0, 32)
#define GET_RX_DESC_BUFF_ADDR64(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+28, 0, 32)
SHIFT_AND_MASK_LE(__pdesc+28, 0, 32)
#define SET_RX_DESC_BUFF_ADDR(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+24, 0, 32, __val)
SET_BITS_OFFSET_LE(__pdesc+24, 0, 32, __val)
#define SET_RX_DESC_BUFF_ADDR64(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+28, 0, 32, __val)
SET_BITS_OFFSET_LE(__pdesc+28, 0, 32, __val)
#define CLEAR_PCI_TX_DESC_CONTENT(__pdesc, _size) \
do { \
@ -711,4 +735,6 @@ void rtl92ce_tx_polling(struct ieee80211_hw *hw, unsigned int hw_queue);
void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
bool b_firstseg, bool b_lastseg,
struct sk_buff *skb);
bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb);
#endif

View File

@ -0,0 +1,15 @@
rtl8192cu-objs := \
dm.o \
fw.o \
hw.o \
led.o \
mac.o \
phy.o \
rf.o \
sw.o \
table.o \
trx.o
obj-$(CONFIG_RTL8192CU) += rtl8192cu.o
ccflags-y += -D__CHECK_ENDIAN__

View File

@ -0,0 +1,62 @@
/******************************************************************************
*
* Copyright(c) 2009-2010 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#include "../rtl8192ce/def.h"
/*-------------------------------------------------------------------------
* Chip specific
*-------------------------------------------------------------------------*/
#define CHIP_8723 BIT(2) /* RTL8723 With BT feature */
#define CHIP_8723_DRV_REV BIT(3) /* RTL8723 Driver Revised */
#define NORMAL_CHIP BIT(4)
#define CHIP_VENDOR_UMC BIT(5)
#define CHIP_VENDOR_UMC_B_CUT BIT(6)
#define IS_NORMAL_CHIP(version) \
(((version) & NORMAL_CHIP) ? true : false)
#define IS_8723_SERIES(version) \
(((version) & CHIP_8723) ? true : false)
#define IS_92C_1T2R(version) \
(((version) & CHIP_92C) && ((version) & CHIP_92C_1T2R))
#define IS_VENDOR_UMC(version) \
(((version) & CHIP_VENDOR_UMC) ? true : false)
#define IS_VENDOR_UMC_A_CUT(version) \
(((version) & CHIP_VENDOR_UMC) ? (((version) & (BIT(6) | BIT(7))) ? \
false : true) : false)
#define IS_VENDOR_8723_A_CUT(version) \
(((version) & CHIP_VENDOR_UMC) ? (((version) & (BIT(6))) ? \
false : true) : false)
#define CHIP_BONDING_92C_1T2R 0x1
#define CHIP_BONDING_IDENTIFIER(_value) (((_value) >> 22) & 0x3)

View File

@ -0,0 +1,116 @@
/******************************************************************************
*
* Copyright(c) 2009-2010 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#include "../wifi.h"
#include "../base.h"
#include "reg.h"
#include "def.h"
#include "phy.h"
#include "dm.h"
#include "fw.h"
#include "../rtl8192c/dm_common.c"
void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
long undecorated_smoothed_pwdb;
if (!rtlpriv->dm.dynamic_txpower_enable)
return;
if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) {
rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
return;
}
if ((mac->link_state < MAC80211_LINKED) &&
(rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) {
RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
("Not connected to any\n"));
rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
return;
}
if (mac->link_state >= MAC80211_LINKED) {
if (mac->opmode == NL80211_IFTYPE_ADHOC) {
undecorated_smoothed_pwdb =
rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
("AP Client PWDB = 0x%lx\n",
undecorated_smoothed_pwdb));
} else {
undecorated_smoothed_pwdb =
rtlpriv->dm.undecorated_smoothed_pwdb;
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
("STA Default Port PWDB = 0x%lx\n",
undecorated_smoothed_pwdb));
}
} else {
undecorated_smoothed_pwdb =
rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
("AP Ext Port PWDB = 0x%lx\n",
undecorated_smoothed_pwdb));
}
if (undecorated_smoothed_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) {
rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"));
} else if ((undecorated_smoothed_pwdb <
(TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) &&
(undecorated_smoothed_pwdb >=
TX_POWER_NEAR_FIELD_THRESH_LVL1)) {
rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"));
} else if (undecorated_smoothed_pwdb <
(TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) {
rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
("TXHIGHPWRLEVEL_NORMAL\n"));
}
if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) {
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
("PHY_SetTxPowerLevel8192S() Channel = %d\n",
rtlphy->current_channel));
rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel);
}
rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl;
}

View File

@ -0,0 +1,32 @@
/******************************************************************************
*
* Copyright(c) 2009-2010 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#include "../rtl8192ce/dm.h"
void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw);

View File

@ -0,0 +1,30 @@
/******************************************************************************
*
* Copyright(c) 2009-2010 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#include "../rtl8192ce/fw.c"

View File

@ -0,0 +1,30 @@
/******************************************************************************
*
* Copyright(c) 2009-2010 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#include "../rtl8192ce/fw.h"

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,107 @@
/******************************************************************************
*
* Copyright(c) 2009-2010 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#ifndef __RTL92CU_HW_H__
#define __RTL92CU_HW_H__
#define LLT_POLLING_LLT_THRESHOLD 20
#define LLT_POLLING_READY_TIMEOUT_COUNT 100
#define LLT_LAST_ENTRY_OF_TX_PKT_BUFFER 255
#define RX_PAGE_SIZE_REG_VALUE PBP_128
/* Note: We will divide number of page equally for each queue
* other than public queue! */
#define TX_TOTAL_PAGE_NUMBER 0xF8
#define TX_PAGE_BOUNDARY (TX_TOTAL_PAGE_NUMBER + 1)
#define CHIP_B_PAGE_NUM_PUBQ 0xE7
/* For Test Chip Setting
* (HPQ + LPQ + PUBQ) shall be TX_TOTAL_PAGE_NUMBER */
#define CHIP_A_PAGE_NUM_PUBQ 0x7E
/* For Chip A Setting */
#define WMM_CHIP_A_TX_TOTAL_PAGE_NUMBER 0xF5
#define WMM_CHIP_A_TX_PAGE_BOUNDARY \
(WMM_CHIP_A_TX_TOTAL_PAGE_NUMBER + 1) /* F6 */
#define WMM_CHIP_A_PAGE_NUM_PUBQ 0xA3
#define WMM_CHIP_A_PAGE_NUM_HPQ 0x29
#define WMM_CHIP_A_PAGE_NUM_LPQ 0x29
/* Note: For Chip B Setting ,modify later */
#define WMM_CHIP_B_TX_TOTAL_PAGE_NUMBER 0xF5
#define WMM_CHIP_B_TX_PAGE_BOUNDARY \
(WMM_CHIP_B_TX_TOTAL_PAGE_NUMBER + 1) /* F6 */
#define WMM_CHIP_B_PAGE_NUM_PUBQ 0xB0
#define WMM_CHIP_B_PAGE_NUM_HPQ 0x29
#define WMM_CHIP_B_PAGE_NUM_LPQ 0x1C
#define WMM_CHIP_B_PAGE_NUM_NPQ 0x1C
#define BOARD_TYPE_NORMAL_MASK 0xE0
#define BOARD_TYPE_TEST_MASK 0x0F
/* should be renamed and moved to another file */
enum _BOARD_TYPE_8192CUSB {
BOARD_USB_DONGLE = 0, /* USB dongle */
BOARD_USB_High_PA = 1, /* USB dongle - high power PA */
BOARD_MINICARD = 2, /* Minicard */
BOARD_USB_SOLO = 3, /* USB solo-Slim module */
BOARD_USB_COMBO = 4, /* USB Combo-Slim module */
};
#define IS_HIGHT_PA(boardtype) \
((boardtype == BOARD_USB_High_PA) ? true : false)
#define RTL92C_DRIVER_INFO_SIZE 4
void rtl92cu_read_eeprom_info(struct ieee80211_hw *hw);
void rtl92cu_enable_hw_security_config(struct ieee80211_hw *hw);
int rtl92cu_hw_init(struct ieee80211_hw *hw);
void rtl92cu_card_disable(struct ieee80211_hw *hw);
int rtl92cu_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type);
void rtl92cu_set_beacon_related_registers(struct ieee80211_hw *hw);
void rtl92cu_set_beacon_interval(struct ieee80211_hw *hw);
void rtl92cu_update_interrupt_mask(struct ieee80211_hw *hw,
u32 add_msr, u32 rm_msr);
void rtl92cu_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw);
void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level);
void rtl92cu_update_channel_access_setting(struct ieee80211_hw *hw);
bool rtl92cu_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid);
void rtl92cu_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid);
u8 _rtl92c_get_chnl_group(u8 chnl);
#endif

View File

@ -0,0 +1,142 @@
/******************************************************************************
*
* Copyright(c) 2009-2010 Realtek Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
*****************************************************************************/
#include "../wifi.h"
#include "../usb.h"
#include "reg.h"
#include "led.h"
static void _rtl92cu_init_led(struct ieee80211_hw *hw,
struct rtl_led *pled, enum rtl_led_pin ledpin)
{
pled->hw = hw;
pled->ledpin = ledpin;
pled->ledon = false;
}
static void _rtl92cu_deInit_led(struct rtl_led *pled)
{
}
void rtl92cu_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
{
u8 ledcfg;
struct rtl_priv *rtlpriv = rtl_priv(hw);
RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin));
ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
switch (pled->ledpin) {
case LED_PIN_GPIO0:
break;
case LED_PIN_LED0:
rtl_write_byte(rtlpriv,
REG_LEDCFG2, (ledcfg & 0xf0) | BIT(5) | BIT(6));
break;
case LED_PIN_LED1:
rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg & 0x0f) | BIT(5));
break;
default:
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
("switch case not process\n"));
break;
}
pled->ledon = true;
}
void rtl92cu_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_usb_priv *usbpriv = rtl_usbpriv(hw);
u8 ledcfg;
RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin));
ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
switch (pled->ledpin) {
case LED_PIN_GPIO0:
break;
case LED_PIN_LED0:
ledcfg &= 0xf0;
if (usbpriv->ledctl.led_opendrain == true)
rtl_write_byte(rtlpriv, REG_LEDCFG2,
(ledcfg | BIT(1) | BIT(5) | BIT(6)));
else
rtl_write_byte(rtlpriv, REG_LEDCFG2,
(ledcfg | BIT(3) | BIT(5) | BIT(6)));
break;
case LED_PIN_LED1:
ledcfg &= 0x0f;
rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg | BIT(3)));
break;
default:
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
("switch case not process\n"));
break;
}
pled->ledon = false;
}
void rtl92cu_init_sw_leds(struct ieee80211_hw *hw)
{
struct rtl_usb_priv *usbpriv = rtl_usbpriv(hw);
_rtl92cu_init_led(hw, &(usbpriv->ledctl.sw_led0), LED_PIN_LED0);
_rtl92cu_init_led(hw, &(usbpriv->ledctl.sw_led1), LED_PIN_LED1);
}
void rtl92cu_deinit_sw_leds(struct ieee80211_hw *hw)
{
struct rtl_usb_priv *usbpriv = rtl_usbpriv(hw);
_rtl92cu_deInit_led(&(usbpriv->ledctl.sw_led0));
_rtl92cu_deInit_led(&(usbpriv->ledctl.sw_led1));
}
static void _rtl92cu_sw_led_control(struct ieee80211_hw *hw,
enum led_ctl_mode ledaction)
{
}
void rtl92cu_led_control(struct ieee80211_hw *hw,
enum led_ctl_mode ledaction)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) &&
(ledaction == LED_CTL_TX ||
ledaction == LED_CTL_RX ||
ledaction == LED_CTL_SITE_SURVEY ||
ledaction == LED_CTL_LINK ||
ledaction == LED_CTL_NO_LINK ||
ledaction == LED_CTL_START_TO_LINK ||
ledaction == LED_CTL_POWER_ON)) {
return;
}
RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, ("ledaction %d,\n",
ledaction));
_rtl92cu_sw_led_control(hw, ledaction);
}

View File

@ -0,0 +1,37 @@
/******************************************************************************
*
* Copyright(c) 2009-2010 Realtek Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
*****************************************************************************/
#ifndef __RTL92CU_LED_H__
#define __RTL92CU_LED_H__
void rtl92cu_init_sw_leds(struct ieee80211_hw *hw);
void rtl92cu_deinit_sw_leds(struct ieee80211_hw *hw);
void rtl92cu_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled);
void rtl92cu_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled);
void rtl92cu_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,180 @@
/******************************************************************************
*
* Copyright(c) 2009-2010 Realtek Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#ifndef __RTL92C_MAC_H__
#define __RTL92C_MAC_H__
#define LLT_LAST_ENTRY_OF_TX_PKT_BUFFER 255
#define DRIVER_EARLY_INT_TIME 0x05
#define BCN_DMA_ATIME_INT_TIME 0x02
void rtl92c_read_chip_version(struct ieee80211_hw *hw);
bool rtl92c_llt_write(struct ieee80211_hw *hw, u32 address, u32 data);
bool rtl92c_init_llt_table(struct ieee80211_hw *hw, u32 boundary);
void rtl92c_set_key(struct ieee80211_hw *hw, u32 key_index,
u8 *p_macaddr, bool is_group, u8 enc_algo,
bool is_wepkey, bool clear_all);
void rtl92c_enable_interrupt(struct ieee80211_hw *hw);
void rtl92c_disable_interrupt(struct ieee80211_hw *hw);
void rtl92c_set_qos(struct ieee80211_hw *hw, int aci);
/*---------------------------------------------------------------
* Hardware init functions
*---------------------------------------------------------------*/
void rtl92c_set_mac_addr(struct ieee80211_hw *hw, const u8 *addr);
void rtl92c_init_interrupt(struct ieee80211_hw *hw);
void rtl92c_init_driver_info_size(struct ieee80211_hw *hw, u8 size);
int rtl92c_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type);
void rtl92c_init_network_type(struct ieee80211_hw *hw);
void rtl92c_init_adaptive_ctrl(struct ieee80211_hw *hw);
void rtl92c_init_rate_fallback(struct ieee80211_hw *hw);
void rtl92c_init_edca_param(struct ieee80211_hw *hw,
u16 queue,
u16 txop,
u8 ecwmax,
u8 ecwmin,
u8 aifs);
void rtl92c_init_edca(struct ieee80211_hw *hw);
void rtl92c_init_ampdu_aggregation(struct ieee80211_hw *hw);
void rtl92c_init_beacon_max_error(struct ieee80211_hw *hw, bool infra_mode);
void rtl92c_init_rdg_setting(struct ieee80211_hw *hw);
void rtl92c_init_retry_function(struct ieee80211_hw *hw);
void rtl92c_init_beacon_parameters(struct ieee80211_hw *hw,
enum version_8192c version);
void rtl92c_disable_fast_edca(struct ieee80211_hw *hw);
void rtl92c_set_min_space(struct ieee80211_hw *hw, bool is2T);
/* For filter */
u16 rtl92c_get_mgt_filter(struct ieee80211_hw *hw);
void rtl92c_set_mgt_filter(struct ieee80211_hw *hw, u16 filter);
u16 rtl92c_get_ctrl_filter(struct ieee80211_hw *hw);
void rtl92c_set_ctrl_filter(struct ieee80211_hw *hw, u16 filter);
u16 rtl92c_get_data_filter(struct ieee80211_hw *hw);
void rtl92c_set_data_filter(struct ieee80211_hw *hw, u16 filter);
u32 rtl92c_get_txdma_status(struct ieee80211_hw *hw);
#define RX_HAL_IS_CCK_RATE(_pdesc)\
(GET_RX_DESC_RX_MCS(_pdesc) == DESC92C_RATE1M ||\
GET_RX_DESC_RX_MCS(_pdesc) == DESC92C_RATE2M ||\
GET_RX_DESC_RX_MCS(_pdesc) == DESC92C_RATE5_5M ||\
GET_RX_DESC_RX_MCS(_pdesc) == DESC92C_RATE11M)
struct rx_fwinfo_92c {
u8 gain_trsw[4];
u8 pwdb_all;
u8 cfosho[4];
u8 cfotail[4];
char rxevm[2];
char rxsnr[4];
u8 pdsnr[2];
u8 csi_current[2];
u8 csi_target[2];
u8 sigevm;
u8 max_ex_pwr;
u8 ex_intf_flag:1;
u8 sgi_en:1;
u8 rxsc:2;
u8 reserve:4;
} __packed;
struct rx_desc_92c {
u32 length:14;
u32 crc32:1;
u32 icverror:1;
u32 drv_infosize:4;
u32 security:3;
u32 qos:1;
u32 shift:2;
u32 phystatus:1;
u32 swdec:1;
u32 lastseg:1;
u32 firstseg:1;
u32 eor:1;
u32 own:1;
u32 macid:5; /* word 1 */
u32 tid:4;
u32 hwrsvd:5;
u32 paggr:1;
u32 faggr:1;
u32 a1_fit:4;
u32 a2_fit:4;
u32 pam:1;
u32 pwr:1;
u32 moredata:1;
u32 morefrag:1;
u32 type:2;
u32 mc:1;
u32 bc:1;
u32 seq:12; /* word 2 */
u32 frag:4;
u32 nextpktlen:14;
u32 nextind:1;
u32 rsvd:1;
u32 rxmcs:6; /* word 3 */
u32 rxht:1;
u32 amsdu:1;
u32 splcp:1;
u32 bandwidth:1;
u32 htc:1;
u32 tcpchk_rpt:1;
u32 ipcchk_rpt:1;
u32 tcpchk_valid:1;
u32 hwpcerr:1;
u32 hwpcind:1;
u32 iv0:16;
u32 iv1; /* word 4 */
u32 tsfl; /* word 5 */
u32 bufferaddress; /* word 6 */
u32 bufferaddress64; /* word 7 */
} __packed;
enum rtl_desc_qsel rtl92c_map_hwqueue_to_fwqueue(u16 fc,
unsigned int
skb_queue);
void rtl92c_translate_rx_signal_stuff(struct ieee80211_hw *hw,
struct sk_buff *skb,
struct rtl_stats *pstats,
struct rx_desc_92c *pdesc,
struct rx_fwinfo_92c *p_drvinfo);
/*---------------------------------------------------------------
* Card disable functions
*---------------------------------------------------------------*/
#endif

View File

@ -0,0 +1,611 @@
/******************************************************************************
*
* Copyright(c) 2009-2010 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#include "../wifi.h"
#include "../pci.h"
#include "../ps.h"
#include "reg.h"
#include "def.h"
#include "phy.h"
#include "rf.h"
#include "dm.h"
#include "table.h"
#include "../rtl8192c/phy_common.c"
u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw,
enum radio_path rfpath, u32 regaddr, u32 bitmask)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u32 original_value, readback_value, bitshift;
struct rtl_phy *rtlphy = &(rtlpriv->phy);
RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), "
"rfpath(%#x), bitmask(%#x)\n",
regaddr, rfpath, bitmask));
if (rtlphy->rf_mode != RF_OP_BY_FW) {
original_value = _rtl92c_phy_rf_serial_read(hw,
rfpath, regaddr);
} else {
original_value = _rtl92c_phy_fw_rf_serial_read(hw,
rfpath, regaddr);
}
bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
readback_value = (original_value & bitmask) >> bitshift;
RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
("regaddr(%#x), rfpath(%#x), "
"bitmask(%#x), original_value(%#x)\n",
regaddr, rfpath, bitmask, original_value));
return readback_value;
}
void rtl92c_phy_set_rf_reg(struct ieee80211_hw *hw,
enum radio_path rfpath,
u32 regaddr, u32 bitmask, u32 data)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
u32 original_value, bitshift;
RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
("regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
regaddr, bitmask, data, rfpath));
if (rtlphy->rf_mode != RF_OP_BY_FW) {
if (bitmask != RFREG_OFFSET_MASK) {
original_value = _rtl92c_phy_rf_serial_read(hw,
rfpath,
regaddr);
bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
data =
((original_value & (~bitmask)) |
(data << bitshift));
}
_rtl92c_phy_rf_serial_write(hw, rfpath, regaddr, data);
} else {
if (bitmask != RFREG_OFFSET_MASK) {
original_value = _rtl92c_phy_fw_rf_serial_read(hw,
rfpath,
regaddr);
bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
data =
((original_value & (~bitmask)) |
(data << bitshift));
}
_rtl92c_phy_fw_rf_serial_write(hw, rfpath, regaddr, data);
}
RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), "
"bitmask(%#x), data(%#x), rfpath(%#x)\n",
regaddr, bitmask, data, rfpath));
}
bool rtl92c_phy_mac_config(struct ieee80211_hw *hw)
{
bool rtstatus;
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
bool is92c = IS_92C_SERIAL(rtlhal->version);
rtstatus = _rtl92c_phy_config_mac_with_headerfile(hw);
if (is92c && IS_HARDWARE_TYPE_8192CE(rtlhal))
rtl_write_byte(rtlpriv, 0x14, 0x71);
return rtstatus;
}
bool rtl92c_phy_bb_config(struct ieee80211_hw *hw)
{
bool rtstatus = true;
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
u16 regval;
u8 b_reg_hwparafile = 1;
_rtl92c_phy_init_bb_rf_register_definition(hw);
regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, regval | BIT(13) |
BIT(0) | BIT(1));
rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x83);
rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL + 1, 0xdb);
rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB);
if (IS_HARDWARE_TYPE_8192CE(rtlhal)) {
rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, FEN_PPLL | FEN_PCIEA |
FEN_DIO_PCIE | FEN_BB_GLB_RSTn | FEN_BBRSTB);
} else if (IS_HARDWARE_TYPE_8192CU(rtlhal)) {
rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, FEN_USBA | FEN_USBD |
FEN_BB_GLB_RSTn | FEN_BBRSTB);
rtl_write_byte(rtlpriv, REG_LDOHCI12_CTRL, 0x0f);
}
rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80);
if (b_reg_hwparafile == 1)
rtstatus = _rtl92c_phy_bb8192c_config_parafile(hw);
return rtstatus;
}
static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
u32 i;
u32 arraylength;
u32 *ptrarray;
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Read Rtl819XMACPHY_Array\n"));
arraylength = rtlphy->hwparam_tables[MAC_REG].length ;
ptrarray = rtlphy->hwparam_tables[MAC_REG].pdata;
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
("Img:RTL8192CEMAC_2T_ARRAY\n"));
for (i = 0; i < arraylength; i = i + 2)
rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]);
return true;
}
static bool _rtl92c_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
u8 configtype)
{
int i;
u32 *phy_regarray_table;
u32 *agctab_array_table;
u16 phy_reg_arraylen, agctab_arraylen;
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
struct rtl_phy *rtlphy = &(rtlpriv->phy);
if (IS_92C_SERIAL(rtlhal->version)) {
agctab_arraylen = rtlphy->hwparam_tables[AGCTAB_2T].length;
agctab_array_table = rtlphy->hwparam_tables[AGCTAB_2T].pdata;
phy_reg_arraylen = rtlphy->hwparam_tables[PHY_REG_2T].length;
phy_regarray_table = rtlphy->hwparam_tables[PHY_REG_2T].pdata;
} else {
agctab_arraylen = rtlphy->hwparam_tables[AGCTAB_1T].length;
agctab_array_table = rtlphy->hwparam_tables[AGCTAB_1T].pdata;
phy_reg_arraylen = rtlphy->hwparam_tables[PHY_REG_1T].length;
phy_regarray_table = rtlphy->hwparam_tables[PHY_REG_1T].pdata;
}
if (configtype == BASEBAND_CONFIG_PHY_REG) {
for (i = 0; i < phy_reg_arraylen; i = i + 2) {
if (phy_regarray_table[i] == 0xfe)
mdelay(50);
else if (phy_regarray_table[i] == 0xfd)
mdelay(5);
else if (phy_regarray_table[i] == 0xfc)
mdelay(1);
else if (phy_regarray_table[i] == 0xfb)
udelay(50);
else if (phy_regarray_table[i] == 0xfa)
udelay(5);
else if (phy_regarray_table[i] == 0xf9)
udelay(1);
rtl_set_bbreg(hw, phy_regarray_table[i], MASKDWORD,
phy_regarray_table[i + 1]);
udelay(1);
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
("The phy_regarray_table[0] is %x"
" Rtl819XPHY_REGArray[1] is %x\n",
phy_regarray_table[i],
phy_regarray_table[i + 1]));
}
rtl92c_phy_config_bb_external_pa(hw);
} else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
for (i = 0; i < agctab_arraylen; i = i + 2) {
rtl_set_bbreg(hw, agctab_array_table[i], MASKDWORD,
agctab_array_table[i + 1]);
udelay(1);
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
("The agctab_array_table[0] is "
"%x Rtl819XPHY_REGArray[1] is %x\n",
agctab_array_table[i],
agctab_array_table[i + 1]));
}
}
return true;
}
static bool _rtl92c_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
u8 configtype)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
int i;
u32 *phy_regarray_table_pg;
u16 phy_regarray_pg_len;
rtlphy->pwrgroup_cnt = 0;
phy_regarray_pg_len = rtlphy->hwparam_tables[PHY_REG_PG].length;
phy_regarray_table_pg = rtlphy->hwparam_tables[PHY_REG_PG].pdata;
if (configtype == BASEBAND_CONFIG_PHY_REG) {
for (i = 0; i < phy_regarray_pg_len; i = i + 3) {
if (phy_regarray_table_pg[i] == 0xfe)
mdelay(50);
else if (phy_regarray_table_pg[i] == 0xfd)
mdelay(5);
else if (phy_regarray_table_pg[i] == 0xfc)
mdelay(1);
else if (phy_regarray_table_pg[i] == 0xfb)
udelay(50);
else if (phy_regarray_table_pg[i] == 0xfa)
udelay(5);
else if (phy_regarray_table_pg[i] == 0xf9)
udelay(1);
_rtl92c_store_pwrIndex_diffrate_offset(hw,
phy_regarray_table_pg[i],
phy_regarray_table_pg[i + 1],
phy_regarray_table_pg[i + 2]);
}
} else {
RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
("configtype != BaseBand_Config_PHY_REG\n"));
}
return true;
}
bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
enum radio_path rfpath)
{
int i;
u32 *radioa_array_table;
u32 *radiob_array_table;
u16 radioa_arraylen, radiob_arraylen;
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
struct rtl_phy *rtlphy = &(rtlpriv->phy);
if (IS_92C_SERIAL(rtlhal->version)) {
radioa_arraylen = rtlphy->hwparam_tables[RADIOA_2T].length;
radioa_array_table = rtlphy->hwparam_tables[RADIOA_2T].pdata;
radiob_arraylen = rtlphy->hwparam_tables[RADIOB_2T].length;
radiob_array_table = rtlphy->hwparam_tables[RADIOB_2T].pdata;
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
("Radio_A:RTL8192CERADIOA_2TARRAY\n"));
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
("Radio_B:RTL8192CE_RADIOB_2TARRAY\n"));
} else {
radioa_arraylen = rtlphy->hwparam_tables[RADIOA_1T].length;
radioa_array_table = rtlphy->hwparam_tables[RADIOA_1T].pdata;
radiob_arraylen = rtlphy->hwparam_tables[RADIOB_1T].length;
radiob_array_table = rtlphy->hwparam_tables[RADIOB_1T].pdata;
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
("Radio_A:RTL8192CE_RADIOA_1TARRAY\n"));
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
("Radio_B:RTL8192CE_RADIOB_1TARRAY\n"));
}
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Radio No %x\n", rfpath));
switch (rfpath) {
case RF90_PATH_A:
for (i = 0; i < radioa_arraylen; i = i + 2) {
if (radioa_array_table[i] == 0xfe)
mdelay(50);
else if (radioa_array_table[i] == 0xfd)
mdelay(5);
else if (radioa_array_table[i] == 0xfc)
mdelay(1);
else if (radioa_array_table[i] == 0xfb)
udelay(50);
else if (radioa_array_table[i] == 0xfa)
udelay(5);
else if (radioa_array_table[i] == 0xf9)
udelay(1);
else {
rtl_set_rfreg(hw, rfpath, radioa_array_table[i],
RFREG_OFFSET_MASK,
radioa_array_table[i + 1]);
udelay(1);
}
}
_rtl92c_phy_config_rf_external_pa(hw, rfpath);
break;
case RF90_PATH_B:
for (i = 0; i < radiob_arraylen; i = i + 2) {
if (radiob_array_table[i] == 0xfe) {
mdelay(50);
} else if (radiob_array_table[i] == 0xfd)
mdelay(5);
else if (radiob_array_table[i] == 0xfc)
mdelay(1);
else if (radiob_array_table[i] == 0xfb)
udelay(50);
else if (radiob_array_table[i] == 0xfa)
udelay(5);
else if (radiob_array_table[i] == 0xf9)
udelay(1);
else {
rtl_set_rfreg(hw, rfpath, radiob_array_table[i],
RFREG_OFFSET_MASK,
radiob_array_table[i + 1]);
udelay(1);
}
}
break;
case RF90_PATH_C:
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
("switch case not process\n"));
break;
case RF90_PATH_D:
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
("switch case not process\n"));
break;
}
return true;
}
void rtl92c_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
struct rtl_phy *rtlphy = &(rtlpriv->phy);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
u8 reg_bw_opmode;
u8 reg_prsr_rsc;
RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
("Switch to %s bandwidth\n",
rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
"20MHz" : "40MHz"))
if (is_hal_stop(rtlhal)) {
rtlphy->set_bwmode_inprogress = false;
return;
}
reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);
switch (rtlphy->current_chan_bw) {
case HT_CHANNEL_WIDTH_20:
reg_bw_opmode |= BW_OPMODE_20MHZ;
rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
break;
case HT_CHANNEL_WIDTH_20_40:
reg_bw_opmode &= ~BW_OPMODE_20MHZ;
rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
reg_prsr_rsc =
(reg_prsr_rsc & 0x90) | (mac->cur_40_prime_sc << 5);
rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc);
break;
default:
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
("unknown bandwidth: %#X\n", rtlphy->current_chan_bw));
break;
}
switch (rtlphy->current_chan_bw) {
case HT_CHANNEL_WIDTH_20:
rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1);
break;
case HT_CHANNEL_WIDTH_20_40:
rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
(mac->cur_40_prime_sc >> 1));
rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0);
rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)),
(mac->cur_40_prime_sc ==
HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
break;
default:
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
("unknown bandwidth: %#X\n", rtlphy->current_chan_bw));
break;
}
rtl92c_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
rtlphy->set_bwmode_inprogress = false;
RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n"));
}
void rtl92c_bb_block_on(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
mutex_lock(&rtlpriv->io.bb_mutex);
rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1);
rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1);
mutex_unlock(&rtlpriv->io.bb_mutex);
}
static void _rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
{
u8 tmpreg;
u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
struct rtl_priv *rtlpriv = rtl_priv(hw);
tmpreg = rtl_read_byte(rtlpriv, 0xd03);
if ((tmpreg & 0x70) != 0)
rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F);
else
rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
if ((tmpreg & 0x70) != 0) {
rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS);
if (is2t)
rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00,
MASK12BITS);
rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS,
(rf_a_mode & 0x8FFFF) | 0x10000);
if (is2t)
rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
(rf_b_mode & 0x8FFFF) | 0x10000);
}
lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS);
rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, lc_cal | 0x08000);
mdelay(100);
if ((tmpreg & 0x70) != 0) {
rtl_write_byte(rtlpriv, 0xd03, tmpreg);
rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode);
if (is2t)
rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
rf_b_mode);
} else {
rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
}
}
static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw,
enum rf_pwrstate rfpwr_state)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
bool bresult = true;
u8 i, queue_id;
struct rtl8192_tx_ring *ring = NULL;
ppsc->set_rfpowerstate_inprogress = true;
switch (rfpwr_state) {
case ERFON:
if ((ppsc->rfpwr_state == ERFOFF) &&
RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
bool rtstatus;
u32 InitializeCount = 0;
do {
InitializeCount++;
RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
("IPS Set eRf nic enable\n"));
rtstatus = rtl_ps_enable_nic(hw);
} while ((rtstatus != true)
&& (InitializeCount < 10));
RT_CLEAR_PS_LEVEL(ppsc,
RT_RF_OFF_LEVL_HALT_NIC);
} else {
RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
("Set ERFON sleeped:%d ms\n",
jiffies_to_msecs(jiffies -
ppsc->
last_sleep_jiffies)));
ppsc->last_awake_jiffies = jiffies;
rtl92ce_phy_set_rf_on(hw);
}
if (mac->link_state == MAC80211_LINKED) {
rtlpriv->cfg->ops->led_control(hw,
LED_CTL_LINK);
} else {
rtlpriv->cfg->ops->led_control(hw,
LED_CTL_NO_LINK);
}
break;
case ERFOFF:
for (queue_id = 0, i = 0;
queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
ring = &pcipriv->dev.tx_ring[queue_id];
if (skb_queue_len(&ring->queue) == 0 ||
queue_id == BEACON_QUEUE) {
queue_id++;
continue;
} else {
RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
("eRf Off/Sleep: %d times "
"TcbBusyQueue[%d] "
"=%d before doze!\n", (i + 1),
queue_id,
skb_queue_len(&ring->queue)));
udelay(10);
i++;
}
if (i >= MAX_DOZE_WAITING_TIMES_9x) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
("\nERFOFF: %d times "
"TcbBusyQueue[%d] = %d !\n",
MAX_DOZE_WAITING_TIMES_9x,
queue_id,
skb_queue_len(&ring->queue)));
break;
}
}
if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
("IPS Set eRf nic disable\n"));
rtl_ps_disable_nic(hw);
RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
} else {
if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
rtlpriv->cfg->ops->led_control(hw,
LED_CTL_NO_LINK);
} else {
rtlpriv->cfg->ops->led_control(hw,
LED_CTL_POWER_OFF);
}
}
break;
case ERFSLEEP:
if (ppsc->rfpwr_state == ERFOFF)
break;
for (queue_id = 0, i = 0;
queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
ring = &pcipriv->dev.tx_ring[queue_id];
if (skb_queue_len(&ring->queue) == 0) {
queue_id++;
continue;
} else {
RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
("eRf Off/Sleep: %d times "
"TcbBusyQueue[%d] =%d before "
"doze!\n", (i + 1), queue_id,
skb_queue_len(&ring->queue)));
udelay(10);
i++;
}
if (i >= MAX_DOZE_WAITING_TIMES_9x) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
("\n ERFSLEEP: %d times "
"TcbBusyQueue[%d] = %d !\n",
MAX_DOZE_WAITING_TIMES_9x,
queue_id,
skb_queue_len(&ring->queue)));
break;
}
}
RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
("Set ERFSLEEP awaked:%d ms\n",
jiffies_to_msecs(jiffies -
ppsc->last_awake_jiffies)));
ppsc->last_sleep_jiffies = jiffies;
_rtl92ce_phy_set_rf_sleep(hw);
break;
default:
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
("switch case not process\n"));
bresult = false;
break;
}
if (bresult)
ppsc->rfpwr_state = rfpwr_state;
ppsc->set_rfpowerstate_inprogress = false;
return bresult;
}
bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw,
enum rf_pwrstate rfpwr_state)
{
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
bool bresult = false;
if (rfpwr_state == ppsc->rfpwr_state)
return bresult;
bresult = _rtl92ce_phy_set_rf_power_state(hw, rfpwr_state);
return bresult;
}

View File

@ -0,0 +1,34 @@
/******************************************************************************
*
* Copyright(c) 2009-2010 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#include "../rtl8192ce/phy.h"
void rtl92c_bb_block_on(struct ieee80211_hw *hw);
bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, u32 rfpath);
void rtl92c_phy_set_io(struct ieee80211_hw *hw);

View File

@ -0,0 +1,30 @@
/******************************************************************************
*
* Copyright(c) 2009-2010 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#include "../rtl8192ce/reg.h"

View File

@ -0,0 +1,493 @@
/******************************************************************************
*
* Copyright(c) 2009-2010 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#include "../wifi.h"
#include "reg.h"
#include "def.h"
#include "phy.h"
#include "rf.h"
#include "dm.h"
static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw);
void rtl92c_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
switch (bandwidth) {
case HT_CHANNEL_WIDTH_20:
rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] &
0xfffff3ff) | 0x0400);
rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK,
rtlphy->rfreg_chnlval[0]);
break;
case HT_CHANNEL_WIDTH_20_40:
rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] &
0xfffff3ff));
rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK,
rtlphy->rfreg_chnlval[0]);
break;
default:
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
("unknown bandwidth: %#X\n", bandwidth));
break;
}
}
void rtl92c_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
u8 *ppowerlevel)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
u32 tx_agc[2] = { 0, 0 }, tmpval = 0;
bool turbo_scanoff = false;
u8 idx1, idx2;
u8 *ptr;
if (rtlhal->interface == INTF_PCI) {
if (rtlefuse->eeprom_regulatory != 0)
turbo_scanoff = true;
} else {
if ((rtlefuse->eeprom_regulatory != 0) ||
(rtlefuse->external_pa))
turbo_scanoff = true;
}
if (mac->act_scanning == true) {
tx_agc[RF90_PATH_A] = 0x3f3f3f3f;
tx_agc[RF90_PATH_B] = 0x3f3f3f3f;
if (turbo_scanoff) {
for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
tx_agc[idx1] = ppowerlevel[idx1] |
(ppowerlevel[idx1] << 8) |
(ppowerlevel[idx1] << 16) |
(ppowerlevel[idx1] << 24);
if (rtlhal->interface == INTF_USB) {
if (tx_agc[idx1] > 0x20 &&
rtlefuse->external_pa)
tx_agc[idx1] = 0x20;
}
}
}
} else {
if (rtlpriv->dm.dynamic_txhighpower_lvl ==
TXHIGHPWRLEVEL_LEVEL1) {
tx_agc[RF90_PATH_A] = 0x10101010;
tx_agc[RF90_PATH_B] = 0x10101010;
} else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
TXHIGHPWRLEVEL_LEVEL1) {
tx_agc[RF90_PATH_A] = 0x00000000;
tx_agc[RF90_PATH_B] = 0x00000000;
} else{
for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
tx_agc[idx1] = ppowerlevel[idx1] |
(ppowerlevel[idx1] << 8) |
(ppowerlevel[idx1] << 16) |
(ppowerlevel[idx1] << 24);
}
if (rtlefuse->eeprom_regulatory == 0) {
tmpval = (rtlphy->mcs_txpwrlevel_origoffset
[0][6]) +
(rtlphy->mcs_txpwrlevel_origoffset
[0][7] << 8);
tx_agc[RF90_PATH_A] += tmpval;
tmpval = (rtlphy->mcs_txpwrlevel_origoffset
[0][14]) +
(rtlphy->mcs_txpwrlevel_origoffset
[0][15] << 24);
tx_agc[RF90_PATH_B] += tmpval;
}
}
}
for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
ptr = (u8 *) (&(tx_agc[idx1]));
for (idx2 = 0; idx2 < 4; idx2++) {
if (*ptr > RF6052_MAX_TX_PWR)
*ptr = RF6052_MAX_TX_PWR;
ptr++;
}
}
tmpval = tx_agc[RF90_PATH_A] & 0xff;
rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1, tmpval);
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
("CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", tmpval,
RTXAGC_A_CCK1_MCS32));
tmpval = tx_agc[RF90_PATH_A] >> 8;
if (mac->mode == WIRELESS_MODE_B)
tmpval = tmpval & 0xff00ffff;
rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval);
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
("CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", tmpval,
RTXAGC_B_CCK11_A_CCK2_11));
tmpval = tx_agc[RF90_PATH_B] >> 24;
rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0, tmpval);
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
("CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", tmpval,
RTXAGC_B_CCK11_A_CCK2_11));
tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff;
rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval);
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
("CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", tmpval,
RTXAGC_B_CCK1_55_MCS32));
}
static void rtl92c_phy_get_power_base(struct ieee80211_hw *hw,
u8 *ppowerlevel, u8 channel,
u32 *ofdmbase, u32 *mcsbase)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
u32 powerBase0, powerBase1;
u8 legacy_pwrdiff = 0, ht20_pwrdiff = 0;
u8 i, powerlevel[2];
for (i = 0; i < 2; i++) {
powerlevel[i] = ppowerlevel[i];
legacy_pwrdiff = rtlefuse->txpwr_legacyhtdiff[i][channel - 1];
powerBase0 = powerlevel[i] + legacy_pwrdiff;
powerBase0 = (powerBase0 << 24) | (powerBase0 << 16) |
(powerBase0 << 8) | powerBase0;
*(ofdmbase + i) = powerBase0;
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
(" [OFDM power base index rf(%c) = 0x%x]\n",
((i == 0) ? 'A' : 'B'), *(ofdmbase + i)));
}
for (i = 0; i < 2; i++) {
if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) {
ht20_pwrdiff = rtlefuse->txpwr_ht20diff[i][channel - 1];
powerlevel[i] += ht20_pwrdiff;
}
powerBase1 = powerlevel[i];
powerBase1 = (powerBase1 << 24) |
(powerBase1 << 16) | (powerBase1 << 8) | powerBase1;
*(mcsbase + i) = powerBase1;
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
(" [MCS power base index rf(%c) = 0x%x]\n",
((i == 0) ? 'A' : 'B'), *(mcsbase + i)));
}
}
static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw,
u8 channel, u8 index,
u32 *powerBase0,
u32 *powerBase1,
u32 *p_outwriteval)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
u8 i, chnlgroup = 0, pwr_diff_limit[4];
u32 writeVal, customer_limit, rf;
for (rf = 0; rf < 2; rf++) {
switch (rtlefuse->eeprom_regulatory) {
case 0:
chnlgroup = 0;
writeVal = rtlphy->mcs_txpwrlevel_origoffset
[chnlgroup][index + (rf ? 8 : 0)]
+ ((index < 2) ? powerBase0[rf] : powerBase1[rf]);
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
("RTK better performance,writeVal(%c) = 0x%x\n",
((rf == 0) ? 'A' : 'B'), writeVal));
break;
case 1:
if (rtlphy->pwrgroup_cnt == 1)
chnlgroup = 0;
if (rtlphy->pwrgroup_cnt >= 3) {
if (channel <= 3)
chnlgroup = 0;
else if (channel >= 4 && channel <= 9)
chnlgroup = 1;
else if (channel > 9)
chnlgroup = 2;
if (rtlphy->current_chan_bw ==
HT_CHANNEL_WIDTH_20)
chnlgroup++;
else
chnlgroup += 4;
}
writeVal = rtlphy->mcs_txpwrlevel_origoffset
[chnlgroup][index +
(rf ? 8 : 0)] +
((index < 2) ? powerBase0[rf] :
powerBase1[rf]);
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
("Realtek regulatory, 20MHz, "
"writeVal(%c) = 0x%x\n",
((rf == 0) ? 'A' : 'B'), writeVal));
break;
case 2:
writeVal = ((index < 2) ? powerBase0[rf] :
powerBase1[rf]);
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
("Better regulatory,writeVal(%c) = 0x%x\n",
((rf == 0) ? 'A' : 'B'), writeVal));
break;
case 3:
chnlgroup = 0;
if (rtlphy->current_chan_bw ==
HT_CHANNEL_WIDTH_20_40) {
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
("customer's limit, 40MHzrf(%c) = "
"0x%x\n", ((rf == 0) ? 'A' : 'B'),
rtlefuse->pwrgroup_ht40[rf]
[channel - 1]));
} else {
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
("customer's limit, 20MHz rf(%c) = "
"0x%x\n", ((rf == 0) ? 'A' : 'B'),
rtlefuse->pwrgroup_ht20[rf]
[channel - 1]));
}
for (i = 0; i < 4; i++) {
pwr_diff_limit[i] =
(u8) ((rtlphy->mcs_txpwrlevel_origoffset
[chnlgroup][index + (rf ? 8 : 0)]
& (0x7f << (i * 8))) >> (i * 8));
if (rtlphy->current_chan_bw ==
HT_CHANNEL_WIDTH_20_40) {
if (pwr_diff_limit[i] >
rtlefuse->pwrgroup_ht40[rf]
[channel - 1])
pwr_diff_limit[i] = rtlefuse->
pwrgroup_ht40[rf]
[channel - 1];
} else {
if (pwr_diff_limit[i] >
rtlefuse->pwrgroup_ht20[rf]
[channel - 1])
pwr_diff_limit[i] =
rtlefuse->pwrgroup_ht20[rf]
[channel - 1];
}
}
customer_limit = (pwr_diff_limit[3] << 24) |
(pwr_diff_limit[2] << 16) |
(pwr_diff_limit[1] << 8) | (pwr_diff_limit[0]);
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
("Customer's limit rf(%c) = 0x%x\n",
((rf == 0) ? 'A' : 'B'), customer_limit));
writeVal = customer_limit + ((index < 2) ?
powerBase0[rf] : powerBase1[rf]);
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
("Customer, writeVal rf(%c)= 0x%x\n",
((rf == 0) ? 'A' : 'B'), writeVal));
break;
default:
chnlgroup = 0;
writeVal = rtlphy->mcs_txpwrlevel_origoffset[chnlgroup]
[index + (rf ? 8 : 0)] + ((index < 2) ?
powerBase0[rf] : powerBase1[rf]);
RTPRINT(rtlpriv, FPHY, PHY_TXPWR, ("RTK better "
"performance, writeValrf(%c) = 0x%x\n",
((rf == 0) ? 'A' : 'B'), writeVal));
break;
}
if (rtlpriv->dm.dynamic_txhighpower_lvl ==
TXHIGHPWRLEVEL_LEVEL1)
writeVal = 0x14141414;
else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
TXHIGHPWRLEVEL_LEVEL2)
writeVal = 0x00000000;
if (rtlpriv->dm.dynamic_txhighpower_lvl == TXHIGHPWRLEVEL_BT1)
writeVal = writeVal - 0x06060606;
else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
TXHIGHPWRLEVEL_BT2)
writeVal = writeVal;
*(p_outwriteval + rf) = writeVal;
}
}
static void _rtl92c_write_ofdm_power_reg(struct ieee80211_hw *hw,
u8 index, u32 *pValue)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
u16 regoffset_a[6] = {
RTXAGC_A_RATE18_06, RTXAGC_A_RATE54_24,
RTXAGC_A_MCS03_MCS00, RTXAGC_A_MCS07_MCS04,
RTXAGC_A_MCS11_MCS08, RTXAGC_A_MCS15_MCS12
};
u16 regoffset_b[6] = {
RTXAGC_B_RATE18_06, RTXAGC_B_RATE54_24,
RTXAGC_B_MCS03_MCS00, RTXAGC_B_MCS07_MCS04,
RTXAGC_B_MCS11_MCS08, RTXAGC_B_MCS15_MCS12
};
u8 i, rf, pwr_val[4];
u32 writeVal;
u16 regoffset;
for (rf = 0; rf < 2; rf++) {
writeVal = pValue[rf];
for (i = 0; i < 4; i++) {
pwr_val[i] = (u8)((writeVal & (0x7f << (i * 8))) >>
(i * 8));
if (pwr_val[i] > RF6052_MAX_TX_PWR)
pwr_val[i] = RF6052_MAX_TX_PWR;
}
writeVal = (pwr_val[3] << 24) | (pwr_val[2] << 16) |
(pwr_val[1] << 8) | pwr_val[0];
if (rf == 0)
regoffset = regoffset_a[index];
else
regoffset = regoffset_b[index];
rtl_set_bbreg(hw, regoffset, MASKDWORD, writeVal);
RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
("Set 0x%x = %08x\n", regoffset, writeVal));
if (((get_rf_type(rtlphy) == RF_2T2R) &&
(regoffset == RTXAGC_A_MCS15_MCS12 ||
regoffset == RTXAGC_B_MCS15_MCS12)) ||
((get_rf_type(rtlphy) != RF_2T2R) &&
(regoffset == RTXAGC_A_MCS07_MCS04 ||
regoffset == RTXAGC_B_MCS07_MCS04))) {
writeVal = pwr_val[3];
if (regoffset == RTXAGC_A_MCS15_MCS12 ||
regoffset == RTXAGC_A_MCS07_MCS04)
regoffset = 0xc90;
if (regoffset == RTXAGC_B_MCS15_MCS12 ||
regoffset == RTXAGC_B_MCS07_MCS04)
regoffset = 0xc98;
for (i = 0; i < 3; i++) {
writeVal = (writeVal > 6) ? (writeVal - 6) : 0;
rtl_write_byte(rtlpriv, (u32)(regoffset + i),
(u8)writeVal);
}
}
}
}
void rtl92c_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
u8 *ppowerlevel, u8 channel)
{
u32 writeVal[2], powerBase0[2], powerBase1[2];
u8 index = 0;
rtl92c_phy_get_power_base(hw, ppowerlevel,
channel, &powerBase0[0], &powerBase1[0]);
for (index = 0; index < 6; index++) {
_rtl92c_get_txpower_writeval_by_regulatory(hw,
channel, index,
&powerBase0[0],
&powerBase1[0],
&writeVal[0]);
_rtl92c_write_ofdm_power_reg(hw, index, &writeVal[0]);
}
}
bool rtl92c_phy_rf6052_config(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
bool rtstatus = true;
u8 b_reg_hwparafile = 1;
if (rtlphy->rf_type == RF_1T1R)
rtlphy->num_total_rfpath = 1;
else
rtlphy->num_total_rfpath = 2;
if (b_reg_hwparafile == 1)
rtstatus = _rtl92c_phy_rf6052_config_parafile(hw);
return rtstatus;
}
static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
u32 u4_regvalue = 0;
u8 rfpath;
bool rtstatus = true;
struct bb_reg_def *pphyreg;
for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) {
pphyreg = &rtlphy->phyreg_def[rfpath];
switch (rfpath) {
case RF90_PATH_A:
case RF90_PATH_C:
u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs,
BRFSI_RFENV);
break;
case RF90_PATH_B:
case RF90_PATH_D:
u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs,
BRFSI_RFENV << 16);
break;
}
rtl_set_bbreg(hw, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1);
udelay(1);
rtl_set_bbreg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1);
udelay(1);
rtl_set_bbreg(hw, pphyreg->rfhssi_para2,
B3WIREADDREAALENGTH, 0x0);
udelay(1);
rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0);
udelay(1);
switch (rfpath) {
case RF90_PATH_A:
rtstatus = rtl92c_phy_config_rf_with_headerfile(hw,
(enum radio_path) rfpath);
break;
case RF90_PATH_B:
rtstatus = rtl92c_phy_config_rf_with_headerfile(hw,
(enum radio_path) rfpath);
break;
case RF90_PATH_C:
break;
case RF90_PATH_D:
break;
}
switch (rfpath) {
case RF90_PATH_A:
case RF90_PATH_C:
rtl_set_bbreg(hw, pphyreg->rfintfs,
BRFSI_RFENV, u4_regvalue);
break;
case RF90_PATH_B:
case RF90_PATH_D:
rtl_set_bbreg(hw, pphyreg->rfintfs,
BRFSI_RFENV << 16, u4_regvalue);
break;
}
if (rtstatus != true) {
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
("Radio[%d] Fail!!", rfpath));
goto phy_rf_cfg_fail;
}
}
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("<---\n"));
return rtstatus;
phy_rf_cfg_fail:
return rtstatus;
}

View File

@ -0,0 +1,30 @@
/******************************************************************************
*
* Copyright(c) 2009-2010 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#include "../rtl8192ce/rf.h"

View File

@ -0,0 +1,327 @@
/******************************************************************************
*
* Copyright(c) 2009-2010 Realtek Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#include "../wifi.h"
#include "../core.h"
#include "../usb.h"
#include "../efuse.h"
#include "reg.h"
#include "def.h"
#include "phy.h"
#include "mac.h"
#include "dm.h"
#include "sw.h"
#include "trx.h"
#include "led.h"
#include "hw.h"
MODULE_AUTHOR("Georgia <georgia@realtek.com>");
MODULE_AUTHOR("Ziv Huang <ziv_huang@realtek.com>");
MODULE_AUTHOR("Larry Finger <Larry.Finger@lwfinger.net>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Realtek 8192C/8188C 802.11n USB wireless");
MODULE_FIRMWARE("rtlwifi/rtl8192cufw.bin");
static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
rtlpriv->dm.dm_initialgain_enable = 1;
rtlpriv->dm.dm_flag = 0;
rtlpriv->dm.disable_framebursting = 0;
rtlpriv->dm.thermalvalue = 0;
rtlpriv->rtlhal.pfirmware = vmalloc(0x4000);
if (!rtlpriv->rtlhal.pfirmware) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
("Can't alloc buffer for fw.\n"));
return 1;
}
return 0;
}
static void rtl92cu_deinit_sw_vars(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
if (rtlpriv->rtlhal.pfirmware) {
vfree(rtlpriv->rtlhal.pfirmware);
rtlpriv->rtlhal.pfirmware = NULL;
}
}
static struct rtl_hal_ops rtl8192cu_hal_ops = {
.init_sw_vars = rtl92cu_init_sw_vars,
.deinit_sw_vars = rtl92cu_deinit_sw_vars,
.read_chip_version = rtl92c_read_chip_version,
.read_eeprom_info = rtl92cu_read_eeprom_info,
.enable_interrupt = rtl92c_enable_interrupt,
.disable_interrupt = rtl92c_disable_interrupt,
.hw_init = rtl92cu_hw_init,
.hw_disable = rtl92cu_card_disable,
.set_network_type = rtl92cu_set_network_type,
.set_chk_bssid = rtl92cu_set_check_bssid,
.set_qos = rtl92c_set_qos,
.set_bcn_reg = rtl92cu_set_beacon_related_registers,
.set_bcn_intv = rtl92cu_set_beacon_interval,
.update_interrupt_mask = rtl92cu_update_interrupt_mask,
.get_hw_reg = rtl92cu_get_hw_reg,
.set_hw_reg = rtl92cu_set_hw_reg,
.update_rate_table = rtl92cu_update_hal_rate_table,
.update_rate_mask = rtl92cu_update_hal_rate_mask,
.fill_tx_desc = rtl92cu_tx_fill_desc,
.fill_fake_txdesc = rtl92cu_fill_fake_txdesc,
.fill_tx_cmddesc = rtl92cu_tx_fill_cmddesc,
.cmd_send_packet = rtl92cu_cmd_send_packet,
.query_rx_desc = rtl92cu_rx_query_desc,
.set_channel_access = rtl92cu_update_channel_access_setting,
.radio_onoff_checking = rtl92cu_gpio_radio_on_off_checking,
.set_bw_mode = rtl92c_phy_set_bw_mode,
.switch_channel = rtl92c_phy_sw_chnl,
.dm_watchdog = rtl92c_dm_watchdog,
.scan_operation_backup = rtl92c_phy_scan_operation_backup,
.set_rf_power_state = rtl92c_phy_set_rf_power_state,
.led_control = rtl92cu_led_control,
.enable_hw_sec = rtl92cu_enable_hw_security_config,
.set_key = rtl92c_set_key,
.init_sw_leds = rtl92cu_init_sw_leds,
.deinit_sw_leds = rtl92cu_deinit_sw_leds,
.get_bbreg = rtl92c_phy_query_bb_reg,
.set_bbreg = rtl92c_phy_set_bb_reg,
.get_rfreg = rtl92c_phy_query_rf_reg,
.set_rfreg = rtl92c_phy_set_rf_reg,
};
static struct rtl_mod_params rtl92cu_mod_params = {
.sw_crypto = 0,
};
static struct rtl_hal_usbint_cfg rtl92cu_interface_cfg = {
/* rx */
.in_ep_num = RTL92C_USB_BULK_IN_NUM,
.rx_urb_num = RTL92C_NUM_RX_URBS,
.rx_max_size = RTL92C_SIZE_MAX_RX_BUFFER,
.usb_rx_hdl = rtl8192cu_rx_hdl,
.usb_rx_segregate_hdl = NULL, /* rtl8192c_rx_segregate_hdl; */
/* tx */
.usb_tx_cleanup = rtl8192c_tx_cleanup,
.usb_tx_post_hdl = rtl8192c_tx_post_hdl,
.usb_tx_aggregate_hdl = rtl8192c_tx_aggregate_hdl,
/* endpoint mapping */
.usb_endpoint_mapping = rtl8192cu_endpoint_mapping,
.usb_mq_to_hwq = rtl8192cu_mq_to_hwq,
};
static struct rtl_hal_cfg rtl92cu_hal_cfg = {
.name = "rtl92c_usb",
.fw_name = "rtlwifi/rtl8192cufw.bin",
.ops = &rtl8192cu_hal_ops,
.mod_params = &rtl92cu_mod_params,
.usb_interface_cfg = &rtl92cu_interface_cfg,
.maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL,
.maps[SYS_FUNC_EN] = REG_SYS_FUNC_EN,
.maps[SYS_CLK] = REG_SYS_CLKR,
.maps[MAC_RCR_AM] = AM,
.maps[MAC_RCR_AB] = AB,
.maps[MAC_RCR_ACRC32] = ACRC32,
.maps[MAC_RCR_ACF] = ACF,
.maps[MAC_RCR_AAP] = AAP,
.maps[EFUSE_TEST] = REG_EFUSE_TEST,
.maps[EFUSE_CTRL] = REG_EFUSE_CTRL,
.maps[EFUSE_CLK] = 0,
.maps[EFUSE_CLK_CTRL] = REG_EFUSE_CTRL,
.maps[EFUSE_PWC_EV12V] = PWC_EV12V,
.maps[EFUSE_FEN_ELDR] = FEN_ELDR,
.maps[EFUSE_LOADER_CLK_EN] = LOADER_CLK_EN,
.maps[EFUSE_ANA8M] = EFUSE_ANA8M,
.maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE,
.maps[EFUSE_MAX_SECTION_MAP] = EFUSE_MAX_SECTION,
.maps[EFUSE_REAL_CONTENT_SIZE] = EFUSE_REAL_CONTENT_LEN,
.maps[RWCAM] = REG_CAMCMD,
.maps[WCAMI] = REG_CAMWRITE,
.maps[RCAMO] = REG_CAMREAD,
.maps[CAMDBG] = REG_CAMDBG,
.maps[SECR] = REG_SECCFG,
.maps[SEC_CAM_NONE] = CAM_NONE,
.maps[SEC_CAM_WEP40] = CAM_WEP40,
.maps[SEC_CAM_TKIP] = CAM_TKIP,
.maps[SEC_CAM_AES] = CAM_AES,
.maps[SEC_CAM_WEP104] = CAM_WEP104,
.maps[RTL_IMR_BCNDMAINT6] = IMR_BCNDMAINT6,
.maps[RTL_IMR_BCNDMAINT5] = IMR_BCNDMAINT5,
.maps[RTL_IMR_BCNDMAINT4] = IMR_BCNDMAINT4,
.maps[RTL_IMR_BCNDMAINT3] = IMR_BCNDMAINT3,
.maps[RTL_IMR_BCNDMAINT2] = IMR_BCNDMAINT2,
.maps[RTL_IMR_BCNDMAINT1] = IMR_BCNDMAINT1,
.maps[RTL_IMR_BCNDOK8] = IMR_BCNDOK8,
.maps[RTL_IMR_BCNDOK7] = IMR_BCNDOK7,
.maps[RTL_IMR_BCNDOK6] = IMR_BCNDOK6,
.maps[RTL_IMR_BCNDOK5] = IMR_BCNDOK5,
.maps[RTL_IMR_BCNDOK4] = IMR_BCNDOK4,
.maps[RTL_IMR_BCNDOK3] = IMR_BCNDOK3,
.maps[RTL_IMR_BCNDOK2] = IMR_BCNDOK2,
.maps[RTL_IMR_BCNDOK1] = IMR_BCNDOK1,
.maps[RTL_IMR_TIMEOUT2] = IMR_TIMEOUT2,
.maps[RTL_IMR_TIMEOUT1] = IMR_TIMEOUT1,
.maps[RTL_IMR_TXFOVW] = IMR_TXFOVW,
.maps[RTL_IMR_PSTIMEOUT] = IMR_PSTIMEOUT,
.maps[RTL_IMR_BcnInt] = IMR_BCNINT,
.maps[RTL_IMR_RXFOVW] = IMR_RXFOVW,
.maps[RTL_IMR_RDU] = IMR_RDU,
.maps[RTL_IMR_ATIMEND] = IMR_ATIMEND,
.maps[RTL_IMR_BDOK] = IMR_BDOK,
.maps[RTL_IMR_MGNTDOK] = IMR_MGNTDOK,
.maps[RTL_IMR_TBDER] = IMR_TBDER,
.maps[RTL_IMR_HIGHDOK] = IMR_HIGHDOK,
.maps[RTL_IMR_TBDOK] = IMR_TBDOK,
.maps[RTL_IMR_BKDOK] = IMR_BKDOK,
.maps[RTL_IMR_BEDOK] = IMR_BEDOK,
.maps[RTL_IMR_VIDOK] = IMR_VIDOK,
.maps[RTL_IMR_VODOK] = IMR_VODOK,
.maps[RTL_IMR_ROK] = IMR_ROK,
.maps[RTL_IBSS_INT_MASKS] = (IMR_BCNINT | IMR_TBDOK | IMR_TBDER),
.maps[RTL_RC_CCK_RATE1M] = DESC92C_RATE1M,
.maps[RTL_RC_CCK_RATE2M] = DESC92C_RATE2M,
.maps[RTL_RC_CCK_RATE5_5M] = DESC92C_RATE5_5M,
.maps[RTL_RC_CCK_RATE11M] = DESC92C_RATE11M,
.maps[RTL_RC_OFDM_RATE6M] = DESC92C_RATE6M,
.maps[RTL_RC_OFDM_RATE9M] = DESC92C_RATE9M,
.maps[RTL_RC_OFDM_RATE12M] = DESC92C_RATE12M,
.maps[RTL_RC_OFDM_RATE18M] = DESC92C_RATE18M,
.maps[RTL_RC_OFDM_RATE24M] = DESC92C_RATE24M,
.maps[RTL_RC_OFDM_RATE36M] = DESC92C_RATE36M,
.maps[RTL_RC_OFDM_RATE48M] = DESC92C_RATE48M,
.maps[RTL_RC_OFDM_RATE54M] = DESC92C_RATE54M,
.maps[RTL_RC_HT_RATEMCS7] = DESC92C_RATEMCS7,
.maps[RTL_RC_HT_RATEMCS15] = DESC92C_RATEMCS15,
};
#define USB_VENDER_ID_REALTEK 0x0bda
/* 2010-10-19 DID_USB_V3.4 */
static struct usb_device_id rtl8192c_usb_ids[] = {
/*=== Realtek demoboard ===*/
/* Default ID */
{RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8191, rtl92cu_hal_cfg)},
/****** 8188CU ********/
/* 8188CE-VAU USB minCard */
{RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8170, rtl92cu_hal_cfg)},
/* 8188cu 1*1 dongle */
{RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8176, rtl92cu_hal_cfg)},
/* 8188cu 1*1 dongle, (b/g mode only) */
{RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8177, rtl92cu_hal_cfg)},
/* 8188cu Slim Solo */
{RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817a, rtl92cu_hal_cfg)},
/* 8188cu Slim Combo */
{RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817b, rtl92cu_hal_cfg)},
/* 8188RU High-power USB Dongle */
{RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817d, rtl92cu_hal_cfg)},
/* 8188CE-VAU USB minCard (b/g mode only) */
{RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817e, rtl92cu_hal_cfg)},
/* 8188 Combo for BC4 */
{RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8754, rtl92cu_hal_cfg)},
/****** 8192CU ********/
/* 8191cu 1*2 */
{RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8177, rtl92cu_hal_cfg)},
/* 8192cu 2*2 */
{RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817b, rtl92cu_hal_cfg)},
/* 8192CE-VAU USB minCard */
{RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817c, rtl92cu_hal_cfg)},
/*=== Customer ID ===*/
/****** 8188CU ********/
{RTL_USB_DEVICE(0x050d, 0x1102, rtl92cu_hal_cfg)}, /*Belkin - Edimax*/
{RTL_USB_DEVICE(0x06f8, 0xe033, rtl92cu_hal_cfg)}, /*Hercules - Edimax*/
{RTL_USB_DEVICE(0x07b8, 0x8188, rtl92cu_hal_cfg)}, /*Abocom - Abocom*/
{RTL_USB_DEVICE(0x07b8, 0x8189, rtl92cu_hal_cfg)}, /*Funai - Abocom*/
{RTL_USB_DEVICE(0x0Df6, 0x0052, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/
{RTL_USB_DEVICE(0x0eb0, 0x9071, rtl92cu_hal_cfg)}, /*NO Brand - Etop*/
/* HP - Lite-On ,8188CUS Slim Combo */
{RTL_USB_DEVICE(0x103c, 0x1629, rtl92cu_hal_cfg)},
{RTL_USB_DEVICE(0x2001, 0x3308, rtl92cu_hal_cfg)}, /*D-Link - Alpha*/
{RTL_USB_DEVICE(0x2019, 0xab2a, rtl92cu_hal_cfg)}, /*Planex - Abocom*/
{RTL_USB_DEVICE(0x2019, 0xed17, rtl92cu_hal_cfg)}, /*PCI - Edimax*/
{RTL_USB_DEVICE(0x20f4, 0x648b, rtl92cu_hal_cfg)}, /*TRENDnet - Cameo*/
{RTL_USB_DEVICE(0x7392, 0x7811, rtl92cu_hal_cfg)}, /*Edimax - Edimax*/
{RTL_USB_DEVICE(0x3358, 0x13d3, rtl92cu_hal_cfg)}, /*Azwave 8188CE-VAU*/
/* Russian customer -Azwave (8188CE-VAU b/g mode only) */
{RTL_USB_DEVICE(0x3359, 0x13d3, rtl92cu_hal_cfg)},
/****** 8192CU ********/
{RTL_USB_DEVICE(0x0586, 0x341f, rtl92cu_hal_cfg)}, /*Zyxel -Abocom*/
{RTL_USB_DEVICE(0x07aa, 0x0056, rtl92cu_hal_cfg)}, /*ATKK-Gemtek*/
{RTL_USB_DEVICE(0x07b8, 0x8178, rtl92cu_hal_cfg)}, /*Funai -Abocom*/
{RTL_USB_DEVICE(0x07b8, 0x8178, rtl92cu_hal_cfg)}, /*Abocom -Abocom*/
{RTL_USB_DEVICE(0x2001, 0x3307, rtl92cu_hal_cfg)}, /*D-Link-Cameo*/
{RTL_USB_DEVICE(0x2001, 0x3309, rtl92cu_hal_cfg)}, /*D-Link-Alpha*/
{RTL_USB_DEVICE(0x2001, 0x330a, rtl92cu_hal_cfg)}, /*D-Link-Alpha*/
{RTL_USB_DEVICE(0x2019, 0xab2b, rtl92cu_hal_cfg)}, /*Planex -Abocom*/
{RTL_USB_DEVICE(0x7392, 0x7822, rtl92cu_hal_cfg)}, /*Edimax -Edimax*/
{}
};
MODULE_DEVICE_TABLE(usb, rtl8192c_usb_ids);
static struct usb_driver rtl8192cu_driver = {
.name = "rtl8192cu",
.probe = rtl_usb_probe,
.disconnect = rtl_usb_disconnect,
.id_table = rtl8192c_usb_ids,
#ifdef CONFIG_PM
/* .suspend = rtl_usb_suspend, */
/* .resume = rtl_usb_resume, */
/* .reset_resume = rtl8192c_resume, */
#endif /* CONFIG_PM */
#ifdef CONFIG_AUTOSUSPEND
.supports_autosuspend = 1,
#endif
};
static int __init rtl8192cu_init(void)
{
return usb_register(&rtl8192cu_driver);
}
static void __exit rtl8192cu_exit(void)
{
usb_deregister(&rtl8192cu_driver);
}
module_init(rtl8192cu_init);
module_exit(rtl8192cu_exit);

View File

@ -0,0 +1,35 @@
/******************************************************************************
*
* Copyright(c) 2009-2010 Realtek Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#ifndef __RTL92CU_SW_H__
#define __RTL92CU_SW_H__
#define EFUSE_MAX_SECTION 16
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,71 @@
/******************************************************************************
*
* Copyright(c) 2009-2010 Realtek Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#ifndef __RTL92CU_TABLE__H_
#define __RTL92CU_TABLE__H_
#include <linux/types.h>
#define RTL8192CUPHY_REG_2TARRAY_LENGTH 374
extern u32 RTL8192CUPHY_REG_2TARRAY[RTL8192CUPHY_REG_2TARRAY_LENGTH];
#define RTL8192CUPHY_REG_1TARRAY_LENGTH 374
extern u32 RTL8192CUPHY_REG_1TARRAY[RTL8192CUPHY_REG_1TARRAY_LENGTH];
#define RTL8192CUPHY_REG_ARRAY_PGLENGTH 336
extern u32 RTL8192CUPHY_REG_ARRAY_PG[RTL8192CUPHY_REG_ARRAY_PGLENGTH];
#define RTL8192CURADIOA_2TARRAYLENGTH 282
extern u32 RTL8192CURADIOA_2TARRAY[RTL8192CURADIOA_2TARRAYLENGTH];
#define RTL8192CURADIOB_2TARRAYLENGTH 78
extern u32 RTL8192CU_RADIOB_2TARRAY[RTL8192CURADIOB_2TARRAYLENGTH];
#define RTL8192CURADIOA_1TARRAYLENGTH 282
extern u32 RTL8192CU_RADIOA_1TARRAY[RTL8192CURADIOA_1TARRAYLENGTH];
#define RTL8192CURADIOB_1TARRAYLENGTH 1
extern u32 RTL8192CU_RADIOB_1TARRAY[RTL8192CURADIOB_1TARRAYLENGTH];
#define RTL8192CUMAC_2T_ARRAYLENGTH 172
extern u32 RTL8192CUMAC_2T_ARRAY[RTL8192CUMAC_2T_ARRAYLENGTH];
#define RTL8192CUAGCTAB_2TARRAYLENGTH 320
extern u32 RTL8192CUAGCTAB_2TARRAY[RTL8192CUAGCTAB_2TARRAYLENGTH];
#define RTL8192CUAGCTAB_1TARRAYLENGTH 320
extern u32 RTL8192CUAGCTAB_1TARRAY[RTL8192CUAGCTAB_1TARRAYLENGTH];
#define RTL8192CUPHY_REG_1T_HPArrayLength 378
extern u32 RTL8192CUPHY_REG_1T_HPArray[RTL8192CUPHY_REG_1T_HPArrayLength];
#define RTL8192CUPHY_REG_Array_PG_HPLength 336
extern u32 RTL8192CUPHY_REG_Array_PG_HP[RTL8192CUPHY_REG_Array_PG_HPLength];
#define RTL8192CURadioA_1T_HPArrayLength 282
extern u32 RTL8192CURadioA_1T_HPArray[RTL8192CURadioA_1T_HPArrayLength];
#define RTL8192CUAGCTAB_1T_HPArrayLength 320
extern u32 Rtl8192CUAGCTAB_1T_HPArray[RTL8192CUAGCTAB_1T_HPArrayLength];
#endif

View File

@ -0,0 +1,684 @@
/******************************************************************************
*
* Copyright(c) 2009-2010 Realtek Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#include "../wifi.h"
#include "../usb.h"
#include "../ps.h"
#include "../base.h"
#include "reg.h"
#include "def.h"
#include "phy.h"
#include "rf.h"
#include "dm.h"
#include "mac.h"
#include "trx.h"
static int _ConfigVerTOutEP(struct ieee80211_hw *hw)
{
u8 ep_cfg, txqsele;
u8 ep_nums = 0;
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_usb_priv *usb_priv = rtl_usbpriv(hw);
struct rtl_usb *rtlusb = rtl_usbdev(usb_priv);
rtlusb->out_queue_sel = 0;
ep_cfg = rtl_read_byte(rtlpriv, REG_TEST_SIE_OPTIONAL);
ep_cfg = (ep_cfg & USB_TEST_EP_MASK) >> USB_TEST_EP_SHIFT;
switch (ep_cfg) {
case 0: /* 2 bulk OUT, 1 bulk IN */
case 3:
rtlusb->out_queue_sel = TX_SELE_HQ | TX_SELE_LQ;
ep_nums = 2;
break;
case 1: /* 1 bulk IN/OUT => map all endpoint to Low queue */
case 2: /* 1 bulk IN, 1 bulk OUT => map all endpoint to High queue */
txqsele = rtl_read_byte(rtlpriv, REG_TEST_USB_TXQS);
if (txqsele & 0x0F) /* /map all endpoint to High queue */
rtlusb->out_queue_sel = TX_SELE_HQ;
else if (txqsele&0xF0) /* map all endpoint to Low queue */
rtlusb->out_queue_sel = TX_SELE_LQ;
ep_nums = 1;
break;
default:
break;
}
return (rtlusb->out_ep_nums == ep_nums) ? 0 : -EINVAL;
}
static int _ConfigVerNOutEP(struct ieee80211_hw *hw)
{
u8 ep_cfg;
u8 ep_nums = 0;
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_usb_priv *usb_priv = rtl_usbpriv(hw);
struct rtl_usb *rtlusb = rtl_usbdev(usb_priv);
rtlusb->out_queue_sel = 0;
/* Normal and High queue */
ep_cfg = rtl_read_byte(rtlpriv, (REG_NORMAL_SIE_EP + 1));
if (ep_cfg & USB_NORMAL_SIE_EP_MASK) {
rtlusb->out_queue_sel |= TX_SELE_HQ;
ep_nums++;
}
if ((ep_cfg >> USB_NORMAL_SIE_EP_SHIFT) & USB_NORMAL_SIE_EP_MASK) {
rtlusb->out_queue_sel |= TX_SELE_NQ;
ep_nums++;
}
/* Low queue */
ep_cfg = rtl_read_byte(rtlpriv, (REG_NORMAL_SIE_EP + 2));
if (ep_cfg & USB_NORMAL_SIE_EP_MASK) {
rtlusb->out_queue_sel |= TX_SELE_LQ;
ep_nums++;
}
return (rtlusb->out_ep_nums == ep_nums) ? 0 : -EINVAL;
}
static void _TwoOutEpMapping(struct ieee80211_hw *hw, bool bIsChipB,
bool bwificfg, struct rtl_ep_map *ep_map)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
if (bwificfg) { /* for WMM */
RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
("USB Chip-B & WMM Setting.....\n"));
ep_map->ep_mapping[RTL_TXQ_BE] = 2;
ep_map->ep_mapping[RTL_TXQ_BK] = 3;
ep_map->ep_mapping[RTL_TXQ_VI] = 3;
ep_map->ep_mapping[RTL_TXQ_VO] = 2;
ep_map->ep_mapping[RTL_TXQ_MGT] = 2;
ep_map->ep_mapping[RTL_TXQ_BCN] = 2;
ep_map->ep_mapping[RTL_TXQ_HI] = 2;
} else { /* typical setting */
RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
("USB typical Setting.....\n"));
ep_map->ep_mapping[RTL_TXQ_BE] = 3;
ep_map->ep_mapping[RTL_TXQ_BK] = 3;
ep_map->ep_mapping[RTL_TXQ_VI] = 2;
ep_map->ep_mapping[RTL_TXQ_VO] = 2;
ep_map->ep_mapping[RTL_TXQ_MGT] = 2;
ep_map->ep_mapping[RTL_TXQ_BCN] = 2;
ep_map->ep_mapping[RTL_TXQ_HI] = 2;
}
}
static void _ThreeOutEpMapping(struct ieee80211_hw *hw, bool bwificfg,
struct rtl_ep_map *ep_map)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
if (bwificfg) { /* for WMM */
RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
("USB 3EP Setting for WMM.....\n"));
ep_map->ep_mapping[RTL_TXQ_BE] = 5;
ep_map->ep_mapping[RTL_TXQ_BK] = 3;
ep_map->ep_mapping[RTL_TXQ_VI] = 3;
ep_map->ep_mapping[RTL_TXQ_VO] = 2;
ep_map->ep_mapping[RTL_TXQ_MGT] = 2;
ep_map->ep_mapping[RTL_TXQ_BCN] = 2;
ep_map->ep_mapping[RTL_TXQ_HI] = 2;
} else { /* typical setting */
RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
("USB 3EP Setting for typical.....\n"));
ep_map->ep_mapping[RTL_TXQ_BE] = 5;
ep_map->ep_mapping[RTL_TXQ_BK] = 5;
ep_map->ep_mapping[RTL_TXQ_VI] = 3;
ep_map->ep_mapping[RTL_TXQ_VO] = 2;
ep_map->ep_mapping[RTL_TXQ_MGT] = 2;
ep_map->ep_mapping[RTL_TXQ_BCN] = 2;
ep_map->ep_mapping[RTL_TXQ_HI] = 2;
}
}
static void _OneOutEpMapping(struct ieee80211_hw *hw, struct rtl_ep_map *ep_map)
{
ep_map->ep_mapping[RTL_TXQ_BE] = 2;
ep_map->ep_mapping[RTL_TXQ_BK] = 2;
ep_map->ep_mapping[RTL_TXQ_VI] = 2;
ep_map->ep_mapping[RTL_TXQ_VO] = 2;
ep_map->ep_mapping[RTL_TXQ_MGT] = 2;
ep_map->ep_mapping[RTL_TXQ_BCN] = 2;
ep_map->ep_mapping[RTL_TXQ_HI] = 2;
}
static int _out_ep_mapping(struct ieee80211_hw *hw)
{
int err = 0;
bool bIsChipN, bwificfg = false;
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
struct rtl_usb_priv *usb_priv = rtl_usbpriv(hw);
struct rtl_usb *rtlusb = rtl_usbdev(usb_priv);
struct rtl_ep_map *ep_map = &(rtlusb->ep_map);
bIsChipN = IS_NORMAL_CHIP(rtlhal->version);
switch (rtlusb->out_ep_nums) {
case 2:
_TwoOutEpMapping(hw, bIsChipN, bwificfg, ep_map);
break;
case 3:
/* Test chip doesn't support three out EPs. */
if (!bIsChipN) {
err = -EINVAL;
goto err_out;
}
_ThreeOutEpMapping(hw, bIsChipN, ep_map);
break;
case 1:
_OneOutEpMapping(hw, ep_map);
break;
default:
err = -EINVAL;
break;
}
err_out:
return err;
}
/* endpoint mapping */
int rtl8192cu_endpoint_mapping(struct ieee80211_hw *hw)
{
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
int error = 0;
if (likely(IS_NORMAL_CHIP(rtlhal->version)))
error = _ConfigVerNOutEP(hw);
else
error = _ConfigVerTOutEP(hw);
if (error)
goto err_out;
error = _out_ep_mapping(hw);
if (error)
goto err_out;
err_out:
return error;
}
u16 rtl8192cu_mq_to_hwq(__le16 fc, u16 mac80211_queue_index)
{
u16 hw_queue_index;
if (unlikely(ieee80211_is_beacon(fc))) {
hw_queue_index = RTL_TXQ_BCN;
goto out;
}
if (ieee80211_is_mgmt(fc)) {
hw_queue_index = RTL_TXQ_MGT;
goto out;
}
switch (mac80211_queue_index) {
case 0:
hw_queue_index = RTL_TXQ_VO;
break;
case 1:
hw_queue_index = RTL_TXQ_VI;
break;
case 2:
hw_queue_index = RTL_TXQ_BE;
break;
case 3:
hw_queue_index = RTL_TXQ_BK;
break;
default:
hw_queue_index = RTL_TXQ_BE;
RT_ASSERT(false, ("QSLT_BE queue, skb_queue:%d\n",
mac80211_queue_index));
break;
}
out:
return hw_queue_index;
}
static enum rtl_desc_qsel _rtl8192cu_mq_to_descq(struct ieee80211_hw *hw,
__le16 fc, u16 mac80211_queue_index)
{
enum rtl_desc_qsel qsel;
struct rtl_priv *rtlpriv = rtl_priv(hw);
if (unlikely(ieee80211_is_beacon(fc))) {
qsel = QSLT_BEACON;
goto out;
}
if (ieee80211_is_mgmt(fc)) {
qsel = QSLT_MGNT;
goto out;
}
switch (mac80211_queue_index) {
case 0: /* VO */
qsel = QSLT_VO;
RT_TRACE(rtlpriv, COMP_USB, DBG_DMESG,
("VO queue, set qsel = 0x%x\n", QSLT_VO));
break;
case 1: /* VI */
qsel = QSLT_VI;
RT_TRACE(rtlpriv, COMP_USB, DBG_DMESG,
("VI queue, set qsel = 0x%x\n", QSLT_VI));
break;
case 3: /* BK */
qsel = QSLT_BK;
RT_TRACE(rtlpriv, COMP_USB, DBG_DMESG,
("BK queue, set qsel = 0x%x\n", QSLT_BK));
break;
case 2: /* BE */
default:
qsel = QSLT_BE;
RT_TRACE(rtlpriv, COMP_USB, DBG_DMESG,
("BE queue, set qsel = 0x%x\n", QSLT_BE));
break;
}
out:
return qsel;
}
/* =============================================================== */
/*----------------------------------------------------------------------
*
* Rx handler
*
*---------------------------------------------------------------------- */
bool rtl92cu_rx_query_desc(struct ieee80211_hw *hw,
struct rtl_stats *stats,
struct ieee80211_rx_status *rx_status,
u8 *p_desc, struct sk_buff *skb)
{
struct rx_fwinfo_92c *p_drvinfo;
struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc;
u32 phystatus = GET_RX_DESC_PHY_STATUS(pdesc);
stats->length = (u16) GET_RX_DESC_PKT_LEN(pdesc);
stats->rx_drvinfo_size = (u8)GET_RX_DESC_DRVINFO_SIZE(pdesc) *
RX_DRV_INFO_SIZE_UNIT;
stats->rx_bufshift = (u8) (GET_RX_DESC_SHIFT(pdesc) & 0x03);
stats->icv = (u16) GET_RX_DESC_ICV(pdesc);
stats->crc = (u16) GET_RX_DESC_CRC32(pdesc);
stats->hwerror = (stats->crc | stats->icv);
stats->decrypted = !GET_RX_DESC_SWDEC(pdesc);
stats->rate = (u8) GET_RX_DESC_RX_MCS(pdesc);
stats->shortpreamble = (u16) GET_RX_DESC_SPLCP(pdesc);
stats->isampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1);
stats->isampdu = (bool) ((GET_RX_DESC_PAGGR(pdesc) == 1)
&& (GET_RX_DESC_FAGGR(pdesc) == 1));
stats->timestamp_low = GET_RX_DESC_TSFL(pdesc);
stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc);
rx_status->freq = hw->conf.channel->center_freq;
rx_status->band = hw->conf.channel->band;
if (GET_RX_DESC_CRC32(pdesc))
rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
if (!GET_RX_DESC_SWDEC(pdesc))
rx_status->flag |= RX_FLAG_DECRYPTED;
if (GET_RX_DESC_BW(pdesc))
rx_status->flag |= RX_FLAG_40MHZ;
if (GET_RX_DESC_RX_HT(pdesc))
rx_status->flag |= RX_FLAG_HT;
rx_status->flag |= RX_FLAG_TSFT;
if (stats->decrypted)
rx_status->flag |= RX_FLAG_DECRYPTED;
rx_status->rate_idx = _rtl92c_rate_mapping(hw,
(bool)GET_RX_DESC_RX_HT(pdesc),
(u8)GET_RX_DESC_RX_MCS(pdesc),
(bool)GET_RX_DESC_PAGGR(pdesc));
rx_status->mactime = GET_RX_DESC_TSFL(pdesc);
if (phystatus == true) {
p_drvinfo = (struct rx_fwinfo_92c *)(pdesc + RTL_RX_DESC_SIZE);
rtl92c_translate_rx_signal_stuff(hw, skb, stats, pdesc,
p_drvinfo);
}
/*rx_status->qual = stats->signal; */
rx_status->signal = stats->rssi + 10;
/*rx_status->noise = -stats->noise; */
return true;
}
#define RTL_RX_DRV_INFO_UNIT 8
static void _rtl_rx_process(struct ieee80211_hw *hw, struct sk_buff *skb)
{
struct ieee80211_rx_status *rx_status =
(struct ieee80211_rx_status *)IEEE80211_SKB_RXCB(skb);
u32 skb_len, pkt_len, drvinfo_len;
struct rtl_priv *rtlpriv = rtl_priv(hw);
u8 *rxdesc;
struct rtl_stats stats = {
.signal = 0,
.noise = -98,
.rate = 0,
};
struct rx_fwinfo_92c *p_drvinfo;
bool bv;
__le16 fc;
struct ieee80211_hdr *hdr;
memset(rx_status, 0, sizeof(rx_status));
rxdesc = skb->data;
skb_len = skb->len;
drvinfo_len = (GET_RX_DESC_DRVINFO_SIZE(rxdesc) * RTL_RX_DRV_INFO_UNIT);
pkt_len = GET_RX_DESC_PKT_LEN(rxdesc);
/* TODO: Error recovery. drop this skb or something. */
WARN_ON(skb_len < (pkt_len + RTL_RX_DESC_SIZE + drvinfo_len));
stats.length = (u16) GET_RX_DESC_PKT_LEN(rxdesc);
stats.rx_drvinfo_size = (u8)GET_RX_DESC_DRVINFO_SIZE(rxdesc) *
RX_DRV_INFO_SIZE_UNIT;
stats.rx_bufshift = (u8) (GET_RX_DESC_SHIFT(rxdesc) & 0x03);
stats.icv = (u16) GET_RX_DESC_ICV(rxdesc);
stats.crc = (u16) GET_RX_DESC_CRC32(rxdesc);
stats.hwerror = (stats.crc | stats.icv);
stats.decrypted = !GET_RX_DESC_SWDEC(rxdesc);
stats.rate = (u8) GET_RX_DESC_RX_MCS(rxdesc);
stats.shortpreamble = (u16) GET_RX_DESC_SPLCP(rxdesc);
stats.isampdu = (bool) ((GET_RX_DESC_PAGGR(rxdesc) == 1)
&& (GET_RX_DESC_FAGGR(rxdesc) == 1));
stats.timestamp_low = GET_RX_DESC_TSFL(rxdesc);
stats.rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(rxdesc);
/* TODO: is center_freq changed when doing scan? */
/* TODO: Shall we add protection or just skip those two step? */
rx_status->freq = hw->conf.channel->center_freq;
rx_status->band = hw->conf.channel->band;
if (GET_RX_DESC_CRC32(rxdesc))
rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
if (!GET_RX_DESC_SWDEC(rxdesc))
rx_status->flag |= RX_FLAG_DECRYPTED;
if (GET_RX_DESC_BW(rxdesc))
rx_status->flag |= RX_FLAG_40MHZ;
if (GET_RX_DESC_RX_HT(rxdesc))
rx_status->flag |= RX_FLAG_HT;
/* Data rate */
rx_status->rate_idx = _rtl92c_rate_mapping(hw,
(bool)GET_RX_DESC_RX_HT(rxdesc),
(u8)GET_RX_DESC_RX_MCS(rxdesc),
(bool)GET_RX_DESC_PAGGR(rxdesc)
);
/* There is a phy status after this rx descriptor. */
if (GET_RX_DESC_PHY_STATUS(rxdesc)) {
p_drvinfo = (struct rx_fwinfo_92c *)(rxdesc + RTL_RX_DESC_SIZE);
rtl92c_translate_rx_signal_stuff(hw, skb, &stats,
(struct rx_desc_92c *)rxdesc, p_drvinfo);
}
skb_pull(skb, (drvinfo_len + RTL_RX_DESC_SIZE));
hdr = (struct ieee80211_hdr *)(skb->data);
fc = hdr->frame_control;
bv = ieee80211_is_probe_resp(fc);
if (bv)
RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
("Got probe response frame.\n"));
if (ieee80211_is_beacon(fc))
RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
("Got beacon frame.\n"));
if (ieee80211_is_data(fc))
RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Got data frame.\n"));
RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
("Fram: fc = 0x%X addr1 = 0x%02X:0x%02X:0x%02X:0x%02X:0x%02X:"
"0x%02X\n", fc, (u32)hdr->addr1[0], (u32)hdr->addr1[1],
(u32)hdr->addr1[2], (u32)hdr->addr1[3], (u32)hdr->addr1[4],
(u32)hdr->addr1[5]));
memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
ieee80211_rx_irqsafe(hw, skb);
}
void rtl8192cu_rx_hdl(struct ieee80211_hw *hw, struct sk_buff * skb)
{
_rtl_rx_process(hw, skb);
}
void rtl8192c_rx_segregate_hdl(
struct ieee80211_hw *hw,
struct sk_buff *skb,
struct sk_buff_head *skb_list)
{
}
/*----------------------------------------------------------------------
*
* Tx handler
*
*---------------------------------------------------------------------- */
void rtl8192c_tx_cleanup(struct ieee80211_hw *hw, struct sk_buff *skb)
{
}
int rtl8192c_tx_post_hdl(struct ieee80211_hw *hw, struct urb *urb,
struct sk_buff *skb)
{
return 0;
}
struct sk_buff *rtl8192c_tx_aggregate_hdl(struct ieee80211_hw *hw,
struct sk_buff_head *list)
{
return skb_dequeue(list);
}
/*======================================== trx ===============================*/
static void _rtl_fill_usb_tx_desc(u8 *txdesc)
{
SET_TX_DESC_OWN(txdesc, 1);
SET_TX_DESC_LAST_SEG(txdesc, 1);
SET_TX_DESC_FIRST_SEG(txdesc, 1);
}
/**
* For HW recovery information
*/
static void _rtl_tx_desc_checksum(u8 *txdesc)
{
u16 *ptr = (u16 *)txdesc;
u16 checksum = 0;
u32 index;
/* Clear first */
SET_TX_DESC_TX_DESC_CHECKSUM(txdesc, 0);
for (index = 0; index < 16; index++)
checksum = checksum ^ (*(ptr + index));
SET_TX_DESC_TX_DESC_CHECKSUM(txdesc, checksum);
}
void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw,
struct ieee80211_hdr *hdr, u8 *pdesc_tx,
struct ieee80211_tx_info *info, struct sk_buff *skb,
unsigned int queue_index)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
bool defaultadapter = true;
struct ieee80211_sta *sta = ieee80211_find_sta(mac->vif, mac->bssid);
struct rtl_tcb_desc tcb_desc;
u8 *qc = ieee80211_get_qos_ctl(hdr);
u8 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
u16 seq_number;
__le16 fc = hdr->frame_control;
u8 rate_flag = info->control.rates[0].flags;
u16 pktlen = skb->len;
enum rtl_desc_qsel fw_qsel = _rtl8192cu_mq_to_descq(hw, fc,
skb_get_queue_mapping(skb));
u8 *txdesc;
seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
rtl_get_tcb_desc(hw, info, skb, &tcb_desc);
txdesc = (u8 *)skb_push(skb, RTL_TX_HEADER_SIZE);
memset(txdesc, 0, RTL_TX_HEADER_SIZE);
SET_TX_DESC_PKT_SIZE(txdesc, pktlen);
SET_TX_DESC_LINIP(txdesc, 0);
SET_TX_DESC_PKT_OFFSET(txdesc, RTL_DUMMY_OFFSET);
SET_TX_DESC_OFFSET(txdesc, RTL_TX_HEADER_SIZE);
SET_TX_DESC_TX_RATE(txdesc, tcb_desc.hw_rate);
if (tcb_desc.use_shortgi || tcb_desc.use_shortpreamble)
SET_TX_DESC_DATA_SHORTGI(txdesc, 1);
if (mac->tids[tid].agg.agg_state == RTL_AGG_ON &&
info->flags & IEEE80211_TX_CTL_AMPDU) {
SET_TX_DESC_AGG_ENABLE(txdesc, 1);
SET_TX_DESC_MAX_AGG_NUM(txdesc, 0x14);
} else {
SET_TX_DESC_AGG_BREAK(txdesc, 1);
}
SET_TX_DESC_SEQ(txdesc, seq_number);
SET_TX_DESC_RTS_ENABLE(txdesc, ((tcb_desc.rts_enable &&
!tcb_desc.cts_enable) ? 1 : 0));
SET_TX_DESC_HW_RTS_ENABLE(txdesc, ((tcb_desc.rts_enable ||
tcb_desc.cts_enable) ? 1 : 0));
SET_TX_DESC_CTS2SELF(txdesc, ((tcb_desc.cts_enable) ? 1 : 0));
SET_TX_DESC_RTS_STBC(txdesc, ((tcb_desc.rts_stbc) ? 1 : 0));
SET_TX_DESC_RTS_RATE(txdesc, tcb_desc.rts_rate);
SET_TX_DESC_RTS_BW(txdesc, 0);
SET_TX_DESC_RTS_SC(txdesc, tcb_desc.rts_sc);
SET_TX_DESC_RTS_SHORT(txdesc,
((tcb_desc.rts_rate <= DESC92C_RATE54M) ?
(tcb_desc.rts_use_shortpreamble ? 1 : 0)
: (tcb_desc.rts_use_shortgi ? 1 : 0)));
if (mac->bw_40) {
if (tcb_desc.packet_bw) {
SET_TX_DESC_DATA_BW(txdesc, 1);
SET_TX_DESC_DATA_SC(txdesc, 3);
} else {
SET_TX_DESC_DATA_BW(txdesc, 0);
if (rate_flag & IEEE80211_TX_RC_DUP_DATA)
SET_TX_DESC_DATA_SC(txdesc,
mac->cur_40_prime_sc);
}
} else {
SET_TX_DESC_DATA_BW(txdesc, 0);
SET_TX_DESC_DATA_SC(txdesc, 0);
}
if (sta) {
u8 ampdu_density = sta->ht_cap.ampdu_density;
SET_TX_DESC_AMPDU_DENSITY(txdesc, ampdu_density);
}
if (info->control.hw_key) {
struct ieee80211_key_conf *keyconf = info->control.hw_key;
switch (keyconf->cipher) {
case WLAN_CIPHER_SUITE_WEP40:
case WLAN_CIPHER_SUITE_WEP104:
case WLAN_CIPHER_SUITE_TKIP:
SET_TX_DESC_SEC_TYPE(txdesc, 0x1);
break;
case WLAN_CIPHER_SUITE_CCMP:
SET_TX_DESC_SEC_TYPE(txdesc, 0x3);
break;
default:
SET_TX_DESC_SEC_TYPE(txdesc, 0x0);
break;
}
}
SET_TX_DESC_PKT_ID(txdesc, 0);
SET_TX_DESC_QUEUE_SEL(txdesc, fw_qsel);
SET_TX_DESC_DATA_RATE_FB_LIMIT(txdesc, 0x1F);
SET_TX_DESC_RTS_RATE_FB_LIMIT(txdesc, 0xF);
SET_TX_DESC_DISABLE_FB(txdesc, 0);
SET_TX_DESC_USE_RATE(txdesc, tcb_desc.use_driver_rate ? 1 : 0);
if (ieee80211_is_data_qos(fc)) {
if (mac->rdg_en) {
RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
("Enable RDG function.\n"));
SET_TX_DESC_RDG_ENABLE(txdesc, 1);
SET_TX_DESC_HTC(txdesc, 1);
}
}
if (rtlpriv->dm.useramask) {
SET_TX_DESC_RATE_ID(txdesc, tcb_desc.ratr_index);
SET_TX_DESC_MACID(txdesc, tcb_desc.mac_id);
} else {
SET_TX_DESC_RATE_ID(txdesc, 0xC + tcb_desc.ratr_index);
SET_TX_DESC_MACID(txdesc, tcb_desc.ratr_index);
}
if ((!ieee80211_is_data_qos(fc)) && ppsc->leisure_ps &&
ppsc->fwctrl_lps) {
SET_TX_DESC_HWSEQ_EN(txdesc, 1);
SET_TX_DESC_PKT_ID(txdesc, 8);
if (!defaultadapter)
SET_TX_DESC_QOS(txdesc, 1);
}
if (ieee80211_has_morefrags(fc))
SET_TX_DESC_MORE_FRAG(txdesc, 1);
if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) ||
is_broadcast_ether_addr(ieee80211_get_DA(hdr)))
SET_TX_DESC_BMC(txdesc, 1);
_rtl_fill_usb_tx_desc(txdesc);
_rtl_tx_desc_checksum(txdesc);
RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, (" %s ==>\n", __func__));
}
void rtl92cu_fill_fake_txdesc(struct ieee80211_hw *hw, u8 * pDesc,
u32 buffer_len, bool bIsPsPoll)
{
/* Clear all status */
memset(pDesc, 0, RTL_TX_HEADER_SIZE);
SET_TX_DESC_FIRST_SEG(pDesc, 1); /* bFirstSeg; */
SET_TX_DESC_LAST_SEG(pDesc, 1); /* bLastSeg; */
SET_TX_DESC_OFFSET(pDesc, RTL_TX_HEADER_SIZE); /* Offset = 32 */
SET_TX_DESC_PKT_SIZE(pDesc, buffer_len); /* Buffer size + command hdr */
SET_TX_DESC_QUEUE_SEL(pDesc, QSLT_MGNT); /* Fixed queue of Mgnt queue */
/* Set NAVUSEHDR to prevent Ps-poll AId filed to be changed to error
* vlaue by Hw. */
if (bIsPsPoll) {
SET_TX_DESC_NAV_USE_HDR(pDesc, 1);
} else {
SET_TX_DESC_HWSEQ_EN(pDesc, 1); /* Hw set sequence number */
SET_TX_DESC_PKT_ID(pDesc, 0x100); /* set bit3 to 1. */
}
SET_TX_DESC_USE_RATE(pDesc, 1); /* use data rate which is set by Sw */
SET_TX_DESC_OWN(pDesc, 1);
SET_TX_DESC_TX_RATE(pDesc, DESC92C_RATE1M);
_rtl_tx_desc_checksum(pDesc);
}
void rtl92cu_tx_fill_cmddesc(struct ieee80211_hw *hw,
u8 *pdesc, bool firstseg,
bool lastseg, struct sk_buff *skb)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u8 fw_queue = QSLT_BEACON;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
__le16 fc = hdr->frame_control;
memset((void *)pdesc, 0, RTL_TX_HEADER_SIZE);
if (firstseg)
SET_TX_DESC_OFFSET(pdesc, RTL_TX_HEADER_SIZE);
SET_TX_DESC_TX_RATE(pdesc, DESC92C_RATE1M);
SET_TX_DESC_SEQ(pdesc, 0);
SET_TX_DESC_LINIP(pdesc, 0);
SET_TX_DESC_QUEUE_SEL(pdesc, fw_queue);
SET_TX_DESC_FIRST_SEG(pdesc, 1);
SET_TX_DESC_LAST_SEG(pdesc, 1);
SET_TX_DESC_RATE_ID(pdesc, 7);
SET_TX_DESC_MACID(pdesc, 0);
SET_TX_DESC_OWN(pdesc, 1);
SET_TX_DESC_PKT_SIZE((u8 *) pdesc, (u16) (skb->len));
SET_TX_DESC_FIRST_SEG(pdesc, 1);
SET_TX_DESC_LAST_SEG(pdesc, 1);
SET_TX_DESC_OFFSET(pdesc, 0x20);
SET_TX_DESC_USE_RATE(pdesc, 1);
if (!ieee80211_is_data_qos(fc)) {
SET_TX_DESC_HWSEQ_EN(pdesc, 1);
SET_TX_DESC_PKT_ID(pdesc, 8);
}
RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, "H2C Tx Cmd Content\n",
pdesc, RTL_TX_DESC_SIZE);
}
bool rtl92cu_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb)
{
return true;
}

View File

@ -0,0 +1,430 @@
/******************************************************************************
*
* Copyright(c) 2009-2010 Realtek Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#ifndef __RTL92CU_TRX_H__
#define __RTL92CU_TRX_H__
#define RTL92C_USB_BULK_IN_NUM 1
#define RTL92C_NUM_RX_URBS 8
#define RTL92C_NUM_TX_URBS 32
#define RTL92C_SIZE_MAX_RX_BUFFER 15360 /* 8192 */
#define RX_DRV_INFO_SIZE_UNIT 8
enum usb_rx_agg_mode {
USB_RX_AGG_DISABLE,
USB_RX_AGG_DMA,
USB_RX_AGG_USB,
USB_RX_AGG_DMA_USB
};
#define TX_SELE_HQ BIT(0) /* High Queue */
#define TX_SELE_LQ BIT(1) /* Low Queue */
#define TX_SELE_NQ BIT(2) /* Normal Queue */
#define RTL_USB_TX_AGG_NUM_DESC 5
#define RTL_USB_RX_AGG_PAGE_NUM 4
#define RTL_USB_RX_AGG_PAGE_TIMEOUT 3
#define RTL_USB_RX_AGG_BLOCK_NUM 5
#define RTL_USB_RX_AGG_BLOCK_TIMEOUT 3
/*======================== rx status =========================================*/
struct rx_drv_info_92c {
/*
* Driver info contain PHY status and other variabel size info
* PHY Status content as below
*/
/* DWORD 0 */
u8 gain_trsw[4];
/* DWORD 1 */
u8 pwdb_all;
u8 cfosho[4];
/* DWORD 2 */
u8 cfotail[4];
/* DWORD 3 */
s8 rxevm[2];
s8 rxsnr[4];
/* DWORD 4 */
u8 pdsnr[2];
/* DWORD 5 */
u8 csi_current[2];
u8 csi_target[2];
/* DWORD 6 */
u8 sigevm;
u8 max_ex_pwr;
u8 ex_intf_flag:1;
u8 sgi_en:1;
u8 rxsc:2;
u8 reserve:4;
} __packed;
/* Define a macro that takes a le32 word, converts it to host ordering,
* right shifts by a specified count, creates a mask of the specified
* bit count, and extracts that number of bits.
*/
#define SHIFT_AND_MASK_LE(__pdesc, __shift, __bits) \
((le32_to_cpu(*(((__le32 *)(__pdesc)))) >> (__shift)) & \
BIT_LEN_MASK_32(__bits))
/* Define a macro that clears a bit field in an le32 word and
* sets the specified value into that bit field. The resulting
* value remains in le32 ordering; however, it is properly converted
* to host ordering for the clear and set operations before conversion
* back to le32.
*/
#define SET_BITS_OFFSET_LE(__pdesc, __shift, __len, __val) \
(*(__le32 *)(__pdesc) = \
(cpu_to_le32((le32_to_cpu(*((__le32 *)(__pdesc))) & \
(~(BIT_OFFSET_LEN_MASK_32((__shift), __len)))) | \
(((u32)(__val) & BIT_LEN_MASK_32(__len)) << (__shift)))));
/* macros to read various fields in RX descriptor */
/* DWORD 0 */
#define GET_RX_DESC_PKT_LEN(__rxdesc) \
SHIFT_AND_MASK_LE((__rxdesc), 0, 14)
#define GET_RX_DESC_CRC32(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc, 14, 1)
#define GET_RX_DESC_ICV(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc, 15, 1)
#define GET_RX_DESC_DRVINFO_SIZE(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc, 16, 4)
#define GET_RX_DESC_SECURITY(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc, 20, 3)
#define GET_RX_DESC_QOS(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc, 23, 1)
#define GET_RX_DESC_SHIFT(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc, 24, 2)
#define GET_RX_DESC_PHY_STATUS(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc, 26, 1)
#define GET_RX_DESC_SWDEC(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc, 27, 1)
#define GET_RX_DESC_LAST_SEG(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc, 28, 1)
#define GET_RX_DESC_FIRST_SEG(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc, 29, 1)
#define GET_RX_DESC_EOR(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc, 30, 1)
#define GET_RX_DESC_OWN(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc, 31, 1)
/* DWORD 1 */
#define GET_RX_DESC_MACID(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+4, 0, 5)
#define GET_RX_DESC_TID(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+4, 5, 4)
#define GET_RX_DESC_PAGGR(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+4, 14, 1)
#define GET_RX_DESC_FAGGR(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+4, 15, 1)
#define GET_RX_DESC_A1_FIT(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+4, 16, 4)
#define GET_RX_DESC_A2_FIT(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+4, 20, 4)
#define GET_RX_DESC_PAM(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+4, 24, 1)
#define GET_RX_DESC_PWR(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+4, 25, 1)
#define GET_RX_DESC_MORE_DATA(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+4, 26, 1)
#define GET_RX_DESC_MORE_FRAG(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+4, 27, 1)
#define GET_RX_DESC_TYPE(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+4, 28, 2)
#define GET_RX_DESC_MC(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+4, 30, 1)
#define GET_RX_DESC_BC(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+4, 31, 1)
/* DWORD 2 */
#define GET_RX_DESC_SEQ(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+8, 0, 12)
#define GET_RX_DESC_FRAG(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+8, 12, 4)
#define GET_RX_DESC_USB_AGG_PKTNUM(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+8, 16, 8)
#define GET_RX_DESC_NEXT_IND(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+8, 30, 1)
/* DWORD 3 */
#define GET_RX_DESC_RX_MCS(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+12, 0, 6)
#define GET_RX_DESC_RX_HT(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+12, 6, 1)
#define GET_RX_DESC_AMSDU(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+12, 7, 1)
#define GET_RX_DESC_SPLCP(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+12, 8, 1)
#define GET_RX_DESC_BW(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+12, 9, 1)
#define GET_RX_DESC_HTC(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+12, 10, 1)
#define GET_RX_DESC_TCP_CHK_RPT(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+12, 11, 1)
#define GET_RX_DESC_IP_CHK_RPT(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+12, 12, 1)
#define GET_RX_DESC_TCP_CHK_VALID(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+12, 13, 1)
#define GET_RX_DESC_HWPC_ERR(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+12, 14, 1)
#define GET_RX_DESC_HWPC_IND(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+12, 15, 1)
#define GET_RX_DESC_IV0(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+12, 16, 16)
/* DWORD 4 */
#define GET_RX_DESC_IV1(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+16, 0, 32)
/* DWORD 5 */
#define GET_RX_DESC_TSFL(__rxdesc) \
SHIFT_AND_MASK_LE(__rxdesc+20, 0, 32)
/*======================= tx desc ============================================*/
/* macros to set various fields in TX descriptor */
/* Dword 0 */
#define SET_TX_DESC_PKT_SIZE(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc, 0, 16, __value)
#define SET_TX_DESC_OFFSET(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc, 16, 8, __value)
#define SET_TX_DESC_BMC(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc, 24, 1, __value)
#define SET_TX_DESC_HTC(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc, 25, 1, __value)
#define SET_TX_DESC_LAST_SEG(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc, 26, 1, __value)
#define SET_TX_DESC_FIRST_SEG(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc, 27, 1, __value)
#define SET_TX_DESC_LINIP(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc, 28, 1, __value)
#define SET_TX_DESC_NO_ACM(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc, 29, 1, __value)
#define SET_TX_DESC_GF(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc, 30, 1, __value)
#define SET_TX_DESC_OWN(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc, 31, 1, __value)
/* Dword 1 */
#define SET_TX_DESC_MACID(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+4, 0, 5, __value)
#define SET_TX_DESC_AGG_ENABLE(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+4, 5, 1, __value)
#define SET_TX_DESC_AGG_BREAK(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+4, 6, 1, __value)
#define SET_TX_DESC_RDG_ENABLE(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+4, 7, 1, __value)
#define SET_TX_DESC_QUEUE_SEL(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+4, 8, 5, __value)
#define SET_TX_DESC_RDG_NAV_EXT(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+4, 13, 1, __value)
#define SET_TX_DESC_LSIG_TXOP_EN(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+4, 14, 1, __value)
#define SET_TX_DESC_PIFS(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+4, 15, 1, __value)
#define SET_TX_DESC_RATE_ID(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+4, 16, 4, __value)
#define SET_TX_DESC_RA_BRSR_ID(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+4, 16, 4, __value)
#define SET_TX_DESC_NAV_USE_HDR(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+4, 20, 1, __value)
#define SET_TX_DESC_EN_DESC_ID(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+4, 21, 1, __value)
#define SET_TX_DESC_SEC_TYPE(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+4, 22, 2, __value)
#define SET_TX_DESC_PKT_OFFSET(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+4, 26, 5, __value)
/* Dword 2 */
#define SET_TX_DESC_RTS_RC(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+8, 0, 6, __value)
#define SET_TX_DESC_DATA_RC(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+8, 6, 6, __value)
#define SET_TX_DESC_BAR_RTY_TH(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+8, 14, 2, __value)
#define SET_TX_DESC_MORE_FRAG(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+8, 17, 1, __value)
#define SET_TX_DESC_RAW(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+8, 18, 1, __value)
#define SET_TX_DESC_CCX(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+8, 19, 1, __value)
#define SET_TX_DESC_AMPDU_DENSITY(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+8, 20, 3, __value)
#define SET_TX_DESC_ANTSEL_A(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+8, 24, 1, __value)
#define SET_TX_DESC_ANTSEL_B(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+8, 25, 1, __value)
#define SET_TX_DESC_TX_ANT_CCK(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+8, 26, 2, __value)
#define SET_TX_DESC_TX_ANTL(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+8, 28, 2, __value)
#define SET_TX_DESC_TX_ANT_HT(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+8, 30, 2, __value)
/* Dword 3 */
#define SET_TX_DESC_NEXT_HEAP_PAGE(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+12, 0, 8, __value)
#define SET_TX_DESC_TAIL_PAGE(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+12, 8, 8, __value)
#define SET_TX_DESC_SEQ(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+12, 16, 12, __value)
#define SET_TX_DESC_PKT_ID(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+12, 28, 4, __value)
/* Dword 4 */
#define SET_TX_DESC_RTS_RATE(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+16, 0, 5, __value)
#define SET_TX_DESC_AP_DCFE(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+16, 5, 1, __value)
#define SET_TX_DESC_QOS(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+16, 6, 1, __value)
#define SET_TX_DESC_HWSEQ_EN(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+16, 7, 1, __value)
#define SET_TX_DESC_USE_RATE(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+16, 8, 1, __value)
#define SET_TX_DESC_DISABLE_RTS_FB(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+16, 9, 1, __value)
#define SET_TX_DESC_DISABLE_FB(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+16, 10, 1, __value)
#define SET_TX_DESC_CTS2SELF(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+16, 11, 1, __value)
#define SET_TX_DESC_RTS_ENABLE(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+16, 12, 1, __value)
#define SET_TX_DESC_HW_RTS_ENABLE(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+16, 13, 1, __value)
#define SET_TX_DESC_WAIT_DCTS(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+16, 18, 1, __value)
#define SET_TX_DESC_CTS2AP_EN(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+16, 19, 1, __value)
#define SET_TX_DESC_DATA_SC(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+16, 20, 2, __value)
#define SET_TX_DESC_DATA_STBC(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+16, 22, 2, __value)
#define SET_TX_DESC_DATA_SHORT(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+16, 24, 1, __value)
#define SET_TX_DESC_DATA_BW(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+16, 25, 1, __value)
#define SET_TX_DESC_RTS_SHORT(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+16, 26, 1, __value)
#define SET_TX_DESC_RTS_BW(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+16, 27, 1, __value)
#define SET_TX_DESC_RTS_SC(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+16, 28, 2, __value)
#define SET_TX_DESC_RTS_STBC(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+16, 30, 2, __value)
/* Dword 5 */
#define SET_TX_DESC_TX_RATE(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+20, 0, 6, __val)
#define SET_TX_DESC_DATA_SHORTGI(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+20, 6, 1, __val)
#define SET_TX_DESC_CCX_TAG(__pdesc, __val) \
SET_BITS_OFFSET_LE(__pdesc+20, 7, 1, __val)
#define SET_TX_DESC_DATA_RATE_FB_LIMIT(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+20, 8, 5, __value)
#define SET_TX_DESC_RTS_RATE_FB_LIMIT(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+20, 13, 4, __value)
#define SET_TX_DESC_RETRY_LIMIT_ENABLE(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+20, 17, 1, __value)
#define SET_TX_DESC_DATA_RETRY_LIMIT(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+20, 18, 6, __value)
#define SET_TX_DESC_USB_TXAGG_NUM(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+20, 24, 8, __value)
/* Dword 6 */
#define SET_TX_DESC_TXAGC_A(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+24, 0, 5, __value)
#define SET_TX_DESC_TXAGC_B(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+24, 5, 5, __value)
#define SET_TX_DESC_USB_MAX_LEN(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+24, 10, 1, __value)
#define SET_TX_DESC_MAX_AGG_NUM(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+24, 11, 5, __value)
#define SET_TX_DESC_MCSG1_MAX_LEN(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+24, 16, 4, __value)
#define SET_TX_DESC_MCSG2_MAX_LEN(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+24, 20, 4, __value)
#define SET_TX_DESC_MCSG3_MAX_LEN(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+24, 24, 4, __value)
#define SET_TX_DESC_MCSG7_MAX_LEN(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+24, 28, 4, __value)
/* Dword 7 */
#define SET_TX_DESC_TX_DESC_CHECKSUM(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+28, 0, 16, __value)
#define SET_TX_DESC_MCSG4_MAX_LEN(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+28, 16, 4, __value)
#define SET_TX_DESC_MCSG5_MAX_LEN(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+28, 20, 4, __value)
#define SET_TX_DESC_MCSG6_MAX_LEN(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+28, 24, 4, __value)
#define SET_TX_DESC_MCSG15_MAX_LEN(__txdesc, __value) \
SET_BITS_OFFSET_LE(__txdesc+28, 28, 4, __value)
int rtl8192cu_endpoint_mapping(struct ieee80211_hw *hw);
u16 rtl8192cu_mq_to_hwq(__le16 fc, u16 mac80211_queue_index);
bool rtl92cu_rx_query_desc(struct ieee80211_hw *hw,
struct rtl_stats *stats,
struct ieee80211_rx_status *rx_status,
u8 *p_desc, struct sk_buff *skb);
void rtl8192cu_rx_hdl(struct ieee80211_hw *hw, struct sk_buff * skb);
void rtl8192c_rx_segregate_hdl(struct ieee80211_hw *, struct sk_buff *,
struct sk_buff_head *);
void rtl8192c_tx_cleanup(struct ieee80211_hw *hw, struct sk_buff *skb);
int rtl8192c_tx_post_hdl(struct ieee80211_hw *hw, struct urb *urb,
struct sk_buff *skb);
struct sk_buff *rtl8192c_tx_aggregate_hdl(struct ieee80211_hw *,
struct sk_buff_head *);
void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw,
struct ieee80211_hdr *hdr, u8 *pdesc_tx,
struct ieee80211_tx_info *info, struct sk_buff *skb,
unsigned int queue_index);
void rtl92cu_fill_fake_txdesc(struct ieee80211_hw *hw, u8 * pDesc,
u32 buffer_len, bool bIsPsPoll);
void rtl92cu_tx_fill_cmddesc(struct ieee80211_hw *hw,
u8 *pdesc, bool b_firstseg,
bool b_lastseg, struct sk_buff *skb);
bool rtl92cu_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,164 @@
/******************************************************************************
*
* Copyright(c) 2009-2011 Realtek Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
*****************************************************************************/
#ifndef __RTL_USB_H__
#define __RTL_USB_H__
#include <linux/usb.h>
#include <linux/skbuff.h>
#define RTL_USB_DEVICE(vend, prod, cfg) \
.match_flags = USB_DEVICE_ID_MATCH_DEVICE, \
.idVendor = (vend), \
.idProduct = (prod), \
.driver_info = (kernel_ulong_t)&(cfg)
#define USB_HIGH_SPEED_BULK_SIZE 512
#define USB_FULL_SPEED_BULK_SIZE 64
#define RTL_USB_MAX_TXQ_NUM 4 /* max tx queue */
#define RTL_USB_MAX_EP_NUM 6 /* max ep number */
#define RTL_USB_MAX_TX_URBS_NUM 8
enum rtl_txq {
/* These definitions shall be consistent with value
* returned by skb_get_queue_mapping
*------------------------------------*/
RTL_TXQ_BK,
RTL_TXQ_BE,
RTL_TXQ_VI,
RTL_TXQ_VO,
/*------------------------------------*/
RTL_TXQ_BCN,
RTL_TXQ_MGT,
RTL_TXQ_HI,
/* Must be last */
__RTL_TXQ_NUM,
};
struct rtl_ep_map {
u32 ep_mapping[__RTL_TXQ_NUM];
};
struct _trx_info {
struct rtl_usb *rtlusb;
u32 ep_num;
};
static inline void _rtl_install_trx_info(struct rtl_usb *rtlusb,
struct sk_buff *skb,
u32 ep_num)
{
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
info->rate_driver_data[0] = rtlusb;
info->rate_driver_data[1] = (void *)(__kernel_size_t)ep_num;
}
/* Add suspend/resume later */
enum rtl_usb_state {
USB_STATE_STOP = 0,
USB_STATE_START = 1,
};
#define IS_USB_STOP(rtlusb_ptr) (USB_STATE_STOP == (rtlusb_ptr)->state)
#define IS_USB_START(rtlusb_ptr) (USB_STATE_START == (rtlusb_ptr)->state)
#define SET_USB_STOP(rtlusb_ptr) \
do { \
(rtlusb_ptr)->state = USB_STATE_STOP; \
} while (0)
#define SET_USB_START(rtlusb_ptr) \
do { \
(rtlusb_ptr)->state = USB_STATE_START; \
} while (0)
struct rtl_usb {
struct usb_device *udev;
struct usb_interface *intf;
enum rtl_usb_state state;
/* Bcn control register setting */
u32 reg_bcn_ctrl_val;
/* for 88/92cu card disable */
u8 disableHWSM;
/*QOS & EDCA */
enum acm_method acm_method;
/* irq . HIMR,HIMR_EX */
u32 irq_mask[2];
bool irq_enabled;
u16 (*usb_mq_to_hwq)(__le16 fc, u16 mac80211_queue_index);
/* Tx */
u8 out_ep_nums ;
u8 out_queue_sel;
struct rtl_ep_map ep_map;
u32 max_bulk_out_size;
u32 tx_submitted_urbs;
struct sk_buff_head tx_skb_queue[RTL_USB_MAX_EP_NUM];
struct usb_anchor tx_pending[RTL_USB_MAX_EP_NUM];
struct usb_anchor tx_submitted;
struct sk_buff *(*usb_tx_aggregate_hdl)(struct ieee80211_hw *,
struct sk_buff_head *);
int (*usb_tx_post_hdl)(struct ieee80211_hw *,
struct urb *, struct sk_buff *);
void (*usb_tx_cleanup)(struct ieee80211_hw *, struct sk_buff *);
/* Rx */
u8 in_ep_nums ;
u32 in_ep; /* Bulk IN endpoint number */
u32 rx_max_size; /* Bulk IN max buffer size */
u32 rx_urb_num; /* How many Bulk INs are submitted to host. */
struct usb_anchor rx_submitted;
void (*usb_rx_segregate_hdl)(struct ieee80211_hw *, struct sk_buff *,
struct sk_buff_head *);
void (*usb_rx_hdl)(struct ieee80211_hw *, struct sk_buff *);
};
struct rtl_usb_priv {
struct rtl_usb dev;
struct rtl_led_ctl ledctl;
};
#define rtl_usbpriv(hw) (((struct rtl_usb_priv *)(rtl_priv(hw))->priv))
#define rtl_usbdev(usbpriv) (&((usbpriv)->dev))
int __devinit rtl_usb_probe(struct usb_interface *intf,
const struct usb_device_id *id);
void rtl_usb_disconnect(struct usb_interface *intf);
int rtl_usb_suspend(struct usb_interface *pusb_intf, pm_message_t message);
int rtl_usb_resume(struct usb_interface *pusb_intf);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -54,7 +54,7 @@ config WL12XX_SDIO
config WL12XX_SDIO_TEST
tristate "TI wl12xx SDIO testing support"
depends on WL12XX && MMC
depends on WL12XX && MMC && WL12XX_SDIO
default n
---help---
This module adds support for the SDIO bus testing with the

View File

@ -783,6 +783,10 @@ int wl1271_acx_sta_rate_policies(struct wl1271 *wl)
acx->rate_class_cnt = cpu_to_le32(ACX_TX_RATE_POLICY_CNT);
wl1271_debug(DEBUG_ACX, "basic_rate: 0x%x, full_rate: 0x%x",
acx->rate_class[ACX_TX_BASIC_RATE].enabled_rates,
acx->rate_class[ACX_TX_AP_FULL_RATE].enabled_rates);
ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx));
if (ret < 0) {
wl1271_warning("Setting of rate policies failed: %d", ret);
@ -947,9 +951,9 @@ out:
return ret;
}
int wl1271_acx_mem_cfg(struct wl1271 *wl)
int wl1271_acx_ap_mem_cfg(struct wl1271 *wl)
{
struct wl1271_acx_config_memory *mem_conf;
struct wl1271_acx_ap_config_memory *mem_conf;
int ret;
wl1271_debug(DEBUG_ACX, "wl1271 mem cfg");
@ -961,10 +965,10 @@ int wl1271_acx_mem_cfg(struct wl1271 *wl)
}
/* memory config */
mem_conf->num_stations = DEFAULT_NUM_STATIONS;
mem_conf->rx_mem_block_num = ACX_RX_MEM_BLOCKS;
mem_conf->tx_min_mem_block_num = ACX_TX_MIN_MEM_BLOCKS;
mem_conf->num_ssid_profiles = ACX_NUM_SSID_PROFILES;
mem_conf->num_stations = wl->conf.mem.num_stations;
mem_conf->rx_mem_block_num = wl->conf.mem.rx_block_num;
mem_conf->tx_min_mem_block_num = wl->conf.mem.tx_min_block_num;
mem_conf->num_ssid_profiles = wl->conf.mem.ssid_profiles;
mem_conf->total_tx_descriptors = cpu_to_le32(ACX_TX_DESCRIPTORS);
ret = wl1271_cmd_configure(wl, ACX_MEM_CFG, mem_conf,
@ -979,14 +983,46 @@ out:
return ret;
}
int wl1271_acx_sta_mem_cfg(struct wl1271 *wl)
{
struct wl1271_acx_sta_config_memory *mem_conf;
int ret;
wl1271_debug(DEBUG_ACX, "wl1271 mem cfg");
mem_conf = kzalloc(sizeof(*mem_conf), GFP_KERNEL);
if (!mem_conf) {
ret = -ENOMEM;
goto out;
}
/* memory config */
mem_conf->num_stations = wl->conf.mem.num_stations;
mem_conf->rx_mem_block_num = wl->conf.mem.rx_block_num;
mem_conf->tx_min_mem_block_num = wl->conf.mem.tx_min_block_num;
mem_conf->num_ssid_profiles = wl->conf.mem.ssid_profiles;
mem_conf->total_tx_descriptors = cpu_to_le32(ACX_TX_DESCRIPTORS);
mem_conf->dyn_mem_enable = wl->conf.mem.dynamic_memory;
mem_conf->tx_free_req = wl->conf.mem.min_req_tx_blocks;
mem_conf->rx_free_req = wl->conf.mem.min_req_rx_blocks;
mem_conf->tx_min = wl->conf.mem.tx_min;
ret = wl1271_cmd_configure(wl, ACX_MEM_CFG, mem_conf,
sizeof(*mem_conf));
if (ret < 0) {
wl1271_warning("wl1271 mem config failed: %d", ret);
goto out;
}
out:
kfree(mem_conf);
return ret;
}
int wl1271_acx_init_mem_config(struct wl1271 *wl)
{
int ret;
ret = wl1271_acx_mem_cfg(wl);
if (ret < 0)
return ret;
wl->target_mem_map = kzalloc(sizeof(struct wl1271_acx_mem_map),
GFP_KERNEL);
if (!wl->target_mem_map) {
@ -1476,3 +1512,33 @@ out:
kfree(acx);
return ret;
}
int wl1271_acx_config_ps(struct wl1271 *wl)
{
struct wl1271_acx_config_ps *config_ps;
int ret;
wl1271_debug(DEBUG_ACX, "acx config ps");
config_ps = kzalloc(sizeof(*config_ps), GFP_KERNEL);
if (!config_ps) {
ret = -ENOMEM;
goto out;
}
config_ps->exit_retries = wl->conf.conn.psm_exit_retries;
config_ps->enter_retries = wl->conf.conn.psm_entry_retries;
config_ps->null_data_rate = cpu_to_le32(wl->basic_rate);
ret = wl1271_cmd_configure(wl, ACX_CONFIG_PS, config_ps,
sizeof(*config_ps));
if (ret < 0) {
wl1271_warning("acx config ps failed: %d", ret);
goto out;
}
out:
kfree(config_ps);
return ret;
}

View File

@ -133,7 +133,6 @@ enum {
#define DEFAULT_UCAST_PRIORITY 0
#define DEFAULT_RX_Q_PRIORITY 0
#define DEFAULT_NUM_STATIONS 1
#define DEFAULT_RXQ_PRIORITY 0 /* low 0 .. 15 high */
#define DEFAULT_RXQ_TYPE 0x07 /* All frames, Data/Ctrl/Mgmt */
#define TRACE_BUFFER_MAX_SIZE 256
@ -797,12 +796,9 @@ struct acx_tx_config_options {
__le16 tx_compl_threshold; /* number of packets */
} __packed;
#define ACX_RX_MEM_BLOCKS 70
#define ACX_TX_MIN_MEM_BLOCKS 40
#define ACX_TX_DESCRIPTORS 32
#define ACX_NUM_SSID_PROFILES 1
struct wl1271_acx_config_memory {
struct wl1271_acx_ap_config_memory {
struct acx_header header;
u8 rx_mem_block_num;
@ -812,6 +808,20 @@ struct wl1271_acx_config_memory {
__le32 total_tx_descriptors;
} __packed;
struct wl1271_acx_sta_config_memory {
struct acx_header header;
u8 rx_mem_block_num;
u8 tx_min_mem_block_num;
u8 num_stations;
u8 num_ssid_profiles;
__le32 total_tx_descriptors;
u8 dyn_mem_enable;
u8 tx_free_req;
u8 rx_free_req;
u8 tx_min;
} __packed;
struct wl1271_acx_mem_map {
struct acx_header header;
@ -1136,6 +1146,15 @@ struct wl1271_acx_max_tx_retry {
u8 padding_1[2];
} __packed;
struct wl1271_acx_config_ps {
struct acx_header header;
u8 exit_retries;
u8 enter_retries;
u8 padding[2];
__le32 null_data_rate;
} __packed;
enum {
ACX_WAKE_UP_CONDITIONS = 0x0002,
ACX_MEM_CFG = 0x0003,
@ -1193,6 +1212,8 @@ enum {
ACX_HT_BSS_OPERATION = 0x0058,
ACX_COEX_ACTIVITY = 0x0059,
ACX_SET_DCO_ITRIM_PARAMS = 0x0061,
ACX_GEN_FW_CMD = 0x0070,
ACX_HOST_IF_CFG_BITMAP = 0x0071,
ACX_MAX_TX_FAILURE = 0x0072,
DOT11_RX_MSDU_LIFE_TIME = 0x1004,
DOT11_CUR_TX_PWR = 0x100D,
@ -1200,10 +1221,8 @@ enum {
DOT11_RTS_THRESHOLD = 0x1013,
DOT11_GROUP_ADDRESS_TBL = 0x1014,
ACX_PM_CONFIG = 0x1016,
MAX_DOT11_IE = DOT11_GROUP_ADDRESS_TBL,
MAX_IE = 0xFFFF
ACX_CONFIG_PS = 0x1017,
ACX_CONFIG_HANGOVER = 0x1018,
};
@ -1245,7 +1264,8 @@ int wl1271_acx_tid_cfg(struct wl1271 *wl, u8 queue_id, u8 channel_type,
u32 apsd_conf0, u32 apsd_conf1);
int wl1271_acx_frag_threshold(struct wl1271 *wl, u16 frag_threshold);
int wl1271_acx_tx_config_options(struct wl1271 *wl);
int wl1271_acx_mem_cfg(struct wl1271 *wl);
int wl1271_acx_ap_mem_cfg(struct wl1271 *wl);
int wl1271_acx_sta_mem_cfg(struct wl1271 *wl);
int wl1271_acx_init_mem_config(struct wl1271 *wl);
int wl1271_acx_init_rx_interrupt(struct wl1271 *wl);
int wl1271_acx_smart_reflex(struct wl1271 *wl);
@ -1269,5 +1289,6 @@ int wl1271_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index, u16 ssn,
bool enable);
int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime);
int wl1271_acx_max_tx_retry(struct wl1271 *wl);
int wl1271_acx_config_ps(struct wl1271 *wl);
#endif /* __WL1271_ACX_H__ */

View File

@ -286,6 +286,7 @@ int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type)
join->rx_filter_options = cpu_to_le32(wl->rx_filter);
join->bss_type = bss_type;
join->basic_rate_set = cpu_to_le32(wl->basic_rate_set);
join->supported_rate_set = cpu_to_le32(wl->rate_set);
if (wl->band == IEEE80211_BAND_5GHZ)
join->bss_type |= WL1271_JOIN_CMD_BSS_TYPE_5GHZ;
@ -303,6 +304,9 @@ int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type)
wl->tx_security_last_seq = 0;
wl->tx_security_seq = 0;
wl1271_debug(DEBUG_CMD, "cmd join: basic_rate_set=0x%x, rate_set=0x%x",
join->basic_rate_set, join->supported_rate_set);
ret = wl1271_cmd_send(wl, CMD_START_JOIN, join, sizeof(*join), 0);
if (ret < 0) {
wl1271_error("failed to initiate cmd join");
@ -454,7 +458,7 @@ out:
return ret;
}
int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, u32 rates, bool send)
int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode)
{
struct wl1271_cmd_ps_params *ps_params = NULL;
int ret = 0;
@ -468,10 +472,6 @@ int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, u32 rates, bool send)
}
ps_params->ps_mode = ps_mode;
ps_params->send_null_data = send;
ps_params->retries = wl->conf.conn.psm_entry_nullfunc_retries;
ps_params->hang_over_period = wl->conf.conn.psm_entry_hangover_period;
ps_params->null_data_rate = cpu_to_le32(rates);
ret = wl1271_cmd_send(wl, CMD_SET_PS_MODE, ps_params,
sizeof(*ps_params), 0);

View File

@ -39,7 +39,7 @@ int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer);
int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len);
int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len);
int wl1271_cmd_data_path(struct wl1271 *wl, bool enable);
int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, u32 rates, bool send);
int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode);
int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer,
size_t len);
int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id,
@ -140,6 +140,7 @@ enum cmd_templ {
* For CTS-to-self (FastCTS) mechanism
* for BT/WLAN coexistence (SoftGemini). */
CMD_TEMPL_ARP_RSP,
CMD_TEMPL_LINK_MEASUREMENT_REPORT,
/* AP-mode specific */
CMD_TEMPL_AP_BEACON = 13,
@ -216,6 +217,7 @@ struct wl1271_cmd_join {
* ACK or CTS frames).
*/
__le32 basic_rate_set;
__le32 supported_rate_set;
u8 dtim_interval;
/*
* bits 0-2: This bitwise field specifies the type
@ -278,15 +280,7 @@ struct wl1271_cmd_ps_params {
struct wl1271_cmd_header header;
u8 ps_mode; /* STATION_* */
u8 send_null_data; /* Do we have to send NULL data packet ? */
u8 retries; /* Number of retires for the initial NULL data packet */
/*
* TUs during which the target stays awake after switching
* to power save mode.
*/
u8 hang_over_period;
__le32 null_data_rate;
u8 padding[3];
} __packed;
/* HW encryption keys */

View File

@ -959,6 +959,14 @@ struct conf_conn_settings {
*/
u8 psm_entry_retries;
/*
* Specifies the maximum number of times to try PSM exit if it fails
* (if sending the appropriate null-func message fails.)
*
* Range 0 - 255
*/
u8 psm_exit_retries;
/*
* Specifies the maximum number of times to try transmit the PSM entry
* null-func frame for each PSM entry attempt
@ -1143,6 +1151,46 @@ struct conf_ht_setting {
u16 inactivity_timeout;
};
struct conf_memory_settings {
/* Number of stations supported in IBSS mode */
u8 num_stations;
/* Number of ssid profiles used in IBSS mode */
u8 ssid_profiles;
/* Number of memory buffers allocated to rx pool */
u8 rx_block_num;
/* Minimum number of blocks allocated to tx pool */
u8 tx_min_block_num;
/* Disable/Enable dynamic memory */
u8 dynamic_memory;
/*
* Minimum required free tx memory blocks in order to assure optimum
* performence
*
* Range: 0-120
*/
u8 min_req_tx_blocks;
/*
* Minimum required free rx memory blocks in order to assure optimum
* performence
*
* Range: 0-120
*/
u8 min_req_rx_blocks;
/*
* Minimum number of mem blocks (free+used) guaranteed for TX
*
* Range: 0-120
*/
u8 tx_min;
};
struct conf_drv_settings {
struct conf_sg_settings sg;
struct conf_rx_settings rx;
@ -1154,6 +1202,7 @@ struct conf_drv_settings {
struct conf_scan_settings scan;
struct conf_rf_settings rf;
struct conf_ht_setting ht;
struct conf_memory_settings mem;
};
#endif

View File

@ -135,20 +135,6 @@ static int wl1271_event_ps_report(struct wl1271 *wl,
/* go to extremely low power mode */
wl1271_ps_elp_sleep(wl);
break;
case EVENT_EXIT_POWER_SAVE_FAIL:
wl1271_debug(DEBUG_PSM, "PSM exit failed");
if (test_bit(WL1271_FLAG_PSM, &wl->flags)) {
wl->psm_entry_retry = 0;
break;
}
/* make sure the firmware goes to active mode - the frame to
be sent next will indicate to the AP, that we are active. */
ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE,
wl->basic_rate, false);
break;
case EVENT_EXIT_POWER_SAVE_SUCCESS:
default:
break;
}

Some files were not shown because too many files have changed in this diff Show More