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

John W. Linville says:

====================
pull request: wireless-next 2014-03-31

Please accept this one last round of general wireless updates for
the 3.15 merge window!

For the Bluetooth bits, Gustavo says:

"Here follow another set of patches to 3.15. This is mostly a bug fix
pull request with the exception of one commit from Marcel which adds
tracking to the current configured LE scan type parameter."

Beyond that, notable bits include some final refactoring of rtl8180
and the addition of the rtl8187se driver, fixes for a number of
problems identified by Dan Carpenter and his static analysis tools,
and a handful of other bits here and there.

Please let me know if there are problems!
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2014-03-31 16:44:55 -04:00
commit ce22bb6122
49 changed files with 1805 additions and 395 deletions

View file

@ -218,7 +218,14 @@ int bcma_gpio_init(struct bcma_drv_cc *cc)
#if IS_BUILTIN(CONFIG_BCMA_HOST_SOC)
chip->to_irq = bcma_gpio_to_irq;
#endif
chip->ngpio = 16;
switch (cc->core->bus->chipinfo.id) {
case BCMA_CHIP_ID_BCM5357:
chip->ngpio = 32;
break;
default:
chip->ngpio = 16;
}
/* There is just one SoC in one device and its GPIO addresses should be
* deterministic to address them more easily. The other buses could get
* a random base number. */

View file

@ -901,7 +901,7 @@ static void bluecard_release(struct pcmcia_device *link)
bluecard_close(info);
del_timer(&(info->timer));
del_timer_sync(&(info->timer));
pcmcia_disable_device(link);
}

View file

@ -59,12 +59,13 @@ bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb)
priv->btmrvl_dev.sendcmdflag = false;
priv->adapter->cmd_complete = true;
wake_up_interruptible(&priv->adapter->cmd_wait_q);
}
if (hci_opcode_ogf(opcode) == 0x3F) {
BT_DBG("vendor event skipped: opcode=%#4.4x", opcode);
kfree_skb(skb);
return false;
if (hci_opcode_ogf(opcode) == 0x3F) {
BT_DBG("vendor event skipped: opcode=%#4.4x",
opcode);
kfree_skb(skb);
return false;
}
}
}

View file

@ -572,7 +572,7 @@ static void carl9170_ps_beacon(struct ar9170 *ar, void *data, unsigned int len)
static void carl9170_ba_check(struct ar9170 *ar, void *data, unsigned int len)
{
struct ieee80211_bar *bar = (void *) data;
struct ieee80211_bar *bar = data;
struct carl9170_bar_list_entry *entry;
unsigned int queue;

View file

@ -1354,13 +1354,14 @@ static s32 brcmf_set_auth_type(struct net_device *ndev,
}
static s32
brcmf_set_set_cipher(struct net_device *ndev,
struct cfg80211_connect_params *sme)
brcmf_set_wsec_mode(struct net_device *ndev,
struct cfg80211_connect_params *sme, bool mfp)
{
struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
struct brcmf_cfg80211_security *sec;
s32 pval = 0;
s32 gval = 0;
s32 wsec;
s32 err = 0;
if (sme->crypto.n_ciphers_pairwise) {
@ -1412,7 +1413,12 @@ brcmf_set_set_cipher(struct net_device *ndev,
if (brcmf_find_wpsie(sme->ie, sme->ie_len) && !pval && !gval &&
sme->privacy)
pval = AES_ENABLED;
err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wsec", pval | gval);
if (mfp)
wsec = pval | gval | MFP_CAPABLE;
else
wsec = pval | gval;
err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wsec", wsec);
if (err) {
brcmf_err("error (%d)\n", err);
return err;
@ -1582,7 +1588,6 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
u32 ie_len;
struct brcmf_ext_join_params_le *ext_join_params;
u16 chanspec;
s32 err = 0;
brcmf_dbg(TRACE, "Enter\n");
@ -1651,7 +1656,7 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
goto done;
}
err = brcmf_set_set_cipher(ndev, sme);
err = brcmf_set_wsec_mode(ndev, sme, sme->mfp == NL80211_MFP_REQUIRED);
if (err) {
brcmf_err("wl_set_set_cipher failed (%d)\n", err);
goto done;

View file

@ -217,6 +217,9 @@ static inline bool ac_bitmap_tst(u8 bitmap, int prec)
#define WSEC_SWFLAG 0x0008
/* to go into transition mode without setting wep */
#define SES_OW_ENABLED 0x0040
/* MFP */
#define MFP_CAPABLE 0x0200
#define MFP_REQUIRED 0x0400
/* WPA authentication mode bitvec */
#define WPA_AUTH_DISABLED 0x0000 /* Legacy (i.e., non-WPA) */

View file

@ -277,11 +277,11 @@ static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter)
priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
adapter->seq_num++;
sleep_cfm_buf->seq_num =
cpu_to_le16((HostCmd_SET_SEQ_NO_BSS_INFO
(adapter->seq_num, priv->bss_num,
priv->bss_type)));
adapter->seq_num++;
if (adapter->iface_type == MWIFIEX_USB) {
sleep_cfm_tmp =
@ -509,6 +509,11 @@ int mwifiex_send_cmd(struct mwifiex_private *priv, u16 cmd_no,
return -1;
}
if (adapter->hs_enabling && cmd_no != HostCmd_CMD_802_11_HS_CFG_ENH) {
dev_err(adapter->dev, "PREP_CMD: host entering sleep state\n");
return -1;
}
if (adapter->surprise_removed) {
dev_err(adapter->dev, "PREP_CMD: card is removed\n");
return -1;
@ -976,11 +981,10 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter)
struct mwifiex_private *priv;
int i;
spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags);
/* Cancel current cmd */
if ((adapter->curr_cmd) && (adapter->curr_cmd->wait_q_enabled)) {
spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
adapter->curr_cmd->wait_q_enabled = false;
spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
adapter->cmd_wait_q.status = -1;
mwifiex_complete_cmd(adapter, adapter->curr_cmd);
}
@ -1000,6 +1004,7 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter)
spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
}
spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
/* Cancel all pending scan command */
spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);

View file

@ -38,7 +38,8 @@ static void scan_delay_timer_fn(unsigned long data)
if (adapter->surprise_removed)
return;
if (adapter->scan_delay_cnt == MWIFIEX_MAX_SCAN_DELAY_CNT) {
if (adapter->scan_delay_cnt == MWIFIEX_MAX_SCAN_DELAY_CNT ||
!adapter->scan_processing) {
/*
* Abort scan operation by cancelling all pending scan
* commands

View file

@ -774,6 +774,7 @@ struct mwifiex_adapter {
u16 hs_activate_wait_q_woken;
wait_queue_head_t hs_activate_wait_q;
bool is_suspended;
bool hs_enabling;
u8 event_body[MAX_EVENT_SIZE];
u32 hw_dot_11n_dev_cap;
u8 hw_dev_mcs_support;

View file

@ -120,6 +120,7 @@ static int mwifiex_pcie_suspend(struct device *dev)
/* Indicate device suspended */
adapter->is_suspended = true;
adapter->hs_enabling = false;
return 0;
}
@ -1033,7 +1034,7 @@ static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter)
card->tx_buf_list[wrdoneidx] = NULL;
if (reg->pfu_enabled) {
desc2 = (void *)card->txbd_ring[wrdoneidx];
desc2 = card->txbd_ring[wrdoneidx];
memset(desc2, 0, sizeof(*desc2));
} else {
desc = card->txbd_ring[wrdoneidx];
@ -1118,7 +1119,7 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb,
card->tx_buf_list[wrindx] = skb;
if (reg->pfu_enabled) {
desc2 = (void *)card->txbd_ring[wrindx];
desc2 = card->txbd_ring[wrindx];
desc2->paddr = buf_pa;
desc2->len = (u16)skb->len;
desc2->frag_len = (u16)skb->len;
@ -1278,7 +1279,7 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter)
card->rx_buf_list[rd_index] = skb_tmp;
if (reg->pfu_enabled) {
desc2 = (void *)card->rxbd_ring[rd_index];
desc2 = card->rxbd_ring[rd_index];
desc2->paddr = buf_pa;
desc2->len = skb_tmp->len;
desc2->frag_len = skb_tmp->len;

View file

@ -591,10 +591,12 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv,
*chan_tlv_out,
struct mwifiex_chan_scan_param_set *scan_chan_list)
{
struct mwifiex_adapter *adapter = priv->adapter;
int ret = 0;
struct mwifiex_chan_scan_param_set *tmp_chan_list;
struct mwifiex_chan_scan_param_set *start_chan;
struct cmd_ctrl_node *cmd_node, *tmp_node;
unsigned long flags;
u32 tlv_idx, rates_size, cmd_no;
u32 total_scan_time;
u32 done_early;
@ -748,8 +750,19 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv,
scan_cfg_out->tlv_buf_len -=
sizeof(struct mwifiex_ie_types_header) + rates_size;
if (ret)
if (ret) {
spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
list_for_each_entry_safe(cmd_node, tmp_node,
&adapter->scan_pending_q,
list) {
list_del(&cmd_node->list);
cmd_node->wait_q_enabled = false;
mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
}
spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
flags);
break;
}
}
if (ret)
@ -1653,7 +1666,7 @@ mwifiex_parse_single_response_buf(struct mwifiex_private *priv, u8 **bss_info,
curr_bcn_bytes -= ETH_ALEN;
if (!ext_scan) {
rssi = (s32) *(u8 *)current_ptr;
rssi = (s32) *current_ptr;
rssi = (-rssi) * 100; /* Convert dBm to mBm */
current_ptr += sizeof(u8);
curr_bcn_bytes -= sizeof(u8);

View file

@ -237,6 +237,7 @@ static int mwifiex_sdio_suspend(struct device *dev)
/* Enable the Host Sleep */
if (!mwifiex_enable_hs(adapter)) {
dev_err(adapter->dev, "cmd: failed to suspend\n");
adapter->hs_enabling = false;
return -EFAULT;
}
@ -245,6 +246,7 @@ static int mwifiex_sdio_suspend(struct device *dev)
/* Indicate device suspended */
adapter->is_suspended = true;
adapter->hs_enabling = false;
return ret;
}

View file

@ -64,6 +64,7 @@ int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter,
*(cmd_queued->condition));
if (status) {
dev_err(adapter->dev, "cmd_wait_q terminated: %d\n", status);
mwifiex_cancel_all_pending_cmd(adapter);
return status;
}
@ -508,6 +509,9 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter)
memset(&hscfg, 0, sizeof(struct mwifiex_ds_hs_cfg));
hscfg.is_invoke_hostcmd = true;
adapter->hs_enabling = true;
mwifiex_cancel_all_pending_cmd(adapter);
if (mwifiex_set_hs_params(mwifiex_get_priv(adapter,
MWIFIEX_BSS_ROLE_STA),
HostCmd_ACT_GEN_SET, MWIFIEX_SYNC_CMD,
@ -516,8 +520,9 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter)
return false;
}
if (wait_event_interruptible(adapter->hs_activate_wait_q,
adapter->hs_activate_wait_q_woken)) {
if (wait_event_interruptible_timeout(adapter->hs_activate_wait_q,
adapter->hs_activate_wait_q_woken,
(10 * HZ)) <= 0) {
dev_err(adapter->dev, "hs_activate_wait_q terminated\n");
return false;
}

View file

@ -730,13 +730,13 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv,
if (len < (sizeof(struct ethhdr) + 3))
return;
if (*(u8 *)(buf + sizeof(struct ethhdr)) != WLAN_TDLS_SNAP_RFTYPE)
if (*(buf + sizeof(struct ethhdr)) != WLAN_TDLS_SNAP_RFTYPE)
return;
if (*(u8 *)(buf + sizeof(struct ethhdr) + 1) != WLAN_CATEGORY_TDLS)
if (*(buf + sizeof(struct ethhdr) + 1) != WLAN_CATEGORY_TDLS)
return;
peer = buf + ETH_ALEN;
action = *(u8 *)(buf + sizeof(struct ethhdr) + 2);
action = *(buf + sizeof(struct ethhdr) + 2);
/* just handle TDLS setup request/response/confirm */
if (action > WLAN_TDLS_SETUP_CONFIRM)

View file

@ -459,6 +459,7 @@ static int mwifiex_usb_suspend(struct usb_interface *intf, pm_message_t message)
* 'suspended' state and a 'disconnect' one.
*/
adapter->is_suspended = true;
adapter->hs_enabling = false;
if (atomic_read(&card->rx_cmd_urb_pending) && card->rx_cmd.urb)
usb_kill_urb(card->rx_cmd.urb);

View file

@ -1292,10 +1292,11 @@ int rsi_mgmt_pkt_recv(struct rsi_common *common, u8 *msg)
return -EINVAL;
}
} else if (msg_type == TX_STATUS_IND) {
if (msg[15] == PROBEREQ_CONFIRM)
if (msg[15] == PROBEREQ_CONFIRM) {
common->mgmt_q_block = false;
rsi_dbg(FSM_ZONE, "%s: Probe confirm received\n",
__func__);
}
} else {
return rsi_mgmt_pkt_to_core(common, msg, msg_len, msg_type);
}

