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

This commit is contained in:
John W. Linville 2014-03-31 15:22:17 -04:00
commit 96da266e77
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) #if IS_BUILTIN(CONFIG_BCMA_HOST_SOC)
chip->to_irq = bcma_gpio_to_irq; chip->to_irq = bcma_gpio_to_irq;
#endif #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 /* 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 * deterministic to address them more easily. The other buses could get
* a random base number. */ * a random base number. */

View File

@ -901,7 +901,7 @@ static void bluecard_release(struct pcmcia_device *link)
bluecard_close(info); bluecard_close(info);
del_timer(&(info->timer)); del_timer_sync(&(info->timer));
pcmcia_disable_device(link); 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->btmrvl_dev.sendcmdflag = false;
priv->adapter->cmd_complete = true; priv->adapter->cmd_complete = true;
wake_up_interruptible(&priv->adapter->cmd_wait_q); wake_up_interruptible(&priv->adapter->cmd_wait_q);
}
if (hci_opcode_ogf(opcode) == 0x3F) { if (hci_opcode_ogf(opcode) == 0x3F) {
BT_DBG("vendor event skipped: opcode=%#4.4x", opcode); BT_DBG("vendor event skipped: opcode=%#4.4x",
kfree_skb(skb); opcode);
return false; 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) 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; struct carl9170_bar_list_entry *entry;
unsigned int queue; unsigned int queue;

View File

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

View File

@ -217,6 +217,9 @@ static inline bool ac_bitmap_tst(u8 bitmap, int prec)
#define WSEC_SWFLAG 0x0008 #define WSEC_SWFLAG 0x0008
/* to go into transition mode without setting wep */ /* to go into transition mode without setting wep */
#define SES_OW_ENABLED 0x0040 #define SES_OW_ENABLED 0x0040
/* MFP */
#define MFP_CAPABLE 0x0200
#define MFP_REQUIRED 0x0400
/* WPA authentication mode bitvec */ /* WPA authentication mode bitvec */
#define WPA_AUTH_DISABLED 0x0000 /* Legacy (i.e., non-WPA) */ #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); priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
adapter->seq_num++;
sleep_cfm_buf->seq_num = sleep_cfm_buf->seq_num =
cpu_to_le16((HostCmd_SET_SEQ_NO_BSS_INFO cpu_to_le16((HostCmd_SET_SEQ_NO_BSS_INFO
(adapter->seq_num, priv->bss_num, (adapter->seq_num, priv->bss_num,
priv->bss_type))); priv->bss_type)));
adapter->seq_num++;
if (adapter->iface_type == MWIFIEX_USB) { if (adapter->iface_type == MWIFIEX_USB) {
sleep_cfm_tmp = sleep_cfm_tmp =
@ -509,6 +509,11 @@ int mwifiex_send_cmd(struct mwifiex_private *priv, u16 cmd_no,
return -1; 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) { if (adapter->surprise_removed) {
dev_err(adapter->dev, "PREP_CMD: card is removed\n"); dev_err(adapter->dev, "PREP_CMD: card is removed\n");
return -1; return -1;
@ -976,11 +981,10 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter)
struct mwifiex_private *priv; struct mwifiex_private *priv;
int i; int i;
spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags);
/* Cancel current cmd */ /* Cancel current cmd */
if ((adapter->curr_cmd) && (adapter->curr_cmd->wait_q_enabled)) { 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; adapter->curr_cmd->wait_q_enabled = false;
spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
adapter->cmd_wait_q.status = -1; adapter->cmd_wait_q.status = -1;
mwifiex_complete_cmd(adapter, adapter->curr_cmd); 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_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
} }
spin_unlock_irqrestore(&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 */ /* Cancel all pending scan command */
spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); 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) if (adapter->surprise_removed)
return; 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 * Abort scan operation by cancelling all pending scan
* commands * commands

View File

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

View File

@ -120,6 +120,7 @@ static int mwifiex_pcie_suspend(struct device *dev)
/* Indicate device suspended */ /* Indicate device suspended */
adapter->is_suspended = true; adapter->is_suspended = true;
adapter->hs_enabling = false;
return 0; return 0;
} }
@ -1033,7 +1034,7 @@ static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter)
card->tx_buf_list[wrdoneidx] = NULL; card->tx_buf_list[wrdoneidx] = NULL;
if (reg->pfu_enabled) { if (reg->pfu_enabled) {
desc2 = (void *)card->txbd_ring[wrdoneidx]; desc2 = card->txbd_ring[wrdoneidx];
memset(desc2, 0, sizeof(*desc2)); memset(desc2, 0, sizeof(*desc2));
} else { } else {
desc = card->txbd_ring[wrdoneidx]; 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; card->tx_buf_list[wrindx] = skb;
if (reg->pfu_enabled) { if (reg->pfu_enabled) {
desc2 = (void *)card->txbd_ring[wrindx]; desc2 = card->txbd_ring[wrindx];
desc2->paddr = buf_pa; desc2->paddr = buf_pa;
desc2->len = (u16)skb->len; desc2->len = (u16)skb->len;
desc2->frag_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; card->rx_buf_list[rd_index] = skb_tmp;
if (reg->pfu_enabled) { if (reg->pfu_enabled) {
desc2 = (void *)card->rxbd_ring[rd_index]; desc2 = card->rxbd_ring[rd_index];
desc2->paddr = buf_pa; desc2->paddr = buf_pa;
desc2->len = skb_tmp->len; desc2->len = skb_tmp->len;
desc2->frag_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, *chan_tlv_out,
struct mwifiex_chan_scan_param_set *scan_chan_list) struct mwifiex_chan_scan_param_set *scan_chan_list)
{ {
struct mwifiex_adapter *adapter = priv->adapter;
int ret = 0; int ret = 0;
struct mwifiex_chan_scan_param_set *tmp_chan_list; struct mwifiex_chan_scan_param_set *tmp_chan_list;
struct mwifiex_chan_scan_param_set *start_chan; 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 tlv_idx, rates_size, cmd_no;
u32 total_scan_time; u32 total_scan_time;
u32 done_early; u32 done_early;
@ -748,8 +750,19 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv,
scan_cfg_out->tlv_buf_len -= scan_cfg_out->tlv_buf_len -=
sizeof(struct mwifiex_ie_types_header) + rates_size; 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; break;
}
} }
if (ret) if (ret)
@ -1653,7 +1666,7 @@ mwifiex_parse_single_response_buf(struct mwifiex_private *priv, u8 **bss_info,
curr_bcn_bytes -= ETH_ALEN; curr_bcn_bytes -= ETH_ALEN;
if (!ext_scan) { if (!ext_scan) {
rssi = (s32) *(u8 *)current_ptr; rssi = (s32) *current_ptr;
rssi = (-rssi) * 100; /* Convert dBm to mBm */ rssi = (-rssi) * 100; /* Convert dBm to mBm */
current_ptr += sizeof(u8); current_ptr += sizeof(u8);
curr_bcn_bytes -= 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 */ /* Enable the Host Sleep */
if (!mwifiex_enable_hs(adapter)) { if (!mwifiex_enable_hs(adapter)) {
dev_err(adapter->dev, "cmd: failed to suspend\n"); dev_err(adapter->dev, "cmd: failed to suspend\n");
adapter->hs_enabling = false;
return -EFAULT; return -EFAULT;
} }
@ -245,6 +246,7 @@ static int mwifiex_sdio_suspend(struct device *dev)
/* Indicate device suspended */ /* Indicate device suspended */
adapter->is_suspended = true; adapter->is_suspended = true;
adapter->hs_enabling = false;
return ret; return ret;
} }

View File

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

View File

@ -730,13 +730,13 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv,
if (len < (sizeof(struct ethhdr) + 3)) if (len < (sizeof(struct ethhdr) + 3))
return; return;
if (*(u8 *)(buf + sizeof(struct ethhdr)) != WLAN_TDLS_SNAP_RFTYPE) if (*(buf + sizeof(struct ethhdr)) != WLAN_TDLS_SNAP_RFTYPE)
return; return;
if (*(u8 *)(buf + sizeof(struct ethhdr) + 1) != WLAN_CATEGORY_TDLS) if (*(buf + sizeof(struct ethhdr) + 1) != WLAN_CATEGORY_TDLS)
return; return;
peer = buf + ETH_ALEN; peer = buf + ETH_ALEN;
action = *(u8 *)(buf + sizeof(struct ethhdr) + 2); action = *(buf + sizeof(struct ethhdr) + 2);
/* just handle TDLS setup request/response/confirm */ /* just handle TDLS setup request/response/confirm */
if (action > WLAN_TDLS_SETUP_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. * 'suspended' state and a 'disconnect' one.
*/ */
adapter->is_suspended = true; adapter->is_suspended = true;
adapter->hs_enabling = false;
if (atomic_read(&card->rx_cmd_urb_pending) && card->rx_cmd.urb) if (atomic_read(&card->rx_cmd_urb_pending) && card->rx_cmd.urb)
usb_kill_urb(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; return -EINVAL;
} }
} else if (msg_type == TX_STATUS_IND) { } else if (msg_type == TX_STATUS_IND) {
if (msg[15] == PROBEREQ_CONFIRM) if (msg[15] == PROBEREQ_CONFIRM) {
common->mgmt_q_block = false; common->mgmt_q_block = false;
rsi_dbg(FSM_ZONE, "%s: Probe confirm received\n", rsi_dbg(FSM_ZONE, "%s: Probe confirm received\n",
__func__); __func__);
}
} else { } else {
return rsi_mgmt_pkt_to_core(common, msg, msg_len, msg_type); return rsi_mgmt_pkt_to_core(common, msg, msg_len, msg_type);
} }

View File

@ -2,11 +2,11 @@
# RTL818X Wireless LAN device configuration # RTL818X Wireless LAN device configuration
# #
config RTL8180 config RTL8180
tristate "Realtek 8180/8185 PCI support" tristate "Realtek 8180/8185/8187SE PCI support"
depends on MAC80211 && PCI depends on MAC80211 && PCI
select EEPROM_93CX6 select EEPROM_93CX6
---help--- ---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: These are PCI based chips found in cards such as:
(RTL8185 802.11g) (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 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_SHIFT 20
#define ANAPARAM_PWR1_MASK (0x7F << ANAPARAM_PWR1_SHIFT) #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 { struct rtl8180_tx_desc {
__le32 flags; __le32 flags;
__le16 rts_duration; __le16 rts_duration;
__le16 plcp_len; __le16 plcp_len;
__le32 tx_buf; __le32 tx_buf;
__le32 frame_len; union{
__le32 frame_len;
struct {
__le16 frame_len_se;
__le16 frame_duration;
} __packed;
} __packed;
__le32 next_tx_desc; __le32 next_tx_desc;
u8 cw; u8 cw;
u8 retry_limit; u8 retry_limit;
u8 agc; u8 agc;
u8 flags2; 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; } __packed;
struct rtl8180_rx_desc { struct rtl8180_rx_desc {
__le32 flags; __le32 flags;
__le32 flags2; __le32 flags2;
union { __le64 tsft;
__le32 rx_buf;
__le64 tsft; } __packed;
};
struct rtl8187se_rx_desc {
__le32 flags;
__le64 tsft;
__le32 flags2;
__le32 flags3;
u32 reserved[3];
} __packed; } __packed;
struct rtl8180_tx_ring { struct rtl8180_tx_ring {
@ -71,14 +108,16 @@ struct rtl8180_priv {
/* rtl8180 driver specific */ /* rtl8180 driver specific */
spinlock_t lock; spinlock_t lock;
struct rtl8180_rx_desc *rx_ring; void *rx_ring;
u8 rx_ring_sz;
dma_addr_t rx_ring_dma; dma_addr_t rx_ring_dma;
unsigned int rx_idx; unsigned int rx_idx;
struct sk_buff *rx_buf[32]; 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_channel channels[14];
struct ieee80211_rate rates[12]; struct ieee80211_rate rates[12];
struct ieee80211_supported_band band; struct ieee80211_supported_band band;
struct ieee80211_tx_queue_params queue_param[4];
struct pci_dev *pdev; struct pci_dev *pdev;
u32 rx_conf; u32 rx_conf;
u8 slot_time; u8 slot_time;
@ -87,18 +126,27 @@ struct rtl8180_priv {
enum { enum {
RTL818X_CHIP_FAMILY_RTL8180, RTL818X_CHIP_FAMILY_RTL8180,
RTL818X_CHIP_FAMILY_RTL8185, RTL818X_CHIP_FAMILY_RTL8185,
RTL818X_CHIP_FAMILY_RTL8187SE,
} chip_family; } chip_family;
u32 anaparam; u32 anaparam;
u16 rfparam; u16 rfparam;
u8 csthreshold; u8 csthreshold;
u8 mac_addr[ETH_ALEN]; u8 mac_addr[ETH_ALEN];
u8 rf_type; 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 # */ /* sequence # */
u16 seqno; u16 seqno;
}; };
void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data); 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_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) 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? */ msleep(1); /* FIXME: optional? */
/* TODO: use set_anaparam2 dev.c_func*/
/* anaparam2 on */ /* anaparam2 on */
rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); 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->ANAPARAM, anaparam);
rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, anaparam2); rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, anaparam2);
if (priv->is_rtl8187b) if (priv->is_rtl8187b)
rtl818x_iowrite8(priv, &priv->map->ANAPARAM3, anaparam3); rtl818x_iowrite8(priv, &priv->map->ANAPARAM3A, anaparam3);
reg &= ~RTL818X_CONFIG3_ANAPARAM_WRITE; reg &= ~RTL818X_CONFIG3_ANAPARAM_WRITE;
rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg); rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg);
rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
@ -1636,10 +1636,10 @@ static int rtl8187_probe(struct usb_interface *intf,
err_free_dmabuf: err_free_dmabuf:
kfree(priv->io_dmabuf); kfree(priv->io_dmabuf);
err_free_dev:
ieee80211_free_hw(dev);
usb_set_intfdata(intf, NULL); usb_set_intfdata(intf, NULL);
usb_put_dev(udev); usb_put_dev(udev);
err_free_dev:
ieee80211_free_hw(dev);
return err; return err;
} }

