Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
This commit is contained in:
commit
96da266e77
@ -218,7 +218,14 @@ int bcma_gpio_init(struct bcma_drv_cc *cc)
|
||||
#if IS_BUILTIN(CONFIG_BCMA_HOST_SOC)
|
||||
chip->to_irq = bcma_gpio_to_irq;
|
||||
#endif
|
||||
chip->ngpio = 16;
|
||||
switch (cc->core->bus->chipinfo.id) {
|
||||
case BCMA_CHIP_ID_BCM5357:
|
||||
chip->ngpio = 32;
|
||||
break;
|
||||
default:
|
||||
chip->ngpio = 16;
|
||||
}
|
||||
|
||||
/* There is just one SoC in one device and its GPIO addresses should be
|
||||
* deterministic to address them more easily. The other buses could get
|
||||
* a random base number. */
|
||||
|
@ -901,7 +901,7 @@ static void bluecard_release(struct pcmcia_device *link)
|
||||
|
||||
bluecard_close(info);
|
||||
|
||||
del_timer(&(info->timer));
|
||||
del_timer_sync(&(info->timer));
|
||||
|
||||
pcmcia_disable_device(link);
|
||||
}
|
||||
|
@ -59,12 +59,13 @@ bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb)
|
||||
priv->btmrvl_dev.sendcmdflag = false;
|
||||
priv->adapter->cmd_complete = true;
|
||||
wake_up_interruptible(&priv->adapter->cmd_wait_q);
|
||||
}
|
||||
|
||||
if (hci_opcode_ogf(opcode) == 0x3F) {
|
||||
BT_DBG("vendor event skipped: opcode=%#4.4x", opcode);
|
||||
kfree_skb(skb);
|
||||
return false;
|
||||
if (hci_opcode_ogf(opcode) == 0x3F) {
|
||||
BT_DBG("vendor event skipped: opcode=%#4.4x",
|
||||
opcode);
|
||||
kfree_skb(skb);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -572,7 +572,7 @@ static void carl9170_ps_beacon(struct ar9170 *ar, void *data, unsigned int len)
|
||||
|
||||
static void carl9170_ba_check(struct ar9170 *ar, void *data, unsigned int len)
|
||||
{
|
||||
struct ieee80211_bar *bar = (void *) data;
|
||||
struct ieee80211_bar *bar = data;
|
||||
struct carl9170_bar_list_entry *entry;
|
||||
unsigned int queue;
|
||||
|
||||
|
@ -1354,13 +1354,14 @@ static s32 brcmf_set_auth_type(struct net_device *ndev,
|
||||
}
|
||||
|
||||
static s32
|
||||
brcmf_set_set_cipher(struct net_device *ndev,
|
||||
struct cfg80211_connect_params *sme)
|
||||
brcmf_set_wsec_mode(struct net_device *ndev,
|
||||
struct cfg80211_connect_params *sme, bool mfp)
|
||||
{
|
||||
struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
|
||||
struct brcmf_cfg80211_security *sec;
|
||||
s32 pval = 0;
|
||||
s32 gval = 0;
|
||||
s32 wsec;
|
||||
s32 err = 0;
|
||||
|
||||
if (sme->crypto.n_ciphers_pairwise) {
|
||||
@ -1412,7 +1413,12 @@ brcmf_set_set_cipher(struct net_device *ndev,
|
||||
if (brcmf_find_wpsie(sme->ie, sme->ie_len) && !pval && !gval &&
|
||||
sme->privacy)
|
||||
pval = AES_ENABLED;
|
||||
err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wsec", pval | gval);
|
||||
|
||||
if (mfp)
|
||||
wsec = pval | gval | MFP_CAPABLE;
|
||||
else
|
||||
wsec = pval | gval;
|
||||
err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wsec", wsec);
|
||||
if (err) {
|
||||
brcmf_err("error (%d)\n", err);
|
||||
return err;
|
||||
@ -1582,7 +1588,6 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
|
||||
u32 ie_len;
|
||||
struct brcmf_ext_join_params_le *ext_join_params;
|
||||
u16 chanspec;
|
||||
|
||||
s32 err = 0;
|
||||
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
@ -1651,7 +1656,7 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
|
||||
goto done;
|
||||
}
|
||||
|
||||
err = brcmf_set_set_cipher(ndev, sme);
|
||||
err = brcmf_set_wsec_mode(ndev, sme, sme->mfp == NL80211_MFP_REQUIRED);
|
||||
if (err) {
|
||||
brcmf_err("wl_set_set_cipher failed (%d)\n", err);
|
||||
goto done;
|
||||
|
@ -217,6 +217,9 @@ static inline bool ac_bitmap_tst(u8 bitmap, int prec)
|
||||
#define WSEC_SWFLAG 0x0008
|
||||
/* to go into transition mode without setting wep */
|
||||
#define SES_OW_ENABLED 0x0040
|
||||
/* MFP */
|
||||
#define MFP_CAPABLE 0x0200
|
||||
#define MFP_REQUIRED 0x0400
|
||||
|
||||
/* WPA authentication mode bitvec */
|
||||
#define WPA_AUTH_DISABLED 0x0000 /* Legacy (i.e., non-WPA) */
|
||||
|
@ -277,11 +277,11 @@ static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter)
|
||||
|
||||
priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
|
||||
|
||||
adapter->seq_num++;
|
||||
sleep_cfm_buf->seq_num =
|
||||
cpu_to_le16((HostCmd_SET_SEQ_NO_BSS_INFO
|
||||
(adapter->seq_num, priv->bss_num,
|
||||
priv->bss_type)));
|
||||
adapter->seq_num++;
|
||||
|
||||
if (adapter->iface_type == MWIFIEX_USB) {
|
||||
sleep_cfm_tmp =
|
||||
@ -509,6 +509,11 @@ int mwifiex_send_cmd(struct mwifiex_private *priv, u16 cmd_no,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (adapter->hs_enabling && cmd_no != HostCmd_CMD_802_11_HS_CFG_ENH) {
|
||||
dev_err(adapter->dev, "PREP_CMD: host entering sleep state\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (adapter->surprise_removed) {
|
||||
dev_err(adapter->dev, "PREP_CMD: card is removed\n");
|
||||
return -1;
|
||||
@ -976,11 +981,10 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter)
|
||||
struct mwifiex_private *priv;
|
||||
int i;
|
||||
|
||||
spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags);
|
||||
/* Cancel current cmd */
|
||||
if ((adapter->curr_cmd) && (adapter->curr_cmd->wait_q_enabled)) {
|
||||
spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
|
||||
adapter->curr_cmd->wait_q_enabled = false;
|
||||
spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
|
||||
adapter->cmd_wait_q.status = -1;
|
||||
mwifiex_complete_cmd(adapter, adapter->curr_cmd);
|
||||
}
|
||||
@ -1000,6 +1004,7 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter)
|
||||
spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
|
||||
}
|
||||
spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
|
||||
spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
|
||||
|
||||
/* Cancel all pending scan command */
|
||||
spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
|
||||
|
@ -38,7 +38,8 @@ static void scan_delay_timer_fn(unsigned long data)
|
||||
if (adapter->surprise_removed)
|
||||
return;
|
||||
|
||||
if (adapter->scan_delay_cnt == MWIFIEX_MAX_SCAN_DELAY_CNT) {
|
||||
if (adapter->scan_delay_cnt == MWIFIEX_MAX_SCAN_DELAY_CNT ||
|
||||
!adapter->scan_processing) {
|
||||
/*
|
||||
* Abort scan operation by cancelling all pending scan
|
||||
* commands
|
||||
|
@ -774,6 +774,7 @@ struct mwifiex_adapter {
|
||||
u16 hs_activate_wait_q_woken;
|
||||
wait_queue_head_t hs_activate_wait_q;
|
||||
bool is_suspended;
|
||||
bool hs_enabling;
|
||||
u8 event_body[MAX_EVENT_SIZE];
|
||||
u32 hw_dot_11n_dev_cap;
|
||||
u8 hw_dev_mcs_support;
|
||||
|
@ -120,6 +120,7 @@ static int mwifiex_pcie_suspend(struct device *dev)
|
||||
|
||||
/* Indicate device suspended */
|
||||
adapter->is_suspended = true;
|
||||
adapter->hs_enabling = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1033,7 +1034,7 @@ static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter)
|
||||
card->tx_buf_list[wrdoneidx] = NULL;
|
||||
|
||||
if (reg->pfu_enabled) {
|
||||
desc2 = (void *)card->txbd_ring[wrdoneidx];
|
||||
desc2 = card->txbd_ring[wrdoneidx];
|
||||
memset(desc2, 0, sizeof(*desc2));
|
||||
} else {
|
||||
desc = card->txbd_ring[wrdoneidx];
|
||||
@ -1118,7 +1119,7 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb,
|
||||
card->tx_buf_list[wrindx] = skb;
|
||||
|
||||
if (reg->pfu_enabled) {
|
||||
desc2 = (void *)card->txbd_ring[wrindx];
|
||||
desc2 = card->txbd_ring[wrindx];
|
||||
desc2->paddr = buf_pa;
|
||||
desc2->len = (u16)skb->len;
|
||||
desc2->frag_len = (u16)skb->len;
|
||||
@ -1278,7 +1279,7 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter)
|
||||
card->rx_buf_list[rd_index] = skb_tmp;
|
||||
|
||||
if (reg->pfu_enabled) {
|
||||
desc2 = (void *)card->rxbd_ring[rd_index];
|
||||
desc2 = card->rxbd_ring[rd_index];
|
||||
desc2->paddr = buf_pa;
|
||||
desc2->len = skb_tmp->len;
|
||||
desc2->frag_len = skb_tmp->len;
|
||||
|
@ -591,10 +591,12 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv,
|
||||
*chan_tlv_out,
|
||||
struct mwifiex_chan_scan_param_set *scan_chan_list)
|
||||
{
|
||||
struct mwifiex_adapter *adapter = priv->adapter;
|
||||
int ret = 0;
|
||||
struct mwifiex_chan_scan_param_set *tmp_chan_list;
|
||||
struct mwifiex_chan_scan_param_set *start_chan;
|
||||
|
||||
struct cmd_ctrl_node *cmd_node, *tmp_node;
|
||||
unsigned long flags;
|
||||
u32 tlv_idx, rates_size, cmd_no;
|
||||
u32 total_scan_time;
|
||||
u32 done_early;
|
||||
@ -748,8 +750,19 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv,
|
||||
scan_cfg_out->tlv_buf_len -=
|
||||
sizeof(struct mwifiex_ie_types_header) + rates_size;
|
||||
|
||||
if (ret)
|
||||
if (ret) {
|
||||
spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
|
||||
list_for_each_entry_safe(cmd_node, tmp_node,
|
||||
&adapter->scan_pending_q,
|
||||
list) {
|
||||
list_del(&cmd_node->list);
|
||||
cmd_node->wait_q_enabled = false;
|
||||
mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
|
||||
}
|
||||
spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
|
||||
flags);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret)
|
||||
@ -1653,7 +1666,7 @@ mwifiex_parse_single_response_buf(struct mwifiex_private *priv, u8 **bss_info,
|
||||
curr_bcn_bytes -= ETH_ALEN;
|
||||
|
||||
if (!ext_scan) {
|
||||
rssi = (s32) *(u8 *)current_ptr;
|
||||
rssi = (s32) *current_ptr;
|
||||
rssi = (-rssi) * 100; /* Convert dBm to mBm */
|
||||
current_ptr += sizeof(u8);
|
||||
curr_bcn_bytes -= sizeof(u8);
|
||||
|
@ -237,6 +237,7 @@ static int mwifiex_sdio_suspend(struct device *dev)
|
||||
/* Enable the Host Sleep */
|
||||
if (!mwifiex_enable_hs(adapter)) {
|
||||
dev_err(adapter->dev, "cmd: failed to suspend\n");
|
||||
adapter->hs_enabling = false;
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
@ -245,6 +246,7 @@ static int mwifiex_sdio_suspend(struct device *dev)
|
||||
|
||||
/* Indicate device suspended */
|
||||
adapter->is_suspended = true;
|
||||
adapter->hs_enabling = false;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -64,6 +64,7 @@ int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter,
|
||||
*(cmd_queued->condition));
|
||||
if (status) {
|
||||
dev_err(adapter->dev, "cmd_wait_q terminated: %d\n", status);
|
||||
mwifiex_cancel_all_pending_cmd(adapter);
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -508,6 +509,9 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter)
|
||||
memset(&hscfg, 0, sizeof(struct mwifiex_ds_hs_cfg));
|
||||
hscfg.is_invoke_hostcmd = true;
|
||||
|
||||
adapter->hs_enabling = true;
|
||||
mwifiex_cancel_all_pending_cmd(adapter);
|
||||
|
||||
if (mwifiex_set_hs_params(mwifiex_get_priv(adapter,
|
||||
MWIFIEX_BSS_ROLE_STA),
|
||||
HostCmd_ACT_GEN_SET, MWIFIEX_SYNC_CMD,
|
||||
@ -516,8 +520,9 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (wait_event_interruptible(adapter->hs_activate_wait_q,
|
||||
adapter->hs_activate_wait_q_woken)) {
|
||||
if (wait_event_interruptible_timeout(adapter->hs_activate_wait_q,
|
||||
adapter->hs_activate_wait_q_woken,
|
||||
(10 * HZ)) <= 0) {
|
||||
dev_err(adapter->dev, "hs_activate_wait_q terminated\n");
|
||||
return false;
|
||||
}
|
||||
|
@ -730,13 +730,13 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv,
|
||||
|
||||
if (len < (sizeof(struct ethhdr) + 3))
|
||||
return;
|
||||
if (*(u8 *)(buf + sizeof(struct ethhdr)) != WLAN_TDLS_SNAP_RFTYPE)
|
||||
if (*(buf + sizeof(struct ethhdr)) != WLAN_TDLS_SNAP_RFTYPE)
|
||||
return;
|
||||
if (*(u8 *)(buf + sizeof(struct ethhdr) + 1) != WLAN_CATEGORY_TDLS)
|
||||
if (*(buf + sizeof(struct ethhdr) + 1) != WLAN_CATEGORY_TDLS)
|
||||
return;
|
||||
|
||||
peer = buf + ETH_ALEN;
|
||||
action = *(u8 *)(buf + sizeof(struct ethhdr) + 2);
|
||||
action = *(buf + sizeof(struct ethhdr) + 2);
|
||||
|
||||
/* just handle TDLS setup request/response/confirm */
|
||||
if (action > WLAN_TDLS_SETUP_CONFIRM)
|
||||
|
@ -459,6 +459,7 @@ static int mwifiex_usb_suspend(struct usb_interface *intf, pm_message_t message)
|
||||
* 'suspended' state and a 'disconnect' one.
|
||||
*/
|
||||
adapter->is_suspended = true;
|
||||
adapter->hs_enabling = false;
|
||||
|
||||
if (atomic_read(&card->rx_cmd_urb_pending) && card->rx_cmd.urb)
|
||||
usb_kill_urb(card->rx_cmd.urb);
|
||||
|
@ -1292,10 +1292,11 @@ int rsi_mgmt_pkt_recv(struct rsi_common *common, u8 *msg)
|
||||
return -EINVAL;
|
||||
}
|
||||
} else if (msg_type == TX_STATUS_IND) {
|
||||
if (msg[15] == PROBEREQ_CONFIRM)
|
||||
if (msg[15] == PROBEREQ_CONFIRM) {
|
||||
common->mgmt_q_block = false;
|
||||
rsi_dbg(FSM_ZONE, "%s: Probe confirm received\n",
|
||||
__func__);
|
||||
}
|
||||
} else {
|
||||
return rsi_mgmt_pkt_to_core(common, msg, msg_len, msg_type);
|
||||
}
|
||||
|
@ -2,11 +2,11 @@
|
||||
# RTL818X Wireless LAN device configuration
|
||||
#
|
||||
config RTL8180
|
||||
tristate "Realtek 8180/8185 PCI support"
|
||||
tristate "Realtek 8180/8185/8187SE PCI support"
|
||||
depends on MAC80211 && PCI
|
||||
select EEPROM_93CX6
|
||||
---help---
|
||||
This is a driver for RTL8180 and RTL8185 based cards.
|
||||
This is a driver for RTL8180, RTL8185 and RTL8187SE based cards.
|
||||
These are PCI based chips found in cards such as:
|
||||
|
||||
(RTL8185 802.11g)
|
||||
|
@ -1,4 +1,4 @@
|
||||
rtl8180-objs := dev.o rtl8225.o sa2400.o max2820.o grf5101.o
|
||||
rtl8180-objs := dev.o rtl8225.o sa2400.o max2820.o grf5101.o rtl8225se.o
|
||||
|
||||
obj-$(CONFIG_RTL8180) += rtl8180.o
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -24,27 +24,64 @@
|
||||
#define ANAPARAM_PWR1_SHIFT 20
|
||||
#define ANAPARAM_PWR1_MASK (0x7F << ANAPARAM_PWR1_SHIFT)
|
||||
|
||||
/* rtl8180/rtl8185 have 3 queue + beacon queue.
|
||||
* mac80211 can use just one, + beacon = 2 tot.
|
||||
*/
|
||||
#define RTL8180_NR_TX_QUEUES 2
|
||||
|
||||
/* rtl8187SE have 6 queues + beacon queues
|
||||
* mac80211 can use 4 QoS data queue, + beacon = 5 tot
|
||||
*/
|
||||
#define RTL8187SE_NR_TX_QUEUES 5
|
||||
|
||||
/* for array static allocation, it is the max of above */
|
||||
#define RTL818X_NR_TX_QUEUES 5
|
||||
|
||||
struct rtl8180_tx_desc {
|
||||
__le32 flags;
|
||||
__le16 rts_duration;
|
||||
__le16 plcp_len;
|
||||
__le32 tx_buf;
|
||||
__le32 frame_len;
|
||||
union{
|
||||
__le32 frame_len;
|
||||
struct {
|
||||
__le16 frame_len_se;
|
||||
__le16 frame_duration;
|
||||
} __packed;
|
||||
} __packed;
|
||||
__le32 next_tx_desc;
|
||||
u8 cw;
|
||||
u8 retry_limit;
|
||||
u8 agc;
|
||||
u8 flags2;
|
||||
u32 reserved[2];
|
||||
/* rsvd for 8180/8185.
|
||||
* valid for 8187se but we dont use it
|
||||
*/
|
||||
u32 reserved;
|
||||
/* all rsvd for 8180/8185 */
|
||||
__le16 flags3;
|
||||
__le16 frag_qsize;
|
||||
} __packed;
|
||||
|
||||
struct rtl818x_rx_cmd_desc {
|
||||
__le32 flags;
|
||||
u32 reserved;
|
||||
__le32 rx_buf;
|
||||
} __packed;
|
||||
|
||||
struct rtl8180_rx_desc {
|
||||
__le32 flags;
|
||||
__le32 flags2;
|
||||
union {
|
||||
__le32 rx_buf;
|
||||
__le64 tsft;
|
||||
};
|
||||
__le64 tsft;
|
||||
|
||||
} __packed;
|
||||
|
||||
struct rtl8187se_rx_desc {
|
||||
__le32 flags;
|
||||
__le64 tsft;
|
||||
__le32 flags2;
|
||||
__le32 flags3;
|
||||
u32 reserved[3];
|
||||
} __packed;
|
||||
|
||||
struct rtl8180_tx_ring {
|
||||
@ -71,14 +108,16 @@ struct rtl8180_priv {
|
||||
|
||||
/* rtl8180 driver specific */
|
||||
spinlock_t lock;
|
||||
struct rtl8180_rx_desc *rx_ring;
|
||||
void *rx_ring;
|
||||
u8 rx_ring_sz;
|
||||
dma_addr_t rx_ring_dma;
|
||||
unsigned int rx_idx;
|
||||
struct sk_buff *rx_buf[32];
|
||||
struct rtl8180_tx_ring tx_ring[4];
|
||||
struct rtl8180_tx_ring tx_ring[RTL818X_NR_TX_QUEUES];
|
||||
struct ieee80211_channel channels[14];
|
||||
struct ieee80211_rate rates[12];
|
||||
struct ieee80211_supported_band band;
|
||||
struct ieee80211_tx_queue_params queue_param[4];
|
||||
struct pci_dev *pdev;
|
||||
u32 rx_conf;
|
||||
u8 slot_time;
|
||||
@ -87,18 +126,27 @@ struct rtl8180_priv {
|
||||
enum {
|
||||
RTL818X_CHIP_FAMILY_RTL8180,
|
||||
RTL818X_CHIP_FAMILY_RTL8185,
|
||||
RTL818X_CHIP_FAMILY_RTL8187SE,
|
||||
} chip_family;
|
||||
u32 anaparam;
|
||||
u16 rfparam;
|
||||
u8 csthreshold;
|
||||
u8 mac_addr[ETH_ALEN];
|
||||
u8 rf_type;
|
||||
u8 xtal_out;
|
||||
u8 xtal_in;
|
||||
u8 xtal_cal;
|
||||
u8 thermal_meter_val;
|
||||
u8 thermal_meter_en;
|
||||
u8 antenna_diversity_en;
|
||||
u8 antenna_diversity_default;
|
||||
/* sequence # */
|
||||
u16 seqno;
|
||||
};
|
||||
|
||||
void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data);
|
||||
void rtl8180_set_anaparam(struct rtl8180_priv *priv, u32 anaparam);
|
||||
void rtl8180_set_anaparam2(struct rtl8180_priv *priv, u32 anaparam2);
|
||||
|
||||
static inline u8 rtl818x_ioread8(struct rtl8180_priv *priv, u8 __iomem *addr)
|
||||
{
|
||||
|
@ -282,6 +282,7 @@ static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
|
||||
|
||||
msleep(1); /* FIXME: optional? */
|
||||
|
||||
/* TODO: use set_anaparam2 dev.c_func*/
|
||||
/* anaparam2 on */
|
||||
rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
|
||||
reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
|
||||
|
475
drivers/net/wireless/rtl818x/rtl8180/rtl8225se.c
Normal file
475
drivers/net/wireless/rtl818x/rtl8180/rtl8225se.c
Normal 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;
|
||||
}
|
61
drivers/net/wireless/rtl818x/rtl8180/rtl8225se.h
Normal file
61
drivers/net/wireless/rtl818x/rtl8180/rtl8225se.h
Normal 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 */
|
@ -592,7 +592,7 @@ static void rtl8187_set_anaparam(struct rtl8187_priv *priv, bool rfon)
|
||||
rtl818x_iowrite32(priv, &priv->map->ANAPARAM, anaparam);
|
||||
rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, anaparam2);
|
||||
if (priv->is_rtl8187b)
|
||||
rtl818x_iowrite8(priv, &priv->map->ANAPARAM3, anaparam3);
|
||||
rtl818x_iowrite8(priv, &priv->map->ANAPARAM3A, anaparam3);
|
||||
reg &= ~RTL818X_CONFIG3_ANAPARAM_WRITE;
|
||||
rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg);
|
||||
rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
|
||||
@ -1636,10 +1636,10 @@ static int rtl8187_probe(struct usb_interface *intf,
|
||||
|
||||
err_free_dmabuf:
|
||||
kfree(priv->io_dmabuf);
|
||||
err_free_dev:
|
||||
ieee80211_free_hw(dev);
|
||||
usb_set_intfdata(intf, NULL);
|
||||
usb_put_dev(udev);
|
||||
err_free_dev:
|
||||
ieee80211_free_hw(dev);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -16,30 +16,82 @@
|
||||
#define RTL818X_H
|
||||
|
||||
struct rtl818x_csr {
|
||||
|
||||
u8 MAC[6];
|
||||
u8 reserved_0[2];
|
||||
__le32 MAR[2];
|
||||
u8 RX_FIFO_COUNT;
|
||||
u8 reserved_1;
|
||||
u8 TX_FIFO_COUNT;
|
||||
u8 BQREQ;
|
||||
u8 reserved_2[4];
|
||||
|
||||
union {
|
||||
__le32 MAR[2]; /* 0x8 */
|
||||
|
||||
struct{ /* rtl8187se */
|
||||
u8 rf_sw_config; /* 0x8 */
|
||||
u8 reserved_01[3];
|
||||
__le32 TMGDA; /* 0xc */
|
||||
} __packed;
|
||||
} __packed;
|
||||
|
||||
union { /* 0x10 */
|
||||
struct {
|
||||
u8 RX_FIFO_COUNT;
|
||||
u8 reserved_1;
|
||||
u8 TX_FIFO_COUNT;
|
||||
u8 BQREQ;
|
||||
} __packed;
|
||||
|
||||
__le32 TBKDA; /* for 8187se */
|
||||
} __packed;
|
||||
|
||||
__le32 TBEDA; /* 0x14 - for rtl8187se */
|
||||
|
||||
__le32 TSFT[2];
|
||||
__le32 TLPDA;
|
||||
__le32 TNPDA;
|
||||
__le32 THPDA;
|
||||
__le16 BRSR;
|
||||
u8 BSSID[6];
|
||||
u8 RESP_RATE;
|
||||
u8 EIFS;
|
||||
u8 reserved_3[1];
|
||||
u8 CMD;
|
||||
|
||||
union { /* 0x20 */
|
||||
__le32 TLPDA;
|
||||
__le32 TVIDA; /* for 8187se */
|
||||
} __packed;
|
||||
|
||||
union { /* 0x24 */
|
||||
__le32 TNPDA;
|
||||
__le32 TVODA; /* for 8187se */
|
||||
} __packed;
|
||||
|
||||
/* hi pri ring for all cards */
|
||||
__le32 THPDA; /* 0x28 */
|
||||
|
||||
union { /* 0x2c */
|
||||
struct {
|
||||
u8 reserved_2a;
|
||||
u8 EIFS_8187SE;
|
||||
} __packed;
|
||||
|
||||
__le16 BRSR;
|
||||
} __packed;
|
||||
|
||||
u8 BSSID[6]; /* 0x2e */
|
||||
|
||||
union { /* 0x34 */
|
||||
struct {
|
||||
u8 RESP_RATE;
|
||||
u8 EIFS;
|
||||
} __packed;
|
||||
__le16 BRSR_8187SE;
|
||||
} __packed;
|
||||
|
||||
u8 reserved_3[1]; /* 0x36 */
|
||||
u8 CMD; /* 0x37 */
|
||||
#define RTL818X_CMD_TX_ENABLE (1 << 2)
|
||||
#define RTL818X_CMD_RX_ENABLE (1 << 3)
|
||||
#define RTL818X_CMD_RESET (1 << 4)
|
||||
u8 reserved_4[4];
|
||||
__le16 INT_MASK;
|
||||
__le16 INT_STATUS;
|
||||
u8 reserved_4[4]; /* 0x38 */
|
||||
union {
|
||||
struct {
|
||||
__le16 INT_MASK;
|
||||
__le16 INT_STATUS;
|
||||
} __packed;
|
||||
|
||||
__le32 INT_STATUS_SE; /* 0x3c */
|
||||
} __packed;
|
||||
/* status bits for rtl8187 and rtl8180/8185 */
|
||||
#define RTL818X_INT_RX_OK (1 << 0)
|
||||
#define RTL818X_INT_RX_ERR (1 << 1)
|
||||
#define RTL818X_INT_TXL_OK (1 << 2)
|
||||
@ -56,7 +108,34 @@ struct rtl818x_csr {
|
||||
#define RTL818X_INT_BEACON (1 << 13)
|
||||
#define RTL818X_INT_TIME_OUT (1 << 14)
|
||||
#define RTL818X_INT_TX_FO (1 << 15)
|
||||
__le32 TX_CONF;
|
||||
/* status bits for rtl8187se */
|
||||
#define RTL818X_INT_SE_TIMER3 (1 << 0)
|
||||
#define RTL818X_INT_SE_TIMER2 (1 << 1)
|
||||
#define RTL818X_INT_SE_RQ0SOR (1 << 2)
|
||||
#define RTL818X_INT_SE_TXBED_OK (1 << 3)
|
||||
#define RTL818X_INT_SE_TXBED_ERR (1 << 4)
|
||||
#define RTL818X_INT_SE_TXBE_OK (1 << 5)
|
||||
#define RTL818X_INT_SE_TXBE_ERR (1 << 6)
|
||||
#define RTL818X_INT_SE_RX_OK (1 << 7)
|
||||
#define RTL818X_INT_SE_RX_ERR (1 << 8)
|
||||
#define RTL818X_INT_SE_TXL_OK (1 << 9)
|
||||
#define RTL818X_INT_SE_TXL_ERR (1 << 10)
|
||||
#define RTL818X_INT_SE_RX_DU (1 << 11)
|
||||
#define RTL818X_INT_SE_RX_FIFO (1 << 12)
|
||||
#define RTL818X_INT_SE_TXN_OK (1 << 13)
|
||||
#define RTL818X_INT_SE_TXN_ERR (1 << 14)
|
||||
#define RTL818X_INT_SE_TXH_OK (1 << 15)
|
||||
#define RTL818X_INT_SE_TXH_ERR (1 << 16)
|
||||
#define RTL818X_INT_SE_TXB_OK (1 << 17)
|
||||
#define RTL818X_INT_SE_TXB_ERR (1 << 18)
|
||||
#define RTL818X_INT_SE_ATIM_TO (1 << 19)
|
||||
#define RTL818X_INT_SE_BK_TO (1 << 20)
|
||||
#define RTL818X_INT_SE_TIMER1 (1 << 21)
|
||||
#define RTL818X_INT_SE_TX_FIFO (1 << 22)
|
||||
#define RTL818X_INT_SE_WAKEUP (1 << 23)
|
||||
#define RTL818X_INT_SE_BK_DMA (1 << 24)
|
||||
#define RTL818X_INT_SE_TMGD_OK (1 << 30)
|
||||
__le32 TX_CONF; /* 0x40 */
|
||||
#define RTL818X_TX_CONF_LOOPBACK_MAC (1 << 17)
|
||||
#define RTL818X_TX_CONF_LOOPBACK_CONT (3 << 17)
|
||||
#define RTL818X_TX_CONF_NO_ICV (1 << 19)
|
||||
@ -68,6 +147,7 @@ struct rtl818x_csr {
|
||||
#define RTL818X_TX_CONF_R8185_D (5 << 25)
|
||||
#define RTL818X_TX_CONF_R8187vD (5 << 25)
|
||||
#define RTL818X_TX_CONF_R8187vD_B (6 << 25)
|
||||
#define RTL818X_TX_CONF_RTL8187SE (6 << 25)
|
||||
#define RTL818X_TX_CONF_HWVER_MASK (7 << 25)
|
||||
#define RTL818X_TX_CONF_DISREQQSIZE (1 << 28)
|
||||
#define RTL818X_TX_CONF_PROBE_DTS (1 << 29)
|
||||
@ -122,28 +202,64 @@ struct rtl818x_csr {
|
||||
u8 PGSELECT;
|
||||
u8 SECURITY;
|
||||
__le32 ANAPARAM2;
|
||||
u8 reserved_10[12];
|
||||
__le16 BEACON_INTERVAL;
|
||||
__le16 ATIM_WND;
|
||||
__le16 BEACON_INTERVAL_TIME;
|
||||
__le16 ATIMTR_INTERVAL;
|
||||
u8 PHY_DELAY;
|
||||
u8 CARRIER_SENSE_COUNTER;
|
||||
u8 reserved_11[2];
|
||||
u8 PHY[4];
|
||||
__le16 RFPinsOutput;
|
||||
__le16 RFPinsEnable;
|
||||
__le16 RFPinsSelect;
|
||||
__le16 RFPinsInput;
|
||||
__le32 RF_PARA;
|
||||
__le32 RF_TIMING;
|
||||
u8 GP_ENABLE;
|
||||
u8 GPIO0;
|
||||
u8 GPIO1;
|
||||
u8 reserved_12;
|
||||
__le32 HSSI_PARA;
|
||||
u8 reserved_13[4];
|
||||
u8 TX_AGC_CTL;
|
||||
u8 reserved_10[8];
|
||||
__le32 IMR; /* 0x6c - Interrupt mask reg for 8187se */
|
||||
#define IMR_TMGDOK ((1 << 30))
|
||||
#define IMR_DOT11HINT ((1 << 25)) /* 802.11h Measurement Interrupt */
|
||||
#define IMR_BCNDMAINT ((1 << 24)) /* Beacon DMA Interrupt */
|
||||
#define IMR_WAKEINT ((1 << 23)) /* Wake Up Interrupt */
|
||||
#define IMR_TXFOVW ((1 << 22)) /* Tx FIFO Overflow */
|
||||
#define IMR_TIMEOUT1 ((1 << 21)) /* Time Out Interrupt 1 */
|
||||
#define IMR_BCNINT ((1 << 20)) /* Beacon Time out */
|
||||
#define IMR_ATIMINT ((1 << 19)) /* ATIM Time Out */
|
||||
#define IMR_TBDER ((1 << 18)) /* Tx Beacon Descriptor Error */
|
||||
#define IMR_TBDOK ((1 << 17)) /* Tx Beacon Descriptor OK */
|
||||
#define IMR_THPDER ((1 << 16)) /* Tx High Priority Descriptor Error */
|
||||
#define IMR_THPDOK ((1 << 15)) /* Tx High Priority Descriptor OK */
|
||||
#define IMR_TVODER ((1 << 14)) /* Tx AC_VO Descriptor Error Int */
|
||||
#define IMR_TVODOK ((1 << 13)) /* Tx AC_VO Descriptor OK Interrupt */
|
||||
#define IMR_FOVW ((1 << 12)) /* Rx FIFO Overflow Interrupt */
|
||||
#define IMR_RDU ((1 << 11)) /* Rx Descriptor Unavailable */
|
||||
#define IMR_TVIDER ((1 << 10)) /* Tx AC_VI Descriptor Error */
|
||||
#define IMR_TVIDOK ((1 << 9)) /* Tx AC_VI Descriptor OK Interrupt */
|
||||
#define IMR_RER ((1 << 8)) /* Rx Error Interrupt */
|
||||
#define IMR_ROK ((1 << 7)) /* Receive OK Interrupt */
|
||||
#define IMR_TBEDER ((1 << 6)) /* Tx AC_BE Descriptor Error */
|
||||
#define IMR_TBEDOK ((1 << 5)) /* Tx AC_BE Descriptor OK */
|
||||
#define IMR_TBKDER ((1 << 4)) /* Tx AC_BK Descriptor Error */
|
||||
#define IMR_TBKDOK ((1 << 3)) /* Tx AC_BK Descriptor OK */
|
||||
#define IMR_RQOSOK ((1 << 2)) /* Rx QoS OK Interrupt */
|
||||
#define IMR_TIMEOUT2 ((1 << 1)) /* Time Out Interrupt 2 */
|
||||
#define IMR_TIMEOUT3 ((1 << 0)) /* Time Out Interrupt 3 */
|
||||
__le16 BEACON_INTERVAL; /* 0x70 */
|
||||
__le16 ATIM_WND; /* 0x72 */
|
||||
__le16 BEACON_INTERVAL_TIME; /* 0x74 */
|
||||
__le16 ATIMTR_INTERVAL; /* 0x76 */
|
||||
u8 PHY_DELAY; /* 0x78 */
|
||||
u8 CARRIER_SENSE_COUNTER; /* 0x79 */
|
||||
u8 reserved_11[2]; /* 0x7a */
|
||||
u8 PHY[4]; /* 0x7c */
|
||||
__le16 RFPinsOutput; /* 0x80 */
|
||||
__le16 RFPinsEnable; /* 0x82 */
|
||||
__le16 RFPinsSelect; /* 0x84 */
|
||||
__le16 RFPinsInput; /* 0x86 */
|
||||
__le32 RF_PARA; /* 0x88 */
|
||||
__le32 RF_TIMING; /* 0x8c */
|
||||
u8 GP_ENABLE; /* 0x90 */
|
||||
u8 GPIO0; /* 0x91 */
|
||||
u8 GPIO1; /* 0x92 */
|
||||
u8 TPPOLL_STOP; /* 0x93 - rtl8187se only */
|
||||
#define RTL818x_TPPOLL_STOP_BQ (1 << 7)
|
||||
#define RTL818x_TPPOLL_STOP_VI (1 << 4)
|
||||
#define RTL818x_TPPOLL_STOP_VO (1 << 5)
|
||||
#define RTL818x_TPPOLL_STOP_BE (1 << 3)
|
||||
#define RTL818x_TPPOLL_STOP_BK (1 << 2)
|
||||
#define RTL818x_TPPOLL_STOP_MG (1 << 1)
|
||||
#define RTL818x_TPPOLL_STOP_HI (1 << 6)
|
||||
|
||||
__le32 HSSI_PARA; /* 0x94 */
|
||||
u8 reserved_13[4]; /* 0x98 */
|
||||
u8 TX_AGC_CTL; /* 0x9c */
|
||||
#define RTL818X_TX_AGC_CTL_PERPACKET_GAIN (1 << 0)
|
||||
#define RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL (1 << 1)
|
||||
#define RTL818X_TX_AGC_CTL_FEEDBACK_ANT (1 << 2)
|
||||
@ -167,7 +283,8 @@ struct rtl818x_csr {
|
||||
u8 reserved_17[24];
|
||||
u8 CONFIG5;
|
||||
u8 TX_DMA_POLLING;
|
||||
u8 reserved_18[2];
|
||||
u8 PHY_PR;
|
||||
u8 reserved_18;
|
||||
__le16 CWR;
|
||||
u8 RETRY_CTR;
|
||||
u8 reserved_19[3];
|
||||
@ -179,14 +296,59 @@ struct rtl818x_csr {
|
||||
__le32 RDSAR;
|
||||
__le16 TID_AC_MAP;
|
||||
u8 reserved_20[4];
|
||||
u8 ANAPARAM3;
|
||||
u8 reserved_21[5];
|
||||
__le16 FEMR;
|
||||
u8 reserved_22[4];
|
||||
__le16 TALLY_CNT;
|
||||
u8 TALLY_SEL;
|
||||
union {
|
||||
__le16 ANAPARAM3; /* 0xee */
|
||||
u8 ANAPARAM3A; /* for rtl8187 */
|
||||
};
|
||||
|
||||
#define AC_PARAM_TXOP_LIMIT_SHIFT 16
|
||||
#define AC_PARAM_ECW_MAX_SHIFT 12
|
||||
#define AC_PARAM_ECW_MIN_SHIFT 8
|
||||
#define AC_PARAM_AIFS_SHIFT 0
|
||||
|
||||
__le32 AC_VO_PARAM; /* 0xf0 */
|
||||
|
||||
union { /* 0xf4 */
|
||||
__le32 AC_VI_PARAM;
|
||||
__le16 FEMR;
|
||||
} __packed;
|
||||
|
||||
union{ /* 0xf8 */
|
||||
__le32 AC_BE_PARAM; /* rtl8187se */
|
||||
struct{
|
||||
u8 reserved_21[2];
|
||||
__le16 TALLY_CNT; /* 0xfa */
|
||||
} __packed;
|
||||
} __packed;
|
||||
|
||||
union {
|
||||
u8 TALLY_SEL; /* 0xfc */
|
||||
__le32 AC_BK_PARAM;
|
||||
|
||||
} __packed;
|
||||
|
||||
} __packed;
|
||||
|
||||
/* These are addresses with NON-standard usage.
|
||||
* They have offsets very far from this struct.
|
||||
* I don't like to introduce a ton of "reserved"..
|
||||
* They are for RTL8187SE
|
||||
*/
|
||||
#define REG_ADDR1(addr) ((u8 __iomem *)priv->map + addr)
|
||||
#define REG_ADDR2(addr) ((__le16 __iomem *)priv->map + (addr >> 1))
|
||||
#define REG_ADDR4(addr) ((__le32 __iomem *)priv->map + (addr >> 2))
|
||||
|
||||
#define FEMR_SE REG_ADDR2(0x1D4)
|
||||
#define ARFR REG_ADDR2(0x1E0)
|
||||
#define RFSW_CTRL REG_ADDR2(0x272)
|
||||
#define SW_3W_DB0 REG_ADDR2(0x274)
|
||||
#define SW_3W_DB0_4 REG_ADDR4(0x274)
|
||||
#define SW_3W_DB1 REG_ADDR2(0x278)
|
||||
#define SW_3W_DB1_4 REG_ADDR4(0x278)
|
||||
#define SW_3W_CMD1 REG_ADDR1(0x27D)
|
||||
#define PI_DATA_REG REG_ADDR2(0x360)
|
||||
#define SI_DATA_REG REG_ADDR2(0x362)
|
||||
|
||||
struct rtl818x_rf_ops {
|
||||
char *name;
|
||||
void (*init)(struct ieee80211_hw *);
|
||||
|
@ -982,7 +982,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
|
||||
u8 keep_alive = 10;
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw,
|
||||
HW_VAR_KEEP_ALIVE,
|
||||
(u8 *)(&keep_alive));
|
||||
&keep_alive);
|
||||
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw,
|
||||
HW_VAR_H2C_FW_JOINBSSRPT,
|
||||
|
@ -1509,10 +1509,10 @@ static int rtl_pci_tx(struct ieee80211_hw *hw,
|
||||
|
||||
if (rtlpriv->use_new_trx_flow) {
|
||||
rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, true,
|
||||
HW_DESC_OWN, (u8 *)&hw_queue);
|
||||
HW_DESC_OWN, &hw_queue);
|
||||
} else {
|
||||
rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, true,
|
||||
HW_DESC_OWN, (u8 *)&temp_one);
|
||||
HW_DESC_OWN, &temp_one);
|
||||
}
|
||||
|
||||
if ((ring->entries - skb_queue_len(&ring->queue)) < 2 &&
|
||||
@ -1853,6 +1853,65 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev,
|
||||
return true;
|
||||
}
|
||||
|
||||
static int rtl_pci_intr_mode_msi(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
|
||||
struct rtl_pci *rtlpci = rtl_pcidev(pcipriv);
|
||||
int ret;
|
||||
|
||||
ret = pci_enable_msi(rtlpci->pdev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = request_irq(rtlpci->pdev->irq, &_rtl_pci_interrupt,
|
||||
IRQF_SHARED, KBUILD_MODNAME, hw);
|
||||
if (ret < 0) {
|
||||
pci_disable_msi(rtlpci->pdev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
rtlpci->using_msi = true;
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_INIT|COMP_INTR, DBG_DMESG,
|
||||
"MSI Interrupt Mode!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtl_pci_intr_mode_legacy(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
|
||||
struct rtl_pci *rtlpci = rtl_pcidev(pcipriv);
|
||||
int ret;
|
||||
|
||||
ret = request_irq(rtlpci->pdev->irq, &_rtl_pci_interrupt,
|
||||
IRQF_SHARED, KBUILD_MODNAME, hw);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
rtlpci->using_msi = false;
|
||||
RT_TRACE(rtlpriv, COMP_INIT|COMP_INTR, DBG_DMESG,
|
||||
"Pin-based Interrupt Mode!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtl_pci_intr_mode_decide(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
|
||||
struct rtl_pci *rtlpci = rtl_pcidev(pcipriv);
|
||||
int ret;
|
||||
|
||||
if (rtlpci->msi_support) {
|
||||
ret = rtl_pci_intr_mode_msi(hw);
|
||||
if (ret < 0)
|
||||
ret = rtl_pci_intr_mode_legacy(hw);
|
||||
} else {
|
||||
ret = rtl_pci_intr_mode_legacy(hw);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int rtl_pci_probe(struct pci_dev *pdev,
|
||||
const struct pci_device_id *id)
|
||||
{
|
||||
@ -1995,8 +2054,7 @@ int rtl_pci_probe(struct pci_dev *pdev,
|
||||
}
|
||||
|
||||
rtlpci = rtl_pcidev(pcipriv);
|
||||
err = request_irq(rtlpci->pdev->irq, &_rtl_pci_interrupt,
|
||||
IRQF_SHARED, KBUILD_MODNAME, hw);
|
||||
err = rtl_pci_intr_mode_decide(hw);
|
||||
if (err) {
|
||||
RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
|
||||
"%s: failed to register IRQ handler\n",
|
||||
@ -2064,6 +2122,9 @@ void rtl_pci_disconnect(struct pci_dev *pdev)
|
||||
rtlpci->irq_alloc = 0;
|
||||
}
|
||||
|
||||
if (rtlpci->using_msi)
|
||||
pci_disable_msi(rtlpci->pdev);
|
||||
|
||||
list_del(&rtlpriv->list);
|
||||
if (rtlpriv->io.pci_mem_start != 0) {
|
||||
pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start);
|
||||
|
@ -759,7 +759,7 @@ static void rtl_p2p_noa_ie(struct ieee80211_hw *hw, void *data,
|
||||
unsigned int len)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct ieee80211_mgmt *mgmt = (void *)data;
|
||||
struct ieee80211_mgmt *mgmt = data;
|
||||
struct rtl_p2p_ps_info *p2pinfo = &(rtlpriv->psc.p2p_ps_info);
|
||||
u8 *pos, *end, *ie;
|
||||
u16 noa_len;
|
||||
@ -858,7 +858,7 @@ static void rtl_p2p_action_ie(struct ieee80211_hw *hw, void *data,
|
||||
unsigned int len)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct ieee80211_mgmt *mgmt = (void *)data;
|
||||
struct ieee80211_mgmt *mgmt = data;
|
||||
struct rtl_p2p_ps_info *p2pinfo = &(rtlpriv->psc.p2p_ps_info);
|
||||
u8 noa_num, index, i, noa_index = 0;
|
||||
u8 *pos, *end, *ie;
|
||||
@ -950,9 +950,8 @@ void rtl_p2p_ps_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)
|
||||
switch (p2p_ps_state) {
|
||||
case P2P_PS_DISABLE:
|
||||
p2pinfo->p2p_ps_state = p2p_ps_state;
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw,
|
||||
HW_VAR_H2C_FW_P2P_PS_OFFLOAD,
|
||||
(u8 *)(&p2p_ps_state));
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_P2P_PS_OFFLOAD,
|
||||
&p2p_ps_state);
|
||||
|
||||
p2pinfo->noa_index = 0;
|
||||
p2pinfo->ctwindow = 0;
|
||||
@ -964,7 +963,7 @@ void rtl_p2p_ps_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)
|
||||
rtlps->smart_ps = 2;
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw,
|
||||
HW_VAR_H2C_FW_PWRMODE,
|
||||
(u8 *)(&rtlps->pwr_mode));
|
||||
&rtlps->pwr_mode);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -977,12 +976,12 @@ void rtl_p2p_ps_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)
|
||||
rtlps->smart_ps = 0;
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw,
|
||||
HW_VAR_H2C_FW_PWRMODE,
|
||||
(u8 *)(&rtlps->pwr_mode));
|
||||
&rtlps->pwr_mode);
|
||||
}
|
||||
}
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw,
|
||||
HW_VAR_H2C_FW_P2P_PS_OFFLOAD,
|
||||
(u8 *)(&p2p_ps_state));
|
||||
&p2p_ps_state);
|
||||
}
|
||||
break;
|
||||
case P2P_PS_SCAN:
|
||||
@ -992,7 +991,7 @@ void rtl_p2p_ps_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)
|
||||
p2pinfo->p2p_ps_state = p2p_ps_state;
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw,
|
||||
HW_VAR_H2C_FW_P2P_PS_OFFLOAD,
|
||||
(u8 *)(&p2p_ps_state));
|
||||
&p2p_ps_state);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -1012,7 +1011,7 @@ void rtl_p2p_info(struct ieee80211_hw *hw, void *data, unsigned int len)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
|
||||
struct ieee80211_hdr *hdr = (void *)data;
|
||||
struct ieee80211_hdr *hdr = data;
|
||||
|
||||
if (!mac->p2p)
|
||||
return;
|
||||
|
@ -851,9 +851,8 @@ static void rtl88e_dm_check_edca_turbo(struct ieee80211_hw *hw)
|
||||
} else {
|
||||
if (rtlpriv->dm.current_turbo_edca) {
|
||||
u8 tmp = AC0_BE;
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw,
|
||||
HW_VAR_AC_PARAM,
|
||||
(u8 *)(&tmp));
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
|
||||
&tmp);
|
||||
rtlpriv->dm.current_turbo_edca = false;
|
||||
}
|
||||
}
|
||||
|
@ -119,7 +119,7 @@ static void _rtl88e_write_fw(struct ieee80211_hw *hw,
|
||||
enum version_8188e version, u8 *buffer, u32 size)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
u8 *buf_ptr = (u8 *)buffer;
|
||||
u8 *buf_ptr = buffer;
|
||||
u32 page_no, remain;
|
||||
u32 page, offset;
|
||||
|
||||
@ -213,7 +213,7 @@ int rtl88e_download_fw(struct ieee80211_hw *hw, bool buse_wake_on_wlan_fw)
|
||||
return 1;
|
||||
|
||||
pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware;
|
||||
pfwdata = (u8 *)rtlhal->pfirmware;
|
||||
pfwdata = rtlhal->pfirmware;
|
||||
fwsize = rtlhal->fwsize;
|
||||
RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
|
||||
"normal Firmware SIZE %d\n", fwsize);
|
||||
|
@ -147,8 +147,7 @@ static void _rtl88ee_set_fw_clock_on(struct ieee80211_hw *hw,
|
||||
}
|
||||
|
||||
if (IS_IN_LOW_POWER_STATE_88E(rtlhal->fw_ps_state)) {
|
||||
rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_SET_RPWM,
|
||||
(u8 *)(&rpwm_val));
|
||||
rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_SET_RPWM, &rpwm_val);
|
||||
if (FW_PS_IS_ACK(rpwm_val)) {
|
||||
isr_regaddr = REG_HISR;
|
||||
content = rtl_read_dword(rtlpriv, isr_regaddr);
|
||||
@ -225,7 +224,7 @@ static void _rtl88ee_set_fw_clock_off(struct ieee80211_hw *hw,
|
||||
rtlhal->fw_ps_state = FW_PS_STATE(rpwm_val);
|
||||
rtl_write_word(rtlpriv, REG_HISR, 0x0100);
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
|
||||
(u8 *)(&rpwm_val));
|
||||
&rpwm_val);
|
||||
spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
|
||||
rtlhal->fw_clk_change_in_progress = false;
|
||||
spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
|
||||
@ -273,15 +272,14 @@ static void _rtl88ee_fwlps_leave(struct ieee80211_hw *hw)
|
||||
_rtl88ee_set_fw_clock_on(hw, rpwm_val, false);
|
||||
rtlhal->allow_sw_to_change_hwclc = false;
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
|
||||
(u8 *)(&fw_pwrmode));
|
||||
&fw_pwrmode);
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
|
||||
(u8 *)(&fw_current_inps));
|
||||
} else {
|
||||
rpwm_val = FW_PS_STATE_ALL_ON_88E; /* RF on */
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
|
||||
(u8 *)(&rpwm_val));
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, &rpwm_val);
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
|
||||
(u8 *)(&fw_pwrmode));
|
||||
&fw_pwrmode);
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
|
||||
(u8 *)(&fw_current_inps));
|
||||
}
|
||||
@ -300,7 +298,7 @@ static void _rtl88ee_fwlps_enter(struct ieee80211_hw *hw)
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
|
||||
(u8 *)(&fw_current_inps));
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
|
||||
(u8 *)(&ppsc->fwctrl_psmode));
|
||||
&ppsc->fwctrl_psmode);
|
||||
rtlhal->allow_sw_to_change_hwclc = true;
|
||||
_rtl88ee_set_fw_clock_off(hw, rpwm_val);
|
||||
} else {
|
||||
@ -308,9 +306,8 @@ static void _rtl88ee_fwlps_enter(struct ieee80211_hw *hw)
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
|
||||
(u8 *)(&fw_current_inps));
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
|
||||
(u8 *)(&ppsc->fwctrl_psmode));
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
|
||||
(u8 *)(&rpwm_val));
|
||||
&ppsc->fwctrl_psmode);
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, &rpwm_val);
|
||||
}
|
||||
}
|
||||
|
||||
@ -419,12 +416,12 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
|
||||
|
||||
for (e_aci = 0; e_aci < AC_MAX; e_aci++) {
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
|
||||
(u8 *)(&e_aci));
|
||||
&e_aci);
|
||||
}
|
||||
break; }
|
||||
case HW_VAR_ACK_PREAMBLE:{
|
||||
u8 reg_tmp;
|
||||
u8 short_preamble = (bool) (*(u8 *)val);
|
||||
u8 short_preamble = (bool)*val;
|
||||
reg_tmp = rtl_read_byte(rtlpriv, REG_TRXPTCL_CTL+2);
|
||||
if (short_preamble) {
|
||||
reg_tmp |= 0x02;
|
||||
@ -435,13 +432,13 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
|
||||
}
|
||||
break; }
|
||||
case HW_VAR_WPA_CONFIG:
|
||||
rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *)val));
|
||||
rtl_write_byte(rtlpriv, REG_SECCFG, *val);
|
||||
break;
|
||||
case HW_VAR_AMPDU_MIN_SPACE:{
|
||||
u8 min_spacing_to_set;
|
||||
u8 sec_min_space;
|
||||
|
||||
min_spacing_to_set = *((u8 *)val);
|
||||
min_spacing_to_set = *val;
|
||||
if (min_spacing_to_set <= 7) {
|
||||
sec_min_space = 0;
|
||||
|
||||
@ -464,7 +461,7 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
|
||||
case HW_VAR_SHORTGI_DENSITY:{
|
||||
u8 density_to_set;
|
||||
|
||||
density_to_set = *((u8 *)val);
|
||||
density_to_set = *val;
|
||||
mac->min_space_cfg |= (density_to_set << 3);
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
|
||||
@ -482,7 +479,7 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
|
||||
|
||||
reg = regtoset_normal;
|
||||
|
||||
factor = *((u8 *)val);
|
||||
factor = *val;
|
||||
if (factor <= 3) {
|
||||
factor = (1 << (factor + 2));
|
||||
if (factor > 0xf)
|
||||
@ -505,15 +502,15 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
|
||||
}
|
||||
break; }
|
||||
case HW_VAR_AC_PARAM:{
|
||||
u8 e_aci = *((u8 *)val);
|
||||
u8 e_aci = *val;
|
||||
rtl88e_dm_init_edca_turbo(hw);
|
||||
|
||||
if (rtlpci->acm_method != EACMWAY2_SW)
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL,
|
||||
(u8 *)(&e_aci));
|
||||
&e_aci);
|
||||
break; }
|
||||
case HW_VAR_ACM_CTRL:{
|
||||
u8 e_aci = *((u8 *)val);
|
||||
u8 e_aci = *val;
|
||||
union aci_aifsn *p_aci_aifsn =
|
||||
(union aci_aifsn *)(&(mac->ac[0].aifs));
|
||||
u8 acm = p_aci_aifsn->f.acm;
|
||||
@ -566,7 +563,7 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
|
||||
rtlpci->receive_config = ((u32 *)(val))[0];
|
||||
break;
|
||||
case HW_VAR_RETRY_LIMIT:{
|
||||
u8 retry_limit = ((u8 *)(val))[0];
|
||||
u8 retry_limit = *val;
|
||||
|
||||
rtl_write_word(rtlpriv, REG_RL,
|
||||
retry_limit << RETRY_LIMIT_SHORT_SHIFT |
|
||||
@ -579,7 +576,7 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
|
||||
rtlefuse->efuse_usedbytes = *((u16 *)val);
|
||||
break;
|
||||
case HW_VAR_EFUSE_USAGE:
|
||||
rtlefuse->efuse_usedpercentage = *((u8 *)val);
|
||||
rtlefuse->efuse_usedpercentage = *val;
|
||||
break;
|
||||
case HW_VAR_IO_CMD:
|
||||
rtl88e_phy_set_io_cmd(hw, (*(enum io_type *)val));
|
||||
@ -591,15 +588,13 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
|
||||
udelay(1);
|
||||
|
||||
if (rpwm_val & BIT(7)) {
|
||||
rtl_write_byte(rtlpriv, REG_PCIE_HRPWM,
|
||||
(*(u8 *)val));
|
||||
rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, *val);
|
||||
} else {
|
||||
rtl_write_byte(rtlpriv, REG_PCIE_HRPWM,
|
||||
((*(u8 *)val) | BIT(7)));
|
||||
rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, *val | BIT(7));
|
||||
}
|
||||
break; }
|
||||
case HW_VAR_H2C_FW_PWRMODE:
|
||||
rtl88e_set_fw_pwrmode_cmd(hw, (*(u8 *)val));
|
||||
rtl88e_set_fw_pwrmode_cmd(hw, *val);
|
||||
break;
|
||||
case HW_VAR_FW_PSMODE_STATUS:
|
||||
ppsc->fw_current_inpsmode = *((bool *)val);
|
||||
@ -616,7 +611,7 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
|
||||
_rtl88ee_fwlps_leave(hw);
|
||||
break; }
|
||||
case HW_VAR_H2C_FW_JOINBSSRPT:{
|
||||
u8 mstatus = (*(u8 *)val);
|
||||
u8 mstatus = *val;
|
||||
u8 tmp, tmp_reg422, uval;
|
||||
u8 count = 0, dlbcn_count = 0;
|
||||
bool recover = false;
|
||||
@ -667,10 +662,10 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
|
||||
}
|
||||
rtl_write_byte(rtlpriv, REG_CR + 1, (tmp & ~(BIT(0))));
|
||||
}
|
||||
rtl88e_set_fw_joinbss_report_cmd(hw, (*(u8 *)val));
|
||||
rtl88e_set_fw_joinbss_report_cmd(hw, *val);
|
||||
break; }
|
||||
case HW_VAR_H2C_FW_P2P_PS_OFFLOAD:
|
||||
rtl88e_set_p2p_ps_offload_cmd(hw, (*(u8 *)val));
|
||||
rtl88e_set_p2p_ps_offload_cmd(hw, *val);
|
||||
break;
|
||||
case HW_VAR_AID:{
|
||||
u16 u2btmp;
|
||||
@ -680,7 +675,7 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
|
||||
mac->assoc_id));
|
||||
break; }
|
||||
case HW_VAR_CORRECT_TSF:{
|
||||
u8 btype_ibss = ((u8 *)(val))[0];
|
||||
u8 btype_ibss = *val;
|
||||
|
||||
if (btype_ibss == true)
|
||||
_rtl88ee_stop_tx_beacon(hw);
|
||||
@ -1828,7 +1823,7 @@ static void _rtl88ee_read_adapter_info(struct ieee80211_hw *hw)
|
||||
RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
|
||||
"EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid);
|
||||
/*customer ID*/
|
||||
rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID];
|
||||
rtlefuse->eeprom_oemid = hwinfo[EEPROM_CUSTOMER_ID];
|
||||
if (rtlefuse->eeprom_oemid == 0xFF)
|
||||
rtlefuse->eeprom_oemid = 0;
|
||||
|
||||
@ -1845,7 +1840,7 @@ static void _rtl88ee_read_adapter_info(struct ieee80211_hw *hw)
|
||||
RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
|
||||
"dev_addr: %pM\n", rtlefuse->dev_addr);
|
||||
/*channel plan */
|
||||
rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN];
|
||||
rtlefuse->eeprom_channelplan = hwinfo[EEPROM_CHANNELPLAN];
|
||||
/* set channel paln to world wide 13 */
|
||||
rtlefuse->channel_plan = COUNTRY_CODE_WORLD_WIDE_13;
|
||||
/*tx power*/
|
||||
@ -1857,7 +1852,7 @@ static void _rtl88ee_read_adapter_info(struct ieee80211_hw *hw)
|
||||
rtlefuse->autoload_failflag,
|
||||
hwinfo);
|
||||
/*board type*/
|
||||
rtlefuse->board_type = (((*(u8 *)&hwinfo[jj]) & 0xE0) >> 5);
|
||||
rtlefuse->board_type = (hwinfo[jj] & 0xE0) >> 5;
|
||||
/*Wake on wlan*/
|
||||
rtlefuse->wowlan_enable = ((hwinfo[kk] & 0x40) >> 6);
|
||||
/*parse xtal*/
|
||||
@ -2223,8 +2218,7 @@ void rtl88ee_update_channel_access_setting(struct ieee80211_hw *hw)
|
||||
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
|
||||
u16 sifs_timer;
|
||||
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME,
|
||||
(u8 *)&mac->slot_time);
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, &mac->slot_time);
|
||||
if (!mac->ht_enable)
|
||||
sifs_timer = 0x0a0a;
|
||||
else
|
||||
|
@ -93,6 +93,7 @@ int rtl88e_init_sw_vars(struct ieee80211_hw *hw)
|
||||
u8 tid;
|
||||
|
||||
rtl8188ee_bt_reg_init(hw);
|
||||
rtlpci->msi_support = true;
|
||||
|
||||
rtlpriv->dm.dm_initialgain_enable = 1;
|
||||
rtlpriv->dm.dm_flag = 0;
|
||||
|
@ -497,7 +497,7 @@ void rtl88ee_tx_fill_desc(struct ieee80211_hw *hw,
|
||||
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
|
||||
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
|
||||
struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
|
||||
u8 *pdesc = (u8 *)pdesc_tx;
|
||||
u8 *pdesc = pdesc_tx;
|
||||
u16 seq_number;
|
||||
__le16 fc = hdr->frame_control;
|
||||
unsigned int buf_len = 0;
|
||||
@ -716,7 +716,7 @@ void rtl88ee_tx_fill_cmddesc(struct ieee80211_hw *hw,
|
||||
|
||||
SET_TX_DESC_OWN(pdesc, 1);
|
||||
|
||||
SET_TX_DESC_PKT_SIZE((u8 *)pdesc, (u16)(skb->len));
|
||||
SET_TX_DESC_PKT_SIZE(pdesc, (u16)(skb->len));
|
||||
|
||||
SET_TX_DESC_FIRST_SEG(pdesc, 1);
|
||||
SET_TX_DESC_LAST_SEG(pdesc, 1);
|
||||
|
@ -476,7 +476,7 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
|
||||
break;
|
||||
}
|
||||
case HW_VAR_H2C_FW_P2P_PS_OFFLOAD:
|
||||
rtl92c_set_p2p_ps_offload_cmd(hw, (*(u8 *)val));
|
||||
rtl92c_set_p2p_ps_offload_cmd(hw, *val);
|
||||
break;
|
||||
case HW_VAR_AID:{
|
||||
u16 u2btmp;
|
||||
@ -521,21 +521,21 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
|
||||
(u8 *)(&fw_current_inps));
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw,
|
||||
HW_VAR_H2C_FW_PWRMODE,
|
||||
(u8 *)(&ppsc->fwctrl_psmode));
|
||||
&ppsc->fwctrl_psmode);
|
||||
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw,
|
||||
HW_VAR_SET_RPWM,
|
||||
(u8 *)(&rpwm_val));
|
||||
HW_VAR_SET_RPWM,
|
||||
&rpwm_val);
|
||||
} else {
|
||||
rpwm_val = 0x0C; /* RF on */
|
||||
fw_pwrmode = FW_PS_ACTIVE_MODE;
|
||||
fw_current_inps = false;
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw,
|
||||
HW_VAR_SET_RPWM,
|
||||
(u8 *)(&rpwm_val));
|
||||
HW_VAR_SET_RPWM,
|
||||
&rpwm_val);
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw,
|
||||
HW_VAR_H2C_FW_PWRMODE,
|
||||
(u8 *)(&fw_pwrmode));
|
||||
&fw_pwrmode);
|
||||
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw,
|
||||
HW_VAR_FW_PSMODE_STATUS,
|
||||
|
@ -413,20 +413,18 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
|
||||
(u8 *)(&fw_current_inps));
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw,
|
||||
HW_VAR_H2C_FW_PWRMODE,
|
||||
(u8 *)(&ppsc->fwctrl_psmode));
|
||||
&ppsc->fwctrl_psmode);
|
||||
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw,
|
||||
HW_VAR_SET_RPWM,
|
||||
(u8 *)(&rpwm_val));
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
|
||||
&rpwm_val);
|
||||
} else {
|
||||
rpwm_val = 0x0C; /* RF on */
|
||||
fw_pwrmode = FW_PS_ACTIVE_MODE;
|
||||
fw_current_inps = false;
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
|
||||
(u8 *)(&rpwm_val));
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw,
|
||||
HW_VAR_H2C_FW_PWRMODE,
|
||||
(u8 *)(&fw_pwrmode));
|
||||
&rpwm_val);
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
|
||||
&fw_pwrmode);
|
||||
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw,
|
||||
HW_VAR_FW_PSMODE_STATUS,
|
||||
|
@ -647,9 +647,8 @@ static void rtl8723ae_dm_check_edca_turbo(struct ieee80211_hw *hw)
|
||||
} else {
|
||||
if (rtlpriv->dm.current_turbo_edca) {
|
||||
u8 tmp = AC0_BE;
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw,
|
||||
HW_VAR_AC_PARAM,
|
||||
(u8 *) (&tmp));
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
|
||||
&tmp);
|
||||
rtlpriv->dm.current_turbo_edca = false;
|
||||
}
|
||||
}
|
||||
|
@ -207,14 +207,13 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
|
||||
rtl_write_byte(rtlpriv, REG_SLOT, val[0]);
|
||||
|
||||
for (e_aci = 0; e_aci < AC_MAX; e_aci++) {
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw,
|
||||
HW_VAR_AC_PARAM,
|
||||
(u8 *) (&e_aci));
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
|
||||
&e_aci);
|
||||
}
|
||||
break; }
|
||||
case HW_VAR_ACK_PREAMBLE:{
|
||||
u8 reg_tmp;
|
||||
u8 short_preamble = (bool) (*(u8 *) val);
|
||||
u8 short_preamble = (bool)*val;
|
||||
reg_tmp = (mac->cur_40_prime_sc) << 5;
|
||||
if (short_preamble)
|
||||
reg_tmp |= 0x80;
|
||||
@ -225,7 +224,7 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
|
||||
u8 min_spacing_to_set;
|
||||
u8 sec_min_space;
|
||||
|
||||
min_spacing_to_set = *((u8 *) val);
|
||||
min_spacing_to_set = *val;
|
||||
if (min_spacing_to_set <= 7) {
|
||||
sec_min_space = 0;
|
||||
|
||||
@ -249,7 +248,7 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
|
||||
case HW_VAR_SHORTGI_DENSITY:{
|
||||
u8 density_to_set;
|
||||
|
||||
density_to_set = *((u8 *) val);
|
||||
density_to_set = *val;
|
||||
mac->min_space_cfg |= (density_to_set << 3);
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
|
||||
@ -273,7 +272,7 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
|
||||
else
|
||||
p_regtoset = regtoset_normal;
|
||||
|
||||
factor_toset = *((u8 *) val);
|
||||
factor_toset = *val;
|
||||
if (factor_toset <= 3) {
|
||||
factor_toset = (1 << (factor_toset + 2));
|
||||
if (factor_toset > 0xf)
|
||||
@ -304,16 +303,15 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
|
||||
}
|
||||
break; }
|
||||
case HW_VAR_AC_PARAM:{
|
||||
u8 e_aci = *((u8 *) val);
|
||||
u8 e_aci = *val;
|
||||
rtl8723_dm_init_edca_turbo(hw);
|
||||
|
||||
if (rtlpci->acm_method != EACMWAY2_SW)
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw,
|
||||
HW_VAR_ACM_CTRL,
|
||||
(u8 *) (&e_aci));
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL,
|
||||
&e_aci);
|
||||
break; }
|
||||
case HW_VAR_ACM_CTRL:{
|
||||
u8 e_aci = *((u8 *) val);
|
||||
u8 e_aci = *val;
|
||||
union aci_aifsn *p_aci_aifsn =
|
||||
(union aci_aifsn *)(&(mac->ac[0].aifs));
|
||||
u8 acm = p_aci_aifsn->f.acm;
|
||||
@ -366,7 +364,7 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
|
||||
rtlpci->receive_config = ((u32 *) (val))[0];
|
||||
break;
|
||||
case HW_VAR_RETRY_LIMIT:{
|
||||
u8 retry_limit = ((u8 *) (val))[0];
|
||||
u8 retry_limit = *val;
|
||||
|
||||
rtl_write_word(rtlpriv, REG_RL,
|
||||
retry_limit << RETRY_LIMIT_SHORT_SHIFT |
|
||||
@ -379,13 +377,13 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
|
||||
rtlefuse->efuse_usedbytes = *((u16 *) val);
|
||||
break;
|
||||
case HW_VAR_EFUSE_USAGE:
|
||||
rtlefuse->efuse_usedpercentage = *((u8 *) val);
|
||||
rtlefuse->efuse_usedpercentage = *val;
|
||||
break;
|
||||
case HW_VAR_IO_CMD:
|
||||
rtl8723ae_phy_set_io_cmd(hw, (*(enum io_type *)val));
|
||||
break;
|
||||
case HW_VAR_WPA_CONFIG:
|
||||
rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *) val));
|
||||
rtl_write_byte(rtlpriv, REG_SECCFG, *val);
|
||||
break;
|
||||
case HW_VAR_SET_RPWM:{
|
||||
u8 rpwm_val;
|
||||
@ -394,27 +392,25 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
|
||||
udelay(1);
|
||||
|
||||
if (rpwm_val & BIT(7)) {
|
||||
rtl_write_byte(rtlpriv, REG_PCIE_HRPWM,
|
||||
(*(u8 *) val));
|
||||
rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, *val);
|
||||
} else {
|
||||
rtl_write_byte(rtlpriv, REG_PCIE_HRPWM,
|
||||
((*(u8 *) val) | BIT(7)));
|
||||
rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, *val | BIT(7));
|
||||
}
|
||||
|
||||
break; }
|
||||
case HW_VAR_H2C_FW_PWRMODE:{
|
||||
u8 psmode = (*(u8 *) val);
|
||||
u8 psmode = *val;
|
||||
|
||||
if (psmode != FW_PS_ACTIVE_MODE)
|
||||
rtl8723ae_dm_rf_saving(hw, true);
|
||||
|
||||
rtl8723ae_set_fw_pwrmode_cmd(hw, (*(u8 *) val));
|
||||
rtl8723ae_set_fw_pwrmode_cmd(hw, *val);
|
||||
break; }
|
||||
case HW_VAR_FW_PSMODE_STATUS:
|
||||
ppsc->fw_current_inpsmode = *((bool *) val);
|
||||
break;
|
||||
case HW_VAR_H2C_FW_JOINBSSRPT:{
|
||||
u8 mstatus = (*(u8 *) val);
|
||||
u8 mstatus = *val;
|
||||
u8 tmp_regcr, tmp_reg422;
|
||||
bool recover = false;
|
||||
|
||||
@ -447,11 +443,11 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
|
||||
rtl_write_byte(rtlpriv, REG_CR + 1,
|
||||
(tmp_regcr & ~(BIT(0))));
|
||||
}
|
||||
rtl8723ae_set_fw_joinbss_report_cmd(hw, (*(u8 *) val));
|
||||
rtl8723ae_set_fw_joinbss_report_cmd(hw, *val);
|
||||
|
||||
break; }
|
||||
case HW_VAR_H2C_FW_P2P_PS_OFFLOAD:
|
||||
rtl8723ae_set_p2p_ps_offload_cmd(hw, (*(u8 *)val));
|
||||
rtl8723ae_set_p2p_ps_offload_cmd(hw, *val);
|
||||
break;
|
||||
case HW_VAR_AID:{
|
||||
u16 u2btmp;
|
||||
@ -461,7 +457,7 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
|
||||
mac->assoc_id));
|
||||
break; }
|
||||
case HW_VAR_CORRECT_TSF:{
|
||||
u8 btype_ibss = ((u8 *) (val))[0];
|
||||
u8 btype_ibss = *val;
|
||||
|
||||
if (btype_ibss == true)
|
||||
_rtl8723ae_stop_tx_beacon(hw);
|
||||
@ -491,20 +487,18 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
|
||||
(u8 *)(&fw_current_inps));
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw,
|
||||
HW_VAR_H2C_FW_PWRMODE,
|
||||
(u8 *)(&ppsc->fwctrl_psmode));
|
||||
&ppsc->fwctrl_psmode);
|
||||
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw,
|
||||
HW_VAR_SET_RPWM,
|
||||
(u8 *)(&rpwm_val));
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
|
||||
&rpwm_val);
|
||||
} else {
|
||||
rpwm_val = 0x0C; /* RF on */
|
||||
fw_pwrmode = FW_PS_ACTIVE_MODE;
|
||||
fw_current_inps = false;
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
|
||||
(u8 *)(&rpwm_val));
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw,
|
||||
HW_VAR_H2C_FW_PWRMODE,
|
||||
(u8 *)(&fw_pwrmode));
|
||||
&rpwm_val);
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
|
||||
&fw_pwrmode);
|
||||
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw,
|
||||
HW_VAR_FW_PSMODE_STATUS,
|
||||
@ -1628,10 +1622,10 @@ static void _rtl8723ae_read_adapter_info(struct ieee80211_hw *hw,
|
||||
rtl8723ae_read_bt_coexist_info_from_hwpg(hw,
|
||||
rtlefuse->autoload_failflag, hwinfo);
|
||||
|
||||
rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN];
|
||||
rtlefuse->eeprom_channelplan = hwinfo[EEPROM_CHANNELPLAN];
|
||||
rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION];
|
||||
rtlefuse->txpwr_fromeprom = true;
|
||||
rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID];
|
||||
rtlefuse->eeprom_oemid = hwinfo[EEPROM_CUSTOMER_ID];
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
|
||||
"EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid);
|
||||
@ -2051,8 +2045,7 @@ void rtl8723ae_update_channel_access_setting(struct ieee80211_hw *hw)
|
||||
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
|
||||
u16 sifs_timer;
|
||||
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME,
|
||||
(u8 *)&mac->slot_time);
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, &mac->slot_time);
|
||||
if (!mac->ht_enable)
|
||||
sifs_timer = 0x0a0a;
|
||||
else
|
||||
|
@ -375,7 +375,7 @@ void rtl8723ae_tx_fill_desc(struct ieee80211_hw *hw,
|
||||
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
|
||||
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
|
||||
bool defaultadapter = true;
|
||||
u8 *pdesc = (u8 *) pdesc_tx;
|
||||
u8 *pdesc = pdesc_tx;
|
||||
u16 seq_number;
|
||||
__le16 fc = hdr->frame_control;
|
||||
u8 fw_qsel = _rtl8723ae_map_hwqueue_to_fwqueue(skb, hw_queue);
|
||||
@ -577,7 +577,7 @@ void rtl8723ae_tx_fill_cmddesc(struct ieee80211_hw *hw,
|
||||
|
||||
SET_TX_DESC_OWN(pdesc, 1);
|
||||
|
||||
SET_TX_DESC_PKT_SIZE((u8 *) pdesc, (u16) (skb->len));
|
||||
SET_TX_DESC_PKT_SIZE(pdesc, (u16) (skb->len));
|
||||
|
||||
SET_TX_DESC_FIRST_SEG(pdesc, 1);
|
||||
SET_TX_DESC_LAST_SEG(pdesc, 1);
|
||||
|
@ -1083,7 +1083,7 @@ static void rtl8723be_dm_check_edca_turbo(struct ieee80211_hw *hw)
|
||||
if (rtlpriv->dm.current_turbo_edca) {
|
||||
u8 tmp = AC0_BE;
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
|
||||
(u8 *)(&tmp));
|
||||
&tmp);
|
||||
}
|
||||
rtlpriv->dm.current_turbo_edca = false;
|
||||
}
|
||||
|
@ -147,7 +147,7 @@ static void _rtl8723be_set_fw_clock_on(struct ieee80211_hw *hw, u8 rpwm_val,
|
||||
}
|
||||
if (IS_IN_LOW_POWER_STATE_88E(rtlhal->fw_ps_state)) {
|
||||
rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_SET_RPWM,
|
||||
(u8 *)(&rpwm_val));
|
||||
&rpwm_val);
|
||||
if (FW_PS_IS_ACK(rpwm_val)) {
|
||||
isr_regaddr = REG_HISR;
|
||||
content = rtl_read_dword(rtlpriv, isr_regaddr);
|
||||
@ -221,7 +221,7 @@ static void _rtl8723be_set_fw_clock_off(struct ieee80211_hw *hw, u8 rpwm_val)
|
||||
rtlhal->fw_ps_state = FW_PS_STATE(rpwm_val);
|
||||
rtl_write_word(rtlpriv, REG_HISR, 0x0100);
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
|
||||
(u8 *)(&rpwm_val));
|
||||
&rpwm_val);
|
||||
spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
|
||||
rtlhal->fw_clk_change_in_progress = false;
|
||||
spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
|
||||
@ -253,15 +253,14 @@ static void _rtl8723be_fwlps_leave(struct ieee80211_hw *hw)
|
||||
_rtl8723be_set_fw_clock_on(hw, rpwm_val, false);
|
||||
rtlhal->allow_sw_to_change_hwclc = false;
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
|
||||
(u8 *)(&fw_pwrmode));
|
||||
&fw_pwrmode);
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
|
||||
(u8 *)(&fw_current_inps));
|
||||
} else {
|
||||
rpwm_val = FW_PS_STATE_ALL_ON_88E; /* RF on */
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
|
||||
(u8 *)(&rpwm_val));
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, &rpwm_val);
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
|
||||
(u8 *)(&fw_pwrmode));
|
||||
&fw_pwrmode);
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
|
||||
(u8 *)(&fw_current_inps));
|
||||
}
|
||||
@ -280,7 +279,7 @@ static void _rtl8723be_fwlps_enter(struct ieee80211_hw *hw)
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
|
||||
(u8 *)(&fw_current_inps));
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
|
||||
(u8 *)(&ppsc->fwctrl_psmode));
|
||||
&ppsc->fwctrl_psmode);
|
||||
rtlhal->allow_sw_to_change_hwclc = true;
|
||||
_rtl8723be_set_fw_clock_off(hw, rpwm_val);
|
||||
|
||||
@ -289,9 +288,8 @@ static void _rtl8723be_fwlps_enter(struct ieee80211_hw *hw)
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
|
||||
(u8 *)(&fw_current_inps));
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
|
||||
(u8 *)(&ppsc->fwctrl_psmode));
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
|
||||
(u8 *)(&rpwm_val));
|
||||
&ppsc->fwctrl_psmode);
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, &rpwm_val);
|
||||
}
|
||||
}
|
||||
|
||||
@ -400,12 +398,12 @@ void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
|
||||
|
||||
for (e_aci = 0; e_aci < AC_MAX; e_aci++) {
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
|
||||
(u8 *)(&e_aci));
|
||||
&e_aci);
|
||||
}
|
||||
break; }
|
||||
case HW_VAR_ACK_PREAMBLE: {
|
||||
u8 reg_tmp;
|
||||
u8 short_preamble = (bool) (*(u8 *)val);
|
||||
u8 short_preamble = (bool)*val;
|
||||
reg_tmp = rtl_read_byte(rtlpriv, REG_TRXPTCL_CTL + 2);
|
||||
if (short_preamble) {
|
||||
reg_tmp |= 0x02;
|
||||
@ -416,13 +414,13 @@ void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
|
||||
}
|
||||
break; }
|
||||
case HW_VAR_WPA_CONFIG:
|
||||
rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *)val));
|
||||
rtl_write_byte(rtlpriv, REG_SECCFG, *val);
|
||||
break;
|
||||
case HW_VAR_AMPDU_MIN_SPACE: {
|
||||
u8 min_spacing_to_set;
|
||||
u8 sec_min_space;
|
||||
|
||||
min_spacing_to_set = *((u8 *)val);
|
||||
min_spacing_to_set = *val;
|
||||
if (min_spacing_to_set <= 7) {
|
||||
sec_min_space = 0;
|
||||
|
||||
@ -445,7 +443,7 @@ void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
|
||||
case HW_VAR_SHORTGI_DENSITY: {
|
||||
u8 density_to_set;
|
||||
|
||||
density_to_set = *((u8 *)val);
|
||||
density_to_set = *val;
|
||||
mac->min_space_cfg |= (density_to_set << 3);
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
|
||||
@ -463,7 +461,7 @@ void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
|
||||
|
||||
p_regtoset = regtoset_normal;
|
||||
|
||||
factor_toset = *((u8 *)val);
|
||||
factor_toset = *val;
|
||||
if (factor_toset <= 3) {
|
||||
factor_toset = (1 << (factor_toset + 2));
|
||||
if (factor_toset > 0xf)
|
||||
@ -491,15 +489,15 @@ void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
|
||||
}
|
||||
break; }
|
||||
case HW_VAR_AC_PARAM: {
|
||||
u8 e_aci = *((u8 *)val);
|
||||
u8 e_aci = *val;
|
||||
rtl8723_dm_init_edca_turbo(hw);
|
||||
|
||||
if (rtlpci->acm_method != EACMWAY2_SW)
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL,
|
||||
(u8 *)(&e_aci));
|
||||
&e_aci);
|
||||
break; }
|
||||
case HW_VAR_ACM_CTRL: {
|
||||
u8 e_aci = *((u8 *)val);
|
||||
u8 e_aci = *val;
|
||||
union aci_aifsn *p_aci_aifsn =
|
||||
(union aci_aifsn *)(&(mac->ac[0].aifs));
|
||||
u8 acm = p_aci_aifsn->f.acm;
|
||||
@ -552,7 +550,7 @@ void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
|
||||
rtlpci->receive_config = ((u32 *)(val))[0];
|
||||
break;
|
||||
case HW_VAR_RETRY_LIMIT: {
|
||||
u8 retry_limit = ((u8 *)(val))[0];
|
||||
u8 retry_limit = *val;
|
||||
|
||||
rtl_write_word(rtlpriv, REG_RL,
|
||||
retry_limit << RETRY_LIMIT_SHORT_SHIFT |
|
||||
@ -565,7 +563,7 @@ void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
|
||||
rtlefuse->efuse_usedbytes = *((u16 *)val);
|
||||
break;
|
||||
case HW_VAR_EFUSE_USAGE:
|
||||
rtlefuse->efuse_usedpercentage = *((u8 *)val);
|
||||
rtlefuse->efuse_usedpercentage = *val;
|
||||
break;
|
||||
case HW_VAR_IO_CMD:
|
||||
rtl8723be_phy_set_io_cmd(hw, (*(enum io_type *)val));
|
||||
@ -577,14 +575,13 @@ void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
|
||||
udelay(1);
|
||||
|
||||
if (rpwm_val & BIT(7)) {
|
||||
rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, (*(u8 *)val));
|
||||
rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, *val);
|
||||
} else {
|
||||
rtl_write_byte(rtlpriv, REG_PCIE_HRPWM,
|
||||
((*(u8 *)val) | BIT(7)));
|
||||
rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, *val | BIT(7));
|
||||
}
|
||||
break; }
|
||||
case HW_VAR_H2C_FW_PWRMODE:
|
||||
rtl8723be_set_fw_pwrmode_cmd(hw, (*(u8 *)val));
|
||||
rtl8723be_set_fw_pwrmode_cmd(hw, *val);
|
||||
break;
|
||||
case HW_VAR_FW_PSMODE_STATUS:
|
||||
ppsc->fw_current_inpsmode = *((bool *)val);
|
||||
@ -602,7 +599,7 @@ void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
|
||||
|
||||
break; }
|
||||
case HW_VAR_H2C_FW_JOINBSSRPT: {
|
||||
u8 mstatus = (*(u8 *)val);
|
||||
u8 mstatus = *val;
|
||||
u8 tmp_regcr, tmp_reg422, bcnvalid_reg;
|
||||
u8 count = 0, dlbcn_count = 0;
|
||||
bool recover = false;
|
||||
@ -657,10 +654,10 @@ void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
|
||||
rtl_write_byte(rtlpriv, REG_CR + 1,
|
||||
(tmp_regcr & ~(BIT(0))));
|
||||
}
|
||||
rtl8723be_set_fw_joinbss_report_cmd(hw, (*(u8 *)val));
|
||||
rtl8723be_set_fw_joinbss_report_cmd(hw, *val);
|
||||
break; }
|
||||
case HW_VAR_H2C_FW_P2P_PS_OFFLOAD:
|
||||
rtl8723be_set_p2p_ps_offload_cmd(hw, (*(u8 *)val));
|
||||
rtl8723be_set_p2p_ps_offload_cmd(hw, *val);
|
||||
break;
|
||||
case HW_VAR_AID: {
|
||||
u16 u2btmp;
|
||||
@ -670,7 +667,7 @@ void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
|
||||
(u2btmp | mac->assoc_id));
|
||||
break; }
|
||||
case HW_VAR_CORRECT_TSF: {
|
||||
u8 btype_ibss = ((u8 *)(val))[0];
|
||||
u8 btype_ibss = *val;
|
||||
|
||||
if (btype_ibss)
|
||||
_rtl8723be_stop_tx_beacon(hw);
|
||||
@ -690,7 +687,7 @@ void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
|
||||
case HW_VAR_KEEP_ALIVE: {
|
||||
u8 array[2];
|
||||
array[0] = 0xff;
|
||||
array[1] = *((u8 *)val);
|
||||
array[1] = *val;
|
||||
rtl8723be_fill_h2c_cmd(hw, H2C_8723BE_KEEP_ALIVE_CTRL,
|
||||
2, array);
|
||||
break; }
|
||||
@ -1783,10 +1780,10 @@ static void _rtl8723be_read_adapter_info(struct ieee80211_hw *hw,
|
||||
rtlefuse->autoload_failflag,
|
||||
hwinfo);
|
||||
|
||||
rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN];
|
||||
rtlefuse->eeprom_channelplan = hwinfo[EEPROM_CHANNELPLAN];
|
||||
rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION];
|
||||
rtlefuse->txpwr_fromeprom = true;
|
||||
rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID];
|
||||
rtlefuse->eeprom_oemid = hwinfo[EEPROM_CUSTOMER_ID];
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
|
||||
"EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid);
|
||||
@ -2252,8 +2249,7 @@ void rtl8723be_update_channel_access_setting(struct ieee80211_hw *hw)
|
||||
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
|
||||
u16 sifs_timer;
|
||||
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME,
|
||||
(u8 *)&mac->slot_time);
|
||||
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, &mac->slot_time);
|
||||
if (!mac->ht_enable)
|
||||
sifs_timer = 0x0a0a;
|
||||
else
|
||||
|
@ -647,7 +647,7 @@ void rtl8723be_tx_fill_desc(struct ieee80211_hw *hw,
|
||||
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
|
||||
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
|
||||
struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
|
||||
u8 *pdesc = (u8 *)pdesc_tx;
|
||||
u8 *pdesc = pdesc_tx;
|
||||
u16 seq_number;
|
||||
__le16 fc = hdr->frame_control;
|
||||
unsigned int buf_len = 0;
|
||||
@ -850,7 +850,7 @@ void rtl8723be_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
|
||||
|
||||
SET_TX_DESC_OWN(pdesc, 1);
|
||||
|
||||
SET_TX_DESC_PKT_SIZE((u8 *)pdesc, (u16)(skb->len));
|
||||
SET_TX_DESC_PKT_SIZE(pdesc, (u16)(skb->len));
|
||||
|
||||
SET_TX_DESC_FIRST_SEG(pdesc, 1);
|
||||
SET_TX_DESC_LAST_SEG(pdesc, 1);
|
||||
|
@ -115,7 +115,7 @@ void rtl8723_write_fw(struct ieee80211_hw *hw,
|
||||
u8 *buffer, u32 size)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
u8 *bufferptr = (u8 *)buffer;
|
||||
u8 *bufferptr = buffer;
|
||||
u32 pagenums, remainsize;
|
||||
u32 page, offset;
|
||||
|
||||
@ -257,7 +257,7 @@ int rtl8723_download_fw(struct ieee80211_hw *hw,
|
||||
return 1;
|
||||
|
||||
pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware;
|
||||
pfwdata = (u8 *)rtlhal->pfirmware;
|
||||
pfwdata = rtlhal->pfirmware;
|
||||
fwsize = rtlhal->fwsize;
|
||||
RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
|
||||
"normal Firmware SIZE %d\n", fwsize);
|
||||
|
@ -189,6 +189,7 @@ struct hci_dev {
|
||||
__u16 page_scan_window;
|
||||
__u8 page_scan_type;
|
||||
__u8 le_adv_channel_map;
|
||||
__u8 le_scan_type;
|
||||
__u16 le_scan_interval;
|
||||
__u16 le_scan_window;
|
||||
__u16 le_conn_min_interval;
|
||||
@ -1236,7 +1237,7 @@ void mgmt_pin_code_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
|
||||
void mgmt_pin_code_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
|
||||
u8 status);
|
||||
int mgmt_user_confirm_request(struct hci_dev *hdev, bdaddr_t *bdaddr,
|
||||
u8 link_type, u8 addr_type, __le32 value,
|
||||
u8 link_type, u8 addr_type, u32 value,
|
||||
u8 confirm_hint);
|
||||
int mgmt_user_confirm_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
|
||||
u8 link_type, u8 addr_type, u8 status);
|
||||
|
@ -199,6 +199,8 @@ static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
memset(hdev->scan_rsp_data, 0, sizeof(hdev->scan_rsp_data));
|
||||
hdev->scan_rsp_data_len = 0;
|
||||
|
||||
hdev->le_scan_type = LE_SCAN_PASSIVE;
|
||||
|
||||
hdev->ssp_debug_mode = 0;
|
||||
}
|
||||
|
||||
@ -997,6 +999,25 @@ static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
hci_dev_unlock(hdev);
|
||||
}
|
||||
|
||||
static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
{
|
||||
struct hci_cp_le_set_scan_param *cp;
|
||||
__u8 status = *((__u8 *) skb->data);
|
||||
|
||||
BT_DBG("%s status 0x%2.2x", hdev->name, status);
|
||||
|
||||
cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_PARAM);
|
||||
if (!cp)
|
||||
return;
|
||||
|
||||
hci_dev_lock(hdev);
|
||||
|
||||
if (!status)
|
||||
hdev->le_scan_type = cp->type;
|
||||
|
||||
hci_dev_unlock(hdev);
|
||||
}
|
||||
|
||||
static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
@ -1704,6 +1725,36 @@ unlock:
|
||||
hci_dev_unlock(hdev);
|
||||
}
|
||||
|
||||
static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
|
||||
{
|
||||
struct hci_cp_le_start_enc *cp;
|
||||
struct hci_conn *conn;
|
||||
|
||||
BT_DBG("%s status 0x%2.2x", hdev->name, status);
|
||||
|
||||
if (!status)
|
||||
return;
|
||||
|
||||
hci_dev_lock(hdev);
|
||||
|
||||
cp = hci_sent_cmd_data(hdev, HCI_OP_LE_START_ENC);
|
||||
if (!cp)
|
||||
goto unlock;
|
||||
|
||||
conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
|
||||
if (!conn)
|
||||
goto unlock;
|
||||
|
||||
if (conn->state != BT_CONNECTED)
|
||||
goto unlock;
|
||||
|
||||
hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
|
||||
hci_conn_drop(conn);
|
||||
|
||||
unlock:
|
||||
hci_dev_unlock(hdev);
|
||||
}
|
||||
|
||||
static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
{
|
||||
__u8 status = *((__u8 *) skb->data);
|
||||
@ -2488,6 +2539,10 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
hci_cc_le_set_adv_enable(hdev, skb);
|
||||
break;
|
||||
|
||||
case HCI_OP_LE_SET_SCAN_PARAM:
|
||||
hci_cc_le_set_scan_param(hdev, skb);
|
||||
break;
|
||||
|
||||
case HCI_OP_LE_SET_SCAN_ENABLE:
|
||||
hci_cc_le_set_scan_enable(hdev, skb);
|
||||
break;
|
||||
@ -2611,6 +2666,10 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
hci_cs_le_create_conn(hdev, ev->status);
|
||||
break;
|
||||
|
||||
case HCI_OP_LE_START_ENC:
|
||||
hci_cs_le_start_enc(hdev, ev->status);
|
||||
break;
|
||||
|
||||
default:
|
||||
BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
|
||||
break;
|
||||
@ -3459,8 +3518,8 @@ static void hci_user_confirm_request_evt(struct hci_dev *hdev,
|
||||
}
|
||||
|
||||
confirm:
|
||||
mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey,
|
||||
confirm_hint);
|
||||
mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0,
|
||||
le32_to_cpu(ev->passkey), confirm_hint);
|
||||
|
||||
unlock:
|
||||
hci_dev_unlock(hdev);
|
||||
|
@ -360,7 +360,8 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr,
|
||||
|
||||
BT_DBG("sock %p, sk %p", sock, sk);
|
||||
|
||||
if (peer && sk->sk_state != BT_CONNECTED)
|
||||
if (peer && sk->sk_state != BT_CONNECTED &&
|
||||
sk->sk_state != BT_CONNECT && sk->sk_state != BT_CONNECT2)
|
||||
return -ENOTCONN;
|
||||
|
||||
memset(la, 0, sizeof(struct sockaddr_l2));
|
||||
|
@ -2762,23 +2762,11 @@ static struct pending_cmd *find_pairing(struct hci_conn *conn)
|
||||
|
||||
static void pairing_complete(struct pending_cmd *cmd, u8 status)
|
||||
{
|
||||
const struct mgmt_cp_pair_device *cp = cmd->param;
|
||||
struct mgmt_rp_pair_device rp;
|
||||
struct hci_conn *conn = cmd->user_data;
|
||||
|
||||
/* If we had a pairing failure we might have already received
|
||||
* the remote Identity Address Information and updated the
|
||||
* hci_conn variables with it, however we would not yet have
|
||||
* notified user space of the resolved identity. Therefore, use
|
||||
* the address given in the Pair Device command in case the
|
||||
* pairing failed.
|
||||
*/
|
||||
if (status) {
|
||||
memcpy(&rp.addr, &cp->addr, sizeof(rp.addr));
|
||||
} else {
|
||||
bacpy(&rp.addr.bdaddr, &conn->dst);
|
||||
rp.addr.type = link_to_bdaddr(conn->type, conn->dst_type);
|
||||
}
|
||||
bacpy(&rp.addr.bdaddr, &conn->dst);
|
||||
rp.addr.type = link_to_bdaddr(conn->type, conn->dst_type);
|
||||
|
||||
cmd_complete(cmd->sk, cmd->index, MGMT_OP_PAIR_DEVICE, status,
|
||||
&rp, sizeof(rp));
|
||||
@ -5338,7 +5326,7 @@ void mgmt_pin_code_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
|
||||
}
|
||||
|
||||
int mgmt_user_confirm_request(struct hci_dev *hdev, bdaddr_t *bdaddr,
|
||||
u8 link_type, u8 addr_type, __le32 value,
|
||||
u8 link_type, u8 addr_type, u32 value,
|
||||
u8 confirm_hint)
|
||||
{
|
||||
struct mgmt_ev_user_confirm_request ev;
|
||||
@ -5348,7 +5336,7 @@ int mgmt_user_confirm_request(struct hci_dev *hdev, bdaddr_t *bdaddr,
|
||||
bacpy(&ev.addr.bdaddr, bdaddr);
|
||||
ev.addr.type = link_to_bdaddr(link_type, addr_type);
|
||||
ev.confirm_hint = confirm_hint;
|
||||
ev.value = value;
|
||||
ev.value = cpu_to_le32(value);
|
||||
|
||||
return mgmt_event(MGMT_EV_USER_CONFIRM_REQUEST, hdev, &ev, sizeof(ev),
|
||||
NULL);
|
||||
|
@ -534,7 +534,8 @@ static int rfcomm_sock_getname(struct socket *sock, struct sockaddr *addr, int *
|
||||
|
||||
BT_DBG("sock %p, sk %p", sock, sk);
|
||||
|
||||
if (peer && sk->sk_state != BT_CONNECTED)
|
||||
if (peer && sk->sk_state != BT_CONNECTED &&
|
||||
sk->sk_state != BT_CONNECT && sk->sk_state != BT_CONNECT2)
|
||||
return -ENOTCONN;
|
||||
|
||||
memset(sa, 0, sizeof(*sa));
|
||||
|
@ -387,6 +387,11 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
|
||||
if (!(auth & SMP_AUTH_BONDING) && method == JUST_CFM)
|
||||
method = JUST_WORKS;
|
||||
|
||||
/* Don't confirm locally initiated pairing attempts */
|
||||
if (method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR,
|
||||
&smp->smp_flags))
|
||||
method = JUST_WORKS;
|
||||
|
||||
/* If Just Works, Continue with Zero TK */
|
||||
if (method == JUST_WORKS) {
|
||||
set_bit(SMP_FLAG_TK_VALID, &smp->smp_flags);
|
||||
@ -422,10 +427,14 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
|
||||
if (method == REQ_PASSKEY)
|
||||
ret = mgmt_user_passkey_request(hcon->hdev, &hcon->dst,
|
||||
hcon->type, hcon->dst_type);
|
||||
else if (method == JUST_CFM)
|
||||
ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst,
|
||||
hcon->type, hcon->dst_type,
|
||||
passkey, 1);
|
||||
else
|
||||
ret = mgmt_user_passkey_notify(hcon->hdev, &hcon->dst,
|
||||
hcon->type, hcon->dst_type,
|
||||
cpu_to_le32(passkey), 0);
|
||||
passkey, 0);
|
||||
|
||||
hci_dev_unlock(hcon->hdev);
|
||||
|
||||
@ -547,20 +556,6 @@ error:
|
||||
smp_failure(conn, reason);
|
||||
}
|
||||
|
||||
static void smp_reencrypt(struct work_struct *work)
|
||||
{
|
||||
struct smp_chan *smp = container_of(work, struct smp_chan,
|
||||
reencrypt.work);
|
||||
struct l2cap_conn *conn = smp->conn;
|
||||
struct hci_conn *hcon = conn->hcon;
|
||||
struct smp_ltk *ltk = smp->ltk;
|
||||
|
||||
BT_DBG("");
|
||||
|
||||
hci_le_start_enc(hcon, ltk->ediv, ltk->rand, ltk->val);
|
||||
hcon->enc_key_size = ltk->enc_size;
|
||||
}
|
||||
|
||||
static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
|
||||
{
|
||||
struct smp_chan *smp;
|
||||
@ -571,7 +566,6 @@ static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
|
||||
|
||||
INIT_WORK(&smp->confirm, confirm_work);
|
||||
INIT_WORK(&smp->random, random_work);
|
||||
INIT_DELAYED_WORK(&smp->reencrypt, smp_reencrypt);
|
||||
|
||||
smp->conn = conn;
|
||||
conn->smp_chan = smp;
|
||||
@ -589,8 +583,6 @@ void smp_chan_destroy(struct l2cap_conn *conn)
|
||||
|
||||
BUG_ON(!smp);
|
||||
|
||||
cancel_delayed_work_sync(&smp->reencrypt);
|
||||
|
||||
complete = test_bit(SMP_FLAG_COMPLETE, &smp->smp_flags);
|
||||
mgmt_smp_complete(conn->hcon, complete);
|
||||
|
||||
@ -712,6 +704,8 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
|
||||
if (ret)
|
||||
return SMP_UNSPECIFIED;
|
||||
|
||||
clear_bit(SMP_FLAG_INITIATOR, &smp->smp_flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -867,6 +861,8 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
|
||||
|
||||
smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
|
||||
|
||||
clear_bit(SMP_FLAG_INITIATOR, &smp->smp_flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -884,11 +880,15 @@ bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level)
|
||||
int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
|
||||
{
|
||||
struct l2cap_conn *conn = hcon->l2cap_data;
|
||||
struct smp_chan *smp = conn->smp_chan;
|
||||
struct smp_chan *smp;
|
||||
__u8 authreq;
|
||||
|
||||
BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level);
|
||||
|
||||
/* This may be NULL if there's an unexpected disconnection */
|
||||
if (!conn)
|
||||
return 1;
|
||||
|
||||
if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags))
|
||||
return 1;
|
||||
|
||||
@ -928,6 +928,8 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
|
||||
smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
|
||||
}
|
||||
|
||||
set_bit(SMP_FLAG_INITIATOR, &smp->smp_flags);
|
||||
|
||||
done:
|
||||
hcon->pending_sec_level = sec_level;
|
||||
|
||||
@ -1058,12 +1060,6 @@ static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
|
||||
smp->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr,
|
||||
smp->id_addr_type, smp->irk, &rpa);
|
||||
|
||||
/* Track the connection based on the Identity Address from now on */
|
||||
bacpy(&hcon->dst, &smp->id_addr);
|
||||
hcon->dst_type = smp->id_addr_type;
|
||||
|
||||
l2cap_conn_update_id_addr(hcon);
|
||||
|
||||
smp_distribute_keys(conn);
|
||||
|
||||
return 0;
|
||||
@ -1214,8 +1210,16 @@ static void smp_notify_keys(struct l2cap_conn *conn)
|
||||
struct smp_cmd_pairing *rsp = (void *) &smp->prsp[1];
|
||||
bool persistent;
|
||||
|
||||
if (smp->remote_irk)
|
||||
if (smp->remote_irk) {
|
||||
mgmt_new_irk(hdev, smp->remote_irk);
|
||||
/* Now that user space can be considered to know the
|
||||
* identity address track the connection based on it
|
||||
* from now on.
|
||||
*/
|
||||
bacpy(&hcon->dst, &smp->remote_irk->bdaddr);
|
||||
hcon->dst_type = smp->remote_irk->addr_type;
|
||||
l2cap_conn_update_id_addr(hcon);
|
||||
}
|
||||
|
||||
/* The LTKs and CSRKs should be persistent only if both sides
|
||||
* had the bonding bit set in their authentication requests.
|
||||
@ -1253,7 +1257,6 @@ int smp_distribute_keys(struct l2cap_conn *conn)
|
||||
struct smp_chan *smp = conn->smp_chan;
|
||||
struct hci_conn *hcon = conn->hcon;
|
||||
struct hci_dev *hdev = hcon->hdev;
|
||||
bool ltk_encrypt;
|
||||
__u8 *keydist;
|
||||
|
||||
BT_DBG("conn %p", conn);
|
||||
@ -1353,32 +1356,12 @@ int smp_distribute_keys(struct l2cap_conn *conn)
|
||||
if ((smp->remote_key_dist & 0x07))
|
||||
return 0;
|
||||
|
||||
/* Check if we should try to re-encrypt the link with the LTK.
|
||||
* SMP_FLAG_LTK_ENCRYPT flag is used to track whether we've
|
||||
* already tried this (in which case we shouldn't try again).
|
||||
*
|
||||
* The request will trigger an encryption key refresh event
|
||||
* which will cause a call to auth_cfm and eventually lead to
|
||||
* l2cap_core.c calling this smp_distribute_keys function again
|
||||
* and thereby completing the process.
|
||||
*/
|
||||
if (smp->ltk)
|
||||
ltk_encrypt = !test_and_set_bit(SMP_FLAG_LTK_ENCRYPT,
|
||||
&smp->smp_flags);
|
||||
else
|
||||
ltk_encrypt = false;
|
||||
clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags);
|
||||
cancel_delayed_work_sync(&conn->security_timer);
|
||||
set_bit(SMP_FLAG_COMPLETE, &smp->smp_flags);
|
||||
smp_notify_keys(conn);
|
||||
|
||||
/* Re-encrypt the link with LTK if possible */
|
||||
if (ltk_encrypt && hcon->out) {
|
||||
queue_delayed_work(hdev->req_workqueue, &smp->reencrypt,
|
||||
SMP_REENCRYPT_TIMEOUT);
|
||||
} else {
|
||||
clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags);
|
||||
cancel_delayed_work_sync(&conn->security_timer);
|
||||
set_bit(SMP_FLAG_COMPLETE, &smp->smp_flags);
|
||||
smp_notify_keys(conn);
|
||||
smp_chan_destroy(conn);
|
||||
}
|
||||
smp_chan_destroy(conn);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -118,10 +118,8 @@ struct smp_cmd_security_req {
|
||||
#define SMP_FLAG_TK_VALID 1
|
||||
#define SMP_FLAG_CFM_PENDING 2
|
||||
#define SMP_FLAG_MITM_AUTH 3
|
||||
#define SMP_FLAG_LTK_ENCRYPT 4
|
||||
#define SMP_FLAG_COMPLETE 5
|
||||
|
||||
#define SMP_REENCRYPT_TIMEOUT msecs_to_jiffies(500)
|
||||
#define SMP_FLAG_COMPLETE 4
|
||||
#define SMP_FLAG_INITIATOR 5
|
||||
|
||||
struct smp_chan {
|
||||
struct l2cap_conn *conn;
|
||||
@ -144,7 +142,6 @@ struct smp_chan {
|
||||
unsigned long smp_flags;
|
||||
struct work_struct confirm;
|
||||
struct work_struct random;
|
||||
struct delayed_work reencrypt;
|
||||
};
|
||||
|
||||
/* SMP Commands */
|
||||
|
Loading…
Reference in New Issue
Block a user