View file

@ -2,11 +2,11 @@
# RTL818X Wireless LAN device configuration
#
config RTL8180
tristate "Realtek 8180/8185 PCI support"
tristate "Realtek 8180/8185/8187SE PCI support"
depends on MAC80211 && PCI
select EEPROM_93CX6
---help---
This is a driver for RTL8180 and RTL8185 based cards.
This is a driver for RTL8180, RTL8185 and RTL8187SE based cards.
These are PCI based chips found in cards such as:
(RTL8185 802.11g)

View file

@ -1,4 +1,4 @@
rtl8180-objs := dev.o rtl8225.o sa2400.o max2820.o grf5101.o
rtl8180-objs := dev.o rtl8225.o sa2400.o max2820.o grf5101.o rtl8225se.o
obj-$(CONFIG_RTL8180) += rtl8180.o

File diff suppressed because it is too large Load diff

View file

@ -24,27 +24,64 @@
#define ANAPARAM_PWR1_SHIFT 20
#define ANAPARAM_PWR1_MASK (0x7F << ANAPARAM_PWR1_SHIFT)
/* rtl8180/rtl8185 have 3 queue + beacon queue.
* mac80211 can use just one, + beacon = 2 tot.
*/
#define RTL8180_NR_TX_QUEUES 2
/* rtl8187SE have 6 queues + beacon queues
* mac80211 can use 4 QoS data queue, + beacon = 5 tot
*/
#define RTL8187SE_NR_TX_QUEUES 5
/* for array static allocation, it is the max of above */
#define RTL818X_NR_TX_QUEUES 5
struct rtl8180_tx_desc {
__le32 flags;
__le16 rts_duration;
__le16 plcp_len;
__le32 tx_buf;
__le32 frame_len;
union{
__le32 frame_len;
struct {
__le16 frame_len_se;
__le16 frame_duration;
} __packed;
} __packed;
__le32 next_tx_desc;
u8 cw;
u8 retry_limit;
u8 agc;
u8 flags2;
u32 reserved[2];
/* rsvd for 8180/8185.
* valid for 8187se but we dont use it
*/
u32 reserved;
/* all rsvd for 8180/8185 */
__le16 flags3;
__le16 frag_qsize;
} __packed;
struct rtl818x_rx_cmd_desc {
__le32 flags;
u32 reserved;
__le32 rx_buf;
} __packed;
struct rtl8180_rx_desc {
__le32 flags;
__le32 flags2;
union {
__le32 rx_buf;
__le64 tsft;
};
__le64 tsft;
} __packed;
struct rtl8187se_rx_desc {
__le32 flags;
__le64 tsft;
__le32 flags2;
__le32 flags3;
u32 reserved[3];
} __packed;
struct rtl8180_tx_ring {
@ -71,14 +108,16 @@ struct rtl8180_priv {
/* rtl8180 driver specific */
spinlock_t lock;
struct rtl8180_rx_desc *rx_ring;
void *rx_ring;
u8 rx_ring_sz;
dma_addr_t rx_ring_dma;
unsigned int rx_idx;
struct sk_buff *rx_buf[32];
struct rtl8180_tx_ring tx_ring[4];
struct rtl8180_tx_ring tx_ring[RTL818X_NR_TX_QUEUES];
struct ieee80211_channel channels[14];
struct ieee80211_rate rates[12];
struct ieee80211_supported_band band;
struct ieee80211_tx_queue_params queue_param[4];
struct pci_dev *pdev;
u32 rx_conf;
u8 slot_time;
@ -87,18 +126,27 @@ struct rtl8180_priv {
enum {
RTL818X_CHIP_FAMILY_RTL8180,
RTL818X_CHIP_FAMILY_RTL8185,
RTL818X_CHIP_FAMILY_RTL8187SE,
} chip_family;
u32 anaparam;
u16 rfparam;
u8 csthreshold;
u8 mac_addr[ETH_ALEN];
u8 rf_type;
u8 xtal_out;
u8 xtal_in;
u8 xtal_cal;
u8 thermal_meter_val;
u8 thermal_meter_en;
u8 antenna_diversity_en;
u8 antenna_diversity_default;
/* sequence # */
u16 seqno;
};
void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data);
void rtl8180_set_anaparam(struct rtl8180_priv *priv, u32 anaparam);
void rtl8180_set_anaparam2(struct rtl8180_priv *priv, u32 anaparam2);
static inline u8 rtl818x_ioread8(struct rtl8180_priv *priv, u8 __iomem *addr)
{

View file

@ -282,6 +282,7 @@ static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
msleep(1); /* FIXME: optional? */
/* TODO: use set_anaparam2 dev.c_func*/
/* anaparam2 on */
rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);

View file

@ -0,0 +1,475 @@
/* Radio tuning for RTL8225 on RTL8187SE
*
* Copyright 2009 Larry Finger <Larry.Finger@lwfinger.net>
* Copyright 2014 Andrea Merello <andrea.merello@gmail.com>
*
* Based on the r8180 and Realtek r8187se drivers, which are:
* Copyright 2004-2005 Andrea Merello <andrea.merello@gmail.com>, et al.
*
* Also based on the rtl8187 driver, which is:
* Copyright 2007 Michael Wu <flamingice@sourmilk.net>
* Copyright 2007 Andrea Merello <andrea.merello@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <net/mac80211.h>
#include "rtl8180.h"
#include "rtl8225se.h"
#define PFX "rtl8225 (se) "
static const u32 RF_GAIN_TABLE[] = {
0x0096, 0x0076, 0x0056, 0x0036, 0x0016, 0x01f6, 0x01d6, 0x01b6,
0x0196, 0x0176, 0x00F7, 0x00D7, 0x00B7, 0x0097, 0x0077, 0x0057,
0x0037, 0x00FB, 0x00DB, 0x00BB, 0x00FF, 0x00E3, 0x00C3, 0x00A3,
0x0083, 0x0063, 0x0043, 0x0023, 0x0003, 0x01E3, 0x01C3, 0x01A3,
0x0183, 0x0163, 0x0143, 0x0123, 0x0103
};
static const u8 cck_ofdm_gain_settings[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
};
static const u8 rtl8225se_tx_gain_cck_ofdm[] = {
0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e
};
static const u8 rtl8225se_tx_power_cck[] = {
0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02,
0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02,
0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02,
0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02,
0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03,
0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03
};
static const u8 rtl8225se_tx_power_cck_ch14[] = {
0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00,
0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00,
0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00,
0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00,
0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00,
0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00
};
static const u8 rtl8225se_tx_power_ofdm[] = {
0x80, 0x90, 0xa2, 0xb5, 0xcb, 0xe4
};
static const u32 rtl8225se_chan[] = {
0x0080, 0x0100, 0x0180, 0x0200, 0x0280, 0x0300, 0x0380,
0x0400, 0x0480, 0x0500, 0x0580, 0x0600, 0x0680, 0x074A,
};
static const u8 rtl8225sez2_tx_power_cck_ch14[] = {
0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00
};
static const u8 rtl8225sez2_tx_power_cck_B[] = {
0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x04
};
static const u8 rtl8225sez2_tx_power_cck_A[] = {
0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04
};
static const u8 rtl8225sez2_tx_power_cck[] = {
0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04
};
static const u8 ZEBRA_AGC[] = {
0x7E, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, 0x7B, 0x7A,
0x79, 0x78, 0x77, 0x76, 0x75, 0x74, 0x73, 0x72,
0x71, 0x70, 0x6F, 0x6E, 0x6D, 0x6C, 0x6B, 0x6A,
0x69, 0x68, 0x67, 0x66, 0x65, 0x64, 0x63, 0x62,
0x48, 0x47, 0x46, 0x45, 0x44, 0x29, 0x28, 0x27,
0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x08, 0x07,
0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
0x0f, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x15, 0x16,
0x17, 0x17, 0x18, 0x18, 0x19, 0x1a, 0x1a, 0x1b,
0x1b, 0x1c, 0x1c, 0x1d, 0x1d, 0x1d, 0x1e, 0x1e,
0x1f, 0x1f, 0x1f, 0x20, 0x20, 0x20, 0x20, 0x21,
0x21, 0x21, 0x22, 0x22, 0x22, 0x23, 0x23, 0x24,
0x24, 0x25, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27,
0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F
};
static const u8 OFDM_CONFIG[] = {
0x10, 0x0F, 0x0A, 0x0C, 0x14, 0xFA, 0xFF, 0x50,
0x00, 0x50, 0x00, 0x00, 0x00, 0x5C, 0x00, 0x00,
0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0xA8, 0x26,
0x32, 0x33, 0x06, 0xA5, 0x6F, 0x55, 0xC8, 0xBB,
0x0A, 0xE1, 0x2C, 0x4A, 0x86, 0x83, 0x34, 0x00,
0x4F, 0x24, 0x6F, 0xC2, 0x03, 0x40, 0x80, 0x00,
0xC0, 0xC1, 0x58, 0xF1, 0x00, 0xC4, 0x90, 0x3e,
0xD8, 0x3C, 0x7B, 0x10, 0x10
};
static void rtl8187se_three_wire_io(struct ieee80211_hw *dev, u8 *data,
u8 len, bool write)
{
struct rtl8180_priv *priv = dev->priv;
int i;
u8 tmp;
do {
for (i = 0; i < 5; i++) {
tmp = rtl818x_ioread8(priv, SW_3W_CMD1);
if (!(tmp & 0x3))
break;
udelay(10);
}
if (i == 5)
wiphy_err(dev->wiphy, PFX
"CmdReg: 0x%x RE/WE bits aren't clear\n", tmp);
tmp = rtl818x_ioread8(priv, &priv->map->rf_sw_config) | 0x02;
rtl818x_iowrite8(priv, &priv->map->rf_sw_config, tmp);
tmp = rtl818x_ioread8(priv, REG_ADDR1(0x84)) & 0xF7;
rtl818x_iowrite8(priv, REG_ADDR1(0x84), tmp);
if (write) {
if (len == 16) {
rtl818x_iowrite16(priv, SW_3W_DB0,
*(u16 *)data);
} else if (len == 64) {
rtl818x_iowrite32(priv, SW_3W_DB0_4,
*((u32 *)data));
rtl818x_iowrite32(priv, SW_3W_DB1_4,
*((u32 *)(data + 4)));
} else
wiphy_err(dev->wiphy, PFX
"Unimplemented length\n");
} else {
rtl818x_iowrite16(priv, SW_3W_DB0, *(u16 *)data);
}
if (write)
tmp = 2;
else
tmp = 1;
rtl818x_iowrite8(priv, SW_3W_CMD1, tmp);
for (i = 0; i < 5; i++) {
tmp = rtl818x_ioread8(priv, SW_3W_CMD1);
if (!(tmp & 0x3))
break;
udelay(10);
}
rtl818x_iowrite8(priv, SW_3W_CMD1, 0);
if (!write) {
*((u16 *)data) = rtl818x_ioread16(priv, SI_DATA_REG);
*((u16 *)data) &= 0x0FFF;
}
} while (0);
}
static u32 rtl8187se_rf_readreg(struct ieee80211_hw *dev, u8 addr)
{
u32 dataread = addr & 0x0F;
rtl8187se_three_wire_io(dev, (u8 *)&dataread, 16, 0);
return dataread;
}
static void rtl8187se_rf_writereg(struct ieee80211_hw *dev, u8 addr, u32 data)
{
u32 outdata = (data << 4) | (u32)(addr & 0x0F);
rtl8187se_three_wire_io(dev, (u8 *)&outdata, 16, 1);
}
static void rtl8225se_write_zebra_agc(struct ieee80211_hw *dev)
{
int i;
for (i = 0; i < 128; i++) {
rtl8225se_write_phy_ofdm(dev, 0xF, ZEBRA_AGC[i]);
rtl8225se_write_phy_ofdm(dev, 0xE, i+0x80);
rtl8225se_write_phy_ofdm(dev, 0xE, 0);
}
}
static void rtl8187se_write_ofdm_config(struct ieee80211_hw *dev)
{
/* write OFDM_CONFIG table */
int i;
for (i = 0; i < 60; i++)
rtl8225se_write_phy_ofdm(dev, i, OFDM_CONFIG[i]);
}
static void rtl8225sez2_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
{
struct rtl8180_priv *priv = dev->priv;
u8 cck_power, ofdm_power;
cck_power = priv->channels[channel - 1].hw_value & 0xFF;
if (cck_power > 35)
cck_power = 35;
rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK,
cck_ofdm_gain_settings[cck_power]);
usleep_range(1000, 5000);
ofdm_power = priv->channels[channel - 1].hw_value >> 8;
if (ofdm_power > 35)
ofdm_power = 35;
rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM,
cck_ofdm_gain_settings[ofdm_power]);
if (ofdm_power < 12) {
rtl8225se_write_phy_ofdm(dev, 7, 0x5C);
rtl8225se_write_phy_ofdm(dev, 9, 0x5C);
}
if (ofdm_power < 18) {
rtl8225se_write_phy_ofdm(dev, 7, 0x54);
rtl8225se_write_phy_ofdm(dev, 9, 0x54);
} else {
rtl8225se_write_phy_ofdm(dev, 7, 0x50);
rtl8225se_write_phy_ofdm(dev, 9, 0x50);
}
usleep_range(1000, 5000);
}
static void rtl8187se_write_rf_gain(struct ieee80211_hw *dev)
{
int i;
for (i = 0; i <= 36; i++) {
rtl8187se_rf_writereg(dev, 0x01, i); mdelay(1);
rtl8187se_rf_writereg(dev, 0x02, RF_GAIN_TABLE[i]); mdelay(1);
}
}
static void rtl8187se_write_initial_gain(struct ieee80211_hw *dev,
int init_gain)
{
switch (init_gain) {
default:
rtl8225se_write_phy_ofdm(dev, 0x17, 0x26); mdelay(1);
rtl8225se_write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
rtl8225se_write_phy_ofdm(dev, 0x05, 0xFA); mdelay(1);
break;
case 2:
rtl8225se_write_phy_ofdm(dev, 0x17, 0x36); mdelay(1);
rtl8225se_write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
rtl8225se_write_phy_ofdm(dev, 0x05, 0xFA); mdelay(1);
break;
case 3:
rtl8225se_write_phy_ofdm(dev, 0x17, 0x36); mdelay(1);
rtl8225se_write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
rtl8225se_write_phy_ofdm(dev, 0x05, 0xFB); mdelay(1);
break;
case 4:
rtl8225se_write_phy_ofdm(dev, 0x17, 0x46); mdelay(1);
rtl8225se_write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
rtl8225se_write_phy_ofdm(dev, 0x05, 0xFB); mdelay(1);
break;
case 5:
rtl8225se_write_phy_ofdm(dev, 0x17, 0x46); mdelay(1);
rtl8225se_write_phy_ofdm(dev, 0x24, 0x96); mdelay(1);
rtl8225se_write_phy_ofdm(dev, 0x05, 0xFB); mdelay(1);
break;
case 6:
rtl8225se_write_phy_ofdm(dev, 0x17, 0x56); mdelay(1);
rtl8225se_write_phy_ofdm(dev, 0x24, 0x96); mdelay(1);
rtl8225se_write_phy_ofdm(dev, 0x05, 0xFC); mdelay(1);
break;
case 7:
rtl8225se_write_phy_ofdm(dev, 0x17, 0x56); mdelay(1);
rtl8225se_write_phy_ofdm(dev, 0x24, 0xA6); mdelay(1);
rtl8225se_write_phy_ofdm(dev, 0x05, 0xFC); mdelay(1);
break;
case 8:
rtl8225se_write_phy_ofdm(dev, 0x17, 0x66); mdelay(1);
rtl8225se_write_phy_ofdm(dev, 0x24, 0xB6); mdelay(1);
rtl8225se_write_phy_ofdm(dev, 0x05, 0xFC); mdelay(1);
break;
}
}
void rtl8225se_rf_init(struct ieee80211_hw *dev)
{
struct rtl8180_priv *priv = dev->priv;
u32 rf23, rf24;
u8 d_cut = 0;
u8 tmp;
/* Page 1 */
rtl8187se_rf_writereg(dev, 0x00, 0x013F); mdelay(1);
rf23 = rtl8187se_rf_readreg(dev, 0x08); mdelay(1);
rf24 = rtl8187se_rf_readreg(dev, 0x09); mdelay(1);
if (rf23 == 0x0818 && rf24 == 0x070C)
d_cut = 1;
wiphy_info(dev->wiphy, "RTL8225-SE version %s\n",
d_cut ? "D" : "not-D");
/* Page 0: reg 0 - 15 */
rtl8187se_rf_writereg(dev, 0x00, 0x009F); mdelay(1);
rtl8187se_rf_writereg(dev, 0x01, 0x06E0); mdelay(1);
rtl8187se_rf_writereg(dev, 0x02, 0x004D); mdelay(1);
rtl8187se_rf_writereg(dev, 0x03, 0x07F1); mdelay(1);
rtl8187se_rf_writereg(dev, 0x04, 0x0975); mdelay(1);
rtl8187se_rf_writereg(dev, 0x05, 0x0C72); mdelay(1);
rtl8187se_rf_writereg(dev, 0x06, 0x0AE6); mdelay(1);
rtl8187se_rf_writereg(dev, 0x07, 0x00CA); mdelay(1);
rtl8187se_rf_writereg(dev, 0x08, 0x0E1C); mdelay(1);
rtl8187se_rf_writereg(dev, 0x09, 0x02F0); mdelay(1);
rtl8187se_rf_writereg(dev, 0x0A, 0x09D0); mdelay(1);
rtl8187se_rf_writereg(dev, 0x0B, 0x01BA); mdelay(1);
rtl8187se_rf_writereg(dev, 0x0C, 0x0640); mdelay(1);
rtl8187se_rf_writereg(dev, 0x0D, 0x08DF); mdelay(1);
rtl8187se_rf_writereg(dev, 0x0E, 0x0020); mdelay(1);
rtl8187se_rf_writereg(dev, 0x0F, 0x0990); mdelay(1);
/* page 1: reg 16-30 */
rtl8187se_rf_writereg(dev, 0x00, 0x013F); mdelay(1);
rtl8187se_rf_writereg(dev, 0x03, 0x0806); mdelay(1);
rtl8187se_rf_writereg(dev, 0x04, 0x03A7); mdelay(1);
rtl8187se_rf_writereg(dev, 0x05, 0x059B); mdelay(1);
rtl8187se_rf_writereg(dev, 0x06, 0x0081); mdelay(1);
rtl8187se_rf_writereg(dev, 0x07, 0x01A0); mdelay(1);
rtl8187se_rf_writereg(dev, 0x0A, 0x0001); mdelay(1);
rtl8187se_rf_writereg(dev, 0x0B, 0x0418); mdelay(1);
rtl8187se_rf_writereg(dev, 0x0C, 0x0FBE); mdelay(1);
rtl8187se_rf_writereg(dev, 0x0D, 0x0008); mdelay(1);
if (d_cut)
rtl8187se_rf_writereg(dev, 0x0E, 0x0807);
else
rtl8187se_rf_writereg(dev, 0x0E, 0x0806);
mdelay(1);
rtl8187se_rf_writereg(dev, 0x0F, 0x0ACC); mdelay(1);
rtl8187se_rf_writereg(dev, 0x00, 0x01D7); mdelay(1);
rtl8187se_rf_writereg(dev, 0x03, 0x0E00); mdelay(1);
rtl8187se_rf_writereg(dev, 0x04, 0x0E50); mdelay(1);
rtl8187se_write_rf_gain(dev);
rtl8187se_rf_writereg(dev, 0x05, 0x0203); mdelay(1);
rtl8187se_rf_writereg(dev, 0x06, 0x0200); mdelay(1);
rtl8187se_rf_writereg(dev, 0x00, 0x0137); mdelay(11);
rtl8187se_rf_writereg(dev, 0x0D, 0x0008); mdelay(11);
rtl8187se_rf_writereg(dev, 0x00, 0x0037); mdelay(11);
rtl8187se_rf_writereg(dev, 0x04, 0x0160); mdelay(11);
rtl8187se_rf_writereg(dev, 0x07, 0x0080); mdelay(11);
rtl8187se_rf_writereg(dev, 0x02, 0x088D); mdelay(221);
rtl8187se_rf_writereg(dev, 0x00, 0x0137); mdelay(11);
rtl8187se_rf_writereg(dev, 0x07, 0x0000); mdelay(1);
rtl8187se_rf_writereg(dev, 0x07, 0x0180); mdelay(1);
rtl8187se_rf_writereg(dev, 0x07, 0x0220); mdelay(1);
rtl8187se_rf_writereg(dev, 0x07, 0x03E0); mdelay(1);
rtl8187se_rf_writereg(dev, 0x06, 0x00C1); mdelay(1);
rtl8187se_rf_writereg(dev, 0x0A, 0x0001); mdelay(1);
if (priv->xtal_cal) {
tmp = (priv->xtal_in << 4) | (priv->xtal_out << 1) |
(1 << 11) | (1 << 9);
rtl8187se_rf_writereg(dev, 0x0F, tmp);
wiphy_info(dev->wiphy, "Xtal cal\n");
mdelay(1);
} else {
wiphy_info(dev->wiphy, "NO Xtal cal\n");
rtl8187se_rf_writereg(dev, 0x0F, 0x0ACC);
mdelay(1);
}
/* page 0 */
rtl8187se_rf_writereg(dev, 0x00, 0x00BF); mdelay(1);
rtl8187se_rf_writereg(dev, 0x0D, 0x08DF); mdelay(1);
rtl8187se_rf_writereg(dev, 0x02, 0x004D); mdelay(1);
rtl8187se_rf_writereg(dev, 0x04, 0x0975); mdelay(31);
rtl8187se_rf_writereg(dev, 0x00, 0x0197); mdelay(1);
rtl8187se_rf_writereg(dev, 0x05, 0x05AB); mdelay(1);
rtl8187se_rf_writereg(dev, 0x00, 0x009F); mdelay(1);
rtl8187se_rf_writereg(dev, 0x01, 0x0000); mdelay(1);
rtl8187se_rf_writereg(dev, 0x02, 0x0000); mdelay(1);
/* power save parameters */
/* TODO: move to dev.c */
rtl818x_iowrite8(priv, REG_ADDR1(0x024E),
rtl818x_ioread8(priv, REG_ADDR1(0x24E)) & 0x9F);
rtl8225se_write_phy_cck(dev, 0x00, 0xC8);
rtl8225se_write_phy_cck(dev, 0x06, 0x1C);
rtl8225se_write_phy_cck(dev, 0x10, 0x78);
rtl8225se_write_phy_cck(dev, 0x2E, 0xD0);
rtl8225se_write_phy_cck(dev, 0x2F, 0x06);
rtl8225se_write_phy_cck(dev, 0x01, 0x46);
/* power control */
rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, 0x10);
rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, 0x1B);
rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03);
rtl8225se_write_phy_ofdm(dev, 0x00, 0x12);
rtl8225se_write_zebra_agc(dev);
rtl8225se_write_phy_ofdm(dev, 0x10, 0x00);
rtl8187se_write_ofdm_config(dev);
/* turn on RF */
rtl8187se_rf_writereg(dev, 0x00, 0x009F); udelay(500);
rtl8187se_rf_writereg(dev, 0x04, 0x0972); udelay(500);
/* turn on RF again */
rtl8187se_rf_writereg(dev, 0x00, 0x009F); udelay(500);
rtl8187se_rf_writereg(dev, 0x04, 0x0972); udelay(500);
/* turn on BB */
rtl8225se_write_phy_ofdm(dev, 0x10, 0x40);
rtl8225se_write_phy_ofdm(dev, 0x12, 0x40);
rtl8187se_write_initial_gain(dev, 4);
}
void rtl8225se_rf_stop(struct ieee80211_hw *dev)
{
/* checked for 8187se */
struct rtl8180_priv *priv = dev->priv;
/* turn off BB RXIQ matrix to cut off rx signal */
rtl8225se_write_phy_ofdm(dev, 0x10, 0x00);
rtl8225se_write_phy_ofdm(dev, 0x12, 0x00);
/* turn off RF */
rtl8187se_rf_writereg(dev, 0x04, 0x0000);
rtl8187se_rf_writereg(dev, 0x00, 0x0000);
usleep_range(1000, 5000);
/* turn off A/D and D/A */
rtl8180_set_anaparam(priv, RTL8225SE_ANAPARAM_OFF);
rtl8180_set_anaparam2(priv, RTL8225SE_ANAPARAM2_OFF);
}
void rtl8225se_rf_set_channel(struct ieee80211_hw *dev,
struct ieee80211_conf *conf)
{
int chan =
ieee80211_frequency_to_channel(conf->chandef.chan->center_freq);
rtl8225sez2_rf_set_tx_power(dev, chan);
rtl8187se_rf_writereg(dev, 0x7, rtl8225se_chan[chan - 1]);
if ((rtl8187se_rf_readreg(dev, 0x7) & 0x0F80) !=
rtl8225se_chan[chan - 1])
rtl8187se_rf_writereg(dev, 0x7, rtl8225se_chan[chan - 1]);
usleep_range(10000, 20000);
}
static const struct rtl818x_rf_ops rtl8225se_ops = {
.name = "rtl8225-se",
.init = rtl8225se_rf_init,
.stop = rtl8225se_rf_stop,
.set_chan = rtl8225se_rf_set_channel,
};
const struct rtl818x_rf_ops *rtl8187se_detect_rf(struct ieee80211_hw *dev)
{
return &rtl8225se_ops;
}