View File

@ -16,30 +16,82 @@
#define RTL818X_H #define RTL818X_H
struct rtl818x_csr { struct rtl818x_csr {
u8 MAC[6]; u8 MAC[6];
u8 reserved_0[2]; u8 reserved_0[2];
__le32 MAR[2];
u8 RX_FIFO_COUNT; union {
u8 reserved_1; __le32 MAR[2]; /* 0x8 */
u8 TX_FIFO_COUNT;
u8 BQREQ; struct{ /* rtl8187se */
u8 reserved_2[4]; 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 TSFT[2];
__le32 TLPDA;
__le32 TNPDA; union { /* 0x20 */
__le32 THPDA; __le32 TLPDA;
__le16 BRSR; __le32 TVIDA; /* for 8187se */
u8 BSSID[6]; } __packed;
u8 RESP_RATE;
u8 EIFS; union { /* 0x24 */
u8 reserved_3[1]; __le32 TNPDA;
u8 CMD; __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_TX_ENABLE (1 << 2)
#define RTL818X_CMD_RX_ENABLE (1 << 3) #define RTL818X_CMD_RX_ENABLE (1 << 3)
#define RTL818X_CMD_RESET (1 << 4) #define RTL818X_CMD_RESET (1 << 4)
u8 reserved_4[4]; u8 reserved_4[4]; /* 0x38 */
__le16 INT_MASK; union {
__le16 INT_STATUS; 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_OK (1 << 0)
#define RTL818X_INT_RX_ERR (1 << 1) #define RTL818X_INT_RX_ERR (1 << 1)
#define RTL818X_INT_TXL_OK (1 << 2) #define RTL818X_INT_TXL_OK (1 << 2)
@ -56,7 +108,34 @@ struct rtl818x_csr {
#define RTL818X_INT_BEACON (1 << 13) #define RTL818X_INT_BEACON (1 << 13)
#define RTL818X_INT_TIME_OUT (1 << 14) #define RTL818X_INT_TIME_OUT (1 << 14)
#define RTL818X_INT_TX_FO (1 << 15) #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_MAC (1 << 17)
#define RTL818X_TX_CONF_LOOPBACK_CONT (3 << 17) #define RTL818X_TX_CONF_LOOPBACK_CONT (3 << 17)
#define RTL818X_TX_CONF_NO_ICV (1 << 19) #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_R8185_D (5 << 25)
#define RTL818X_TX_CONF_R8187vD (5 << 25) #define RTL818X_TX_CONF_R8187vD (5 << 25)
#define RTL818X_TX_CONF_R8187vD_B (6 << 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_HWVER_MASK (7 << 25)
#define RTL818X_TX_CONF_DISREQQSIZE (1 << 28) #define RTL818X_TX_CONF_DISREQQSIZE (1 << 28)
#define RTL818X_TX_CONF_PROBE_DTS (1 << 29) #define RTL818X_TX_CONF_PROBE_DTS (1 << 29)
@ -122,28 +202,64 @@ struct rtl818x_csr {
u8 PGSELECT; u8 PGSELECT;
u8 SECURITY; u8 SECURITY;
__le32 ANAPARAM2; __le32 ANAPARAM2;
u8 reserved_10[12]; u8 reserved_10[8];
__le16 BEACON_INTERVAL; __le32 IMR; /* 0x6c - Interrupt mask reg for 8187se */
__le16 ATIM_WND; #define IMR_TMGDOK ((1 << 30))
__le16 BEACON_INTERVAL_TIME; #define IMR_DOT11HINT ((1 << 25)) /* 802.11h Measurement Interrupt */
__le16 ATIMTR_INTERVAL; #define IMR_BCNDMAINT ((1 << 24)) /* Beacon DMA Interrupt */
u8 PHY_DELAY; #define IMR_WAKEINT ((1 << 23)) /* Wake Up Interrupt */
u8 CARRIER_SENSE_COUNTER; #define IMR_TXFOVW ((1 << 22)) /* Tx FIFO Overflow */
u8 reserved_11[2]; #define IMR_TIMEOUT1 ((1 << 21)) /* Time Out Interrupt 1 */
u8 PHY[4]; #define IMR_BCNINT ((1 << 20)) /* Beacon Time out */
__le16 RFPinsOutput; #define IMR_ATIMINT ((1 << 19)) /* ATIM Time Out */
__le16 RFPinsEnable; #define IMR_TBDER ((1 << 18)) /* Tx Beacon Descriptor Error */
__le16 RFPinsSelect; #define IMR_TBDOK ((1 << 17)) /* Tx Beacon Descriptor OK */
__le16 RFPinsInput; #define IMR_THPDER ((1 << 16)) /* Tx High Priority Descriptor Error */
__le32 RF_PARA; #define IMR_THPDOK ((1 << 15)) /* Tx High Priority Descriptor OK */
__le32 RF_TIMING; #define IMR_TVODER ((1 << 14)) /* Tx AC_VO Descriptor Error Int */
u8 GP_ENABLE; #define IMR_TVODOK ((1 << 13)) /* Tx AC_VO Descriptor OK Interrupt */
u8 GPIO0; #define IMR_FOVW ((1 << 12)) /* Rx FIFO Overflow Interrupt */
u8 GPIO1; #define IMR_RDU ((1 << 11)) /* Rx Descriptor Unavailable */
u8 reserved_12; #define IMR_TVIDER ((1 << 10)) /* Tx AC_VI Descriptor Error */
__le32 HSSI_PARA; #define IMR_TVIDOK ((1 << 9)) /* Tx AC_VI Descriptor OK Interrupt */
u8 reserved_13[4]; #define IMR_RER ((1 << 8)) /* Rx Error Interrupt */
u8 TX_AGC_CTL; #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_GAIN (1 << 0)
#define RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL (1 << 1) #define RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL (1 << 1)
#define RTL818X_TX_AGC_CTL_FEEDBACK_ANT (1 << 2) #define RTL818X_TX_AGC_CTL_FEEDBACK_ANT (1 << 2)
@ -167,7 +283,8 @@ struct rtl818x_csr {
u8 reserved_17[24]; u8 reserved_17[24];
u8 CONFIG5; u8 CONFIG5;
u8 TX_DMA_POLLING; u8 TX_DMA_POLLING;
u8 reserved_18[2]; u8 PHY_PR;
u8 reserved_18;
__le16 CWR; __le16 CWR;
u8 RETRY_CTR; u8 RETRY_CTR;
u8 reserved_19[3]; u8 reserved_19[3];
@ -179,14 +296,59 @@ struct rtl818x_csr {
__le32 RDSAR; __le32 RDSAR;
__le16 TID_AC_MAP; __le16 TID_AC_MAP;
u8 reserved_20[4]; u8 reserved_20[4];
u8 ANAPARAM3; union {
u8 reserved_21[5]; __le16 ANAPARAM3; /* 0xee */
__le16 FEMR; u8 ANAPARAM3A; /* for rtl8187 */
u8 reserved_22[4]; };
__le16 TALLY_CNT;
u8 TALLY_SEL; #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; } __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 { struct rtl818x_rf_ops {
char *name; char *name;
void (*init)(struct ieee80211_hw *); 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; u8 keep_alive = 10;
rtlpriv->cfg->ops->set_hw_reg(hw, rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_KEEP_ALIVE, HW_VAR_KEEP_ALIVE,
(u8 *)(&keep_alive)); &keep_alive);
rtlpriv->cfg->ops->set_hw_reg(hw, rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_H2C_FW_JOINBSSRPT, 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) { if (rtlpriv->use_new_trx_flow) {
rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, true, rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, true,
HW_DESC_OWN, (u8 *)&hw_queue); HW_DESC_OWN, &hw_queue);
} else { } else {
rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, true, 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 && 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; 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, int rtl_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *id) const struct pci_device_id *id)
{ {
@ -1995,8 +2054,7 @@ int rtl_pci_probe(struct pci_dev *pdev,
} }
rtlpci = rtl_pcidev(pcipriv); rtlpci = rtl_pcidev(pcipriv);
err = request_irq(rtlpci->pdev->irq, &_rtl_pci_interrupt, err = rtl_pci_intr_mode_decide(hw);
IRQF_SHARED, KBUILD_MODNAME, hw);
if (err) { if (err) {
RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"%s: failed to register IRQ handler\n", "%s: failed to register IRQ handler\n",
@ -2064,6 +2122,9 @@ void rtl_pci_disconnect(struct pci_dev *pdev)
rtlpci->irq_alloc = 0; rtlpci->irq_alloc = 0;
} }
if (rtlpci->using_msi)
pci_disable_msi(rtlpci->pdev);
list_del(&rtlpriv->list); list_del(&rtlpriv->list);
if (rtlpriv->io.pci_mem_start != 0) { if (rtlpriv->io.pci_mem_start != 0) {
pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start); 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) unsigned int len)
{ {
struct rtl_priv *rtlpriv = rtl_priv(hw); 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); struct rtl_p2p_ps_info *p2pinfo = &(rtlpriv->psc.p2p_ps_info);
u8 *pos, *end, *ie; u8 *pos, *end, *ie;
u16 noa_len; u16 noa_len;
@ -858,7 +858,7 @@ static void rtl_p2p_action_ie(struct ieee80211_hw *hw, void *data,
unsigned int len) unsigned int len)
{ {
struct rtl_priv *rtlpriv = rtl_priv(hw); 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); struct rtl_p2p_ps_info *p2pinfo = &(rtlpriv->psc.p2p_ps_info);
u8 noa_num, index, i, noa_index = 0; u8 noa_num, index, i, noa_index = 0;
u8 *pos, *end, *ie; 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) { switch (p2p_ps_state) {
case P2P_PS_DISABLE: case P2P_PS_DISABLE:
p2pinfo->p2p_ps_state = p2p_ps_state; p2pinfo->p2p_ps_state = p2p_ps_state;
rtlpriv->cfg->ops->set_hw_reg(hw, rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_P2P_PS_OFFLOAD,
HW_VAR_H2C_FW_P2P_PS_OFFLOAD, &p2p_ps_state);
(u8 *)(&p2p_ps_state));
p2pinfo->noa_index = 0; p2pinfo->noa_index = 0;
p2pinfo->ctwindow = 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; rtlps->smart_ps = 2;
rtlpriv->cfg->ops->set_hw_reg(hw, rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_H2C_FW_PWRMODE, HW_VAR_H2C_FW_PWRMODE,
(u8 *)(&rtlps->pwr_mode)); &rtlps->pwr_mode);
} }
} }
break; break;
@ -977,12 +976,12 @@ void rtl_p2p_ps_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)
rtlps->smart_ps = 0; rtlps->smart_ps = 0;
rtlpriv->cfg->ops->set_hw_reg(hw, rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_H2C_FW_PWRMODE, HW_VAR_H2C_FW_PWRMODE,
(u8 *)(&rtlps->pwr_mode)); &rtlps->pwr_mode);
} }
} }
rtlpriv->cfg->ops->set_hw_reg(hw, rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_H2C_FW_P2P_PS_OFFLOAD, HW_VAR_H2C_FW_P2P_PS_OFFLOAD,
(u8 *)(&p2p_ps_state)); &p2p_ps_state);
} }
break; break;
case P2P_PS_SCAN: 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; p2pinfo->p2p_ps_state = p2p_ps_state;
rtlpriv->cfg->ops->set_hw_reg(hw, rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_H2C_FW_P2P_PS_OFFLOAD, HW_VAR_H2C_FW_P2P_PS_OFFLOAD,
(u8 *)(&p2p_ps_state)); &p2p_ps_state);
} }
break; break;
default: 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_priv *rtlpriv = rtl_priv(hw);
struct rtl_mac *mac = rtl_mac(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) if (!mac->p2p)
return; return;