View file

@ -0,0 +1,61 @@
/* Definitions for RTL8187SE hardware
*
* Copyright 2009 Larry Finger <Larry.Finger@lwfinger.net>
* Copyright 2014 Andrea Merello <andrea.merello@gmail.com>
*
* Based on the r8180 and Realtek r8187se drivers, which are:
* Copyright 2004-2005 Andrea Merello <andrea.merello@gmail.com>, et al.
*
* Also based on the rtl8187 driver, which is:
* Copyright 2007 Michael Wu <flamingice@sourmilk.net>
* Copyright 2007 Andrea Merello <andrea.merello@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef RTL8187SE_RTL8225_H
#define RTL8187SE_RTL8225_H
#define RTL8225SE_ANAPARAM_ON 0xb0054d00
#define RTL8225SE_ANAPARAM2_ON 0x000004c6
/* all off except PLL */
#define RTL8225SE_ANAPARAM_OFF 0xb0054dec
/* all on including PLL */
#define RTL8225SE_ANAPARAM_OFF2 0xb0054dfc
#define RTL8225SE_ANAPARAM2_OFF 0x00ff04c6
#define RTL8225SE_ANAPARAM3 0x10
enum rtl8187se_power_state {
RTL8187SE_POWER_ON,
RTL8187SE_POWER_OFF,
RTL8187SE_POWER_SLEEP
};
static inline void rtl8225se_write_phy_ofdm(struct ieee80211_hw *dev,
u8 addr, u8 data)
{
rtl8180_write_phy(dev, addr, data);
}
static inline void rtl8225se_write_phy_cck(struct ieee80211_hw *dev,
u8 addr, u8 data)
{
rtl8180_write_phy(dev, addr, data | 0x10000);
}
const struct rtl818x_rf_ops *rtl8187se_detect_rf(struct ieee80211_hw *);
void rtl8225se_rf_stop(struct ieee80211_hw *dev);
void rtl8225se_rf_set_channel(struct ieee80211_hw *dev,
struct ieee80211_conf *conf);
void rtl8225se_rf_conf_erp(struct ieee80211_hw *dev,
struct ieee80211_bss_conf *info);
void rtl8225se_rf_init(struct ieee80211_hw *dev);
#endif /* RTL8187SE_RTL8225_H */

View file

@ -592,7 +592,7 @@ static void rtl8187_set_anaparam(struct rtl8187_priv *priv, bool rfon)
rtl818x_iowrite32(priv, &priv->map->ANAPARAM, anaparam);
rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, anaparam2);
if (priv->is_rtl8187b)
rtl818x_iowrite8(priv, &priv->map->ANAPARAM3, anaparam3);
rtl818x_iowrite8(priv, &priv->map->ANAPARAM3A, anaparam3);
reg &= ~RTL818X_CONFIG3_ANAPARAM_WRITE;
rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg);
rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
@ -1636,10 +1636,10 @@ static int rtl8187_probe(struct usb_interface *intf,
err_free_dmabuf:
kfree(priv->io_dmabuf);
err_free_dev:
ieee80211_free_hw(dev);
usb_set_intfdata(intf, NULL);
usb_put_dev(udev);
err_free_dev:
ieee80211_free_hw(dev);
return err;
}

View file

@ -16,30 +16,82 @@
#define RTL818X_H
struct rtl818x_csr {
u8 MAC[6];
u8 reserved_0[2];
__le32 MAR[2];
u8 RX_FIFO_COUNT;
u8 reserved_1;
u8 TX_FIFO_COUNT;
u8 BQREQ;
u8 reserved_2[4];
union {
__le32 MAR[2]; /* 0x8 */
struct{ /* rtl8187se */
u8 rf_sw_config; /* 0x8 */
u8 reserved_01[3];
__le32 TMGDA; /* 0xc */
} __packed;
} __packed;
union { /* 0x10 */
struct {
u8 RX_FIFO_COUNT;
u8 reserved_1;
u8 TX_FIFO_COUNT;
u8 BQREQ;
} __packed;
__le32 TBKDA; /* for 8187se */
} __packed;
__le32 TBEDA; /* 0x14 - for rtl8187se */
__le32 TSFT[2];
__le32 TLPDA;
__le32 TNPDA;
__le32 THPDA;
__le16 BRSR;
u8 BSSID[6];
u8 RESP_RATE;
u8 EIFS;
u8 reserved_3[1];
u8 CMD;
union { /* 0x20 */
__le32 TLPDA;
__le32 TVIDA; /* for 8187se */
} __packed;
union { /* 0x24 */
__le32 TNPDA;
__le32 TVODA; /* for 8187se */
} __packed;
/* hi pri ring for all cards */
__le32 THPDA; /* 0x28 */
union { /* 0x2c */
struct {
u8 reserved_2a;
u8 EIFS_8187SE;
} __packed;
__le16 BRSR;
} __packed;
u8 BSSID[6]; /* 0x2e */
union { /* 0x34 */
struct {
u8 RESP_RATE;
u8 EIFS;
} __packed;
__le16 BRSR_8187SE;
} __packed;
u8 reserved_3[1]; /* 0x36 */
u8 CMD; /* 0x37 */
#define RTL818X_CMD_TX_ENABLE (1 << 2)
#define RTL818X_CMD_RX_ENABLE (1 << 3)
#define RTL818X_CMD_RESET (1 << 4)
u8 reserved_4[4];
__le16 INT_MASK;
__le16 INT_STATUS;
u8 reserved_4[4]; /* 0x38 */
union {
struct {
__le16 INT_MASK;
__le16 INT_STATUS;
} __packed;
__le32 INT_STATUS_SE; /* 0x3c */
} __packed;
/* status bits for rtl8187 and rtl8180/8185 */
#define RTL818X_INT_RX_OK (1 << 0)
#define RTL818X_INT_RX_ERR (1 << 1)
#define RTL818X_INT_TXL_OK (1 << 2)
@ -56,7 +108,34 @@ struct rtl818x_csr {
#define RTL818X_INT_BEACON (1 << 13)
#define RTL818X_INT_TIME_OUT (1 << 14)
#define RTL818X_INT_TX_FO (1 << 15)
__le32 TX_CONF;
/* status bits for rtl8187se */
#define RTL818X_INT_SE_TIMER3 (1 << 0)
#define RTL818X_INT_SE_TIMER2 (1 << 1)
#define RTL818X_INT_SE_RQ0SOR (1 << 2)
#define RTL818X_INT_SE_TXBED_OK (1 << 3)
#define RTL818X_INT_SE_TXBED_ERR (1 << 4)
#define RTL818X_INT_SE_TXBE_OK (1 << 5)
#define RTL818X_INT_SE_TXBE_ERR (1 << 6)
#define RTL818X_INT_SE_RX_OK (1 << 7)
#define RTL818X_INT_SE_RX_ERR (1 << 8)
#define RTL818X_INT_SE_TXL_OK (1 << 9)
#define RTL818X_INT_SE_TXL_ERR (1 << 10)
#define RTL818X_INT_SE_RX_DU (1 << 11)
#define RTL818X_INT_SE_RX_FIFO (1 << 12)
#define RTL818X_INT_SE_TXN_OK (1 << 13)
#define RTL818X_INT_SE_TXN_ERR (1 << 14)
#define RTL818X_INT_SE_TXH_OK (1 << 15)
#define RTL818X_INT_SE_TXH_ERR (1 << 16)
#define RTL818X_INT_SE_TXB_OK (1 << 17)
#define RTL818X_INT_SE_TXB_ERR (1 << 18)
#define RTL818X_INT_SE_ATIM_TO (1 << 19)
#define RTL818X_INT_SE_BK_TO (1 << 20)
#define RTL818X_INT_SE_TIMER1 (1 << 21)
#define RTL818X_INT_SE_TX_FIFO (1 << 22)
#define RTL818X_INT_SE_WAKEUP (1 << 23)
#define RTL818X_INT_SE_BK_DMA (1 << 24)
#define RTL818X_INT_SE_TMGD_OK (1 << 30)
__le32 TX_CONF; /* 0x40 */
#define RTL818X_TX_CONF_LOOPBACK_MAC (1 << 17)
#define RTL818X_TX_CONF_LOOPBACK_CONT (3 << 17)
#define RTL818X_TX_CONF_NO_ICV (1 << 19)
@ -68,6 +147,7 @@ struct rtl818x_csr {
#define RTL818X_TX_CONF_R8185_D (5 << 25)
#define RTL818X_TX_CONF_R8187vD (5 << 25)
#define RTL818X_TX_CONF_R8187vD_B (6 << 25)
#define RTL818X_TX_CONF_RTL8187SE (6 << 25)
#define RTL818X_TX_CONF_HWVER_MASK (7 << 25)
#define RTL818X_TX_CONF_DISREQQSIZE (1 << 28)
#define RTL818X_TX_CONF_PROBE_DTS (1 << 29)
@ -122,28 +202,64 @@ struct rtl818x_csr {
u8 PGSELECT;
u8 SECURITY;
__le32 ANAPARAM2;
u8 reserved_10[12];
__le16 BEACON_INTERVAL;
__le16 ATIM_WND;
__le16 BEACON_INTERVAL_TIME;
__le16 ATIMTR_INTERVAL;
u8 PHY_DELAY;
u8 CARRIER_SENSE_COUNTER;
u8 reserved_11[2];
u8 PHY[4];
__le16 RFPinsOutput;
__le16 RFPinsEnable;
__le16 RFPinsSelect;
__le16 RFPinsInput;
__le32 RF_PARA;
__le32 RF_TIMING;
u8 GP_ENABLE;
u8 GPIO0;
u8 GPIO1;
u8 reserved_12;
__le32 HSSI_PARA;
u8 reserved_13[4];
u8 TX_AGC_CTL;
u8 reserved_10[8];
__le32 IMR; /* 0x6c - Interrupt mask reg for 8187se */
#define IMR_TMGDOK ((1 << 30))
#define IMR_DOT11HINT ((1 << 25)) /* 802.11h Measurement Interrupt */
#define IMR_BCNDMAINT ((1 << 24)) /* Beacon DMA Interrupt */
#define IMR_WAKEINT ((1 << 23)) /* Wake Up Interrupt */
#define IMR_TXFOVW ((1 << 22)) /* Tx FIFO Overflow */
#define IMR_TIMEOUT1 ((1 << 21)) /* Time Out Interrupt 1 */
#define IMR_BCNINT ((1 << 20)) /* Beacon Time out */
#define IMR_ATIMINT ((1 << 19)) /* ATIM Time Out */
#define IMR_TBDER ((1 << 18)) /* Tx Beacon Descriptor Error */
#define IMR_TBDOK ((1 << 17)) /* Tx Beacon Descriptor OK */
#define IMR_THPDER ((1 << 16)) /* Tx High Priority Descriptor Error */
#define IMR_THPDOK ((1 << 15)) /* Tx High Priority Descriptor OK */
#define IMR_TVODER ((1 << 14)) /* Tx AC_VO Descriptor Error Int */
#define IMR_TVODOK ((1 << 13)) /* Tx AC_VO Descriptor OK Interrupt */
#define IMR_FOVW ((1 << 12)) /* Rx FIFO Overflow Interrupt */
#define IMR_RDU ((1 << 11)) /* Rx Descriptor Unavailable */
#define IMR_TVIDER ((1 << 10)) /* Tx AC_VI Descriptor Error */
#define IMR_TVIDOK ((1 << 9)) /* Tx AC_VI Descriptor OK Interrupt */
#define IMR_RER ((1 << 8)) /* Rx Error Interrupt */
#define IMR_ROK ((1 << 7)) /* Receive OK Interrupt */
#define IMR_TBEDER ((1 << 6)) /* Tx AC_BE Descriptor Error */
#define IMR_TBEDOK ((1 << 5)) /* Tx AC_BE Descriptor OK */
#define IMR_TBKDER ((1 << 4)) /* Tx AC_BK Descriptor Error */
#define IMR_TBKDOK ((1 << 3)) /* Tx AC_BK Descriptor OK */
#define IMR_RQOSOK ((1 << 2)) /* Rx QoS OK Interrupt */
#define IMR_TIMEOUT2 ((1 << 1)) /* Time Out Interrupt 2 */
#define IMR_TIMEOUT3 ((1 << 0)) /* Time Out Interrupt 3 */
__le16 BEACON_INTERVAL; /* 0x70 */
__le16 ATIM_WND; /* 0x72 */
__le16 BEACON_INTERVAL_TIME; /* 0x74 */
__le16 ATIMTR_INTERVAL; /* 0x76 */
u8 PHY_DELAY; /* 0x78 */
u8 CARRIER_SENSE_COUNTER; /* 0x79 */
u8 reserved_11[2]; /* 0x7a */
u8 PHY[4]; /* 0x7c */
__le16 RFPinsOutput; /* 0x80 */
__le16 RFPinsEnable; /* 0x82 */
__le16 RFPinsSelect; /* 0x84 */
__le16 RFPinsInput; /* 0x86 */
__le32 RF_PARA; /* 0x88 */
__le32 RF_TIMING; /* 0x8c */
u8 GP_ENABLE; /* 0x90 */
u8 GPIO0; /* 0x91 */
u8 GPIO1; /* 0x92 */
u8 TPPOLL_STOP; /* 0x93 - rtl8187se only */
#define RTL818x_TPPOLL_STOP_BQ (1 << 7)
#define RTL818x_TPPOLL_STOP_VI (1 << 4)
#define RTL818x_TPPOLL_STOP_VO (1 << 5)
#define RTL818x_TPPOLL_STOP_BE (1 << 3)
#define RTL818x_TPPOLL_STOP_BK (1 << 2)
#define RTL818x_TPPOLL_STOP_MG (1 << 1)
#define RTL818x_TPPOLL_STOP_HI (1 << 6)
__le32 HSSI_PARA; /* 0x94 */
u8 reserved_13[4]; /* 0x98 */
u8 TX_AGC_CTL; /* 0x9c */
#define RTL818X_TX_AGC_CTL_PERPACKET_GAIN (1 << 0)
#define RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL (1 << 1)
#define RTL818X_TX_AGC_CTL_FEEDBACK_ANT (1 << 2)
@ -167,7 +283,8 @@ struct rtl818x_csr {
u8 reserved_17[24];
u8 CONFIG5;
u8 TX_DMA_POLLING;
u8 reserved_18[2];
u8 PHY_PR;
u8 reserved_18;
__le16 CWR;
u8 RETRY_CTR;
u8 reserved_19[3];
@ -179,14 +296,59 @@ struct rtl818x_csr {
__le32 RDSAR;
__le16 TID_AC_MAP;
u8 reserved_20[4];
u8 ANAPARAM3;
u8 reserved_21[5];
__le16 FEMR;
u8 reserved_22[4];
__le16 TALLY_CNT;
u8 TALLY_SEL;
union {
__le16 ANAPARAM3; /* 0xee */
u8 ANAPARAM3A; /* for rtl8187 */
};
#define AC_PARAM_TXOP_LIMIT_SHIFT 16
#define AC_PARAM_ECW_MAX_SHIFT 12
#define AC_PARAM_ECW_MIN_SHIFT 8
#define AC_PARAM_AIFS_SHIFT 0
__le32 AC_VO_PARAM; /* 0xf0 */
union { /* 0xf4 */
__le32 AC_VI_PARAM;
__le16 FEMR;
} __packed;
union{ /* 0xf8 */
__le32 AC_BE_PARAM; /* rtl8187se */
struct{
u8 reserved_21[2];
__le16 TALLY_CNT; /* 0xfa */
} __packed;
} __packed;
union {
u8 TALLY_SEL; /* 0xfc */
__le32 AC_BK_PARAM;
} __packed;
} __packed;
/* These are addresses with NON-standard usage.
* They have offsets very far from this struct.
* I don't like to introduce a ton of "reserved"..
* They are for RTL8187SE
*/
#define REG_ADDR1(addr) ((u8 __iomem *)priv->map + addr)
#define REG_ADDR2(addr) ((__le16 __iomem *)priv->map + (addr >> 1))
#define REG_ADDR4(addr) ((__le32 __iomem *)priv->map + (addr >> 2))
#define FEMR_SE REG_ADDR2(0x1D4)
#define ARFR REG_ADDR2(0x1E0)
#define RFSW_CTRL REG_ADDR2(0x272)
#define SW_3W_DB0 REG_ADDR2(0x274)
#define SW_3W_DB0_4 REG_ADDR4(0x274)
#define SW_3W_DB1 REG_ADDR2(0x278)
#define SW_3W_DB1_4 REG_ADDR4(0x278)
#define SW_3W_CMD1 REG_ADDR1(0x27D)
#define PI_DATA_REG REG_ADDR2(0x360)
#define SI_DATA_REG REG_ADDR2(0x362)
struct rtl818x_rf_ops {
char *name;
void (*init)(struct ieee80211_hw *);

View file

@ -982,7 +982,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
u8 keep_alive = 10;
rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_KEEP_ALIVE,
(u8 *)(&keep_alive));
&keep_alive);
rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_H2C_FW_JOINBSSRPT,

View file

@ -1509,10 +1509,10 @@ static int rtl_pci_tx(struct ieee80211_hw *hw,
if (rtlpriv->use_new_trx_flow) {
rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, true,
HW_DESC_OWN, (u8 *)&hw_queue);
HW_DESC_OWN, &hw_queue);
} else {
rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, true,
HW_DESC_OWN, (u8 *)&temp_one);
HW_DESC_OWN, &temp_one);
}
if ((ring->entries - skb_queue_len(&ring->queue)) < 2 &&
@ -1853,6 +1853,65 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev,
return true;
}
static int rtl_pci_intr_mode_msi(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
struct rtl_pci *rtlpci = rtl_pcidev(pcipriv);
int ret;
ret = pci_enable_msi(rtlpci->pdev);
if (ret < 0)
return ret;
ret = request_irq(rtlpci->pdev->irq, &_rtl_pci_interrupt,
IRQF_SHARED, KBUILD_MODNAME, hw);
if (ret < 0) {
pci_disable_msi(rtlpci->pdev);
return ret;
}
rtlpci->using_msi = true;
RT_TRACE(rtlpriv, COMP_INIT|COMP_INTR, DBG_DMESG,
"MSI Interrupt Mode!\n");
return 0;
}
static int rtl_pci_intr_mode_legacy(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
struct rtl_pci *rtlpci = rtl_pcidev(pcipriv);
int ret;
ret = request_irq(rtlpci->pdev->irq, &_rtl_pci_interrupt,
IRQF_SHARED, KBUILD_MODNAME, hw);
if (ret < 0)
return ret;
rtlpci->using_msi = false;
RT_TRACE(rtlpriv, COMP_INIT|COMP_INTR, DBG_DMESG,
"Pin-based Interrupt Mode!\n");
return 0;
}
static int rtl_pci_intr_mode_decide(struct ieee80211_hw *hw)
{
struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
struct rtl_pci *rtlpci = rtl_pcidev(pcipriv);
int ret;
if (rtlpci->msi_support) {
ret = rtl_pci_intr_mode_msi(hw);
if (ret < 0)
ret = rtl_pci_intr_mode_legacy(hw);
} else {
ret = rtl_pci_intr_mode_legacy(hw);
}
return ret;
}
int rtl_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
@ -1995,8 +2054,7 @@ int rtl_pci_probe(struct pci_dev *pdev,
}
rtlpci = rtl_pcidev(pcipriv);
err = request_irq(rtlpci->pdev->irq, &_rtl_pci_interrupt,
IRQF_SHARED, KBUILD_MODNAME, hw);
err = rtl_pci_intr_mode_decide(hw);
if (err) {
RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"%s: failed to register IRQ handler\n",
@ -2064,6 +2122,9 @@ void rtl_pci_disconnect(struct pci_dev *pdev)
rtlpci->irq_alloc = 0;
}
if (rtlpci->using_msi)
pci_disable_msi(rtlpci->pdev);
list_del(&rtlpriv->list);
if (rtlpriv->io.pci_mem_start != 0) {
pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start);

View file

@ -759,7 +759,7 @@ static void rtl_p2p_noa_ie(struct ieee80211_hw *hw, void *data,
unsigned int len)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct ieee80211_mgmt *mgmt = (void *)data;
struct ieee80211_mgmt *mgmt = data;
struct rtl_p2p_ps_info *p2pinfo = &(rtlpriv->psc.p2p_ps_info);
u8 *pos, *end, *ie;
u16 noa_len;
@ -858,7 +858,7 @@ static void rtl_p2p_action_ie(struct ieee80211_hw *hw, void *data,
unsigned int len)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct ieee80211_mgmt *mgmt = (void *)data;
struct ieee80211_mgmt *mgmt = data;
struct rtl_p2p_ps_info *p2pinfo = &(rtlpriv->psc.p2p_ps_info);
u8 noa_num, index, i, noa_index = 0;
u8 *pos, *end, *ie;
@ -950,9 +950,8 @@ void rtl_p2p_ps_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)
switch (p2p_ps_state) {
case P2P_PS_DISABLE:
p2pinfo->p2p_ps_state = p2p_ps_state;
rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_H2C_FW_P2P_PS_OFFLOAD,
(u8 *)(&p2p_ps_state));
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_P2P_PS_OFFLOAD,
&p2p_ps_state);
p2pinfo->noa_index = 0;
p2pinfo->ctwindow = 0;
@ -964,7 +963,7 @@ void rtl_p2p_ps_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)
rtlps->smart_ps = 2;
rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_H2C_FW_PWRMODE,
(u8 *)(&rtlps->pwr_mode));
&rtlps->pwr_mode);
}
}
break;
@ -977,12 +976,12 @@ void rtl_p2p_ps_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)
rtlps->smart_ps = 0;
rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_H2C_FW_PWRMODE,
(u8 *)(&rtlps->pwr_mode));
&rtlps->pwr_mode);
}
}
rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_H2C_FW_P2P_PS_OFFLOAD,
(u8 *)(&p2p_ps_state));
&p2p_ps_state);
}
break;
case P2P_PS_SCAN:
@ -992,7 +991,7 @@ void rtl_p2p_ps_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)
p2pinfo->p2p_ps_state = p2p_ps_state;
rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_H2C_FW_P2P_PS_OFFLOAD,
(u8 *)(&p2p_ps_state));
&p2p_ps_state);
}
break;
default:
@ -1012,7 +1011,7 @@ void rtl_p2p_info(struct ieee80211_hw *hw, void *data, unsigned int len)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
struct ieee80211_hdr *hdr = (void *)data;
struct ieee80211_hdr *hdr = data;
if (!mac->p2p)
return;