View File

@ -851,9 +851,8 @@ static void rtl88e_dm_check_edca_turbo(struct ieee80211_hw *hw)
} else { } else {
if (rtlpriv->dm.current_turbo_edca) { if (rtlpriv->dm.current_turbo_edca) {
u8 tmp = AC0_BE; u8 tmp = AC0_BE;
rtlpriv->cfg->ops->set_hw_reg(hw, rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
HW_VAR_AC_PARAM, &tmp);
(u8 *)(&tmp));
rtlpriv->dm.current_turbo_edca = false; 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) enum version_8188e version, u8 *buffer, u32 size)
{ {
struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_priv *rtlpriv = rtl_priv(hw);
u8 *buf_ptr = (u8 *)buffer; u8 *buf_ptr = buffer;
u32 page_no, remain; u32 page_no, remain;
u32 page, offset; u32 page, offset;
@ -213,7 +213,7 @@ int rtl88e_download_fw(struct ieee80211_hw *hw, bool buse_wake_on_wlan_fw)
return 1; return 1;
pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware; pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware;
pfwdata = (u8 *)rtlhal->pfirmware; pfwdata = rtlhal->pfirmware;
fwsize = rtlhal->fwsize; fwsize = rtlhal->fwsize;
RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
"normal Firmware SIZE %d\n", fwsize); "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)) { if (IS_IN_LOW_POWER_STATE_88E(rtlhal->fw_ps_state)) {
rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_SET_RPWM, rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_SET_RPWM, &rpwm_val);
(u8 *)(&rpwm_val));
if (FW_PS_IS_ACK(rpwm_val)) { if (FW_PS_IS_ACK(rpwm_val)) {
isr_regaddr = REG_HISR; isr_regaddr = REG_HISR;
content = rtl_read_dword(rtlpriv, isr_regaddr); 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); rtlhal->fw_ps_state = FW_PS_STATE(rpwm_val);
rtl_write_word(rtlpriv, REG_HISR, 0x0100); rtl_write_word(rtlpriv, REG_HISR, 0x0100);
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
(u8 *)(&rpwm_val)); &rpwm_val);
spin_lock_bh(&rtlpriv->locks.fw_ps_lock); spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
rtlhal->fw_clk_change_in_progress = false; rtlhal->fw_clk_change_in_progress = false;
spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); 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); _rtl88ee_set_fw_clock_on(hw, rpwm_val, false);
rtlhal->allow_sw_to_change_hwclc = false; rtlhal->allow_sw_to_change_hwclc = false;
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, 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, rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
(u8 *)(&fw_current_inps)); (u8 *)(&fw_current_inps));
} else { } else {
rpwm_val = FW_PS_STATE_ALL_ON_88E; /* RF on */ rpwm_val = FW_PS_STATE_ALL_ON_88E; /* RF on */
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, &rpwm_val);
(u8 *)(&rpwm_val));
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, 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, rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
(u8 *)(&fw_current_inps)); (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, rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
(u8 *)(&fw_current_inps)); (u8 *)(&fw_current_inps));
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, 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; rtlhal->allow_sw_to_change_hwclc = true;
_rtl88ee_set_fw_clock_off(hw, rpwm_val); _rtl88ee_set_fw_clock_off(hw, rpwm_val);
} else { } 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, rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
(u8 *)(&fw_current_inps)); (u8 *)(&fw_current_inps));
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, 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, rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, &rpwm_val);
(u8 *)(&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++) { for (e_aci = 0; e_aci < AC_MAX; e_aci++) {
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
(u8 *)(&e_aci)); &e_aci);
} }
break; } break; }
case HW_VAR_ACK_PREAMBLE:{ case HW_VAR_ACK_PREAMBLE:{
u8 reg_tmp; u8 reg_tmp;
u8 short_preamble = (bool) (*(u8 *)val); u8 short_preamble = (bool)*val;
reg_tmp = rtl_read_byte(rtlpriv, REG_TRXPTCL_CTL+2); reg_tmp = rtl_read_byte(rtlpriv, REG_TRXPTCL_CTL+2);
if (short_preamble) { if (short_preamble) {
reg_tmp |= 0x02; reg_tmp |= 0x02;
@ -435,13 +432,13 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
} }
break; } break; }
case HW_VAR_WPA_CONFIG: case HW_VAR_WPA_CONFIG:
rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *)val)); rtl_write_byte(rtlpriv, REG_SECCFG, *val);
break; break;
case HW_VAR_AMPDU_MIN_SPACE:{ case HW_VAR_AMPDU_MIN_SPACE:{
u8 min_spacing_to_set; u8 min_spacing_to_set;
u8 sec_min_space; u8 sec_min_space;
min_spacing_to_set = *((u8 *)val); min_spacing_to_set = *val;
if (min_spacing_to_set <= 7) { if (min_spacing_to_set <= 7) {
sec_min_space = 0; 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:{ case HW_VAR_SHORTGI_DENSITY:{
u8 density_to_set; u8 density_to_set;
density_to_set = *((u8 *)val); density_to_set = *val;
mac->min_space_cfg |= (density_to_set << 3); mac->min_space_cfg |= (density_to_set << 3);
RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, 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; reg = regtoset_normal;
factor = *((u8 *)val); factor = *val;
if (factor <= 3) { if (factor <= 3) {
factor = (1 << (factor + 2)); factor = (1 << (factor + 2));
if (factor > 0xf) if (factor > 0xf)
@ -505,15 +502,15 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
} }
break; } break; }
case HW_VAR_AC_PARAM:{ case HW_VAR_AC_PARAM:{
u8 e_aci = *((u8 *)val); u8 e_aci = *val;
rtl88e_dm_init_edca_turbo(hw); rtl88e_dm_init_edca_turbo(hw);
if (rtlpci->acm_method != EACMWAY2_SW) if (rtlpci->acm_method != EACMWAY2_SW)
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL, rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL,
(u8 *)(&e_aci)); &e_aci);
break; } break; }
case HW_VAR_ACM_CTRL:{ case HW_VAR_ACM_CTRL:{
u8 e_aci = *((u8 *)val); u8 e_aci = *val;
union aci_aifsn *p_aci_aifsn = union aci_aifsn *p_aci_aifsn =
(union aci_aifsn *)(&(mac->ac[0].aifs)); (union aci_aifsn *)(&(mac->ac[0].aifs));
u8 acm = p_aci_aifsn->f.acm; 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]; rtlpci->receive_config = ((u32 *)(val))[0];
break; break;
case HW_VAR_RETRY_LIMIT:{ case HW_VAR_RETRY_LIMIT:{
u8 retry_limit = ((u8 *)(val))[0]; u8 retry_limit = *val;
rtl_write_word(rtlpriv, REG_RL, rtl_write_word(rtlpriv, REG_RL,
retry_limit << RETRY_LIMIT_SHORT_SHIFT | 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); rtlefuse->efuse_usedbytes = *((u16 *)val);
break; break;
case HW_VAR_EFUSE_USAGE: case HW_VAR_EFUSE_USAGE:
rtlefuse->efuse_usedpercentage = *((u8 *)val); rtlefuse->efuse_usedpercentage = *val;
break; break;
case HW_VAR_IO_CMD: case HW_VAR_IO_CMD:
rtl88e_phy_set_io_cmd(hw, (*(enum io_type *)val)); 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); udelay(1);
if (rpwm_val & BIT(7)) { if (rpwm_val & BIT(7)) {
rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, *val);
(*(u8 *)val));
} else { } else {
rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, *val | BIT(7));
((*(u8 *)val) | BIT(7)));
} }
break; } break; }
case HW_VAR_H2C_FW_PWRMODE: case HW_VAR_H2C_FW_PWRMODE:
rtl88e_set_fw_pwrmode_cmd(hw, (*(u8 *)val)); rtl88e_set_fw_pwrmode_cmd(hw, *val);
break; break;
case HW_VAR_FW_PSMODE_STATUS: case HW_VAR_FW_PSMODE_STATUS:
ppsc->fw_current_inpsmode = *((bool *)val); 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); _rtl88ee_fwlps_leave(hw);
break; } break; }
case HW_VAR_H2C_FW_JOINBSSRPT:{ case HW_VAR_H2C_FW_JOINBSSRPT:{
u8 mstatus = (*(u8 *)val); u8 mstatus = *val;
u8 tmp, tmp_reg422, uval; u8 tmp, tmp_reg422, uval;
u8 count = 0, dlbcn_count = 0; u8 count = 0, dlbcn_count = 0;
bool recover = false; 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)))); 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; } break; }
case HW_VAR_H2C_FW_P2P_PS_OFFLOAD: 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; break;
case HW_VAR_AID:{ case HW_VAR_AID:{
u16 u2btmp; u16 u2btmp;
@ -680,7 +675,7 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
mac->assoc_id)); mac->assoc_id));
break; } break; }
case HW_VAR_CORRECT_TSF:{ case HW_VAR_CORRECT_TSF:{
u8 btype_ibss = ((u8 *)(val))[0]; u8 btype_ibss = *val;
if (btype_ibss == true) if (btype_ibss == true)
_rtl88ee_stop_tx_beacon(hw); _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, RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
"EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid); "EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid);
/*customer ID*/ /*customer ID*/
rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID]; rtlefuse->eeprom_oemid = hwinfo[EEPROM_CUSTOMER_ID];
if (rtlefuse->eeprom_oemid == 0xFF) if (rtlefuse->eeprom_oemid == 0xFF)
rtlefuse->eeprom_oemid = 0; 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, RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"dev_addr: %pM\n", rtlefuse->dev_addr); "dev_addr: %pM\n", rtlefuse->dev_addr);
/*channel plan */ /*channel plan */
rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN]; rtlefuse->eeprom_channelplan = hwinfo[EEPROM_CHANNELPLAN];
/* set channel paln to world wide 13 */ /* set channel paln to world wide 13 */
rtlefuse->channel_plan = COUNTRY_CODE_WORLD_WIDE_13; rtlefuse->channel_plan = COUNTRY_CODE_WORLD_WIDE_13;
/*tx power*/ /*tx power*/
@ -1857,7 +1852,7 @@ static void _rtl88ee_read_adapter_info(struct ieee80211_hw *hw)
rtlefuse->autoload_failflag, rtlefuse->autoload_failflag,
hwinfo); hwinfo);
/*board type*/ /*board type*/
rtlefuse->board_type = (((*(u8 *)&hwinfo[jj]) & 0xE0) >> 5); rtlefuse->board_type = (hwinfo[jj] & 0xE0) >> 5;
/*Wake on wlan*/ /*Wake on wlan*/
rtlefuse->wowlan_enable = ((hwinfo[kk] & 0x40) >> 6); rtlefuse->wowlan_enable = ((hwinfo[kk] & 0x40) >> 6);
/*parse xtal*/ /*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)); struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
u16 sifs_timer; u16 sifs_timer;
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, &mac->slot_time);
(u8 *)&mac->slot_time);
if (!mac->ht_enable) if (!mac->ht_enable)
sifs_timer = 0x0a0a; sifs_timer = 0x0a0a;
else else

View File

@ -93,6 +93,7 @@ int rtl88e_init_sw_vars(struct ieee80211_hw *hw)
u8 tid; u8 tid;
rtl8188ee_bt_reg_init(hw); rtl8188ee_bt_reg_init(hw);
rtlpci->msi_support = true;
rtlpriv->dm.dm_initialgain_enable = 1; rtlpriv->dm.dm_initialgain_enable = 1;
rtlpriv->dm.dm_flag = 0; 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_mac *mac = rtl_mac(rtl_priv(hw));
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
struct rtl_hal *rtlhal = rtl_hal(rtlpriv); struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
u8 *pdesc = (u8 *)pdesc_tx; u8 *pdesc = pdesc_tx;
u16 seq_number; u16 seq_number;
__le16 fc = hdr->frame_control; __le16 fc = hdr->frame_control;
unsigned int buf_len = 0; 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_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_FIRST_SEG(pdesc, 1);
SET_TX_DESC_LAST_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; break;
} }
case HW_VAR_H2C_FW_P2P_PS_OFFLOAD: 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; break;
case HW_VAR_AID:{ case HW_VAR_AID:{
u16 u2btmp; u16 u2btmp;
@ -521,21 +521,21 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
(u8 *)(&fw_current_inps)); (u8 *)(&fw_current_inps));
rtlpriv->cfg->ops->set_hw_reg(hw, rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_H2C_FW_PWRMODE, HW_VAR_H2C_FW_PWRMODE,
(u8 *)(&ppsc->fwctrl_psmode)); &ppsc->fwctrl_psmode);
rtlpriv->cfg->ops->set_hw_reg(hw, rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_SET_RPWM, HW_VAR_SET_RPWM,
(u8 *)(&rpwm_val)); &rpwm_val);
} else { } else {
rpwm_val = 0x0C; /* RF on */ rpwm_val = 0x0C; /* RF on */
fw_pwrmode = FW_PS_ACTIVE_MODE; fw_pwrmode = FW_PS_ACTIVE_MODE;
fw_current_inps = false; fw_current_inps = false;
rtlpriv->cfg->ops->set_hw_reg(hw, rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_SET_RPWM, HW_VAR_SET_RPWM,
(u8 *)(&rpwm_val)); &rpwm_val);
rtlpriv->cfg->ops->set_hw_reg(hw, rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_H2C_FW_PWRMODE, HW_VAR_H2C_FW_PWRMODE,
(u8 *)(&fw_pwrmode)); &fw_pwrmode);
rtlpriv->cfg->ops->set_hw_reg(hw, rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_FW_PSMODE_STATUS, 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)); (u8 *)(&fw_current_inps));
rtlpriv->cfg->ops->set_hw_reg(hw, rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_H2C_FW_PWRMODE, HW_VAR_H2C_FW_PWRMODE,
(u8 *)(&ppsc->fwctrl_psmode)); &ppsc->fwctrl_psmode);
rtlpriv->cfg->ops->set_hw_reg(hw, rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
HW_VAR_SET_RPWM, &rpwm_val);
(u8 *)(&rpwm_val));
} else { } else {
rpwm_val = 0x0C; /* RF on */ rpwm_val = 0x0C; /* RF on */
fw_pwrmode = FW_PS_ACTIVE_MODE; fw_pwrmode = FW_PS_ACTIVE_MODE;
fw_current_inps = false; fw_current_inps = false;
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
(u8 *)(&rpwm_val)); &rpwm_val);
rtlpriv->cfg->ops->set_hw_reg(hw, rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
HW_VAR_H2C_FW_PWRMODE, &fw_pwrmode);
(u8 *)(&fw_pwrmode));
rtlpriv->cfg->ops->set_hw_reg(hw, rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_FW_PSMODE_STATUS, HW_VAR_FW_PSMODE_STATUS,

View File

@ -647,9 +647,8 @@ static void rtl8723ae_dm_check_edca_turbo(struct ieee80211_hw *hw)
} else { } else {
if (rtlpriv->dm.current_turbo_edca) { if (rtlpriv->dm.current_turbo_edca) {
u8 tmp = AC0_BE; u8 tmp = AC0_BE;
rtlpriv->cfg->ops->set_hw_reg(hw, rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
HW_VAR_AC_PARAM, &tmp);
(u8 *) (&tmp));
rtlpriv->dm.current_turbo_edca = false; 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]); rtl_write_byte(rtlpriv, REG_SLOT, val[0]);
for (e_aci = 0; e_aci < AC_MAX; e_aci++) { for (e_aci = 0; e_aci < AC_MAX; e_aci++) {
rtlpriv->cfg->ops->set_hw_reg(hw, rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
HW_VAR_AC_PARAM, &e_aci);
(u8 *) (&e_aci));
} }
break; } break; }
case HW_VAR_ACK_PREAMBLE:{ case HW_VAR_ACK_PREAMBLE:{
u8 reg_tmp; u8 reg_tmp;
u8 short_preamble = (bool) (*(u8 *) val); u8 short_preamble = (bool)*val;
reg_tmp = (mac->cur_40_prime_sc) << 5; reg_tmp = (mac->cur_40_prime_sc) << 5;
if (short_preamble) if (short_preamble)
reg_tmp |= 0x80; 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 min_spacing_to_set;
u8 sec_min_space; u8 sec_min_space;
min_spacing_to_set = *((u8 *) val); min_spacing_to_set = *val;
if (min_spacing_to_set <= 7) { if (min_spacing_to_set <= 7) {
sec_min_space = 0; 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:{ case HW_VAR_SHORTGI_DENSITY:{
u8 density_to_set; u8 density_to_set;
density_to_set = *((u8 *) val); density_to_set = *val;
mac->min_space_cfg |= (density_to_set << 3); mac->min_space_cfg |= (density_to_set << 3);
RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, 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 else
p_regtoset = regtoset_normal; p_regtoset = regtoset_normal;
factor_toset = *((u8 *) val); factor_toset = *val;
if (factor_toset <= 3) { if (factor_toset <= 3) {
factor_toset = (1 << (factor_toset + 2)); factor_toset = (1 << (factor_toset + 2));
if (factor_toset > 0xf) if (factor_toset > 0xf)
@ -304,16 +303,15 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
} }
break; } break; }
case HW_VAR_AC_PARAM:{ case HW_VAR_AC_PARAM:{
u8 e_aci = *((u8 *) val); u8 e_aci = *val;
rtl8723_dm_init_edca_turbo(hw); rtl8723_dm_init_edca_turbo(hw);
if (rtlpci->acm_method != EACMWAY2_SW) if (rtlpci->acm_method != EACMWAY2_SW)
rtlpriv->cfg->ops->set_hw_reg(hw, rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL,
HW_VAR_ACM_CTRL, &e_aci);
(u8 *) (&e_aci));
break; } break; }
case HW_VAR_ACM_CTRL:{ case HW_VAR_ACM_CTRL:{
u8 e_aci = *((u8 *) val); u8 e_aci = *val;
union aci_aifsn *p_aci_aifsn = union aci_aifsn *p_aci_aifsn =
(union aci_aifsn *)(&(mac->ac[0].aifs)); (union aci_aifsn *)(&(mac->ac[0].aifs));
u8 acm = p_aci_aifsn->f.acm; 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]; rtlpci->receive_config = ((u32 *) (val))[0];
break; break;
case HW_VAR_RETRY_LIMIT:{ case HW_VAR_RETRY_LIMIT:{
u8 retry_limit = ((u8 *) (val))[0]; u8 retry_limit = *val;
rtl_write_word(rtlpriv, REG_RL, rtl_write_word(rtlpriv, REG_RL,
retry_limit << RETRY_LIMIT_SHORT_SHIFT | 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); rtlefuse->efuse_usedbytes = *((u16 *) val);
break; break;
case HW_VAR_EFUSE_USAGE: case HW_VAR_EFUSE_USAGE:
rtlefuse->efuse_usedpercentage = *((u8 *) val); rtlefuse->efuse_usedpercentage = *val;
break; break;
case HW_VAR_IO_CMD: case HW_VAR_IO_CMD:
rtl8723ae_phy_set_io_cmd(hw, (*(enum io_type *)val)); rtl8723ae_phy_set_io_cmd(hw, (*(enum io_type *)val));
break; break;
case HW_VAR_WPA_CONFIG: case HW_VAR_WPA_CONFIG:
rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *) val)); rtl_write_byte(rtlpriv, REG_SECCFG, *val);
break; break;
case HW_VAR_SET_RPWM:{ case HW_VAR_SET_RPWM:{
u8 rpwm_val; u8 rpwm_val;
@ -394,27 +392,25 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
udelay(1); udelay(1);
if (rpwm_val & BIT(7)) { if (rpwm_val & BIT(7)) {
rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, *val);
(*(u8 *) val));
} else { } else {
rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, *val | BIT(7));
((*(u8 *) val) | BIT(7)));
} }
break; } break; }
case HW_VAR_H2C_FW_PWRMODE:{ case HW_VAR_H2C_FW_PWRMODE:{
u8 psmode = (*(u8 *) val); u8 psmode = *val;
if (psmode != FW_PS_ACTIVE_MODE) if (psmode != FW_PS_ACTIVE_MODE)
rtl8723ae_dm_rf_saving(hw, true); rtl8723ae_dm_rf_saving(hw, true);
rtl8723ae_set_fw_pwrmode_cmd(hw, (*(u8 *) val)); rtl8723ae_set_fw_pwrmode_cmd(hw, *val);
break; } break; }
case HW_VAR_FW_PSMODE_STATUS: case HW_VAR_FW_PSMODE_STATUS:
ppsc->fw_current_inpsmode = *((bool *) val); ppsc->fw_current_inpsmode = *((bool *) val);
break; break;
case HW_VAR_H2C_FW_JOINBSSRPT:{ case HW_VAR_H2C_FW_JOINBSSRPT:{
u8 mstatus = (*(u8 *) val); u8 mstatus = *val;
u8 tmp_regcr, tmp_reg422; u8 tmp_regcr, tmp_reg422;
bool recover = false; 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, rtl_write_byte(rtlpriv, REG_CR + 1,
(tmp_regcr & ~(BIT(0)))); (tmp_regcr & ~(BIT(0))));
} }
rtl8723ae_set_fw_joinbss_report_cmd(hw, (*(u8 *) val)); rtl8723ae_set_fw_joinbss_report_cmd(hw, *val);
break; } break; }
case HW_VAR_H2C_FW_P2P_PS_OFFLOAD: 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; break;
case HW_VAR_AID:{ case HW_VAR_AID:{
u16 u2btmp; u16 u2btmp;
@ -461,7 +457,7 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
mac->assoc_id)); mac->assoc_id));
break; } break; }
case HW_VAR_CORRECT_TSF:{ case HW_VAR_CORRECT_TSF:{
u8 btype_ibss = ((u8 *) (val))[0]; u8 btype_ibss = *val;
if (btype_ibss == true) if (btype_ibss == true)
_rtl8723ae_stop_tx_beacon(hw); _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)); (u8 *)(&fw_current_inps));
rtlpriv->cfg->ops->set_hw_reg(hw, rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_H2C_FW_PWRMODE, HW_VAR_H2C_FW_PWRMODE,
(u8 *)(&ppsc->fwctrl_psmode)); &ppsc->fwctrl_psmode);
rtlpriv->cfg->ops->set_hw_reg(hw, rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
HW_VAR_SET_RPWM, &rpwm_val);
(u8 *)(&rpwm_val));
} else { } else {
rpwm_val = 0x0C; /* RF on */ rpwm_val = 0x0C; /* RF on */
fw_pwrmode = FW_PS_ACTIVE_MODE; fw_pwrmode = FW_PS_ACTIVE_MODE;
fw_current_inps = false; fw_current_inps = false;
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
(u8 *)(&rpwm_val)); &rpwm_val);
rtlpriv->cfg->ops->set_hw_reg(hw, rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
HW_VAR_H2C_FW_PWRMODE, &fw_pwrmode);
(u8 *)(&fw_pwrmode));
rtlpriv->cfg->ops->set_hw_reg(hw, rtlpriv->cfg->ops->set_hw_reg(hw,
HW_VAR_FW_PSMODE_STATUS, 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, rtl8723ae_read_bt_coexist_info_from_hwpg(hw,
rtlefuse->autoload_failflag, hwinfo); 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->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION];
rtlefuse->txpwr_fromeprom = true; 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, RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
"EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid); "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)); struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
u16 sifs_timer; u16 sifs_timer;
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, &mac->slot_time);
(u8 *)&mac->slot_time);
if (!mac->ht_enable) if (!mac->ht_enable)
sifs_timer = 0x0a0a; sifs_timer = 0x0a0a;
else 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_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
bool defaultadapter = true; bool defaultadapter = true;
u8 *pdesc = (u8 *) pdesc_tx; u8 *pdesc = pdesc_tx;
u16 seq_number; u16 seq_number;
__le16 fc = hdr->frame_control; __le16 fc = hdr->frame_control;
u8 fw_qsel = _rtl8723ae_map_hwqueue_to_fwqueue(skb, hw_queue); 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_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_FIRST_SEG(pdesc, 1);
SET_TX_DESC_LAST_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) { if (rtlpriv->dm.current_turbo_edca) {
u8 tmp = AC0_BE; u8 tmp = AC0_BE;
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
(u8 *)(&tmp)); &tmp);
} }
rtlpriv->dm.current_turbo_edca = false; 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)) { if (IS_IN_LOW_POWER_STATE_88E(rtlhal->fw_ps_state)) {
rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_SET_RPWM, rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_SET_RPWM,
(u8 *)(&rpwm_val)); &rpwm_val);
if (FW_PS_IS_ACK(rpwm_val)) { if (FW_PS_IS_ACK(rpwm_val)) {
isr_regaddr = REG_HISR; isr_regaddr = REG_HISR;
content = rtl_read_dword(rtlpriv, isr_regaddr); 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); rtlhal->fw_ps_state = FW_PS_STATE(rpwm_val);
rtl_write_word(rtlpriv, REG_HISR, 0x0100); rtl_write_word(rtlpriv, REG_HISR, 0x0100);
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
(u8 *)(&rpwm_val)); &rpwm_val);
spin_lock_bh(&rtlpriv->locks.fw_ps_lock); spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
rtlhal->fw_clk_change_in_progress = false; rtlhal->fw_clk_change_in_progress = false;
spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); 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); _rtl8723be_set_fw_clock_on(hw, rpwm_val, false);
rtlhal->allow_sw_to_change_hwclc = false; rtlhal->allow_sw_to_change_hwclc = false;
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, 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, rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
(u8 *)(&fw_current_inps)); (u8 *)(&fw_current_inps));
} else { } else {
rpwm_val = FW_PS_STATE_ALL_ON_88E; /* RF on */ rpwm_val = FW_PS_STATE_ALL_ON_88E; /* RF on */
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, &rpwm_val);
(u8 *)(&rpwm_val));
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, 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, rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
(u8 *)(&fw_current_inps)); (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, rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
(u8 *)(&fw_current_inps)); (u8 *)(&fw_current_inps));
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, 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; rtlhal->allow_sw_to_change_hwclc = true;
_rtl8723be_set_fw_clock_off(hw, rpwm_val); _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, rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
(u8 *)(&fw_current_inps)); (u8 *)(&fw_current_inps));
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, 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, rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, &rpwm_val);
(u8 *)(&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++) { for (e_aci = 0; e_aci < AC_MAX; e_aci++) {
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
(u8 *)(&e_aci)); &e_aci);
} }
break; } break; }
case HW_VAR_ACK_PREAMBLE: { case HW_VAR_ACK_PREAMBLE: {
u8 reg_tmp; u8 reg_tmp;
u8 short_preamble = (bool) (*(u8 *)val); u8 short_preamble = (bool)*val;
reg_tmp = rtl_read_byte(rtlpriv, REG_TRXPTCL_CTL + 2); reg_tmp = rtl_read_byte(rtlpriv, REG_TRXPTCL_CTL + 2);
if (short_preamble) { if (short_preamble) {
reg_tmp |= 0x02; reg_tmp |= 0x02;
@ -416,13 +414,13 @@ void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
} }
break; } break; }
case HW_VAR_WPA_CONFIG: case HW_VAR_WPA_CONFIG:
rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *)val)); rtl_write_byte(rtlpriv, REG_SECCFG, *val);
break; break;
case HW_VAR_AMPDU_MIN_SPACE: { case HW_VAR_AMPDU_MIN_SPACE: {
u8 min_spacing_to_set; u8 min_spacing_to_set;
u8 sec_min_space; u8 sec_min_space;
min_spacing_to_set = *((u8 *)val); min_spacing_to_set = *val;
if (min_spacing_to_set <= 7) { if (min_spacing_to_set <= 7) {
sec_min_space = 0; 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: { case HW_VAR_SHORTGI_DENSITY: {
u8 density_to_set; u8 density_to_set;
density_to_set = *((u8 *)val); density_to_set = *val;
mac->min_space_cfg |= (density_to_set << 3); mac->min_space_cfg |= (density_to_set << 3);
RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, 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; p_regtoset = regtoset_normal;
factor_toset = *((u8 *)val); factor_toset = *val;
if (factor_toset <= 3) { if (factor_toset <= 3) {
factor_toset = (1 << (factor_toset + 2)); factor_toset = (1 << (factor_toset + 2));
if (factor_toset > 0xf) if (factor_toset > 0xf)
@ -491,15 +489,15 @@ void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
} }
break; } break; }
case HW_VAR_AC_PARAM: { case HW_VAR_AC_PARAM: {
u8 e_aci = *((u8 *)val); u8 e_aci = *val;
rtl8723_dm_init_edca_turbo(hw); rtl8723_dm_init_edca_turbo(hw);
if (rtlpci->acm_method != EACMWAY2_SW) if (rtlpci->acm_method != EACMWAY2_SW)
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL, rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL,
(u8 *)(&e_aci)); &e_aci);
break; } break; }
case HW_VAR_ACM_CTRL: { case HW_VAR_ACM_CTRL: {
u8 e_aci = *((u8 *)val); u8 e_aci = *val;
union aci_aifsn *p_aci_aifsn = union aci_aifsn *p_aci_aifsn =
(union aci_aifsn *)(&(mac->ac[0].aifs)); (union aci_aifsn *)(&(mac->ac[0].aifs));
u8 acm = p_aci_aifsn->f.acm; 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]; rtlpci->receive_config = ((u32 *)(val))[0];
break; break;
case HW_VAR_RETRY_LIMIT: { case HW_VAR_RETRY_LIMIT: {
u8 retry_limit = ((u8 *)(val))[0]; u8 retry_limit = *val;
rtl_write_word(rtlpriv, REG_RL, rtl_write_word(rtlpriv, REG_RL,
retry_limit << RETRY_LIMIT_SHORT_SHIFT | 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); rtlefuse->efuse_usedbytes = *((u16 *)val);
break; break;
case HW_VAR_EFUSE_USAGE: case HW_VAR_EFUSE_USAGE:
rtlefuse->efuse_usedpercentage = *((u8 *)val); rtlefuse->efuse_usedpercentage = *val;
break; break;
case HW_VAR_IO_CMD: case HW_VAR_IO_CMD:
rtl8723be_phy_set_io_cmd(hw, (*(enum io_type *)val)); 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); udelay(1);
if (rpwm_val & BIT(7)) { if (rpwm_val & BIT(7)) {
rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, (*(u8 *)val)); rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, *val);
} else { } else {
rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, *val | BIT(7));
((*(u8 *)val) | BIT(7)));
} }
break; } break; }
case HW_VAR_H2C_FW_PWRMODE: case HW_VAR_H2C_FW_PWRMODE:
rtl8723be_set_fw_pwrmode_cmd(hw, (*(u8 *)val)); rtl8723be_set_fw_pwrmode_cmd(hw, *val);
break; break;
case HW_VAR_FW_PSMODE_STATUS: case HW_VAR_FW_PSMODE_STATUS:
ppsc->fw_current_inpsmode = *((bool *)val); ppsc->fw_current_inpsmode = *((bool *)val);
@ -602,7 +599,7 @@ void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
break; } break; }
case HW_VAR_H2C_FW_JOINBSSRPT: { case HW_VAR_H2C_FW_JOINBSSRPT: {
u8 mstatus = (*(u8 *)val); u8 mstatus = *val;
u8 tmp_regcr, tmp_reg422, bcnvalid_reg; u8 tmp_regcr, tmp_reg422, bcnvalid_reg;
u8 count = 0, dlbcn_count = 0; u8 count = 0, dlbcn_count = 0;
bool recover = false; 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, rtl_write_byte(rtlpriv, REG_CR + 1,
(tmp_regcr & ~(BIT(0)))); (tmp_regcr & ~(BIT(0))));
} }
rtl8723be_set_fw_joinbss_report_cmd(hw, (*(u8 *)val)); rtl8723be_set_fw_joinbss_report_cmd(hw, *val);
break; } break; }
case HW_VAR_H2C_FW_P2P_PS_OFFLOAD: 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; break;
case HW_VAR_AID: { case HW_VAR_AID: {
u16 u2btmp; u16 u2btmp;
@ -670,7 +667,7 @@ void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
(u2btmp | mac->assoc_id)); (u2btmp | mac->assoc_id));
break; } break; }
case HW_VAR_CORRECT_TSF: { case HW_VAR_CORRECT_TSF: {
u8 btype_ibss = ((u8 *)(val))[0]; u8 btype_ibss = *val;
if (btype_ibss) if (btype_ibss)
_rtl8723be_stop_tx_beacon(hw); _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: { case HW_VAR_KEEP_ALIVE: {
u8 array[2]; u8 array[2];
array[0] = 0xff; array[0] = 0xff;
array[1] = *((u8 *)val); array[1] = *val;
rtl8723be_fill_h2c_cmd(hw, H2C_8723BE_KEEP_ALIVE_CTRL, rtl8723be_fill_h2c_cmd(hw, H2C_8723BE_KEEP_ALIVE_CTRL,
2, array); 2, array);
break; } break; }
@ -1783,10 +1780,10 @@ static void _rtl8723be_read_adapter_info(struct ieee80211_hw *hw,
rtlefuse->autoload_failflag, rtlefuse->autoload_failflag,
hwinfo); hwinfo);
rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN]; rtlefuse->eeprom_channelplan = hwinfo[EEPROM_CHANNELPLAN];
rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION]; rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION];
rtlefuse->txpwr_fromeprom = true; 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, RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
"EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid); "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)); struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
u16 sifs_timer; u16 sifs_timer;
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, &mac->slot_time);
(u8 *)&mac->slot_time);
if (!mac->ht_enable) if (!mac->ht_enable)
sifs_timer = 0x0a0a; sifs_timer = 0x0a0a;
else 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_mac *mac = rtl_mac(rtl_priv(hw));
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
struct rtl_hal *rtlhal = rtl_hal(rtlpriv); struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
u8 *pdesc = (u8 *)pdesc_tx; u8 *pdesc = pdesc_tx;
u16 seq_number; u16 seq_number;
__le16 fc = hdr->frame_control; __le16 fc = hdr->frame_control;
unsigned int buf_len = 0; 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_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_FIRST_SEG(pdesc, 1);
SET_TX_DESC_LAST_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) u8 *buffer, u32 size)
{ {
struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_priv *rtlpriv = rtl_priv(hw);
u8 *bufferptr = (u8 *)buffer; u8 *bufferptr = buffer;
u32 pagenums, remainsize; u32 pagenums, remainsize;
u32 page, offset; u32 page, offset;
@ -257,7 +257,7 @@ int rtl8723_download_fw(struct ieee80211_hw *hw,
return 1; return 1;
pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware; pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware;
pfwdata = (u8 *)rtlhal->pfirmware; pfwdata = rtlhal->pfirmware;
fwsize = rtlhal->fwsize; fwsize = rtlhal->fwsize;
RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
"normal Firmware SIZE %d\n", fwsize); "normal Firmware SIZE %d\n", fwsize);

View File

@ -189,6 +189,7 @@ struct hci_dev {
__u16 page_scan_window; __u16 page_scan_window;
__u8 page_scan_type; __u8 page_scan_type;
__u8 le_adv_channel_map; __u8 le_adv_channel_map;
__u8 le_scan_type;
__u16 le_scan_interval; __u16 le_scan_interval;
__u16 le_scan_window; __u16 le_scan_window;
__u16 le_conn_min_interval; __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, void mgmt_pin_code_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
u8 status); u8 status);
int mgmt_user_confirm_request(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); u8 confirm_hint);
int mgmt_user_confirm_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, int mgmt_user_confirm_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
u8 link_type, u8 addr_type, u8 status); 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)); memset(hdev->scan_rsp_data, 0, sizeof(hdev->scan_rsp_data));
hdev->scan_rsp_data_len = 0; hdev->scan_rsp_data_len = 0;
hdev->le_scan_type = LE_SCAN_PASSIVE;
hdev->ssp_debug_mode = 0; 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); 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, static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
struct sk_buff *skb) struct sk_buff *skb)
{ {
@ -1704,6 +1725,36 @@ unlock:
hci_dev_unlock(hdev); 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) static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
{ {
__u8 status = *((__u8 *) skb->data); __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); hci_cc_le_set_adv_enable(hdev, skb);
break; break;
case HCI_OP_LE_SET_SCAN_PARAM:
hci_cc_le_set_scan_param(hdev, skb);
break;
case HCI_OP_LE_SET_SCAN_ENABLE: case HCI_OP_LE_SET_SCAN_ENABLE:
hci_cc_le_set_scan_enable(hdev, skb); hci_cc_le_set_scan_enable(hdev, skb);
break; 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); hci_cs_le_create_conn(hdev, ev->status);
break; break;
case HCI_OP_LE_START_ENC:
hci_cs_le_start_enc(hdev, ev->status);
break;
default: default:
BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
break; break;
@ -3459,8 +3518,8 @@ static void hci_user_confirm_request_evt(struct hci_dev *hdev,
} }
confirm: confirm:
mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey, mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0,
confirm_hint); le32_to_cpu(ev->passkey), confirm_hint);
unlock: unlock:
hci_dev_unlock(hdev); 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); 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; return -ENOTCONN;
memset(la, 0, sizeof(struct sockaddr_l2)); 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) 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 mgmt_rp_pair_device rp;
struct hci_conn *conn = cmd->user_data; struct hci_conn *conn = cmd->user_data;
/* If we had a pairing failure we might have already received bacpy(&rp.addr.bdaddr, &conn->dst);
* the remote Identity Address Information and updated the rp.addr.type = link_to_bdaddr(conn->type, conn->dst_type);
* 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);
}
cmd_complete(cmd->sk, cmd->index, MGMT_OP_PAIR_DEVICE, status, cmd_complete(cmd->sk, cmd->index, MGMT_OP_PAIR_DEVICE, status,
&rp, sizeof(rp)); &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, 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) u8 confirm_hint)
{ {
struct mgmt_ev_user_confirm_request ev; 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); bacpy(&ev.addr.bdaddr, bdaddr);
ev.addr.type = link_to_bdaddr(link_type, addr_type); ev.addr.type = link_to_bdaddr(link_type, addr_type);
ev.confirm_hint = confirm_hint; 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), return mgmt_event(MGMT_EV_USER_CONFIRM_REQUEST, hdev, &ev, sizeof(ev),
NULL); 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); 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; return -ENOTCONN;
memset(sa, 0, sizeof(*sa)); 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) if (!(auth & SMP_AUTH_BONDING) && method == JUST_CFM)
method = JUST_WORKS; 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 Just Works, Continue with Zero TK */
if (method == JUST_WORKS) { if (method == JUST_WORKS) {
set_bit(SMP_FLAG_TK_VALID, &smp->smp_flags); 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) if (method == REQ_PASSKEY)
ret = mgmt_user_passkey_request(hcon->hdev, &hcon->dst, ret = mgmt_user_passkey_request(hcon->hdev, &hcon->dst,
hcon->type, hcon->dst_type); 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 else
ret = mgmt_user_passkey_notify(hcon->hdev, &hcon->dst, ret = mgmt_user_passkey_notify(hcon->hdev, &hcon->dst,
hcon->type, hcon->dst_type, hcon->type, hcon->dst_type,
cpu_to_le32(passkey), 0); passkey, 0);
hci_dev_unlock(hcon->hdev); hci_dev_unlock(hcon->hdev);
@ -547,20 +556,6 @@ error:
smp_failure(conn, reason); 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) static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
{ {
struct smp_chan *smp; 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->confirm, confirm_work);
INIT_WORK(&smp->random, random_work); INIT_WORK(&smp->random, random_work);
INIT_DELAYED_WORK(&smp->reencrypt, smp_reencrypt);
smp->conn = conn; smp->conn = conn;
conn->smp_chan = smp; conn->smp_chan = smp;
@ -589,8 +583,6 @@ void smp_chan_destroy(struct l2cap_conn *conn)
BUG_ON(!smp); BUG_ON(!smp);
cancel_delayed_work_sync(&smp->reencrypt);
complete = test_bit(SMP_FLAG_COMPLETE, &smp->smp_flags); complete = test_bit(SMP_FLAG_COMPLETE, &smp->smp_flags);
mgmt_smp_complete(conn->hcon, complete); 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) if (ret)
return SMP_UNSPECIFIED; return SMP_UNSPECIFIED;
clear_bit(SMP_FLAG_INITIATOR, &smp->smp_flags);
return 0; 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); smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
clear_bit(SMP_FLAG_INITIATOR, &smp->smp_flags);
return 0; 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) int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
{ {
struct l2cap_conn *conn = hcon->l2cap_data; struct l2cap_conn *conn = hcon->l2cap_data;
struct smp_chan *smp = conn->smp_chan; struct smp_chan *smp;
__u8 authreq; __u8 authreq;
BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level); 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)) if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags))
return 1; 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); smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
} }
set_bit(SMP_FLAG_INITIATOR, &smp->smp_flags);
done: done:
hcon->pending_sec_level = sec_level; 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->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr,
smp->id_addr_type, smp->irk, &rpa); 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); smp_distribute_keys(conn);
return 0; return 0;
@ -1214,8 +1210,16 @@ static void smp_notify_keys(struct l2cap_conn *conn)
struct smp_cmd_pairing *rsp = (void *) &smp->prsp[1]; struct smp_cmd_pairing *rsp = (void *) &smp->prsp[1];
bool persistent; bool persistent;
if (smp->remote_irk) if (smp->remote_irk) {
mgmt_new_irk(hdev, 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 /* The LTKs and CSRKs should be persistent only if both sides
* had the bonding bit set in their authentication requests. * 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 smp_chan *smp = conn->smp_chan;
struct hci_conn *hcon = conn->hcon; struct hci_conn *hcon = conn->hcon;
struct hci_dev *hdev = hcon->hdev; struct hci_dev *hdev = hcon->hdev;
bool ltk_encrypt;
__u8 *keydist; __u8 *keydist;
BT_DBG("conn %p", conn); BT_DBG("conn %p", conn);
@ -1353,32 +1356,12 @@ int smp_distribute_keys(struct l2cap_conn *conn)
if ((smp->remote_key_dist & 0x07)) if ((smp->remote_key_dist & 0x07))
return 0; return 0;
/* Check if we should try to re-encrypt the link with the LTK. clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags);
* SMP_FLAG_LTK_ENCRYPT flag is used to track whether we've cancel_delayed_work_sync(&conn->security_timer);
* already tried this (in which case we shouldn't try again). set_bit(SMP_FLAG_COMPLETE, &smp->smp_flags);
* smp_notify_keys(conn);
* 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;
/* Re-encrypt the link with LTK if possible */ smp_chan_destroy(conn);
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);
}
return 0; return 0;
} }

View File

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