View file

@ -851,9 +851,8 @@ static void rtl88e_dm_check_edca_turbo(struct ieee80211_hw *hw)
} else {
if (rtlpriv->dm.current_turbo_edca) {
u8 tmp = AC0_BE;
rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_AC_PARAM,
(u8 *)(&tmp));
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
&tmp);
rtlpriv->dm.current_turbo_edca = false;
}
}

View file

@ -119,7 +119,7 @@ static void _rtl88e_write_fw(struct ieee80211_hw *hw,
enum version_8188e version, u8 *buffer, u32 size)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u8 *buf_ptr = (u8 *)buffer;
u8 *buf_ptr = buffer;
u32 page_no, remain;
u32 page, offset;
@ -213,7 +213,7 @@ int rtl88e_download_fw(struct ieee80211_hw *hw, bool buse_wake_on_wlan_fw)
return 1;
pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware;
pfwdata = (u8 *)rtlhal->pfirmware;
pfwdata = rtlhal->pfirmware;
fwsize = rtlhal->fwsize;
RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
"normal Firmware SIZE %d\n", fwsize);

View file

@ -147,8 +147,7 @@ static void _rtl88ee_set_fw_clock_on(struct ieee80211_hw *hw,
}
if (IS_IN_LOW_POWER_STATE_88E(rtlhal->fw_ps_state)) {
rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_SET_RPWM,
(u8 *)(&rpwm_val));
rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_SET_RPWM, &rpwm_val);
if (FW_PS_IS_ACK(rpwm_val)) {
isr_regaddr = REG_HISR;
content = rtl_read_dword(rtlpriv, isr_regaddr);
@ -225,7 +224,7 @@ static void _rtl88ee_set_fw_clock_off(struct ieee80211_hw *hw,
rtlhal->fw_ps_state = FW_PS_STATE(rpwm_val);
rtl_write_word(rtlpriv, REG_HISR, 0x0100);
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
(u8 *)(&rpwm_val));
&rpwm_val);
spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
rtlhal->fw_clk_change_in_progress = false;
spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
@ -273,15 +272,14 @@ static void _rtl88ee_fwlps_leave(struct ieee80211_hw *hw)
_rtl88ee_set_fw_clock_on(hw, rpwm_val, false);
rtlhal->allow_sw_to_change_hwclc = false;
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
(u8 *)(&fw_pwrmode));
&fw_pwrmode);
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
(u8 *)(&fw_current_inps));
} else {
rpwm_val = FW_PS_STATE_ALL_ON_88E; /* RF on */
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
(u8 *)(&rpwm_val));
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, &rpwm_val);
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
(u8 *)(&fw_pwrmode));
&fw_pwrmode);
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
(u8 *)(&fw_current_inps));
}
@ -300,7 +298,7 @@ static void _rtl88ee_fwlps_enter(struct ieee80211_hw *hw)
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
(u8 *)(&fw_current_inps));
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
(u8 *)(&ppsc->fwctrl_psmode));
&ppsc->fwctrl_psmode);
rtlhal->allow_sw_to_change_hwclc = true;
_rtl88ee_set_fw_clock_off(hw, rpwm_val);
} else {
@ -308,9 +306,8 @@ static void _rtl88ee_fwlps_enter(struct ieee80211_hw *hw)
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
(u8 *)(&fw_current_inps));
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
(u8 *)(&ppsc->fwctrl_psmode));
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
(u8 *)(&rpwm_val));
&ppsc->fwctrl_psmode);
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, &rpwm_val);
}
}
@ -419,12 +416,12 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
for (e_aci = 0; e_aci < AC_MAX; e_aci++) {
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
(u8 *)(&e_aci));
&e_aci);
}
break; }
case HW_VAR_ACK_PREAMBLE:{
u8 reg_tmp;
u8 short_preamble = (bool) (*(u8 *)val);
u8 short_preamble = (bool)*val;
reg_tmp = rtl_read_byte(rtlpriv, REG_TRXPTCL_CTL+2);
if (short_preamble) {
reg_tmp |= 0x02;
@ -435,13 +432,13 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
}
break; }
case HW_VAR_WPA_CONFIG:
rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *)val));
rtl_write_byte(rtlpriv, REG_SECCFG, *val);
break;
case HW_VAR_AMPDU_MIN_SPACE:{
u8 min_spacing_to_set;
u8 sec_min_space;
min_spacing_to_set = *((u8 *)val);
min_spacing_to_set = *val;
if (min_spacing_to_set <= 7) {
sec_min_space = 0;
@ -464,7 +461,7 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
case HW_VAR_SHORTGI_DENSITY:{
u8 density_to_set;
density_to_set = *((u8 *)val);
density_to_set = *val;
mac->min_space_cfg |= (density_to_set << 3);
RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
@ -482,7 +479,7 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
reg = regtoset_normal;
factor = *((u8 *)val);
factor = *val;
if (factor <= 3) {
factor = (1 << (factor + 2));
if (factor > 0xf)
@ -505,15 +502,15 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
}
break; }
case HW_VAR_AC_PARAM:{
u8 e_aci = *((u8 *)val);
u8 e_aci = *val;
rtl88e_dm_init_edca_turbo(hw);
if (rtlpci->acm_method != EACMWAY2_SW)
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL,
(u8 *)(&e_aci));
&e_aci);
break; }
case HW_VAR_ACM_CTRL:{
u8 e_aci = *((u8 *)val);
u8 e_aci = *val;
union aci_aifsn *p_aci_aifsn =
(union aci_aifsn *)(&(mac->ac[0].aifs));
u8 acm = p_aci_aifsn->f.acm;
@ -566,7 +563,7 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
rtlpci->receive_config = ((u32 *)(val))[0];
break;
case HW_VAR_RETRY_LIMIT:{
u8 retry_limit = ((u8 *)(val))[0];
u8 retry_limit = *val;
rtl_write_word(rtlpriv, REG_RL,
retry_limit << RETRY_LIMIT_SHORT_SHIFT |
@ -579,7 +576,7 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
rtlefuse->efuse_usedbytes = *((u16 *)val);
break;
case HW_VAR_EFUSE_USAGE:
rtlefuse->efuse_usedpercentage = *((u8 *)val);
rtlefuse->efuse_usedpercentage = *val;
break;
case HW_VAR_IO_CMD:
rtl88e_phy_set_io_cmd(hw, (*(enum io_type *)val));
@ -591,15 +588,13 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
udelay(1);
if (rpwm_val & BIT(7)) {
rtl_write_byte(rtlpriv, REG_PCIE_HRPWM,
(*(u8 *)val));
rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, *val);
} else {
rtl_write_byte(rtlpriv, REG_PCIE_HRPWM,
((*(u8 *)val) | BIT(7)));
rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, *val | BIT(7));
}
break; }
case HW_VAR_H2C_FW_PWRMODE:
rtl88e_set_fw_pwrmode_cmd(hw, (*(u8 *)val));
rtl88e_set_fw_pwrmode_cmd(hw, *val);
break;
case HW_VAR_FW_PSMODE_STATUS:
ppsc->fw_current_inpsmode = *((bool *)val);
@ -616,7 +611,7 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
_rtl88ee_fwlps_leave(hw);
break; }
case HW_VAR_H2C_FW_JOINBSSRPT:{
u8 mstatus = (*(u8 *)val);
u8 mstatus = *val;
u8 tmp, tmp_reg422, uval;
u8 count = 0, dlbcn_count = 0;
bool recover = false;
@ -667,10 +662,10 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
}
rtl_write_byte(rtlpriv, REG_CR + 1, (tmp & ~(BIT(0))));
}
rtl88e_set_fw_joinbss_report_cmd(hw, (*(u8 *)val));
rtl88e_set_fw_joinbss_report_cmd(hw, *val);
break; }
case HW_VAR_H2C_FW_P2P_PS_OFFLOAD:
rtl88e_set_p2p_ps_offload_cmd(hw, (*(u8 *)val));
rtl88e_set_p2p_ps_offload_cmd(hw, *val);
break;
case HW_VAR_AID:{
u16 u2btmp;
@ -680,7 +675,7 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
mac->assoc_id));
break; }
case HW_VAR_CORRECT_TSF:{
u8 btype_ibss = ((u8 *)(val))[0];
u8 btype_ibss = *val;
if (btype_ibss == true)
_rtl88ee_stop_tx_beacon(hw);
@ -1828,7 +1823,7 @@ static void _rtl88ee_read_adapter_info(struct ieee80211_hw *hw)
RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
"EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid);
/*customer ID*/
rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID];
rtlefuse->eeprom_oemid = hwinfo[EEPROM_CUSTOMER_ID];
if (rtlefuse->eeprom_oemid == 0xFF)
rtlefuse->eeprom_oemid = 0;
@ -1845,7 +1840,7 @@ static void _rtl88ee_read_adapter_info(struct ieee80211_hw *hw)
RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"dev_addr: %pM\n", rtlefuse->dev_addr);
/*channel plan */
rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN];
rtlefuse->eeprom_channelplan = hwinfo[EEPROM_CHANNELPLAN];
/* set channel paln to world wide 13 */
rtlefuse->channel_plan = COUNTRY_CODE_WORLD_WIDE_13;
/*tx power*/
@ -1857,7 +1852,7 @@ static void _rtl88ee_read_adapter_info(struct ieee80211_hw *hw)
rtlefuse->autoload_failflag,
hwinfo);
/*board type*/
rtlefuse->board_type = (((*(u8 *)&hwinfo[jj]) & 0xE0) >> 5);
rtlefuse->board_type = (hwinfo[jj] & 0xE0) >> 5;
/*Wake on wlan*/
rtlefuse->wowlan_enable = ((hwinfo[kk] & 0x40) >> 6);
/*parse xtal*/
@ -2223,8 +2218,7 @@ void rtl88ee_update_channel_access_setting(struct ieee80211_hw *hw)
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
u16 sifs_timer;
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME,
(u8 *)&mac->slot_time);
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, &mac->slot_time);
if (!mac->ht_enable)
sifs_timer = 0x0a0a;
else

View file

@ -93,6 +93,7 @@ int rtl88e_init_sw_vars(struct ieee80211_hw *hw)
u8 tid;
rtl8188ee_bt_reg_init(hw);
rtlpci->msi_support = true;
rtlpriv->dm.dm_initialgain_enable = 1;
rtlpriv->dm.dm_flag = 0;

View file

@ -497,7 +497,7 @@ void rtl88ee_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_hal *rtlhal = rtl_hal(rtlpriv);
u8 *pdesc = (u8 *)pdesc_tx;
u8 *pdesc = pdesc_tx;
u16 seq_number;
__le16 fc = hdr->frame_control;
unsigned int buf_len = 0;
@ -716,7 +716,7 @@ void rtl88ee_tx_fill_cmddesc(struct ieee80211_hw *hw,
SET_TX_DESC_OWN(pdesc, 1);
SET_TX_DESC_PKT_SIZE((u8 *)pdesc, (u16)(skb->len));
SET_TX_DESC_PKT_SIZE(pdesc, (u16)(skb->len));
SET_TX_DESC_FIRST_SEG(pdesc, 1);
SET_TX_DESC_LAST_SEG(pdesc, 1);

View file

@ -476,7 +476,7 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
break;
}
case HW_VAR_H2C_FW_P2P_PS_OFFLOAD:
rtl92c_set_p2p_ps_offload_cmd(hw, (*(u8 *)val));
rtl92c_set_p2p_ps_offload_cmd(hw, *val);
break;
case HW_VAR_AID:{
u16 u2btmp;
@ -521,21 +521,21 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
(u8 *)(&fw_current_inps));
rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_H2C_FW_PWRMODE,
(u8 *)(&ppsc->fwctrl_psmode));
&ppsc->fwctrl_psmode);
rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_SET_RPWM,
(u8 *)(&rpwm_val));
HW_VAR_SET_RPWM,
&rpwm_val);
} else {
rpwm_val = 0x0C; /* RF on */
fw_pwrmode = FW_PS_ACTIVE_MODE;
fw_current_inps = false;
rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_SET_RPWM,
(u8 *)(&rpwm_val));
HW_VAR_SET_RPWM,
&rpwm_val);
rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_H2C_FW_PWRMODE,
(u8 *)(&fw_pwrmode));
&fw_pwrmode);
rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_FW_PSMODE_STATUS,

View file

@ -413,20 +413,18 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
(u8 *)(&fw_current_inps));
rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_H2C_FW_PWRMODE,
(u8 *)(&ppsc->fwctrl_psmode));
&ppsc->fwctrl_psmode);
rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_SET_RPWM,
(u8 *)(&rpwm_val));
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
&rpwm_val);
} else {
rpwm_val = 0x0C; /* RF on */
fw_pwrmode = FW_PS_ACTIVE_MODE;
fw_current_inps = false;
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
(u8 *)(&rpwm_val));
rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_H2C_FW_PWRMODE,
(u8 *)(&fw_pwrmode));
&rpwm_val);
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
&fw_pwrmode);
rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_FW_PSMODE_STATUS,

View file

@ -647,9 +647,8 @@ static void rtl8723ae_dm_check_edca_turbo(struct ieee80211_hw *hw)
} else {
if (rtlpriv->dm.current_turbo_edca) {
u8 tmp = AC0_BE;
rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_AC_PARAM,
(u8 *) (&tmp));
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
&tmp);
rtlpriv->dm.current_turbo_edca = false;
}
}

View file

@ -207,14 +207,13 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
rtl_write_byte(rtlpriv, REG_SLOT, val[0]);
for (e_aci = 0; e_aci < AC_MAX; e_aci++) {
rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_AC_PARAM,
(u8 *) (&e_aci));
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
&e_aci);
}
break; }
case HW_VAR_ACK_PREAMBLE:{
u8 reg_tmp;
u8 short_preamble = (bool) (*(u8 *) val);
u8 short_preamble = (bool)*val;
reg_tmp = (mac->cur_40_prime_sc) << 5;
if (short_preamble)
reg_tmp |= 0x80;
@ -225,7 +224,7 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
u8 min_spacing_to_set;
u8 sec_min_space;
min_spacing_to_set = *((u8 *) val);
min_spacing_to_set = *val;
if (min_spacing_to_set <= 7) {
sec_min_space = 0;
@ -249,7 +248,7 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
case HW_VAR_SHORTGI_DENSITY:{
u8 density_to_set;
density_to_set = *((u8 *) val);
density_to_set = *val;
mac->min_space_cfg |= (density_to_set << 3);
RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
@ -273,7 +272,7 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
else
p_regtoset = regtoset_normal;
factor_toset = *((u8 *) val);
factor_toset = *val;
if (factor_toset <= 3) {
factor_toset = (1 << (factor_toset + 2));
if (factor_toset > 0xf)
@ -304,16 +303,15 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
}
break; }
case HW_VAR_AC_PARAM:{
u8 e_aci = *((u8 *) val);
u8 e_aci = *val;
rtl8723_dm_init_edca_turbo(hw);
if (rtlpci->acm_method != EACMWAY2_SW)
rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_ACM_CTRL,
(u8 *) (&e_aci));
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL,
&e_aci);
break; }
case HW_VAR_ACM_CTRL:{
u8 e_aci = *((u8 *) val);
u8 e_aci = *val;
union aci_aifsn *p_aci_aifsn =
(union aci_aifsn *)(&(mac->ac[0].aifs));
u8 acm = p_aci_aifsn->f.acm;
@ -366,7 +364,7 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
rtlpci->receive_config = ((u32 *) (val))[0];
break;
case HW_VAR_RETRY_LIMIT:{
u8 retry_limit = ((u8 *) (val))[0];
u8 retry_limit = *val;
rtl_write_word(rtlpriv, REG_RL,
retry_limit << RETRY_LIMIT_SHORT_SHIFT |
@ -379,13 +377,13 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
rtlefuse->efuse_usedbytes = *((u16 *) val);
break;
case HW_VAR_EFUSE_USAGE:
rtlefuse->efuse_usedpercentage = *((u8 *) val);
rtlefuse->efuse_usedpercentage = *val;
break;
case HW_VAR_IO_CMD:
rtl8723ae_phy_set_io_cmd(hw, (*(enum io_type *)val));
break;
case HW_VAR_WPA_CONFIG:
rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *) val));
rtl_write_byte(rtlpriv, REG_SECCFG, *val);
break;
case HW_VAR_SET_RPWM:{
u8 rpwm_val;
@ -394,27 +392,25 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
udelay(1);
if (rpwm_val & BIT(7)) {
rtl_write_byte(rtlpriv, REG_PCIE_HRPWM,
(*(u8 *) val));
rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, *val);
} else {
rtl_write_byte(rtlpriv, REG_PCIE_HRPWM,
((*(u8 *) val) | BIT(7)));
rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, *val | BIT(7));
}
break; }
case HW_VAR_H2C_FW_PWRMODE:{
u8 psmode = (*(u8 *) val);
u8 psmode = *val;
if (psmode != FW_PS_ACTIVE_MODE)
rtl8723ae_dm_rf_saving(hw, true);
rtl8723ae_set_fw_pwrmode_cmd(hw, (*(u8 *) val));
rtl8723ae_set_fw_pwrmode_cmd(hw, *val);
break; }
case HW_VAR_FW_PSMODE_STATUS:
ppsc->fw_current_inpsmode = *((bool *) val);
break;
case HW_VAR_H2C_FW_JOINBSSRPT:{
u8 mstatus = (*(u8 *) val);
u8 mstatus = *val;
u8 tmp_regcr, tmp_reg422;
bool recover = false;
@ -447,11 +443,11 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
rtl_write_byte(rtlpriv, REG_CR + 1,
(tmp_regcr & ~(BIT(0))));
}
rtl8723ae_set_fw_joinbss_report_cmd(hw, (*(u8 *) val));
rtl8723ae_set_fw_joinbss_report_cmd(hw, *val);
break; }
case HW_VAR_H2C_FW_P2P_PS_OFFLOAD:
rtl8723ae_set_p2p_ps_offload_cmd(hw, (*(u8 *)val));
rtl8723ae_set_p2p_ps_offload_cmd(hw, *val);
break;
case HW_VAR_AID:{
u16 u2btmp;
@ -461,7 +457,7 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
mac->assoc_id));
break; }
case HW_VAR_CORRECT_TSF:{
u8 btype_ibss = ((u8 *) (val))[0];
u8 btype_ibss = *val;
if (btype_ibss == true)
_rtl8723ae_stop_tx_beacon(hw);
@ -491,20 +487,18 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
(u8 *)(&fw_current_inps));
rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_H2C_FW_PWRMODE,
(u8 *)(&ppsc->fwctrl_psmode));
&ppsc->fwctrl_psmode);
rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_SET_RPWM,
(u8 *)(&rpwm_val));
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
&rpwm_val);
} else {
rpwm_val = 0x0C; /* RF on */
fw_pwrmode = FW_PS_ACTIVE_MODE;
fw_current_inps = false;
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
(u8 *)(&rpwm_val));
rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_H2C_FW_PWRMODE,
(u8 *)(&fw_pwrmode));
&rpwm_val);
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
&fw_pwrmode);
rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_FW_PSMODE_STATUS,
@ -1628,10 +1622,10 @@ static void _rtl8723ae_read_adapter_info(struct ieee80211_hw *hw,
rtl8723ae_read_bt_coexist_info_from_hwpg(hw,
rtlefuse->autoload_failflag, hwinfo);
rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN];
rtlefuse->eeprom_channelplan = hwinfo[EEPROM_CHANNELPLAN];
rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION];
rtlefuse->txpwr_fromeprom = true;
rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID];
rtlefuse->eeprom_oemid = hwinfo[EEPROM_CUSTOMER_ID];
RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
"EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid);
@ -2051,8 +2045,7 @@ void rtl8723ae_update_channel_access_setting(struct ieee80211_hw *hw)
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
u16 sifs_timer;
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME,
(u8 *)&mac->slot_time);
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, &mac->slot_time);
if (!mac->ht_enable)
sifs_timer = 0x0a0a;
else

View file

@ -375,7 +375,7 @@ void rtl8723ae_tx_fill_desc(struct ieee80211_hw *hw,
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
bool defaultadapter = true;
u8 *pdesc = (u8 *) pdesc_tx;
u8 *pdesc = pdesc_tx;
u16 seq_number;
__le16 fc = hdr->frame_control;
u8 fw_qsel = _rtl8723ae_map_hwqueue_to_fwqueue(skb, hw_queue);
@ -577,7 +577,7 @@ void rtl8723ae_tx_fill_cmddesc(struct ieee80211_hw *hw,
SET_TX_DESC_OWN(pdesc, 1);
SET_TX_DESC_PKT_SIZE((u8 *) pdesc, (u16) (skb->len));
SET_TX_DESC_PKT_SIZE(pdesc, (u16) (skb->len));
SET_TX_DESC_FIRST_SEG(pdesc, 1);
SET_TX_DESC_LAST_SEG(pdesc, 1);

View file

@ -1083,7 +1083,7 @@ static void rtl8723be_dm_check_edca_turbo(struct ieee80211_hw *hw)
if (rtlpriv->dm.current_turbo_edca) {
u8 tmp = AC0_BE;
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
(u8 *)(&tmp));
&tmp);
}
rtlpriv->dm.current_turbo_edca = false;
}

View file

@ -147,7 +147,7 @@ static void _rtl8723be_set_fw_clock_on(struct ieee80211_hw *hw, u8 rpwm_val,
}
if (IS_IN_LOW_POWER_STATE_88E(rtlhal->fw_ps_state)) {
rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_SET_RPWM,
(u8 *)(&rpwm_val));
&rpwm_val);
if (FW_PS_IS_ACK(rpwm_val)) {
isr_regaddr = REG_HISR;
content = rtl_read_dword(rtlpriv, isr_regaddr);
@ -221,7 +221,7 @@ static void _rtl8723be_set_fw_clock_off(struct ieee80211_hw *hw, u8 rpwm_val)
rtlhal->fw_ps_state = FW_PS_STATE(rpwm_val);
rtl_write_word(rtlpriv, REG_HISR, 0x0100);
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
(u8 *)(&rpwm_val));
&rpwm_val);
spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
rtlhal->fw_clk_change_in_progress = false;
spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
@ -253,15 +253,14 @@ static void _rtl8723be_fwlps_leave(struct ieee80211_hw *hw)
_rtl8723be_set_fw_clock_on(hw, rpwm_val, false);
rtlhal->allow_sw_to_change_hwclc = false;
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
(u8 *)(&fw_pwrmode));
&fw_pwrmode);
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
(u8 *)(&fw_current_inps));
} else {
rpwm_val = FW_PS_STATE_ALL_ON_88E; /* RF on */
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
(u8 *)(&rpwm_val));
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, &rpwm_val);
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
(u8 *)(&fw_pwrmode));
&fw_pwrmode);
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
(u8 *)(&fw_current_inps));
}
@ -280,7 +279,7 @@ static void _rtl8723be_fwlps_enter(struct ieee80211_hw *hw)
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
(u8 *)(&fw_current_inps));
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
(u8 *)(&ppsc->fwctrl_psmode));
&ppsc->fwctrl_psmode);
rtlhal->allow_sw_to_change_hwclc = true;
_rtl8723be_set_fw_clock_off(hw, rpwm_val);
@ -289,9 +288,8 @@ static void _rtl8723be_fwlps_enter(struct ieee80211_hw *hw)
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
(u8 *)(&fw_current_inps));
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
(u8 *)(&ppsc->fwctrl_psmode));
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
(u8 *)(&rpwm_val));
&ppsc->fwctrl_psmode);
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, &rpwm_val);
}
}
@ -400,12 +398,12 @@ void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
for (e_aci = 0; e_aci < AC_MAX; e_aci++) {
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
(u8 *)(&e_aci));
&e_aci);
}
break; }
case HW_VAR_ACK_PREAMBLE: {
u8 reg_tmp;
u8 short_preamble = (bool) (*(u8 *)val);
u8 short_preamble = (bool)*val;
reg_tmp = rtl_read_byte(rtlpriv, REG_TRXPTCL_CTL + 2);
if (short_preamble) {
reg_tmp |= 0x02;
@ -416,13 +414,13 @@ void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
}
break; }
case HW_VAR_WPA_CONFIG:
rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *)val));
rtl_write_byte(rtlpriv, REG_SECCFG, *val);
break;
case HW_VAR_AMPDU_MIN_SPACE: {
u8 min_spacing_to_set;
u8 sec_min_space;
min_spacing_to_set = *((u8 *)val);
min_spacing_to_set = *val;
if (min_spacing_to_set <= 7) {
sec_min_space = 0;
@ -445,7 +443,7 @@ void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
case HW_VAR_SHORTGI_DENSITY: {
u8 density_to_set;
density_to_set = *((u8 *)val);
density_to_set = *val;
mac->min_space_cfg |= (density_to_set << 3);
RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
@ -463,7 +461,7 @@ void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
p_regtoset = regtoset_normal;
factor_toset = *((u8 *)val);
factor_toset = *val;
if (factor_toset <= 3) {
factor_toset = (1 << (factor_toset + 2));
if (factor_toset > 0xf)
@ -491,15 +489,15 @@ void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
}
break; }
case HW_VAR_AC_PARAM: {
u8 e_aci = *((u8 *)val);
u8 e_aci = *val;
rtl8723_dm_init_edca_turbo(hw);
if (rtlpci->acm_method != EACMWAY2_SW)
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL,
(u8 *)(&e_aci));
&e_aci);
break; }
case HW_VAR_ACM_CTRL: {
u8 e_aci = *((u8 *)val);
u8 e_aci = *val;
union aci_aifsn *p_aci_aifsn =
(union aci_aifsn *)(&(mac->ac[0].aifs));
u8 acm = p_aci_aifsn->f.acm;
@ -552,7 +550,7 @@ void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
rtlpci->receive_config = ((u32 *)(val))[0];
break;
case HW_VAR_RETRY_LIMIT: {
u8 retry_limit = ((u8 *)(val))[0];
u8 retry_limit = *val;
rtl_write_word(rtlpriv, REG_RL,
retry_limit << RETRY_LIMIT_SHORT_SHIFT |
@ -565,7 +563,7 @@ void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
rtlefuse->efuse_usedbytes = *((u16 *)val);
break;
case HW_VAR_EFUSE_USAGE:
rtlefuse->efuse_usedpercentage = *((u8 *)val);
rtlefuse->efuse_usedpercentage = *val;
break;
case HW_VAR_IO_CMD:
rtl8723be_phy_set_io_cmd(hw, (*(enum io_type *)val));
@ -577,14 +575,13 @@ void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
udelay(1);
if (rpwm_val & BIT(7)) {
rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, (*(u8 *)val));
rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, *val);
} else {
rtl_write_byte(rtlpriv, REG_PCIE_HRPWM,
((*(u8 *)val) | BIT(7)));
rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, *val | BIT(7));
}
break; }
case HW_VAR_H2C_FW_PWRMODE:
rtl8723be_set_fw_pwrmode_cmd(hw, (*(u8 *)val));
rtl8723be_set_fw_pwrmode_cmd(hw, *val);
break;
case HW_VAR_FW_PSMODE_STATUS:
ppsc->fw_current_inpsmode = *((bool *)val);
@ -602,7 +599,7 @@ void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
break; }
case HW_VAR_H2C_FW_JOINBSSRPT: {
u8 mstatus = (*(u8 *)val);
u8 mstatus = *val;
u8 tmp_regcr, tmp_reg422, bcnvalid_reg;
u8 count = 0, dlbcn_count = 0;
bool recover = false;
@ -657,10 +654,10 @@ void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
rtl_write_byte(rtlpriv, REG_CR + 1,
(tmp_regcr & ~(BIT(0))));
}
rtl8723be_set_fw_joinbss_report_cmd(hw, (*(u8 *)val));
rtl8723be_set_fw_joinbss_report_cmd(hw, *val);
break; }
case HW_VAR_H2C_FW_P2P_PS_OFFLOAD:
rtl8723be_set_p2p_ps_offload_cmd(hw, (*(u8 *)val));
rtl8723be_set_p2p_ps_offload_cmd(hw, *val);
break;
case HW_VAR_AID: {
u16 u2btmp;
@ -670,7 +667,7 @@ void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
(u2btmp | mac->assoc_id));
break; }
case HW_VAR_CORRECT_TSF: {
u8 btype_ibss = ((u8 *)(val))[0];
u8 btype_ibss = *val;
if (btype_ibss)
_rtl8723be_stop_tx_beacon(hw);
@ -690,7 +687,7 @@ void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
case HW_VAR_KEEP_ALIVE: {
u8 array[2];
array[0] = 0xff;
array[1] = *((u8 *)val);
array[1] = *val;
rtl8723be_fill_h2c_cmd(hw, H2C_8723BE_KEEP_ALIVE_CTRL,
2, array);
break; }
@ -1783,10 +1780,10 @@ static void _rtl8723be_read_adapter_info(struct ieee80211_hw *hw,
rtlefuse->autoload_failflag,
hwinfo);
rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN];
rtlefuse->eeprom_channelplan = hwinfo[EEPROM_CHANNELPLAN];
rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION];
rtlefuse->txpwr_fromeprom = true;
rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID];
rtlefuse->eeprom_oemid = hwinfo[EEPROM_CUSTOMER_ID];
RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
"EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid);
@ -2252,8 +2249,7 @@ void rtl8723be_update_channel_access_setting(struct ieee80211_hw *hw)
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
u16 sifs_timer;
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME,
(u8 *)&mac->slot_time);
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, &mac->slot_time);
if (!mac->ht_enable)
sifs_timer = 0x0a0a;
else

View file

@ -647,7 +647,7 @@ void rtl8723be_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_hal *rtlhal = rtl_hal(rtlpriv);
u8 *pdesc = (u8 *)pdesc_tx;
u8 *pdesc = pdesc_tx;
u16 seq_number;
__le16 fc = hdr->frame_control;
unsigned int buf_len = 0;
@ -850,7 +850,7 @@ void rtl8723be_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
SET_TX_DESC_OWN(pdesc, 1);
SET_TX_DESC_PKT_SIZE((u8 *)pdesc, (u16)(skb->len));
SET_TX_DESC_PKT_SIZE(pdesc, (u16)(skb->len));
SET_TX_DESC_FIRST_SEG(pdesc, 1);
SET_TX_DESC_LAST_SEG(pdesc, 1);

View file

@ -115,7 +115,7 @@ void rtl8723_write_fw(struct ieee80211_hw *hw,
u8 *buffer, u32 size)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u8 *bufferptr = (u8 *)buffer;
u8 *bufferptr = buffer;
u32 pagenums, remainsize;
u32 page, offset;
@ -257,7 +257,7 @@ int rtl8723_download_fw(struct ieee80211_hw *hw,
return 1;
pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware;
pfwdata = (u8 *)rtlhal->pfirmware;
pfwdata = rtlhal->pfirmware;
fwsize = rtlhal->fwsize;
RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
"normal Firmware SIZE %d\n", fwsize);

View file

@ -189,6 +189,7 @@ struct hci_dev {
__u16 page_scan_window;
__u8 page_scan_type;
__u8 le_adv_channel_map;
__u8 le_scan_type;
__u16 le_scan_interval;
__u16 le_scan_window;
__u16 le_conn_min_interval;
@ -1236,7 +1237,7 @@ void mgmt_pin_code_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
void mgmt_pin_code_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
u8 status);
int mgmt_user_confirm_request(struct hci_dev *hdev, bdaddr_t *bdaddr,
u8 link_type, u8 addr_type, __le32 value,
u8 link_type, u8 addr_type, u32 value,
u8 confirm_hint);
int mgmt_user_confirm_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
u8 link_type, u8 addr_type, u8 status);

View file

@ -199,6 +199,8 @@ static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
memset(hdev->scan_rsp_data, 0, sizeof(hdev->scan_rsp_data));
hdev->scan_rsp_data_len = 0;
hdev->le_scan_type = LE_SCAN_PASSIVE;
hdev->ssp_debug_mode = 0;
}
@ -997,6 +999,25 @@ static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb)
hci_dev_unlock(hdev);
}
static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_cp_le_set_scan_param *cp;
__u8 status = *((__u8 *) skb->data);
BT_DBG("%s status 0x%2.2x", hdev->name, status);
cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_PARAM);
if (!cp)
return;
hci_dev_lock(hdev);
if (!status)
hdev->le_scan_type = cp->type;
hci_dev_unlock(hdev);
}
static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
struct sk_buff *skb)
{
@ -1704,6 +1725,36 @@ unlock:
hci_dev_unlock(hdev);
}
static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
{
struct hci_cp_le_start_enc *cp;
struct hci_conn *conn;
BT_DBG("%s status 0x%2.2x", hdev->name, status);
if (!status)
return;
hci_dev_lock(hdev);
cp = hci_sent_cmd_data(hdev, HCI_OP_LE_START_ENC);
if (!cp)
goto unlock;
conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
if (!conn)
goto unlock;
if (conn->state != BT_CONNECTED)
goto unlock;
hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
hci_conn_drop(conn);
unlock:
hci_dev_unlock(hdev);
}
static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
__u8 status = *((__u8 *) skb->data);
@ -2488,6 +2539,10 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
hci_cc_le_set_adv_enable(hdev, skb);
break;
case HCI_OP_LE_SET_SCAN_PARAM:
hci_cc_le_set_scan_param(hdev, skb);
break;
case HCI_OP_LE_SET_SCAN_ENABLE:
hci_cc_le_set_scan_enable(hdev, skb);
break;
@ -2611,6 +2666,10 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
hci_cs_le_create_conn(hdev, ev->status);
break;
case HCI_OP_LE_START_ENC:
hci_cs_le_start_enc(hdev, ev->status);
break;
default:
BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
break;
@ -3459,8 +3518,8 @@ static void hci_user_confirm_request_evt(struct hci_dev *hdev,
}
confirm:
mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey,
confirm_hint);
mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0,
le32_to_cpu(ev->passkey), confirm_hint);
unlock:
hci_dev_unlock(hdev);

View file

@ -360,7 +360,8 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr,
BT_DBG("sock %p, sk %p", sock, sk);
if (peer && sk->sk_state != BT_CONNECTED)
if (peer && sk->sk_state != BT_CONNECTED &&
sk->sk_state != BT_CONNECT && sk->sk_state != BT_CONNECT2)
return -ENOTCONN;
memset(la, 0, sizeof(struct sockaddr_l2));

View file

@ -2762,23 +2762,11 @@ static struct pending_cmd *find_pairing(struct hci_conn *conn)
static void pairing_complete(struct pending_cmd *cmd, u8 status)
{
const struct mgmt_cp_pair_device *cp = cmd->param;
struct mgmt_rp_pair_device rp;
struct hci_conn *conn = cmd->user_data;
/* If we had a pairing failure we might have already received
* the remote Identity Address Information and updated the
* hci_conn variables with it, however we would not yet have
* notified user space of the resolved identity. Therefore, use
* the address given in the Pair Device command in case the
* pairing failed.
*/
if (status) {
memcpy(&rp.addr, &cp->addr, sizeof(rp.addr));
} else {
bacpy(&rp.addr.bdaddr, &conn->dst);
rp.addr.type = link_to_bdaddr(conn->type, conn->dst_type);
}
bacpy(&rp.addr.bdaddr, &conn->dst);
rp.addr.type = link_to_bdaddr(conn->type, conn->dst_type);
cmd_complete(cmd->sk, cmd->index, MGMT_OP_PAIR_DEVICE, status,
&rp, sizeof(rp));
@ -5338,7 +5326,7 @@ void mgmt_pin_code_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
}
int mgmt_user_confirm_request(struct hci_dev *hdev, bdaddr_t *bdaddr,
u8 link_type, u8 addr_type, __le32 value,
u8 link_type, u8 addr_type, u32 value,
u8 confirm_hint)
{
struct mgmt_ev_user_confirm_request ev;
@ -5348,7 +5336,7 @@ int mgmt_user_confirm_request(struct hci_dev *hdev, bdaddr_t *bdaddr,
bacpy(&ev.addr.bdaddr, bdaddr);
ev.addr.type = link_to_bdaddr(link_type, addr_type);
ev.confirm_hint = confirm_hint;
ev.value = value;
ev.value = cpu_to_le32(value);
return mgmt_event(MGMT_EV_USER_CONFIRM_REQUEST, hdev, &ev, sizeof(ev),
NULL);

View file

@ -534,7 +534,8 @@ static int rfcomm_sock_getname(struct socket *sock, struct sockaddr *addr, int *
BT_DBG("sock %p, sk %p", sock, sk);
if (peer && sk->sk_state != BT_CONNECTED)
if (peer && sk->sk_state != BT_CONNECTED &&
sk->sk_state != BT_CONNECT && sk->sk_state != BT_CONNECT2)
return -ENOTCONN;
memset(sa, 0, sizeof(*sa));

View file

@ -387,6 +387,11 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
if (!(auth & SMP_AUTH_BONDING) && method == JUST_CFM)
method = JUST_WORKS;
/* Don't confirm locally initiated pairing attempts */
if (method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR,
&smp->smp_flags))
method = JUST_WORKS;
/* If Just Works, Continue with Zero TK */
if (method == JUST_WORKS) {
set_bit(SMP_FLAG_TK_VALID, &smp->smp_flags);
@ -422,10 +427,14 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
if (method == REQ_PASSKEY)
ret = mgmt_user_passkey_request(hcon->hdev, &hcon->dst,
hcon->type, hcon->dst_type);
else if (method == JUST_CFM)
ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst,
hcon->type, hcon->dst_type,
passkey, 1);
else
ret = mgmt_user_passkey_notify(hcon->hdev, &hcon->dst,
hcon->type, hcon->dst_type,
cpu_to_le32(passkey), 0);
passkey, 0);
hci_dev_unlock(hcon->hdev);
@ -547,20 +556,6 @@ error:
smp_failure(conn, reason);
}
static void smp_reencrypt(struct work_struct *work)
{
struct smp_chan *smp = container_of(work, struct smp_chan,
reencrypt.work);
struct l2cap_conn *conn = smp->conn;
struct hci_conn *hcon = conn->hcon;
struct smp_ltk *ltk = smp->ltk;
BT_DBG("");
hci_le_start_enc(hcon, ltk->ediv, ltk->rand, ltk->val);
hcon->enc_key_size = ltk->enc_size;
}
static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
{
struct smp_chan *smp;
@ -571,7 +566,6 @@ static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
INIT_WORK(&smp->confirm, confirm_work);
INIT_WORK(&smp->random, random_work);
INIT_DELAYED_WORK(&smp->reencrypt, smp_reencrypt);
smp->conn = conn;
conn->smp_chan = smp;
@ -589,8 +583,6 @@ void smp_chan_destroy(struct l2cap_conn *conn)
BUG_ON(!smp);
cancel_delayed_work_sync(&smp->reencrypt);
complete = test_bit(SMP_FLAG_COMPLETE, &smp->smp_flags);
mgmt_smp_complete(conn->hcon, complete);
@ -712,6 +704,8 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
if (ret)
return SMP_UNSPECIFIED;
clear_bit(SMP_FLAG_INITIATOR, &smp->smp_flags);
return 0;
}
@ -867,6 +861,8 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
clear_bit(SMP_FLAG_INITIATOR, &smp->smp_flags);
return 0;
}
@ -884,11 +880,15 @@ bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level)
int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
{
struct l2cap_conn *conn = hcon->l2cap_data;
struct smp_chan *smp = conn->smp_chan;
struct smp_chan *smp;
__u8 authreq;
BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level);
/* This may be NULL if there's an unexpected disconnection */
if (!conn)
return 1;
if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags))
return 1;
@ -928,6 +928,8 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
}
set_bit(SMP_FLAG_INITIATOR, &smp->smp_flags);
done:
hcon->pending_sec_level = sec_level;
@ -1058,12 +1060,6 @@ static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
smp->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr,
smp->id_addr_type, smp->irk, &rpa);
/* Track the connection based on the Identity Address from now on */
bacpy(&hcon->dst, &smp->id_addr);
hcon->dst_type = smp->id_addr_type;
l2cap_conn_update_id_addr(hcon);
smp_distribute_keys(conn);
return 0;
@ -1214,8 +1210,16 @@ static void smp_notify_keys(struct l2cap_conn *conn)
struct smp_cmd_pairing *rsp = (void *) &smp->prsp[1];
bool persistent;
if (smp->remote_irk)
if (smp->remote_irk) {
mgmt_new_irk(hdev, smp->remote_irk);
/* Now that user space can be considered to know the
* identity address track the connection based on it
* from now on.
*/
bacpy(&hcon->dst, &smp->remote_irk->bdaddr);
hcon->dst_type = smp->remote_irk->addr_type;
l2cap_conn_update_id_addr(hcon);
}
/* The LTKs and CSRKs should be persistent only if both sides
* had the bonding bit set in their authentication requests.
@ -1253,7 +1257,6 @@ int smp_distribute_keys(struct l2cap_conn *conn)
struct smp_chan *smp = conn->smp_chan;
struct hci_conn *hcon = conn->hcon;
struct hci_dev *hdev = hcon->hdev;
bool ltk_encrypt;
__u8 *keydist;
BT_DBG("conn %p", conn);
@ -1353,32 +1356,12 @@ int smp_distribute_keys(struct l2cap_conn *conn)
if ((smp->remote_key_dist & 0x07))
return 0;
/* Check if we should try to re-encrypt the link with the LTK.
* SMP_FLAG_LTK_ENCRYPT flag is used to track whether we've
* already tried this (in which case we shouldn't try again).
*
* The request will trigger an encryption key refresh event
* which will cause a call to auth_cfm and eventually lead to
* l2cap_core.c calling this smp_distribute_keys function again
* and thereby completing the process.
*/
if (smp->ltk)
ltk_encrypt = !test_and_set_bit(SMP_FLAG_LTK_ENCRYPT,
&smp->smp_flags);
else
ltk_encrypt = false;
clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags);
cancel_delayed_work_sync(&conn->security_timer);
set_bit(SMP_FLAG_COMPLETE, &smp->smp_flags);
smp_notify_keys(conn);
/* Re-encrypt the link with LTK if possible */
if (ltk_encrypt && hcon->out) {
queue_delayed_work(hdev->req_workqueue, &smp->reencrypt,
SMP_REENCRYPT_TIMEOUT);
} else {
clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags);
cancel_delayed_work_sync(&conn->security_timer);
set_bit(SMP_FLAG_COMPLETE, &smp->smp_flags);
smp_notify_keys(conn);
smp_chan_destroy(conn);
}
smp_chan_destroy(conn);
return 0;
}

View file

@ -118,10 +118,8 @@ struct smp_cmd_security_req {
#define SMP_FLAG_TK_VALID 1
#define SMP_FLAG_CFM_PENDING 2
#define SMP_FLAG_MITM_AUTH 3
#define SMP_FLAG_LTK_ENCRYPT 4
#define SMP_FLAG_COMPLETE 5
#define SMP_REENCRYPT_TIMEOUT msecs_to_jiffies(500)
#define SMP_FLAG_COMPLETE 4
#define SMP_FLAG_INITIATOR 5
struct smp_chan {
struct l2cap_conn *conn;
@ -144,7 +142,6 @@ struct smp_chan {
unsigned long smp_flags;
struct work_struct confirm;
struct work_struct random;
struct delayed_work reencrypt;
};
/* SMP Commands */