diff options
author | John W. Linville <linville@tuxdriver.com> | 2014-03-31 15:22:17 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2014-03-31 15:22:17 -0400 |
commit | 96da266e77637ae892b196f377908c51fa9f2d1a (patch) | |
tree | bf3da12850bbd46082add3060f9a5253aed144e0 | |
parent | 9109e17f7c3ace48629397b44db5ce06bf168644 (diff) | |
parent | a31267c30880ebdc73e6815f58c69a665052fab8 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
49 files changed, 1805 insertions, 395 deletions
diff --git a/drivers/bcma/driver_gpio.c b/drivers/bcma/driver_gpio.c index 25f9887a35d0..d7f81ad56b8a 100644 --- a/drivers/bcma/driver_gpio.c +++ b/drivers/bcma/driver_gpio.c | |||
@@ -218,7 +218,14 @@ int bcma_gpio_init(struct bcma_drv_cc *cc) | |||
218 | #if IS_BUILTIN(CONFIG_BCMA_HOST_SOC) | 218 | #if IS_BUILTIN(CONFIG_BCMA_HOST_SOC) |
219 | chip->to_irq = bcma_gpio_to_irq; | 219 | chip->to_irq = bcma_gpio_to_irq; |
220 | #endif | 220 | #endif |
221 | chip->ngpio = 16; | 221 | switch (cc->core->bus->chipinfo.id) { |
222 | case BCMA_CHIP_ID_BCM5357: | ||
223 | chip->ngpio = 32; | ||
224 | break; | ||
225 | default: | ||
226 | chip->ngpio = 16; | ||
227 | } | ||
228 | |||
222 | /* There is just one SoC in one device and its GPIO addresses should be | 229 | /* There is just one SoC in one device and its GPIO addresses should be |
223 | * deterministic to address them more easily. The other buses could get | 230 | * deterministic to address them more easily. The other buses could get |
224 | * a random base number. */ | 231 | * a random base number. */ |
diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c index a9a989e5ee88..dfa5043e68ba 100644 --- a/drivers/bluetooth/bluecard_cs.c +++ b/drivers/bluetooth/bluecard_cs.c | |||
@@ -901,7 +901,7 @@ static void bluecard_release(struct pcmcia_device *link) | |||
901 | 901 | ||
902 | bluecard_close(info); | 902 | bluecard_close(info); |
903 | 903 | ||
904 | del_timer(&(info->timer)); | 904 | del_timer_sync(&(info->timer)); |
905 | 905 | ||
906 | pcmcia_disable_device(link); | 906 | pcmcia_disable_device(link); |
907 | } | 907 | } |
diff --git a/drivers/bluetooth/btmrvl_main.c b/drivers/bluetooth/btmrvl_main.c index 1e0320af00c6..2c4997ce2484 100644 --- a/drivers/bluetooth/btmrvl_main.c +++ b/drivers/bluetooth/btmrvl_main.c | |||
@@ -59,12 +59,13 @@ bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb) | |||
59 | priv->btmrvl_dev.sendcmdflag = false; | 59 | priv->btmrvl_dev.sendcmdflag = false; |
60 | priv->adapter->cmd_complete = true; | 60 | priv->adapter->cmd_complete = true; |
61 | wake_up_interruptible(&priv->adapter->cmd_wait_q); | 61 | wake_up_interruptible(&priv->adapter->cmd_wait_q); |
62 | } | ||
63 | 62 | ||
64 | if (hci_opcode_ogf(opcode) == 0x3F) { | 63 | if (hci_opcode_ogf(opcode) == 0x3F) { |
65 | BT_DBG("vendor event skipped: opcode=%#4.4x", opcode); | 64 | BT_DBG("vendor event skipped: opcode=%#4.4x", |
66 | kfree_skb(skb); | 65 | opcode); |
67 | return false; | 66 | kfree_skb(skb); |
67 | return false; | ||
68 | } | ||
68 | } | 69 | } |
69 | } | 70 | } |
70 | 71 | ||
diff --git a/drivers/net/wireless/ath/carl9170/rx.c b/drivers/net/wireless/ath/carl9170/rx.c index 536bc46a2912..924135b8e575 100644 --- a/drivers/net/wireless/ath/carl9170/rx.c +++ b/drivers/net/wireless/ath/carl9170/rx.c | |||
@@ -572,7 +572,7 @@ static void carl9170_ps_beacon(struct ar9170 *ar, void *data, unsigned int len) | |||
572 | 572 | ||
573 | static void carl9170_ba_check(struct ar9170 *ar, void *data, unsigned int len) | 573 | static void carl9170_ba_check(struct ar9170 *ar, void *data, unsigned int len) |
574 | { | 574 | { |
575 | struct ieee80211_bar *bar = (void *) data; | 575 | struct ieee80211_bar *bar = data; |
576 | struct carl9170_bar_list_entry *entry; | 576 | struct carl9170_bar_list_entry *entry; |
577 | unsigned int queue; | 577 | unsigned int queue; |
578 | 578 | ||
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index e0e649aab8db..afb3d15e38ff 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | |||
@@ -1354,13 +1354,14 @@ static s32 brcmf_set_auth_type(struct net_device *ndev, | |||
1354 | } | 1354 | } |
1355 | 1355 | ||
1356 | static s32 | 1356 | static s32 |
1357 | brcmf_set_set_cipher(struct net_device *ndev, | 1357 | brcmf_set_wsec_mode(struct net_device *ndev, |
1358 | struct cfg80211_connect_params *sme) | 1358 | struct cfg80211_connect_params *sme, bool mfp) |
1359 | { | 1359 | { |
1360 | struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev); | 1360 | struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev); |
1361 | struct brcmf_cfg80211_security *sec; | 1361 | struct brcmf_cfg80211_security *sec; |
1362 | s32 pval = 0; | 1362 | s32 pval = 0; |
1363 | s32 gval = 0; | 1363 | s32 gval = 0; |
1364 | s32 wsec; | ||
1364 | s32 err = 0; | 1365 | s32 err = 0; |
1365 | 1366 | ||
1366 | if (sme->crypto.n_ciphers_pairwise) { | 1367 | if (sme->crypto.n_ciphers_pairwise) { |
@@ -1412,7 +1413,12 @@ brcmf_set_set_cipher(struct net_device *ndev, | |||
1412 | if (brcmf_find_wpsie(sme->ie, sme->ie_len) && !pval && !gval && | 1413 | if (brcmf_find_wpsie(sme->ie, sme->ie_len) && !pval && !gval && |
1413 | sme->privacy) | 1414 | sme->privacy) |
1414 | pval = AES_ENABLED; | 1415 | pval = AES_ENABLED; |
1415 | err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wsec", pval | gval); | 1416 | |
1417 | if (mfp) | ||
1418 | wsec = pval | gval | MFP_CAPABLE; | ||
1419 | else | ||
1420 | wsec = pval | gval; | ||
1421 | err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wsec", wsec); | ||
1416 | if (err) { | 1422 | if (err) { |
1417 | brcmf_err("error (%d)\n", err); | 1423 | brcmf_err("error (%d)\n", err); |
1418 | return err; | 1424 | return err; |
@@ -1582,7 +1588,6 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, | |||
1582 | u32 ie_len; | 1588 | u32 ie_len; |
1583 | struct brcmf_ext_join_params_le *ext_join_params; | 1589 | struct brcmf_ext_join_params_le *ext_join_params; |
1584 | u16 chanspec; | 1590 | u16 chanspec; |
1585 | |||
1586 | s32 err = 0; | 1591 | s32 err = 0; |
1587 | 1592 | ||
1588 | brcmf_dbg(TRACE, "Enter\n"); | 1593 | brcmf_dbg(TRACE, "Enter\n"); |
@@ -1651,7 +1656,7 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, | |||
1651 | goto done; | 1656 | goto done; |
1652 | } | 1657 | } |
1653 | 1658 | ||
1654 | err = brcmf_set_set_cipher(ndev, sme); | 1659 | err = brcmf_set_wsec_mode(ndev, sme, sme->mfp == NL80211_MFP_REQUIRED); |
1655 | if (err) { | 1660 | if (err) { |
1656 | brcmf_err("wl_set_set_cipher failed (%d)\n", err); | 1661 | brcmf_err("wl_set_set_cipher failed (%d)\n", err); |
1657 | goto done; | 1662 | goto done; |
diff --git a/drivers/net/wireless/brcm80211/include/brcmu_wifi.h b/drivers/net/wireless/brcm80211/include/brcmu_wifi.h index 7ca2aa1035b2..74419d4bd123 100644 --- a/drivers/net/wireless/brcm80211/include/brcmu_wifi.h +++ b/drivers/net/wireless/brcm80211/include/brcmu_wifi.h | |||
@@ -217,6 +217,9 @@ static inline bool ac_bitmap_tst(u8 bitmap, int prec) | |||
217 | #define WSEC_SWFLAG 0x0008 | 217 | #define WSEC_SWFLAG 0x0008 |
218 | /* to go into transition mode without setting wep */ | 218 | /* to go into transition mode without setting wep */ |
219 | #define SES_OW_ENABLED 0x0040 | 219 | #define SES_OW_ENABLED 0x0040 |
220 | /* MFP */ | ||
221 | #define MFP_CAPABLE 0x0200 | ||
222 | #define MFP_REQUIRED 0x0400 | ||
220 | 223 | ||
221 | /* WPA authentication mode bitvec */ | 224 | /* WPA authentication mode bitvec */ |
222 | #define WPA_AUTH_DISABLED 0x0000 /* Legacy (i.e., non-WPA) */ | 225 | #define WPA_AUTH_DISABLED 0x0000 /* Legacy (i.e., non-WPA) */ |
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index b41155829220..1062c918a7bf 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c | |||
@@ -277,11 +277,11 @@ static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter) | |||
277 | 277 | ||
278 | priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); | 278 | priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); |
279 | 279 | ||
280 | adapter->seq_num++; | ||
280 | sleep_cfm_buf->seq_num = | 281 | sleep_cfm_buf->seq_num = |
281 | cpu_to_le16((HostCmd_SET_SEQ_NO_BSS_INFO | 282 | cpu_to_le16((HostCmd_SET_SEQ_NO_BSS_INFO |
282 | (adapter->seq_num, priv->bss_num, | 283 | (adapter->seq_num, priv->bss_num, |
283 | priv->bss_type))); | 284 | priv->bss_type))); |
284 | adapter->seq_num++; | ||
285 | 285 | ||
286 | if (adapter->iface_type == MWIFIEX_USB) { | 286 | if (adapter->iface_type == MWIFIEX_USB) { |
287 | sleep_cfm_tmp = | 287 | sleep_cfm_tmp = |
@@ -509,6 +509,11 @@ int mwifiex_send_cmd(struct mwifiex_private *priv, u16 cmd_no, | |||
509 | return -1; | 509 | return -1; |
510 | } | 510 | } |
511 | 511 | ||
512 | if (adapter->hs_enabling && cmd_no != HostCmd_CMD_802_11_HS_CFG_ENH) { | ||
513 | dev_err(adapter->dev, "PREP_CMD: host entering sleep state\n"); | ||
514 | return -1; | ||
515 | } | ||
516 | |||
512 | if (adapter->surprise_removed) { | 517 | if (adapter->surprise_removed) { |
513 | dev_err(adapter->dev, "PREP_CMD: card is removed\n"); | 518 | dev_err(adapter->dev, "PREP_CMD: card is removed\n"); |
514 | return -1; | 519 | return -1; |
@@ -976,11 +981,10 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter) | |||
976 | struct mwifiex_private *priv; | 981 | struct mwifiex_private *priv; |
977 | int i; | 982 | int i; |
978 | 983 | ||
984 | spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags); | ||
979 | /* Cancel current cmd */ | 985 | /* Cancel current cmd */ |
980 | if ((adapter->curr_cmd) && (adapter->curr_cmd->wait_q_enabled)) { | 986 | if ((adapter->curr_cmd) && (adapter->curr_cmd->wait_q_enabled)) { |
981 | spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); | ||
982 | adapter->curr_cmd->wait_q_enabled = false; | 987 | adapter->curr_cmd->wait_q_enabled = false; |
983 | spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); | ||
984 | adapter->cmd_wait_q.status = -1; | 988 | adapter->cmd_wait_q.status = -1; |
985 | mwifiex_complete_cmd(adapter, adapter->curr_cmd); | 989 | mwifiex_complete_cmd(adapter, adapter->curr_cmd); |
986 | } | 990 | } |
@@ -1000,6 +1004,7 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter) | |||
1000 | spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags); | 1004 | spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags); |
1001 | } | 1005 | } |
1002 | spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags); | 1006 | spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags); |
1007 | spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags); | ||
1003 | 1008 | ||
1004 | /* Cancel all pending scan command */ | 1009 | /* Cancel all pending scan command */ |
1005 | spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); | 1010 | spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); |
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index 7b4502fefec3..77db0886c6e2 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c | |||
@@ -38,7 +38,8 @@ static void scan_delay_timer_fn(unsigned long data) | |||
38 | if (adapter->surprise_removed) | 38 | if (adapter->surprise_removed) |
39 | return; | 39 | return; |
40 | 40 | ||
41 | if (adapter->scan_delay_cnt == MWIFIEX_MAX_SCAN_DELAY_CNT) { | 41 | if (adapter->scan_delay_cnt == MWIFIEX_MAX_SCAN_DELAY_CNT || |
42 | !adapter->scan_processing) { | ||
42 | /* | 43 | /* |
43 | * Abort scan operation by cancelling all pending scan | 44 | * Abort scan operation by cancelling all pending scan |
44 | * commands | 45 | * commands |
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index a67f7da12b30..d53e1e8c9467 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h | |||
@@ -774,6 +774,7 @@ struct mwifiex_adapter { | |||
774 | u16 hs_activate_wait_q_woken; | 774 | u16 hs_activate_wait_q_woken; |
775 | wait_queue_head_t hs_activate_wait_q; | 775 | wait_queue_head_t hs_activate_wait_q; |
776 | bool is_suspended; | 776 | bool is_suspended; |
777 | bool hs_enabling; | ||
777 | u8 event_body[MAX_EVENT_SIZE]; | 778 | u8 event_body[MAX_EVENT_SIZE]; |
778 | u32 hw_dot_11n_dev_cap; | 779 | u32 hw_dot_11n_dev_cap; |
779 | u8 hw_dev_mcs_support; | 780 | u8 hw_dev_mcs_support; |
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c index 57c353a94b29..a7e8b96b2d90 100644 --- a/drivers/net/wireless/mwifiex/pcie.c +++ b/drivers/net/wireless/mwifiex/pcie.c | |||
@@ -120,6 +120,7 @@ static int mwifiex_pcie_suspend(struct device *dev) | |||
120 | 120 | ||
121 | /* Indicate device suspended */ | 121 | /* Indicate device suspended */ |
122 | adapter->is_suspended = true; | 122 | adapter->is_suspended = true; |
123 | adapter->hs_enabling = false; | ||
123 | 124 | ||
124 | return 0; | 125 | return 0; |
125 | } | 126 | } |
@@ -1033,7 +1034,7 @@ static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter) | |||
1033 | card->tx_buf_list[wrdoneidx] = NULL; | 1034 | card->tx_buf_list[wrdoneidx] = NULL; |
1034 | 1035 | ||
1035 | if (reg->pfu_enabled) { | 1036 | if (reg->pfu_enabled) { |
1036 | desc2 = (void *)card->txbd_ring[wrdoneidx]; | 1037 | desc2 = card->txbd_ring[wrdoneidx]; |
1037 | memset(desc2, 0, sizeof(*desc2)); | 1038 | memset(desc2, 0, sizeof(*desc2)); |
1038 | } else { | 1039 | } else { |
1039 | desc = card->txbd_ring[wrdoneidx]; | 1040 | desc = card->txbd_ring[wrdoneidx]; |
@@ -1118,7 +1119,7 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb, | |||
1118 | card->tx_buf_list[wrindx] = skb; | 1119 | card->tx_buf_list[wrindx] = skb; |
1119 | 1120 | ||
1120 | if (reg->pfu_enabled) { | 1121 | if (reg->pfu_enabled) { |
1121 | desc2 = (void *)card->txbd_ring[wrindx]; | 1122 | desc2 = card->txbd_ring[wrindx]; |
1122 | desc2->paddr = buf_pa; | 1123 | desc2->paddr = buf_pa; |
1123 | desc2->len = (u16)skb->len; | 1124 | desc2->len = (u16)skb->len; |
1124 | desc2->frag_len = (u16)skb->len; | 1125 | desc2->frag_len = (u16)skb->len; |
@@ -1278,7 +1279,7 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) | |||
1278 | card->rx_buf_list[rd_index] = skb_tmp; | 1279 | card->rx_buf_list[rd_index] = skb_tmp; |
1279 | 1280 | ||
1280 | if (reg->pfu_enabled) { | 1281 | if (reg->pfu_enabled) { |
1281 | desc2 = (void *)card->rxbd_ring[rd_index]; | 1282 | desc2 = card->rxbd_ring[rd_index]; |
1282 | desc2->paddr = buf_pa; | 1283 | desc2->paddr = buf_pa; |
1283 | desc2->len = skb_tmp->len; | 1284 | desc2->len = skb_tmp->len; |
1284 | desc2->frag_len = skb_tmp->len; | 1285 | desc2->frag_len = skb_tmp->len; |
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index f13924447a2c..7b3af3d29ded 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c | |||
@@ -591,10 +591,12 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv, | |||
591 | *chan_tlv_out, | 591 | *chan_tlv_out, |
592 | struct mwifiex_chan_scan_param_set *scan_chan_list) | 592 | struct mwifiex_chan_scan_param_set *scan_chan_list) |
593 | { | 593 | { |
594 | struct mwifiex_adapter *adapter = priv->adapter; | ||
594 | int ret = 0; | 595 | int ret = 0; |
595 | struct mwifiex_chan_scan_param_set *tmp_chan_list; | 596 | struct mwifiex_chan_scan_param_set *tmp_chan_list; |
596 | struct mwifiex_chan_scan_param_set *start_chan; | 597 | struct mwifiex_chan_scan_param_set *start_chan; |
597 | 598 | struct cmd_ctrl_node *cmd_node, *tmp_node; | |
599 | unsigned long flags; | ||
598 | u32 tlv_idx, rates_size, cmd_no; | 600 | u32 tlv_idx, rates_size, cmd_no; |
599 | u32 total_scan_time; | 601 | u32 total_scan_time; |
600 | u32 done_early; | 602 | u32 done_early; |
@@ -748,8 +750,19 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv, | |||
748 | scan_cfg_out->tlv_buf_len -= | 750 | scan_cfg_out->tlv_buf_len -= |
749 | sizeof(struct mwifiex_ie_types_header) + rates_size; | 751 | sizeof(struct mwifiex_ie_types_header) + rates_size; |
750 | 752 | ||
751 | if (ret) | 753 | if (ret) { |
754 | spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); | ||
755 | list_for_each_entry_safe(cmd_node, tmp_node, | ||
756 | &adapter->scan_pending_q, | ||
757 | list) { | ||
758 | list_del(&cmd_node->list); | ||
759 | cmd_node->wait_q_enabled = false; | ||
760 | mwifiex_insert_cmd_to_free_q(adapter, cmd_node); | ||
761 | } | ||
762 | spin_unlock_irqrestore(&adapter->scan_pending_q_lock, | ||
763 | flags); | ||
752 | break; | 764 | break; |
765 | } | ||
753 | } | 766 | } |
754 | 767 | ||
755 | if (ret) | 768 | if (ret) |
@@ -1653,7 +1666,7 @@ mwifiex_parse_single_response_buf(struct mwifiex_private *priv, u8 **bss_info, | |||
1653 | curr_bcn_bytes -= ETH_ALEN; | 1666 | curr_bcn_bytes -= ETH_ALEN; |
1654 | 1667 | ||
1655 | if (!ext_scan) { | 1668 | if (!ext_scan) { |
1656 | rssi = (s32) *(u8 *)current_ptr; | 1669 | rssi = (s32) *current_ptr; |
1657 | rssi = (-rssi) * 100; /* Convert dBm to mBm */ | 1670 | rssi = (-rssi) * 100; /* Convert dBm to mBm */ |
1658 | current_ptr += sizeof(u8); | 1671 | current_ptr += sizeof(u8); |
1659 | curr_bcn_bytes -= sizeof(u8); | 1672 | curr_bcn_bytes -= sizeof(u8); |
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c index e0dcd3ed7a69..d206f04d4994 100644 --- a/drivers/net/wireless/mwifiex/sdio.c +++ b/drivers/net/wireless/mwifiex/sdio.c | |||
@@ -237,6 +237,7 @@ static int mwifiex_sdio_suspend(struct device *dev) | |||
237 | /* Enable the Host Sleep */ | 237 | /* Enable the Host Sleep */ |
238 | if (!mwifiex_enable_hs(adapter)) { | 238 | if (!mwifiex_enable_hs(adapter)) { |
239 | dev_err(adapter->dev, "cmd: failed to suspend\n"); | 239 | dev_err(adapter->dev, "cmd: failed to suspend\n"); |
240 | adapter->hs_enabling = false; | ||
240 | return -EFAULT; | 241 | return -EFAULT; |
241 | } | 242 | } |
242 | 243 | ||
@@ -245,6 +246,7 @@ static int mwifiex_sdio_suspend(struct device *dev) | |||
245 | 246 | ||
246 | /* Indicate device suspended */ | 247 | /* Indicate device suspended */ |
247 | adapter->is_suspended = true; | 248 | adapter->is_suspended = true; |
249 | adapter->hs_enabling = false; | ||
248 | 250 | ||
249 | return ret; | 251 | return ret; |
250 | } | 252 | } |
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index 33170af150f6..894270611f2c 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c | |||
@@ -64,6 +64,7 @@ int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter, | |||
64 | *(cmd_queued->condition)); | 64 | *(cmd_queued->condition)); |
65 | if (status) { | 65 | if (status) { |
66 | dev_err(adapter->dev, "cmd_wait_q terminated: %d\n", status); | 66 | dev_err(adapter->dev, "cmd_wait_q terminated: %d\n", status); |
67 | mwifiex_cancel_all_pending_cmd(adapter); | ||
67 | return status; | 68 | return status; |
68 | } | 69 | } |
69 | 70 | ||
@@ -508,6 +509,9 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter) | |||
508 | memset(&hscfg, 0, sizeof(struct mwifiex_ds_hs_cfg)); | 509 | memset(&hscfg, 0, sizeof(struct mwifiex_ds_hs_cfg)); |
509 | hscfg.is_invoke_hostcmd = true; | 510 | hscfg.is_invoke_hostcmd = true; |
510 | 511 | ||
512 | adapter->hs_enabling = true; | ||
513 | mwifiex_cancel_all_pending_cmd(adapter); | ||
514 | |||
511 | if (mwifiex_set_hs_params(mwifiex_get_priv(adapter, | 515 | if (mwifiex_set_hs_params(mwifiex_get_priv(adapter, |
512 | MWIFIEX_BSS_ROLE_STA), | 516 | MWIFIEX_BSS_ROLE_STA), |
513 | HostCmd_ACT_GEN_SET, MWIFIEX_SYNC_CMD, | 517 | HostCmd_ACT_GEN_SET, MWIFIEX_SYNC_CMD, |
@@ -516,8 +520,9 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter) | |||
516 | return false; | 520 | return false; |
517 | } | 521 | } |
518 | 522 | ||
519 | if (wait_event_interruptible(adapter->hs_activate_wait_q, | 523 | if (wait_event_interruptible_timeout(adapter->hs_activate_wait_q, |
520 | adapter->hs_activate_wait_q_woken)) { | 524 | adapter->hs_activate_wait_q_woken, |
525 | (10 * HZ)) <= 0) { | ||
521 | dev_err(adapter->dev, "hs_activate_wait_q terminated\n"); | 526 | dev_err(adapter->dev, "hs_activate_wait_q terminated\n"); |
522 | return false; | 527 | return false; |
523 | } | 528 | } |
diff --git a/drivers/net/wireless/mwifiex/tdls.c b/drivers/net/wireless/mwifiex/tdls.c index 8cec6e4ba8c4..97662a1ba58c 100644 --- a/drivers/net/wireless/mwifiex/tdls.c +++ b/drivers/net/wireless/mwifiex/tdls.c | |||
@@ -730,13 +730,13 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv, | |||
730 | 730 | ||
731 | if (len < (sizeof(struct ethhdr) + 3)) | 731 | if (len < (sizeof(struct ethhdr) + 3)) |
732 | return; | 732 | return; |
733 | if (*(u8 *)(buf + sizeof(struct ethhdr)) != WLAN_TDLS_SNAP_RFTYPE) | 733 | if (*(buf + sizeof(struct ethhdr)) != WLAN_TDLS_SNAP_RFTYPE) |
734 | return; | 734 | return; |
735 | if (*(u8 *)(buf + sizeof(struct ethhdr) + 1) != WLAN_CATEGORY_TDLS) | 735 | if (*(buf + sizeof(struct ethhdr) + 1) != WLAN_CATEGORY_TDLS) |
736 | return; | 736 | return; |
737 | 737 | ||
738 | peer = buf + ETH_ALEN; | 738 | peer = buf + ETH_ALEN; |
739 | action = *(u8 *)(buf + sizeof(struct ethhdr) + 2); | 739 | action = *(buf + sizeof(struct ethhdr) + 2); |
740 | 740 | ||
741 | /* just handle TDLS setup request/response/confirm */ | 741 | /* just handle TDLS setup request/response/confirm */ |
742 | if (action > WLAN_TDLS_SETUP_CONFIRM) | 742 | if (action > WLAN_TDLS_SETUP_CONFIRM) |
diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c index ae30c390ebd3..edbe4aff00d8 100644 --- a/drivers/net/wireless/mwifiex/usb.c +++ b/drivers/net/wireless/mwifiex/usb.c | |||
@@ -459,6 +459,7 @@ static int mwifiex_usb_suspend(struct usb_interface *intf, pm_message_t message) | |||
459 | * 'suspended' state and a 'disconnect' one. | 459 | * 'suspended' state and a 'disconnect' one. |
460 | */ | 460 | */ |
461 | adapter->is_suspended = true; | 461 | adapter->is_suspended = true; |
462 | adapter->hs_enabling = false; | ||
462 | 463 | ||
463 | if (atomic_read(&card->rx_cmd_urb_pending) && card->rx_cmd.urb) | 464 | if (atomic_read(&card->rx_cmd_urb_pending) && card->rx_cmd.urb) |
464 | usb_kill_urb(card->rx_cmd.urb); | 465 | usb_kill_urb(card->rx_cmd.urb); |
diff --git a/drivers/net/wireless/rsi/rsi_91x_mgmt.c b/drivers/net/wireless/rsi/rsi_91x_mgmt.c index ef37d4b27bd4..2361a6849ad7 100644 --- a/drivers/net/wireless/rsi/rsi_91x_mgmt.c +++ b/drivers/net/wireless/rsi/rsi_91x_mgmt.c | |||
@@ -1292,10 +1292,11 @@ int rsi_mgmt_pkt_recv(struct rsi_common *common, u8 *msg) | |||
1292 | return -EINVAL; | 1292 | return -EINVAL; |
1293 | } | 1293 | } |
1294 | } else if (msg_type == TX_STATUS_IND) { | 1294 | } else if (msg_type == TX_STATUS_IND) { |
1295 | if (msg[15] == PROBEREQ_CONFIRM) | 1295 | if (msg[15] == PROBEREQ_CONFIRM) { |
1296 | common->mgmt_q_block = false; | 1296 | common->mgmt_q_block = false; |
1297 | rsi_dbg(FSM_ZONE, "%s: Probe confirm received\n", | 1297 | rsi_dbg(FSM_ZONE, "%s: Probe confirm received\n", |
1298 | __func__); | 1298 | __func__); |
1299 | } | ||
1299 | } else { | 1300 | } else { |
1300 | return rsi_mgmt_pkt_to_core(common, msg, msg_len, msg_type); | 1301 | return rsi_mgmt_pkt_to_core(common, msg, msg_len, msg_type); |
1301 | } | 1302 | } |
diff --git a/drivers/net/wireless/rtl818x/Kconfig b/drivers/net/wireless/rtl818x/Kconfig index 30332175bcd8..1ce1d55f0010 100644 --- a/drivers/net/wireless/rtl818x/Kconfig +++ b/drivers/net/wireless/rtl818x/Kconfig | |||
@@ -2,11 +2,11 @@ | |||
2 | # RTL818X Wireless LAN device configuration | 2 | # RTL818X Wireless LAN device configuration |
3 | # | 3 | # |
4 | config RTL8180 | 4 | config RTL8180 |
5 | tristate "Realtek 8180/8185 PCI support" | 5 | tristate "Realtek 8180/8185/8187SE PCI support" |
6 | depends on MAC80211 && PCI | 6 | depends on MAC80211 && PCI |
7 | select EEPROM_93CX6 | 7 | select EEPROM_93CX6 |
8 | ---help--- | 8 | ---help--- |
9 | This is a driver for RTL8180 and RTL8185 based cards. | 9 | This is a driver for RTL8180, RTL8185 and RTL8187SE based cards. |
10 | These are PCI based chips found in cards such as: | 10 | These are PCI based chips found in cards such as: |
11 | 11 | ||
12 | (RTL8185 802.11g) | 12 | (RTL8185 802.11g) |
diff --git a/drivers/net/wireless/rtl818x/rtl8180/Makefile b/drivers/net/wireless/rtl818x/rtl8180/Makefile index cb4fb8596f0b..08b056db4a3b 100644 --- a/drivers/net/wireless/rtl818x/rtl8180/Makefile +++ b/drivers/net/wireless/rtl818x/rtl8180/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | rtl8180-objs := dev.o rtl8225.o sa2400.o max2820.o grf5101.o | 1 | rtl8180-objs := dev.o rtl8225.o sa2400.o max2820.o grf5101.o rtl8225se.o |
2 | 2 | ||
3 | obj-$(CONFIG_RTL8180) += rtl8180.o | 3 | obj-$(CONFIG_RTL8180) += rtl8180.o |
4 | 4 | ||
diff --git a/drivers/net/wireless/rtl818x/rtl8180/dev.c b/drivers/net/wireless/rtl818x/rtl8180/dev.c index 0b405b8c8d70..98d8256f0377 100644 --- a/drivers/net/wireless/rtl818x/rtl8180/dev.c +++ b/drivers/net/wireless/rtl818x/rtl8180/dev.c | |||
@@ -1,15 +1,42 @@ | |||
1 | 1 | ||
2 | /* | 2 | /* Linux device driver for RTL8180 / RTL8185 / RTL8187SE |
3 | * Linux device driver for RTL8180 / RTL8185 | ||
4 | * | 3 | * |
5 | * Copyright 2007 Michael Wu <flamingice@sourmilk.net> | 4 | * Copyright 2007 Michael Wu <flamingice@sourmilk.net> |
6 | * Copyright 2007 Andrea Merello <andrea.merello@gmail.com> | 5 | * Copyright 2007,2014 Andrea Merello <andrea.merello@gmail.com> |
7 | * | 6 | * |
8 | * Based on the r8180 driver, which is: | 7 | * Based on the r8180 driver, which is: |
9 | * Copyright 2004-2005 Andrea Merello <andrea.merello@gmail.com>, et al. | 8 | * Copyright 2004-2005 Andrea Merello <andrea.merello@gmail.com>, et al. |
10 | * | 9 | * |
11 | * Thanks to Realtek for their support! | 10 | * Thanks to Realtek for their support! |
12 | * | 11 | * |
12 | ************************************************************************ | ||
13 | * | ||
14 | * The driver was extended to the RTL8187SE in 2014 by | ||
15 | * Andrea Merello <andrea.merello@gmail.com> | ||
16 | * | ||
17 | * based also on: | ||
18 | * - portions of rtl8187se Linux staging driver, Copyright Realtek corp. | ||
19 | * - other GPL, unpublished (until now), Linux driver code, | ||
20 | * Copyright Larry Finger <Larry.Finger@lwfinger.net> | ||
21 | * | ||
22 | * A huge thanks goes to Sara V. Nari who forgives me when I'm | ||
23 | * sitting in front of my laptop at evening, week-end, night... | ||
24 | * | ||
25 | * A special thanks goes to Antonio Cuni, who helped me with | ||
26 | * some python userspace stuff I used to debug RTL8187SE code, and who | ||
27 | * bought a laptop with an unsupported Wi-Fi card some years ago... | ||
28 | * | ||
29 | * Thanks to Larry Finger for writing some code for rtl8187se and for | ||
30 | * his suggestions. | ||
31 | * | ||
32 | * Thanks to Dan Carpenter for reviewing my initial patch and for his | ||
33 | * suggestions. | ||
34 | * | ||
35 | * Thanks to Bernhard Schiffner for his help in testing and for his | ||
36 | * suggestions. | ||
37 | * | ||
38 | ************************************************************************ | ||
39 | * | ||
13 | * This program is free software; you can redistribute it and/or modify | 40 | * This program is free software; you can redistribute it and/or modify |
14 | * it under the terms of the GNU General Public License version 2 as | 41 | * it under the terms of the GNU General Public License version 2 as |
15 | * published by the Free Software Foundation. | 42 | * published by the Free Software Foundation. |
@@ -29,13 +56,18 @@ | |||
29 | #include "sa2400.h" | 56 | #include "sa2400.h" |
30 | #include "max2820.h" | 57 | #include "max2820.h" |
31 | #include "grf5101.h" | 58 | #include "grf5101.h" |
59 | #include "rtl8225se.h" | ||
32 | 60 | ||
33 | MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>"); | 61 | MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>"); |
34 | MODULE_AUTHOR("Andrea Merello <andrea.merello@gmail.com>"); | 62 | MODULE_AUTHOR("Andrea Merello <andrea.merello@gmail.com>"); |
35 | MODULE_DESCRIPTION("RTL8180 / RTL8185 PCI wireless driver"); | 63 | MODULE_DESCRIPTION("RTL8180 / RTL8185 / RTL8187SE PCI wireless driver"); |
36 | MODULE_LICENSE("GPL"); | 64 | MODULE_LICENSE("GPL"); |
37 | 65 | ||
38 | static DEFINE_PCI_DEVICE_TABLE(rtl8180_table) = { | 66 | static DEFINE_PCI_DEVICE_TABLE(rtl8180_table) = { |
67 | |||
68 | /* rtl8187se */ | ||
69 | { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8199) }, | ||
70 | |||
39 | /* rtl8185 */ | 71 | /* rtl8185 */ |
40 | { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8185) }, | 72 | { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8185) }, |
41 | { PCI_DEVICE(PCI_VENDOR_ID_BELKIN, 0x700f) }, | 73 | { PCI_DEVICE(PCI_VENDOR_ID_BELKIN, 0x700f) }, |
@@ -85,6 +117,76 @@ static const struct ieee80211_channel rtl818x_channels[] = { | |||
85 | { .center_freq = 2484 }, | 117 | { .center_freq = 2484 }, |
86 | }; | 118 | }; |
87 | 119 | ||
120 | /* Queues for rtl8187se card | ||
121 | * | ||
122 | * name | reg | queue | ||
123 | * BC | 7 | 6 | ||
124 | * MG | 1 | 0 | ||
125 | * HI | 6 | 1 | ||
126 | * VO | 5 | 2 | ||
127 | * VI | 4 | 3 | ||
128 | * BE | 3 | 4 | ||
129 | * BK | 2 | 5 | ||
130 | * | ||
131 | * The complete map for DMA kick reg using use all queue is: | ||
132 | * static const int rtl8187se_queues_map[RTL8187SE_NR_TX_QUEUES] = | ||
133 | * {1, 6, 5, 4, 3, 2, 7}; | ||
134 | * | ||
135 | * .. but.. Because for mac80211 4 queues are enough for QoS we use this | ||
136 | * | ||
137 | * name | reg | queue | ||
138 | * BC | 7 | 4 <- currently not used yet | ||
139 | * MG | 1 | x <- Not used | ||
140 | * HI | 6 | x <- Not used | ||
141 | * VO | 5 | 0 <- used | ||
142 | * VI | 4 | 1 <- used | ||
143 | * BE | 3 | 2 <- used | ||
144 | * BK | 2 | 3 <- used | ||
145 | * | ||
146 | * Beacon queue could be used, but this is not finished yet. | ||
147 | * | ||
148 | * I thougth about using the other two queues but I decided not to do this: | ||
149 | * | ||
150 | * - I'm unsure whether the mac80211 will ever try to use more than 4 queues | ||
151 | * by itself. | ||
152 | * | ||
153 | * - I could route MGMT frames (currently sent over VO queue) to the MGMT | ||
154 | * queue but since mac80211 will do not know about it, I will probably gain | ||
155 | * some HW priority whenever the VO queue is not empty, but this gain is | ||
156 | * limited by the fact that I had to stop the mac80211 queue whenever one of | ||
157 | * the VO or MGMT queues is full, stopping also submitting of MGMT frame | ||
158 | * to the driver. | ||
159 | * | ||
160 | * - I don't know how to set in the HW the contention window params for MGMT | ||
161 | * and HI-prio queues. | ||
162 | */ | ||
163 | |||
164 | static const int rtl8187se_queues_map[RTL8187SE_NR_TX_QUEUES] = {5, 4, 3, 2, 7}; | ||
165 | |||
166 | /* Queues for rtl8180/rtl8185 cards | ||
167 | * | ||
168 | * name | reg | prio | ||
169 | * BC | 7 | 3 | ||
170 | * HI | 6 | 0 | ||
171 | * NO | 5 | 1 | ||
172 | * LO | 4 | 2 | ||
173 | * | ||
174 | * The complete map for DMA kick reg using all queue is: | ||
175 | * static const int rtl8180_queues_map[RTL8180_NR_TX_QUEUES] = {6, 5, 4, 7}; | ||
176 | * | ||
177 | * .. but .. Because the mac80211 needs at least 4 queues for QoS or | ||
178 | * otherwise QoS can't be done, we use just one. | ||
179 | * Beacon queue could be used, but this is not finished yet. | ||
180 | * Actual map is: | ||
181 | * | ||
182 | * name | reg | prio | ||
183 | * BC | 7 | 1 <- currently not used yet. | ||
184 | * HI | 6 | x <- not used | ||
185 | * NO | 5 | x <- not used | ||
186 | * LO | 4 | 0 <- used | ||
187 | */ | ||
188 | |||
189 | static const int rtl8180_queues_map[RTL8180_NR_TX_QUEUES] = {4, 7}; | ||
88 | 190 | ||
89 | void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data) | 191 | void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data) |
90 | { | 192 | { |
@@ -105,14 +207,30 @@ void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data) | |||
105 | static void rtl8180_handle_rx(struct ieee80211_hw *dev) | 207 | static void rtl8180_handle_rx(struct ieee80211_hw *dev) |
106 | { | 208 | { |
107 | struct rtl8180_priv *priv = dev->priv; | 209 | struct rtl8180_priv *priv = dev->priv; |
210 | struct rtl818x_rx_cmd_desc *cmd_desc; | ||
108 | unsigned int count = 32; | 211 | unsigned int count = 32; |
109 | u8 signal, agc, sq; | 212 | u8 signal, agc, sq; |
110 | dma_addr_t mapping; | 213 | dma_addr_t mapping; |
111 | 214 | ||
112 | while (count--) { | 215 | while (count--) { |
113 | struct rtl8180_rx_desc *entry = &priv->rx_ring[priv->rx_idx]; | 216 | void *entry = priv->rx_ring + priv->rx_idx * priv->rx_ring_sz; |
114 | struct sk_buff *skb = priv->rx_buf[priv->rx_idx]; | 217 | struct sk_buff *skb = priv->rx_buf[priv->rx_idx]; |
115 | u32 flags = le32_to_cpu(entry->flags); | 218 | u32 flags, flags2; |
219 | u64 tsft; | ||
220 | |||
221 | if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) { | ||
222 | struct rtl8187se_rx_desc *desc = entry; | ||
223 | |||
224 | flags = le32_to_cpu(desc->flags); | ||
225 | flags2 = le32_to_cpu(desc->flags2); | ||
226 | tsft = le64_to_cpu(desc->tsft); | ||
227 | } else { | ||
228 | struct rtl8180_rx_desc *desc = entry; | ||
229 | |||
230 | flags = le32_to_cpu(desc->flags); | ||
231 | flags2 = le32_to_cpu(desc->flags2); | ||
232 | tsft = le64_to_cpu(desc->tsft); | ||
233 | } | ||
116 | 234 | ||
117 | if (flags & RTL818X_RX_DESC_FLAG_OWN) | 235 | if (flags & RTL818X_RX_DESC_FLAG_OWN) |
118 | return; | 236 | return; |
@@ -122,7 +240,6 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev) | |||
122 | RTL818X_RX_DESC_FLAG_RX_ERR))) | 240 | RTL818X_RX_DESC_FLAG_RX_ERR))) |
123 | goto done; | 241 | goto done; |
124 | else { | 242 | else { |
125 | u32 flags2 = le32_to_cpu(entry->flags2); | ||
126 | struct ieee80211_rx_status rx_status = {0}; | 243 | struct ieee80211_rx_status rx_status = {0}; |
127 | struct sk_buff *new_skb = dev_alloc_skb(MAX_RX_SIZE); | 244 | struct sk_buff *new_skb = dev_alloc_skb(MAX_RX_SIZE); |
128 | 245 | ||
@@ -154,14 +271,18 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev) | |||
154 | signal = 90 - clamp_t(u8, agc, 25, 90); | 271 | signal = 90 - clamp_t(u8, agc, 25, 90); |
155 | else | 272 | else |
156 | signal = 95 - clamp_t(u8, agc, 30, 95); | 273 | signal = 95 - clamp_t(u8, agc, 30, 95); |
157 | } else { | 274 | } else if (priv->chip_family == |
275 | RTL818X_CHIP_FAMILY_RTL8180) { | ||
158 | sq = flags2 & 0xff; | 276 | sq = flags2 & 0xff; |
159 | signal = priv->rf->calc_rssi(agc, sq); | 277 | signal = priv->rf->calc_rssi(agc, sq); |
278 | } else { | ||
279 | /* TODO: rtl8187se rssi */ | ||
280 | signal = 10; | ||
160 | } | 281 | } |
161 | rx_status.signal = signal; | 282 | rx_status.signal = signal; |
162 | rx_status.freq = dev->conf.chandef.chan->center_freq; | 283 | rx_status.freq = dev->conf.chandef.chan->center_freq; |
163 | rx_status.band = dev->conf.chandef.chan->band; | 284 | rx_status.band = dev->conf.chandef.chan->band; |
164 | rx_status.mactime = le64_to_cpu(entry->tsft); | 285 | rx_status.mactime = tsft; |
165 | rx_status.flag |= RX_FLAG_MACTIME_START; | 286 | rx_status.flag |= RX_FLAG_MACTIME_START; |
166 | if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR) | 287 | if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR) |
167 | rx_status.flag |= RX_FLAG_FAILED_FCS_CRC; | 288 | rx_status.flag |= RX_FLAG_FAILED_FCS_CRC; |
@@ -175,11 +296,13 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev) | |||
175 | } | 296 | } |
176 | 297 | ||
177 | done: | 298 | done: |
178 | entry->rx_buf = cpu_to_le32(*((dma_addr_t *)skb->cb)); | 299 | cmd_desc = entry; |
179 | entry->flags = cpu_to_le32(RTL818X_RX_DESC_FLAG_OWN | | 300 | cmd_desc->rx_buf = cpu_to_le32(*((dma_addr_t *)skb->cb)); |
301 | cmd_desc->flags = cpu_to_le32(RTL818X_RX_DESC_FLAG_OWN | | ||
180 | MAX_RX_SIZE); | 302 | MAX_RX_SIZE); |
181 | if (priv->rx_idx == 31) | 303 | if (priv->rx_idx == 31) |
182 | entry->flags |= cpu_to_le32(RTL818X_RX_DESC_FLAG_EOR); | 304 | cmd_desc->flags |= |
305 | cpu_to_le32(RTL818X_RX_DESC_FLAG_EOR); | ||
183 | priv->rx_idx = (priv->rx_idx + 1) % 32; | 306 | priv->rx_idx = (priv->rx_idx + 1) % 32; |
184 | } | 307 | } |
185 | } | 308 | } |
@@ -219,6 +342,55 @@ static void rtl8180_handle_tx(struct ieee80211_hw *dev, unsigned int prio) | |||
219 | } | 342 | } |
220 | } | 343 | } |
221 | 344 | ||
345 | static irqreturn_t rtl8187se_interrupt(int irq, void *dev_id) | ||
346 | { | ||
347 | struct ieee80211_hw *dev = dev_id; | ||
348 | struct rtl8180_priv *priv = dev->priv; | ||
349 | u32 reg; | ||
350 | unsigned long flags; | ||
351 | static int desc_err; | ||
352 | |||
353 | spin_lock_irqsave(&priv->lock, flags); | ||
354 | /* Note: 32-bit interrupt status */ | ||
355 | reg = rtl818x_ioread32(priv, &priv->map->INT_STATUS_SE); | ||
356 | if (unlikely(reg == 0xFFFFFFFF)) { | ||
357 | spin_unlock_irqrestore(&priv->lock, flags); | ||
358 | return IRQ_HANDLED; | ||
359 | } | ||
360 | |||
361 | rtl818x_iowrite32(priv, &priv->map->INT_STATUS_SE, reg); | ||
362 | |||
363 | if (reg & IMR_TIMEOUT1) | ||
364 | rtl818x_iowrite32(priv, &priv->map->INT_TIMEOUT, 0); | ||
365 | |||
366 | if (reg & (IMR_TBDOK | IMR_TBDER)) | ||
367 | rtl8180_handle_tx(dev, 4); | ||
368 | |||
369 | if (reg & (IMR_TVODOK | IMR_TVODER)) | ||
370 | rtl8180_handle_tx(dev, 0); | ||
371 | |||
372 | if (reg & (IMR_TVIDOK | IMR_TVIDER)) | ||
373 | rtl8180_handle_tx(dev, 1); | ||
374 | |||
375 | if (reg & (IMR_TBEDOK | IMR_TBEDER)) | ||
376 | rtl8180_handle_tx(dev, 2); | ||
377 | |||
378 | if (reg & (IMR_TBKDOK | IMR_TBKDER)) | ||
379 | rtl8180_handle_tx(dev, 3); | ||
380 | |||
381 | if (reg & (IMR_ROK | IMR_RER | RTL818X_INT_SE_RX_DU | IMR_RQOSOK)) | ||
382 | rtl8180_handle_rx(dev); | ||
383 | /* The interface sometimes generates several RX DMA descriptor errors | ||
384 | * at startup. Do not report these. | ||
385 | */ | ||
386 | if ((reg & RTL818X_INT_SE_RX_DU) && desc_err++ > 2) | ||
387 | if (net_ratelimit()) | ||
388 | wiphy_err(dev->wiphy, "No RX DMA Descriptor avail\n"); | ||
389 | |||
390 | spin_unlock_irqrestore(&priv->lock, flags); | ||
391 | return IRQ_HANDLED; | ||
392 | } | ||
393 | |||
222 | static irqreturn_t rtl8180_interrupt(int irq, void *dev_id) | 394 | static irqreturn_t rtl8180_interrupt(int irq, void *dev_id) |
223 | { | 395 | { |
224 | struct ieee80211_hw *dev = dev_id; | 396 | struct ieee80211_hw *dev = dev_id; |
@@ -235,12 +407,6 @@ static irqreturn_t rtl8180_interrupt(int irq, void *dev_id) | |||
235 | rtl818x_iowrite16(priv, &priv->map->INT_STATUS, reg); | 407 | rtl818x_iowrite16(priv, &priv->map->INT_STATUS, reg); |
236 | 408 | ||
237 | if (reg & (RTL818X_INT_TXB_OK | RTL818X_INT_TXB_ERR)) | 409 | if (reg & (RTL818X_INT_TXB_OK | RTL818X_INT_TXB_ERR)) |
238 | rtl8180_handle_tx(dev, 3); | ||
239 | |||
240 | if (reg & (RTL818X_INT_TXH_OK | RTL818X_INT_TXH_ERR)) | ||
241 | rtl8180_handle_tx(dev, 2); | ||
242 | |||
243 | if (reg & (RTL818X_INT_TXN_OK | RTL818X_INT_TXN_ERR)) | ||
244 | rtl8180_handle_tx(dev, 1); | 410 | rtl8180_handle_tx(dev, 1); |
245 | 411 | ||
246 | if (reg & (RTL818X_INT_TXL_OK | RTL818X_INT_TXL_ERR)) | 412 | if (reg & (RTL818X_INT_TXL_OK | RTL818X_INT_TXL_ERR)) |
@@ -264,12 +430,14 @@ static void rtl8180_tx(struct ieee80211_hw *dev, | |||
264 | struct rtl8180_tx_ring *ring; | 430 | struct rtl8180_tx_ring *ring; |
265 | struct rtl8180_tx_desc *entry; | 431 | struct rtl8180_tx_desc *entry; |
266 | unsigned long flags; | 432 | unsigned long flags; |
267 | unsigned int idx, prio; | 433 | unsigned int idx, prio, hw_prio; |
268 | dma_addr_t mapping; | 434 | dma_addr_t mapping; |
269 | u32 tx_flags; | 435 | u32 tx_flags; |
270 | u8 rc_flags; | 436 | u8 rc_flags; |
271 | u16 plcp_len = 0; | 437 | u16 plcp_len = 0; |
272 | __le16 rts_duration = 0; | 438 | __le16 rts_duration = 0; |
439 | /* do arithmetic and then convert to le16 */ | ||
440 | u16 frame_duration = 0; | ||
273 | 441 | ||
274 | prio = skb_get_queue_mapping(skb); | 442 | prio = skb_get_queue_mapping(skb); |
275 | ring = &priv->tx_ring[prio]; | 443 | ring = &priv->tx_ring[prio]; |
@@ -281,7 +449,6 @@ static void rtl8180_tx(struct ieee80211_hw *dev, | |||
281 | kfree_skb(skb); | 449 | kfree_skb(skb); |
282 | dev_err(&priv->pdev->dev, "TX DMA mapping error\n"); | 450 | dev_err(&priv->pdev->dev, "TX DMA mapping error\n"); |
283 | return; | 451 | return; |
284 | |||
285 | } | 452 | } |
286 | 453 | ||
287 | tx_flags = RTL818X_TX_DESC_FLAG_OWN | RTL818X_TX_DESC_FLAG_FS | | 454 | tx_flags = RTL818X_TX_DESC_FLAG_OWN | RTL818X_TX_DESC_FLAG_FS | |
@@ -317,6 +484,18 @@ static void rtl8180_tx(struct ieee80211_hw *dev, | |||
317 | plcp_len |= 1 << 15; | 484 | plcp_len |= 1 << 15; |
318 | } | 485 | } |
319 | 486 | ||
487 | if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) { | ||
488 | __le16 duration; | ||
489 | /* SIFS time (required by HW) is already included by | ||
490 | * ieee80211_generic_frame_duration | ||
491 | */ | ||
492 | duration = ieee80211_generic_frame_duration(dev, priv->vif, | ||
493 | IEEE80211_BAND_2GHZ, skb->len, | ||
494 | ieee80211_get_tx_rate(dev, info)); | ||
495 | |||
496 | frame_duration = priv->ack_time + le16_to_cpu(duration); | ||
497 | } | ||
498 | |||
320 | spin_lock_irqsave(&priv->lock, flags); | 499 | spin_lock_irqsave(&priv->lock, flags); |
321 | 500 | ||
322 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { | 501 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { |
@@ -329,10 +508,19 @@ static void rtl8180_tx(struct ieee80211_hw *dev, | |||
329 | idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries; | 508 | idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries; |
330 | entry = &ring->desc[idx]; | 509 | entry = &ring->desc[idx]; |
331 | 510 | ||
511 | if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) { | ||
512 | entry->frame_duration = cpu_to_le16(frame_duration); | ||
513 | entry->frame_len_se = cpu_to_le16(skb->len); | ||
514 | |||
515 | /* tpc polarity */ | ||
516 | entry->flags3 = cpu_to_le16(1<<4); | ||
517 | } else | ||
518 | entry->frame_len = cpu_to_le32(skb->len); | ||
519 | |||
332 | entry->rts_duration = rts_duration; | 520 | entry->rts_duration = rts_duration; |
333 | entry->plcp_len = cpu_to_le16(plcp_len); | 521 | entry->plcp_len = cpu_to_le16(plcp_len); |
334 | entry->tx_buf = cpu_to_le32(mapping); | 522 | entry->tx_buf = cpu_to_le32(mapping); |
335 | entry->frame_len = cpu_to_le32(skb->len); | 523 | |
336 | entry->flags2 = info->control.rates[1].idx >= 0 ? | 524 | entry->flags2 = info->control.rates[1].idx >= 0 ? |
337 | ieee80211_get_alt_retry_rate(dev, info, 0)->bitrate << 4 : 0; | 525 | ieee80211_get_alt_retry_rate(dev, info, 0)->bitrate << 4 : 0; |
338 | entry->retry_limit = info->control.rates[0].count; | 526 | entry->retry_limit = info->control.rates[0].count; |
@@ -354,7 +542,57 @@ static void rtl8180_tx(struct ieee80211_hw *dev, | |||
354 | 542 | ||
355 | spin_unlock_irqrestore(&priv->lock, flags); | 543 | spin_unlock_irqrestore(&priv->lock, flags); |
356 | 544 | ||
357 | rtl818x_iowrite8(priv, &priv->map->TX_DMA_POLLING, (1 << (prio + 4))); | 545 | if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) { |
546 | /* just poll: rings are stopped with TPPollStop reg */ | ||
547 | hw_prio = rtl8187se_queues_map[prio]; | ||
548 | rtl818x_iowrite8(priv, &priv->map->TX_DMA_POLLING, | ||
549 | (1 << hw_prio)); | ||
550 | } else { | ||
551 | hw_prio = rtl8180_queues_map[prio]; | ||
552 | rtl818x_iowrite8(priv, &priv->map->TX_DMA_POLLING, | ||
553 | (1 << hw_prio) | /* ring to poll */ | ||
554 | (1<<1) | (1<<2));/* stopped rings */ | ||
555 | } | ||
556 | } | ||
557 | |||
558 | static void rtl8180_set_anaparam3(struct rtl8180_priv *priv, u16 anaparam3) | ||
559 | { | ||
560 | u8 reg; | ||
561 | |||
562 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, | ||
563 | RTL818X_EEPROM_CMD_CONFIG); | ||
564 | |||
565 | reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); | ||
566 | rtl818x_iowrite8(priv, &priv->map->CONFIG3, | ||
567 | reg | RTL818X_CONFIG3_ANAPARAM_WRITE); | ||
568 | |||
569 | rtl818x_iowrite16(priv, &priv->map->ANAPARAM3, anaparam3); | ||
570 | |||
571 | rtl818x_iowrite8(priv, &priv->map->CONFIG3, | ||
572 | reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE); | ||
573 | |||
574 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, | ||
575 | RTL818X_EEPROM_CMD_NORMAL); | ||
576 | } | ||
577 | |||
578 | void rtl8180_set_anaparam2(struct rtl8180_priv *priv, u32 anaparam2) | ||
579 | { | ||
580 | u8 reg; | ||
581 | |||
582 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, | ||
583 | RTL818X_EEPROM_CMD_CONFIG); | ||
584 | |||
585 | reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); | ||
586 | rtl818x_iowrite8(priv, &priv->map->CONFIG3, | ||
587 | reg | RTL818X_CONFIG3_ANAPARAM_WRITE); | ||
588 | |||
589 | rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, anaparam2); | ||
590 | |||
591 | rtl818x_iowrite8(priv, &priv->map->CONFIG3, | ||
592 | reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE); | ||
593 | |||
594 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, | ||
595 | RTL818X_EEPROM_CMD_NORMAL); | ||
358 | } | 596 | } |
359 | 597 | ||
360 | void rtl8180_set_anaparam(struct rtl8180_priv *priv, u32 anaparam) | 598 | void rtl8180_set_anaparam(struct rtl8180_priv *priv, u32 anaparam) |
@@ -371,6 +609,105 @@ void rtl8180_set_anaparam(struct rtl8180_priv *priv, u32 anaparam) | |||
371 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); | 609 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); |
372 | } | 610 | } |
373 | 611 | ||
612 | static void rtl8187se_mac_config(struct ieee80211_hw *dev) | ||
613 | { | ||
614 | struct rtl8180_priv *priv = dev->priv; | ||
615 | u8 reg; | ||
616 | |||
617 | rtl818x_iowrite32(priv, REG_ADDR4(0x1F0), 0); | ||
618 | rtl818x_ioread32(priv, REG_ADDR4(0x1F0)); | ||
619 | rtl818x_iowrite32(priv, REG_ADDR4(0x1F4), 0); | ||
620 | rtl818x_ioread32(priv, REG_ADDR4(0x1F4)); | ||
621 | rtl818x_iowrite8(priv, REG_ADDR1(0x1F8), 0); | ||
622 | rtl818x_ioread8(priv, REG_ADDR1(0x1F8)); | ||
623 | /* Enable DA10 TX power saving */ | ||
624 | reg = rtl818x_ioread8(priv, &priv->map->PHY_PR); | ||
625 | rtl818x_iowrite8(priv, &priv->map->PHY_PR, reg | 0x04); | ||
626 | /* Power */ | ||
627 | rtl818x_iowrite16(priv, PI_DATA_REG, 0x1000); | ||
628 | rtl818x_iowrite16(priv, SI_DATA_REG, 0x1000); | ||
629 | /* AFE - default to power ON */ | ||
630 | rtl818x_iowrite16(priv, REG_ADDR2(0x370), 0x0560); | ||
631 | rtl818x_iowrite16(priv, REG_ADDR2(0x372), 0x0560); | ||
632 | rtl818x_iowrite16(priv, REG_ADDR2(0x374), 0x0DA4); | ||
633 | rtl818x_iowrite16(priv, REG_ADDR2(0x376), 0x0DA4); | ||
634 | rtl818x_iowrite16(priv, REG_ADDR2(0x378), 0x0560); | ||
635 | rtl818x_iowrite16(priv, REG_ADDR2(0x37A), 0x0560); | ||
636 | rtl818x_iowrite16(priv, REG_ADDR2(0x37C), 0x00EC); | ||
637 | rtl818x_iowrite16(priv, REG_ADDR2(0x37E), 0x00EC); | ||
638 | rtl818x_iowrite8(priv, REG_ADDR1(0x24E), 0x01); | ||
639 | /* unknown, needed for suspend to RAM resume */ | ||
640 | rtl818x_iowrite8(priv, REG_ADDR1(0x0A), 0x72); | ||
641 | } | ||
642 | |||
643 | static void rtl8187se_set_antenna_config(struct ieee80211_hw *dev, u8 def_ant, | ||
644 | bool diversity) | ||
645 | { | ||
646 | struct rtl8180_priv *priv = dev->priv; | ||
647 | |||
648 | rtl8225_write_phy_cck(dev, 0x0C, 0x09); | ||
649 | if (diversity) { | ||
650 | if (def_ant == 1) { | ||
651 | rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x00); | ||
652 | rtl8225_write_phy_cck(dev, 0x11, 0xBB); | ||
653 | rtl8225_write_phy_cck(dev, 0x01, 0xC7); | ||
654 | rtl8225_write_phy_ofdm(dev, 0x0D, 0x54); | ||
655 | rtl8225_write_phy_ofdm(dev, 0x18, 0xB2); | ||
656 | } else { /* main antenna */ | ||
657 | rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03); | ||
658 | rtl8225_write_phy_cck(dev, 0x11, 0x9B); | ||
659 | rtl8225_write_phy_cck(dev, 0x01, 0xC7); | ||
660 | rtl8225_write_phy_ofdm(dev, 0x0D, 0x5C); | ||
661 | rtl8225_write_phy_ofdm(dev, 0x18, 0xB2); | ||
662 | } | ||
663 | } else { /* disable antenna diversity */ | ||
664 | if (def_ant == 1) { | ||
665 | rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x00); | ||
666 | rtl8225_write_phy_cck(dev, 0x11, 0xBB); | ||
667 | rtl8225_write_phy_cck(dev, 0x01, 0x47); | ||
668 | rtl8225_write_phy_ofdm(dev, 0x0D, 0x54); | ||
669 | rtl8225_write_phy_ofdm(dev, 0x18, 0x32); | ||
670 | } else { /* main antenna */ | ||
671 | rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03); | ||
672 | rtl8225_write_phy_cck(dev, 0x11, 0x9B); | ||
673 | rtl8225_write_phy_cck(dev, 0x01, 0x47); | ||
674 | rtl8225_write_phy_ofdm(dev, 0x0D, 0x5C); | ||
675 | rtl8225_write_phy_ofdm(dev, 0x18, 0x32); | ||
676 | } | ||
677 | } | ||
678 | /* priv->curr_ant = def_ant; */ | ||
679 | } | ||
680 | |||
681 | static void rtl8180_int_enable(struct ieee80211_hw *dev) | ||
682 | { | ||
683 | struct rtl8180_priv *priv = dev->priv; | ||
684 | |||
685 | if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) { | ||
686 | rtl818x_iowrite32(priv, &priv->map->IMR, IMR_TMGDOK | | ||
687 | IMR_TBDER | IMR_THPDER | | ||
688 | IMR_THPDER | IMR_THPDOK | | ||
689 | IMR_TVODER | IMR_TVODOK | | ||
690 | IMR_TVIDER | IMR_TVIDOK | | ||
691 | IMR_TBEDER | IMR_TBEDOK | | ||
692 | IMR_TBKDER | IMR_TBKDOK | | ||
693 | IMR_RDU | IMR_RER | | ||
694 | IMR_ROK | IMR_RQOSOK); | ||
695 | } else { | ||
696 | rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0xFFFF); | ||
697 | } | ||
698 | } | ||
699 | |||
700 | static void rtl8180_int_disable(struct ieee80211_hw *dev) | ||
701 | { | ||
702 | struct rtl8180_priv *priv = dev->priv; | ||
703 | |||
704 | if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) { | ||
705 | rtl818x_iowrite32(priv, &priv->map->IMR, 0); | ||
706 | } else { | ||
707 | rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0); | ||
708 | } | ||
709 | } | ||
710 | |||
374 | static void rtl8180_conf_basic_rates(struct ieee80211_hw *dev, | 711 | static void rtl8180_conf_basic_rates(struct ieee80211_hw *dev, |
375 | u32 rates_mask) | 712 | u32 rates_mask) |
376 | { | 713 | { |
@@ -390,7 +727,6 @@ static void rtl8180_conf_basic_rates(struct ieee80211_hw *dev, | |||
390 | reg &= ~3; | 727 | reg &= ~3; |
391 | reg |= max; | 728 | reg |= max; |
392 | rtl818x_iowrite16(priv, &priv->map->BRSR, reg); | 729 | rtl818x_iowrite16(priv, &priv->map->BRSR, reg); |
393 | |||
394 | break; | 730 | break; |
395 | 731 | ||
396 | case RTL818X_CHIP_FAMILY_RTL8185: | 732 | case RTL818X_CHIP_FAMILY_RTL8185: |
@@ -398,20 +734,46 @@ static void rtl8180_conf_basic_rates(struct ieee80211_hw *dev, | |||
398 | rtl818x_iowrite16(priv, &priv->map->BRSR, rates_mask); | 734 | rtl818x_iowrite16(priv, &priv->map->BRSR, rates_mask); |
399 | rtl818x_iowrite8(priv, &priv->map->RESP_RATE, (max << 4) | min); | 735 | rtl818x_iowrite8(priv, &priv->map->RESP_RATE, (max << 4) | min); |
400 | break; | 736 | break; |
737 | |||
738 | case RTL818X_CHIP_FAMILY_RTL8187SE: | ||
739 | /* in 8187se this is a BITMAP */ | ||
740 | rtl818x_iowrite16(priv, &priv->map->BRSR_8187SE, rates_mask); | ||
741 | break; | ||
742 | } | ||
743 | } | ||
744 | |||
745 | static void rtl8180_config_cardbus(struct ieee80211_hw *dev) | ||
746 | { | ||
747 | struct rtl8180_priv *priv = dev->priv; | ||
748 | u16 reg16; | ||
749 | u8 reg8; | ||
750 | |||
751 | reg8 = rtl818x_ioread8(priv, &priv->map->CONFIG3); | ||
752 | reg8 |= 1 << 1; | ||
753 | rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg8); | ||
754 | |||
755 | if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) { | ||
756 | rtl818x_iowrite16(priv, FEMR_SE, 0xffff); | ||
757 | } else { | ||
758 | reg16 = rtl818x_ioread16(priv, &priv->map->FEMR); | ||
759 | reg16 |= (1 << 15) | (1 << 14) | (1 << 4); | ||
760 | rtl818x_iowrite16(priv, &priv->map->FEMR, reg16); | ||
401 | } | 761 | } |
762 | |||
402 | } | 763 | } |
403 | 764 | ||
404 | static int rtl8180_init_hw(struct ieee80211_hw *dev) | 765 | static int rtl8180_init_hw(struct ieee80211_hw *dev) |
405 | { | 766 | { |
406 | struct rtl8180_priv *priv = dev->priv; | 767 | struct rtl8180_priv *priv = dev->priv; |
407 | u16 reg; | 768 | u16 reg; |
769 | u32 reg32; | ||
408 | 770 | ||
409 | rtl818x_iowrite8(priv, &priv->map->CMD, 0); | 771 | rtl818x_iowrite8(priv, &priv->map->CMD, 0); |
410 | rtl818x_ioread8(priv, &priv->map->CMD); | 772 | rtl818x_ioread8(priv, &priv->map->CMD); |
411 | msleep(10); | 773 | msleep(10); |
412 | 774 | ||
413 | /* reset */ | 775 | /* reset */ |
414 | rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0); | 776 | rtl8180_int_disable(dev); |
415 | rtl818x_ioread8(priv, &priv->map->CMD); | 777 | rtl818x_ioread8(priv, &priv->map->CMD); |
416 | 778 | ||
417 | reg = rtl818x_ioread8(priv, &priv->map->CMD); | 779 | reg = rtl818x_ioread8(priv, &priv->map->CMD); |
@@ -432,25 +794,39 @@ static int rtl8180_init_hw(struct ieee80211_hw *dev) | |||
432 | msleep(200); | 794 | msleep(200); |
433 | 795 | ||
434 | if (rtl818x_ioread8(priv, &priv->map->CONFIG3) & (1 << 3)) { | 796 | if (rtl818x_ioread8(priv, &priv->map->CONFIG3) & (1 << 3)) { |
435 | /* For cardbus */ | 797 | rtl8180_config_cardbus(dev); |
436 | reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); | ||
437 | reg |= 1 << 1; | ||
438 | rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg); | ||
439 | reg = rtl818x_ioread16(priv, &priv->map->FEMR); | ||
440 | reg |= (1 << 15) | (1 << 14) | (1 << 4); | ||
441 | rtl818x_iowrite16(priv, &priv->map->FEMR, reg); | ||
442 | } | 798 | } |
443 | 799 | ||
444 | rtl818x_iowrite8(priv, &priv->map->MSR, 0); | 800 | if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) |
801 | rtl818x_iowrite8(priv, &priv->map->MSR, RTL818X_MSR_ENEDCA); | ||
802 | else | ||
803 | rtl818x_iowrite8(priv, &priv->map->MSR, 0); | ||
445 | 804 | ||
446 | if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8180) | 805 | if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8180) |
447 | rtl8180_set_anaparam(priv, priv->anaparam); | 806 | rtl8180_set_anaparam(priv, priv->anaparam); |
448 | 807 | ||
449 | rtl818x_iowrite32(priv, &priv->map->RDSAR, priv->rx_ring_dma); | 808 | rtl818x_iowrite32(priv, &priv->map->RDSAR, priv->rx_ring_dma); |
450 | rtl818x_iowrite32(priv, &priv->map->TBDA, priv->tx_ring[3].dma); | 809 | /* mac80211 queue have higher prio for lower index. The last queue |
451 | rtl818x_iowrite32(priv, &priv->map->THPDA, priv->tx_ring[2].dma); | 810 | * (that mac80211 is not aware of) is reserved for beacons (and have |
452 | rtl818x_iowrite32(priv, &priv->map->TNPDA, priv->tx_ring[1].dma); | 811 | * the highest priority on the NIC) |
453 | rtl818x_iowrite32(priv, &priv->map->TLPDA, priv->tx_ring[0].dma); | 812 | */ |
813 | if (priv->chip_family != RTL818X_CHIP_FAMILY_RTL8187SE) { | ||
814 | rtl818x_iowrite32(priv, &priv->map->TBDA, | ||
815 | priv->tx_ring[1].dma); | ||
816 | rtl818x_iowrite32(priv, &priv->map->TLPDA, | ||
817 | priv->tx_ring[0].dma); | ||
818 | } else { | ||
819 | rtl818x_iowrite32(priv, &priv->map->TBDA, | ||
820 | priv->tx_ring[4].dma); | ||
821 | rtl818x_iowrite32(priv, &priv->map->TVODA, | ||
822 | priv->tx_ring[0].dma); | ||
823 | rtl818x_iowrite32(priv, &priv->map->TVIDA, | ||
824 | priv->tx_ring[1].dma); | ||
825 | rtl818x_iowrite32(priv, &priv->map->TBEDA, | ||
826 | priv->tx_ring[2].dma); | ||
827 | rtl818x_iowrite32(priv, &priv->map->TBKDA, | ||
828 | priv->tx_ring[3].dma); | ||
829 | } | ||
454 | 830 | ||
455 | /* TODO: necessary? specs indicate not */ | 831 | /* TODO: necessary? specs indicate not */ |
456 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); | 832 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); |
@@ -471,7 +847,14 @@ static int rtl8180_init_hw(struct ieee80211_hw *dev) | |||
471 | if (priv->chip_family != RTL818X_CHIP_FAMILY_RTL8180) { | 847 | if (priv->chip_family != RTL818X_CHIP_FAMILY_RTL8180) { |
472 | rtl818x_iowrite8(priv, &priv->map->WPA_CONF, 0); | 848 | rtl818x_iowrite8(priv, &priv->map->WPA_CONF, 0); |
473 | rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, 0x81); | 849 | rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, 0x81); |
850 | } else { | ||
851 | rtl818x_iowrite8(priv, &priv->map->SECURITY, 0); | ||
474 | 852 | ||
853 | rtl818x_iowrite8(priv, &priv->map->PHY_DELAY, 0x6); | ||
854 | rtl818x_iowrite8(priv, &priv->map->CARRIER_SENSE_COUNTER, 0x4C); | ||
855 | } | ||
856 | |||
857 | if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8185) { | ||
475 | /* TODO: set ClkRun enable? necessary? */ | 858 | /* TODO: set ClkRun enable? necessary? */ |
476 | reg = rtl818x_ioread8(priv, &priv->map->GP_ENABLE); | 859 | reg = rtl818x_ioread8(priv, &priv->map->GP_ENABLE); |
477 | rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, reg & ~(1 << 6)); | 860 | rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, reg & ~(1 << 6)); |
@@ -479,11 +862,55 @@ static int rtl8180_init_hw(struct ieee80211_hw *dev) | |||
479 | reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); | 862 | reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); |
480 | rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | (1 << 2)); | 863 | rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | (1 << 2)); |
481 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); | 864 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); |
482 | } else { | 865 | } |
483 | rtl818x_iowrite8(priv, &priv->map->SECURITY, 0); | ||
484 | 866 | ||
485 | rtl818x_iowrite8(priv, &priv->map->PHY_DELAY, 0x6); | 867 | if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) { |
486 | rtl818x_iowrite8(priv, &priv->map->CARRIER_SENSE_COUNTER, 0x4C); | 868 | |
869 | /* the set auto rate fallback bitmask from 1M to 54 Mb/s */ | ||
870 | rtl818x_iowrite16(priv, ARFR, 0xFFF); | ||
871 | rtl818x_ioread16(priv, ARFR); | ||
872 | |||
873 | /* stop unused queus (no dma alloc) */ | ||
874 | rtl818x_iowrite8(priv, &priv->map->TPPOLL_STOP, | ||
875 | RTL818x_TPPOLL_STOP_MG | RTL818x_TPPOLL_STOP_HI); | ||
876 | |||
877 | rtl818x_iowrite8(priv, &priv->map->ACM_CONTROL, 0x00); | ||
878 | rtl818x_iowrite16(priv, &priv->map->TID_AC_MAP, 0xFA50); | ||
879 | |||
880 | rtl818x_iowrite16(priv, &priv->map->INT_MIG, 0); | ||
881 | |||
882 | /* some black magic here.. */ | ||
883 | rtl8187se_mac_config(dev); | ||
884 | |||
885 | rtl818x_iowrite16(priv, RFSW_CTRL, 0x569A); | ||
886 | rtl818x_ioread16(priv, RFSW_CTRL); | ||
887 | |||
888 | rtl8180_set_anaparam(priv, RTL8225SE_ANAPARAM_ON); | ||
889 | rtl8180_set_anaparam2(priv, RTL8225SE_ANAPARAM2_ON); | ||
890 | rtl8180_set_anaparam3(priv, RTL8225SE_ANAPARAM3); | ||
891 | |||
892 | |||
893 | rtl818x_iowrite8(priv, &priv->map->CONFIG5, | ||
894 | rtl818x_ioread8(priv, &priv->map->CONFIG5) & 0x7F); | ||
895 | |||
896 | /*probably this switch led on */ | ||
897 | rtl818x_iowrite8(priv, &priv->map->PGSELECT, | ||
898 | rtl818x_ioread8(priv, &priv->map->PGSELECT) | 0x08); | ||
899 | |||
900 | rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480); | ||
901 | rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1BFF); | ||
902 | rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x2488); | ||
903 | |||
904 | rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x4003); | ||
905 | |||
906 | /* the reference code mac hardcode table write | ||
907 | * this reg by doing byte-wide accesses. | ||
908 | * It does it just for lowest and highest byte.. | ||
909 | */ | ||
910 | reg32 = rtl818x_ioread32(priv, &priv->map->RF_PARA); | ||
911 | reg32 &= 0x00ffff00; | ||
912 | reg32 |= 0xb8000054; | ||
913 | rtl818x_iowrite32(priv, &priv->map->RF_PARA, reg32); | ||
487 | } | 914 | } |
488 | 915 | ||
489 | priv->rf->init(dev); | 916 | priv->rf->init(dev); |
@@ -499,17 +926,26 @@ static int rtl8180_init_hw(struct ieee80211_hw *dev) | |||
499 | else | 926 | else |
500 | rtl8180_conf_basic_rates(dev, 0x1f3); | 927 | rtl8180_conf_basic_rates(dev, 0x1f3); |
501 | 928 | ||
929 | if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) | ||
930 | rtl8187se_set_antenna_config(dev, | ||
931 | priv->antenna_diversity_default, | ||
932 | priv->antenna_diversity_en); | ||
502 | return 0; | 933 | return 0; |
503 | } | 934 | } |
504 | 935 | ||
505 | static int rtl8180_init_rx_ring(struct ieee80211_hw *dev) | 936 | static int rtl8180_init_rx_ring(struct ieee80211_hw *dev) |
506 | { | 937 | { |
507 | struct rtl8180_priv *priv = dev->priv; | 938 | struct rtl8180_priv *priv = dev->priv; |
508 | struct rtl8180_rx_desc *entry; | 939 | struct rtl818x_rx_cmd_desc *entry; |
509 | int i; | 940 | int i; |
510 | 941 | ||
942 | if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) | ||
943 | priv->rx_ring_sz = sizeof(struct rtl8187se_rx_desc); | ||
944 | else | ||
945 | priv->rx_ring_sz = sizeof(struct rtl8180_rx_desc); | ||
946 | |||
511 | priv->rx_ring = pci_alloc_consistent(priv->pdev, | 947 | priv->rx_ring = pci_alloc_consistent(priv->pdev, |
512 | sizeof(*priv->rx_ring) * 32, | 948 | priv->rx_ring_sz * 32, |
513 | &priv->rx_ring_dma); | 949 | &priv->rx_ring_dma); |
514 | 950 | ||
515 | if (!priv->rx_ring || (unsigned long)priv->rx_ring & 0xFF) { | 951 | if (!priv->rx_ring || (unsigned long)priv->rx_ring & 0xFF) { |
@@ -517,13 +953,13 @@ static int rtl8180_init_rx_ring(struct ieee80211_hw *dev) | |||
517 | return -ENOMEM; | 953 | return -ENOMEM; |
518 | } | 954 | } |
519 | 955 | ||
520 | memset(priv->rx_ring, 0, sizeof(*priv->rx_ring) * 32); | 956 | memset(priv->rx_ring, 0, priv->rx_ring_sz * 32); |
521 | priv->rx_idx = 0; | 957 | priv->rx_idx = 0; |
522 | 958 | ||
523 | for (i = 0; i < 32; i++) { | 959 | for (i = 0; i < 32; i++) { |
524 | struct sk_buff *skb = dev_alloc_skb(MAX_RX_SIZE); | 960 | struct sk_buff *skb = dev_alloc_skb(MAX_RX_SIZE); |
525 | dma_addr_t *mapping; | 961 | dma_addr_t *mapping; |
526 | entry = &priv->rx_ring[i]; | 962 | entry = priv->rx_ring + priv->rx_ring_sz*i; |
527 | if (!skb) { | 963 | if (!skb) { |
528 | wiphy_err(dev->wiphy, "Cannot allocate RX skb\n"); | 964 | wiphy_err(dev->wiphy, "Cannot allocate RX skb\n"); |
529 | return -ENOMEM; | 965 | return -ENOMEM; |
@@ -563,7 +999,7 @@ static void rtl8180_free_rx_ring(struct ieee80211_hw *dev) | |||
563 | kfree_skb(skb); | 999 | kfree_skb(skb); |
564 | } | 1000 | } |
565 | 1001 | ||
566 | pci_free_consistent(priv->pdev, sizeof(*priv->rx_ring) * 32, | 1002 | pci_free_consistent(priv->pdev, priv->rx_ring_sz * 32, |
567 | priv->rx_ring, priv->rx_ring_dma); | 1003 | priv->rx_ring, priv->rx_ring_dma); |
568 | priv->rx_ring = NULL; | 1004 | priv->rx_ring = NULL; |
569 | } | 1005 | } |
@@ -627,7 +1063,7 @@ static int rtl8180_start(struct ieee80211_hw *dev) | |||
627 | if (ret) | 1063 | if (ret) |
628 | return ret; | 1064 | return ret; |
629 | 1065 | ||
630 | for (i = 0; i < 4; i++) | 1066 | for (i = 0; i < (dev->queues + 1); i++) |
631 | if ((ret = rtl8180_init_tx_ring(dev, i, 16))) | 1067 | if ((ret = rtl8180_init_tx_ring(dev, i, 16))) |
632 | goto err_free_rings; | 1068 | goto err_free_rings; |
633 | 1069 | ||
@@ -635,23 +1071,28 @@ static int rtl8180_start(struct ieee80211_hw *dev) | |||
635 | if (ret) | 1071 | if (ret) |
636 | goto err_free_rings; | 1072 | goto err_free_rings; |
637 | 1073 | ||
638 | rtl818x_iowrite32(priv, &priv->map->RDSAR, priv->rx_ring_dma); | 1074 | if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) { |
639 | rtl818x_iowrite32(priv, &priv->map->TBDA, priv->tx_ring[3].dma); | 1075 | ret = request_irq(priv->pdev->irq, rtl8187se_interrupt, |
640 | rtl818x_iowrite32(priv, &priv->map->THPDA, priv->tx_ring[2].dma); | ||
641 | rtl818x_iowrite32(priv, &priv->map->TNPDA, priv->tx_ring[1].dma); | ||
642 | rtl818x_iowrite32(priv, &priv->map->TLPDA, priv->tx_ring[0].dma); | ||
643 | |||
644 | ret = request_irq(priv->pdev->irq, rtl8180_interrupt, | ||
645 | IRQF_SHARED, KBUILD_MODNAME, dev); | 1076 | IRQF_SHARED, KBUILD_MODNAME, dev); |
1077 | } else { | ||
1078 | ret = request_irq(priv->pdev->irq, rtl8180_interrupt, | ||
1079 | IRQF_SHARED, KBUILD_MODNAME, dev); | ||
1080 | } | ||
1081 | |||
646 | if (ret) { | 1082 | if (ret) { |
647 | wiphy_err(dev->wiphy, "failed to register IRQ handler\n"); | 1083 | wiphy_err(dev->wiphy, "failed to register IRQ handler\n"); |
648 | goto err_free_rings; | 1084 | goto err_free_rings; |
649 | } | 1085 | } |
650 | 1086 | ||
651 | rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0xFFFF); | 1087 | rtl8180_int_enable(dev); |
652 | 1088 | ||
653 | rtl818x_iowrite32(priv, &priv->map->MAR[0], ~0); | 1089 | /* in rtl8187se at MAR regs offset there is the management |
654 | rtl818x_iowrite32(priv, &priv->map->MAR[1], ~0); | 1090 | * TX descriptor DMA addres.. |
1091 | */ | ||
1092 | if (priv->chip_family != RTL818X_CHIP_FAMILY_RTL8187SE) { | ||
1093 | rtl818x_iowrite32(priv, &priv->map->MAR[0], ~0); | ||
1094 | rtl818x_iowrite32(priv, &priv->map->MAR[1], ~0); | ||
1095 | } | ||
655 | 1096 | ||
656 | reg = RTL818X_RX_CONF_ONLYERLPKT | | 1097 | reg = RTL818X_RX_CONF_ONLYERLPKT | |
657 | RTL818X_RX_CONF_RX_AUTORESETPHY | | 1098 | RTL818X_RX_CONF_RX_AUTORESETPHY | |
@@ -663,11 +1104,13 @@ static int rtl8180_start(struct ieee80211_hw *dev) | |||
663 | 1104 | ||
664 | if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8185) | 1105 | if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8185) |
665 | reg |= RTL818X_RX_CONF_CSDM1 | RTL818X_RX_CONF_CSDM2; | 1106 | reg |= RTL818X_RX_CONF_CSDM1 | RTL818X_RX_CONF_CSDM2; |
666 | else { | 1107 | else if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8180) { |
667 | reg |= (priv->rfparam & RF_PARAM_CARRIERSENSE1) | 1108 | reg |= (priv->rfparam & RF_PARAM_CARRIERSENSE1) |
668 | ? RTL818X_RX_CONF_CSDM1 : 0; | 1109 | ? RTL818X_RX_CONF_CSDM1 : 0; |
669 | reg |= (priv->rfparam & RF_PARAM_CARRIERSENSE2) | 1110 | reg |= (priv->rfparam & RF_PARAM_CARRIERSENSE2) |
670 | ? RTL818X_RX_CONF_CSDM2 : 0; | 1111 | ? RTL818X_RX_CONF_CSDM2 : 0; |
1112 | } else { | ||
1113 | reg &= ~(RTL818X_RX_CONF_CSDM1 | RTL818X_RX_CONF_CSDM2); | ||
671 | } | 1114 | } |
672 | 1115 | ||
673 | priv->rx_conf = reg; | 1116 | priv->rx_conf = reg; |
@@ -678,6 +1121,7 @@ static int rtl8180_start(struct ieee80211_hw *dev) | |||
678 | 1121 | ||
679 | /* CW is not on per-packet basis. | 1122 | /* CW is not on per-packet basis. |
680 | * in rtl8185 the CW_VALUE reg is used. | 1123 | * in rtl8185 the CW_VALUE reg is used. |
1124 | * in rtl8187se the AC param regs are used. | ||
681 | */ | 1125 | */ |
682 | reg &= ~RTL818X_CW_CONF_PERPACKET_CW; | 1126 | reg &= ~RTL818X_CW_CONF_PERPACKET_CW; |
683 | /* retry limit IS on per-packet basis. | 1127 | /* retry limit IS on per-packet basis. |
@@ -705,7 +1149,8 @@ static int rtl8180_start(struct ieee80211_hw *dev) | |||
705 | reg |= (6 << 21 /* MAX TX DMA */) | | 1149 | reg |= (6 << 21 /* MAX TX DMA */) | |
706 | RTL818X_TX_CONF_NO_ICV; | 1150 | RTL818X_TX_CONF_NO_ICV; |
707 | 1151 | ||
708 | 1152 | if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) | |
1153 | reg |= 1<<30; /* "duration procedure mode" */ | ||
709 | 1154 | ||
710 | if (priv->chip_family != RTL818X_CHIP_FAMILY_RTL8180) | 1155 | if (priv->chip_family != RTL818X_CHIP_FAMILY_RTL8180) |
711 | reg &= ~RTL818X_TX_CONF_PROBE_DTS; | 1156 | reg &= ~RTL818X_TX_CONF_PROBE_DTS; |
@@ -728,7 +1173,7 @@ static int rtl8180_start(struct ieee80211_hw *dev) | |||
728 | 1173 | ||
729 | err_free_rings: | 1174 | err_free_rings: |
730 | rtl8180_free_rx_ring(dev); | 1175 | rtl8180_free_rx_ring(dev); |
731 | for (i = 0; i < 4; i++) | 1176 | for (i = 0; i < (dev->queues + 1); i++) |
732 | if (priv->tx_ring[i].desc) | 1177 | if (priv->tx_ring[i].desc) |
733 | rtl8180_free_tx_ring(dev, i); | 1178 | rtl8180_free_tx_ring(dev, i); |
734 | 1179 | ||
@@ -741,7 +1186,7 @@ static void rtl8180_stop(struct ieee80211_hw *dev) | |||
741 | u8 reg; | 1186 | u8 reg; |
742 | int i; | 1187 | int i; |
743 | 1188 | ||
744 | rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0); | 1189 | rtl8180_int_disable(dev); |
745 | 1190 | ||
746 | reg = rtl818x_ioread8(priv, &priv->map->CMD); | 1191 | reg = rtl818x_ioread8(priv, &priv->map->CMD); |
747 | reg &= ~RTL818X_CMD_TX_ENABLE; | 1192 | reg &= ~RTL818X_CMD_TX_ENABLE; |
@@ -758,7 +1203,7 @@ static void rtl8180_stop(struct ieee80211_hw *dev) | |||
758 | free_irq(priv->pdev->irq, dev); | 1203 | free_irq(priv->pdev->irq, dev); |
759 | 1204 | ||
760 | rtl8180_free_rx_ring(dev); | 1205 | rtl8180_free_rx_ring(dev); |
761 | for (i = 0; i < 4; i++) | 1206 | for (i = 0; i < (dev->queues + 1); i++) |
762 | rtl8180_free_tx_ring(dev, i); | 1207 | rtl8180_free_tx_ring(dev, i); |
763 | } | 1208 | } |
764 | 1209 | ||
@@ -866,6 +1311,49 @@ static int rtl8180_config(struct ieee80211_hw *dev, u32 changed) | |||
866 | return 0; | 1311 | return 0; |
867 | } | 1312 | } |
868 | 1313 | ||
1314 | static void rtl8187se_conf_ac_parm(struct ieee80211_hw *dev, u8 queue) | ||
1315 | { | ||
1316 | const struct ieee80211_tx_queue_params *params; | ||
1317 | struct rtl8180_priv *priv = dev->priv; | ||
1318 | |||
1319 | /* hw value */ | ||
1320 | u32 ac_param; | ||
1321 | |||
1322 | u8 aifs; | ||
1323 | u8 txop; | ||
1324 | u8 cw_min, cw_max; | ||
1325 | |||
1326 | params = &priv->queue_param[queue]; | ||
1327 | |||
1328 | cw_min = fls(params->cw_min); | ||
1329 | cw_max = fls(params->cw_max); | ||
1330 | |||
1331 | aifs = 10 + params->aifs * priv->slot_time; | ||
1332 | |||
1333 | /* TODO: check if txop HW is in us (mult by 32) */ | ||
1334 | txop = params->txop; | ||
1335 | |||
1336 | ac_param = txop << AC_PARAM_TXOP_LIMIT_SHIFT | | ||
1337 | cw_max << AC_PARAM_ECW_MAX_SHIFT | | ||
1338 | cw_min << AC_PARAM_ECW_MIN_SHIFT | | ||
1339 | aifs << AC_PARAM_AIFS_SHIFT; | ||
1340 | |||
1341 | switch (queue) { | ||
1342 | case IEEE80211_AC_BK: | ||
1343 | rtl818x_iowrite32(priv, &priv->map->AC_BK_PARAM, ac_param); | ||
1344 | break; | ||
1345 | case IEEE80211_AC_BE: | ||
1346 | rtl818x_iowrite32(priv, &priv->map->AC_BE_PARAM, ac_param); | ||
1347 | break; | ||
1348 | case IEEE80211_AC_VI: | ||
1349 | rtl818x_iowrite32(priv, &priv->map->AC_VI_PARAM, ac_param); | ||
1350 | break; | ||
1351 | case IEEE80211_AC_VO: | ||
1352 | rtl818x_iowrite32(priv, &priv->map->AC_VO_PARAM, ac_param); | ||
1353 | break; | ||
1354 | } | ||
1355 | } | ||
1356 | |||
869 | static int rtl8180_conf_tx(struct ieee80211_hw *dev, | 1357 | static int rtl8180_conf_tx(struct ieee80211_hw *dev, |
870 | struct ieee80211_vif *vif, u16 queue, | 1358 | struct ieee80211_vif *vif, u16 queue, |
871 | const struct ieee80211_tx_queue_params *params) | 1359 | const struct ieee80211_tx_queue_params *params) |
@@ -880,8 +1368,12 @@ static int rtl8180_conf_tx(struct ieee80211_hw *dev, | |||
880 | cw_min = fls(params->cw_min); | 1368 | cw_min = fls(params->cw_min); |
881 | cw_max = fls(params->cw_max); | 1369 | cw_max = fls(params->cw_max); |
882 | 1370 | ||
883 | rtl818x_iowrite8(priv, &priv->map->CW_VAL, (cw_max << 4) | cw_min); | 1371 | if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) { |
884 | 1372 | priv->queue_param[queue] = *params; | |
1373 | rtl8187se_conf_ac_parm(dev, queue); | ||
1374 | } else | ||
1375 | rtl818x_iowrite8(priv, &priv->map->CW_VAL, | ||
1376 | (cw_max << 4) | cw_min); | ||
885 | return 0; | 1377 | return 0; |
886 | } | 1378 | } |
887 | 1379 | ||
@@ -923,13 +1415,17 @@ static void rtl8180_conf_erp(struct ieee80211_hw *dev, | |||
923 | /* from reference code. set ack timeout reg = eifs reg */ | 1415 | /* from reference code. set ack timeout reg = eifs reg */ |
924 | rtl818x_iowrite8(priv, &priv->map->CARRIER_SENSE_COUNTER, hw_eifs); | 1416 | rtl818x_iowrite8(priv, &priv->map->CARRIER_SENSE_COUNTER, hw_eifs); |
925 | 1417 | ||
926 | /* rtl8187/rtl8185 HW bug. After EIFS is elapsed, | 1418 | if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) |
927 | * the HW still wait for DIFS. | 1419 | rtl818x_iowrite8(priv, &priv->map->EIFS_8187SE, hw_eifs); |
928 | * HW uses 4uS units for EIFS. | 1420 | else if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8185) { |
929 | */ | 1421 | /* rtl8187/rtl8185 HW bug. After EIFS is elapsed, |
930 | hw_eifs = DIV_ROUND_UP(eifs - difs, 4); | 1422 | * the HW still wait for DIFS. |
1423 | * HW uses 4uS units for EIFS. | ||
1424 | */ | ||
1425 | hw_eifs = DIV_ROUND_UP(eifs - difs, 4); | ||
931 | 1426 | ||
932 | rtl818x_iowrite8(priv, &priv->map->EIFS, hw_eifs); | 1427 | rtl818x_iowrite8(priv, &priv->map->EIFS, hw_eifs); |
1428 | } | ||
933 | } | 1429 | } |
934 | 1430 | ||
935 | static void rtl8180_bss_info_changed(struct ieee80211_hw *dev, | 1431 | static void rtl8180_bss_info_changed(struct ieee80211_hw *dev, |
@@ -956,6 +1452,10 @@ static void rtl8180_bss_info_changed(struct ieee80211_hw *dev, | |||
956 | reg = RTL818X_MSR_INFRA; | 1452 | reg = RTL818X_MSR_INFRA; |
957 | } else | 1453 | } else |
958 | reg = RTL818X_MSR_NO_LINK; | 1454 | reg = RTL818X_MSR_NO_LINK; |
1455 | |||
1456 | if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) | ||
1457 | reg |= RTL818X_MSR_ENEDCA; | ||
1458 | |||
959 | rtl818x_iowrite8(priv, &priv->map->MSR, reg); | 1459 | rtl818x_iowrite8(priv, &priv->map->MSR, reg); |
960 | } | 1460 | } |
961 | 1461 | ||
@@ -975,6 +1475,16 @@ static void rtl8180_bss_info_changed(struct ieee80211_hw *dev, | |||
975 | &priv->rates[0])) - 10; | 1475 | &priv->rates[0])) - 10; |
976 | 1476 | ||
977 | rtl8180_conf_erp(dev, info); | 1477 | rtl8180_conf_erp(dev, info); |
1478 | |||
1479 | /* mac80211 supplies aifs_n to driver and calls | ||
1480 | * conf_tx callback whether aifs_n changes, NOT | ||
1481 | * when aifs changes. | ||
1482 | * Aifs should be recalculated if slot changes. | ||
1483 | */ | ||
1484 | if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) { | ||
1485 | for (i = 0; i < 4; i++) | ||
1486 | rtl8187se_conf_ac_parm(dev, i); | ||
1487 | } | ||
978 | } | 1488 | } |
979 | 1489 | ||
980 | if (changed & BSS_CHANGED_BEACON_ENABLED) | 1490 | if (changed & BSS_CHANGED_BEACON_ENABLED) |
@@ -1098,7 +1608,10 @@ static void rtl8180_eeprom_read(struct rtl8180_priv *priv) | |||
1098 | 1608 | ||
1099 | eeprom_93cx6_multiread(&eeprom, 0x7, (__le16 *)priv->mac_addr, 3); | 1609 | eeprom_93cx6_multiread(&eeprom, 0x7, (__le16 *)priv->mac_addr, 3); |
1100 | 1610 | ||
1101 | eeprom_cck_table_adr = 0x10; | 1611 | if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) |
1612 | eeprom_cck_table_adr = 0x30; | ||
1613 | else | ||
1614 | eeprom_cck_table_adr = 0x10; | ||
1102 | 1615 | ||
1103 | /* CCK TX power */ | 1616 | /* CCK TX power */ |
1104 | for (i = 0; i < 14; i += 2) { | 1617 | for (i = 0; i < 14; i += 2) { |
@@ -1126,6 +1639,19 @@ static void rtl8180_eeprom_read(struct rtl8180_priv *priv) | |||
1126 | eeprom_93cx6_read(&eeprom, 0x19, &priv->rfparam); | 1639 | eeprom_93cx6_read(&eeprom, 0x19, &priv->rfparam); |
1127 | } | 1640 | } |
1128 | 1641 | ||
1642 | if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) { | ||
1643 | eeprom_93cx6_read(&eeprom, 0x3F, &eeprom_val); | ||
1644 | priv->antenna_diversity_en = !!(eeprom_val & 0x100); | ||
1645 | priv->antenna_diversity_default = (eeprom_val & 0xC00) == 0x400; | ||
1646 | |||
1647 | eeprom_93cx6_read(&eeprom, 0x7C, &eeprom_val); | ||
1648 | priv->xtal_out = eeprom_val & 0xF; | ||
1649 | priv->xtal_in = (eeprom_val & 0xF0) >> 4; | ||
1650 | priv->xtal_cal = !!(eeprom_val & 0x1000); | ||
1651 | priv->thermal_meter_val = (eeprom_val & 0xF00) >> 8; | ||
1652 | priv->thermal_meter_en = !!(eeprom_val & 0x2000); | ||
1653 | } | ||
1654 | |||
1129 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, | 1655 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, |
1130 | RTL818X_EEPROM_CMD_NORMAL); | 1656 | RTL818X_EEPROM_CMD_NORMAL); |
1131 | } | 1657 | } |
@@ -1221,7 +1747,6 @@ static int rtl8180_probe(struct pci_dev *pdev, | |||
1221 | dev->vif_data_size = sizeof(struct rtl8180_vif); | 1747 | dev->vif_data_size = sizeof(struct rtl8180_vif); |
1222 | dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | | 1748 | dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | |
1223 | BIT(NL80211_IFTYPE_ADHOC); | 1749 | BIT(NL80211_IFTYPE_ADHOC); |
1224 | dev->queues = 1; | ||
1225 | dev->max_signal = 65; | 1750 | dev->max_signal = 65; |
1226 | 1751 | ||
1227 | reg = rtl818x_ioread32(priv, &priv->map->TX_CONF); | 1752 | reg = rtl818x_ioread32(priv, &priv->map->TX_CONF); |
@@ -1246,12 +1771,30 @@ static int rtl8180_probe(struct pci_dev *pdev, | |||
1246 | chip_name = "RTL8185vD"; | 1771 | chip_name = "RTL8185vD"; |
1247 | priv->chip_family = RTL818X_CHIP_FAMILY_RTL8185; | 1772 | priv->chip_family = RTL818X_CHIP_FAMILY_RTL8185; |
1248 | break; | 1773 | break; |
1774 | |||
1775 | case RTL818X_TX_CONF_RTL8187SE: | ||
1776 | chip_name = "RTL8187SE"; | ||
1777 | priv->chip_family = RTL818X_CHIP_FAMILY_RTL8187SE; | ||
1778 | break; | ||
1779 | |||
1249 | default: | 1780 | default: |
1250 | printk(KERN_ERR "%s (rtl8180): Unknown chip! (0x%x)\n", | 1781 | printk(KERN_ERR "%s (rtl8180): Unknown chip! (0x%x)\n", |
1251 | pci_name(pdev), reg >> 25); | 1782 | pci_name(pdev), reg >> 25); |
1252 | goto err_iounmap; | 1783 | goto err_iounmap; |
1253 | } | 1784 | } |
1254 | 1785 | ||
1786 | /* we declare to MAC80211 all the queues except for beacon queue | ||
1787 | * that will be eventually handled by DRV. | ||
1788 | * TX rings are arranged in such a way that lower is the IDX, | ||
1789 | * higher is the priority, in order to achieve direct mapping | ||
1790 | * with mac80211, however the beacon queue is an exception and it | ||
1791 | * is mapped on the highst tx ring IDX. | ||
1792 | */ | ||
1793 | if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) | ||
1794 | dev->queues = RTL8187SE_NR_TX_QUEUES - 1; | ||
1795 | else | ||
1796 | dev->queues = RTL8180_NR_TX_QUEUES - 1; | ||
1797 | |||
1255 | if (priv->chip_family != RTL818X_CHIP_FAMILY_RTL8180) { | 1798 | if (priv->chip_family != RTL818X_CHIP_FAMILY_RTL8180) { |
1256 | priv->band.n_bitrates = ARRAY_SIZE(rtl818x_rates); | 1799 | priv->band.n_bitrates = ARRAY_SIZE(rtl818x_rates); |
1257 | pci_try_set_mwi(pdev); | 1800 | pci_try_set_mwi(pdev); |
@@ -1270,7 +1813,11 @@ static int rtl8180_probe(struct pci_dev *pdev, | |||
1270 | break; | 1813 | break; |
1271 | case 5: priv->rf = &grf5101_rf_ops; | 1814 | case 5: priv->rf = &grf5101_rf_ops; |
1272 | break; | 1815 | break; |
1273 | case 9: priv->rf = rtl8180_detect_rf(dev); | 1816 | case 9: |
1817 | if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) | ||
1818 | priv->rf = rtl8187se_detect_rf(dev); | ||
1819 | else | ||
1820 | priv->rf = rtl8180_detect_rf(dev); | ||
1274 | break; | 1821 | break; |
1275 | case 10: | 1822 | case 10: |
1276 | rf_name = "RTL8255"; | 1823 | rf_name = "RTL8255"; |
diff --git a/drivers/net/wireless/rtl818x/rtl8180/rtl8180.h b/drivers/net/wireless/rtl818x/rtl8180/rtl8180.h index 26383d77fc3a..291a55970d1a 100644 --- a/drivers/net/wireless/rtl818x/rtl8180/rtl8180.h +++ b/drivers/net/wireless/rtl818x/rtl8180/rtl8180.h | |||
@@ -24,27 +24,64 @@ | |||
24 | #define ANAPARAM_PWR1_SHIFT 20 | 24 | #define ANAPARAM_PWR1_SHIFT 20 |
25 | #define ANAPARAM_PWR1_MASK (0x7F << ANAPARAM_PWR1_SHIFT) | 25 | #define ANAPARAM_PWR1_MASK (0x7F << ANAPARAM_PWR1_SHIFT) |
26 | 26 | ||
27 | /* rtl8180/rtl8185 have 3 queue + beacon queue. | ||
28 | * mac80211 can use just one, + beacon = 2 tot. | ||
29 | */ | ||
30 | #define RTL8180_NR_TX_QUEUES 2 | ||
31 | |||
32 | /* rtl8187SE have 6 queues + beacon queues | ||
33 | * mac80211 can use 4 QoS data queue, + beacon = 5 tot | ||
34 | */ | ||
35 | #define RTL8187SE_NR_TX_QUEUES 5 | ||
36 | |||
37 | /* for array static allocation, it is the max of above */ | ||
38 | #define RTL818X_NR_TX_QUEUES 5 | ||
39 | |||
27 | struct rtl8180_tx_desc { | 40 | struct rtl8180_tx_desc { |
28 | __le32 flags; | 41 | __le32 flags; |
29 | __le16 rts_duration; | 42 | __le16 rts_duration; |
30 | __le16 plcp_len; | 43 | __le16 plcp_len; |
31 | __le32 tx_buf; | 44 | __le32 tx_buf; |
32 | __le32 frame_len; | 45 | union{ |
46 | __le32 frame_len; | ||
47 | struct { | ||
48 | __le16 frame_len_se; | ||
49 | __le16 frame_duration; | ||
50 | } __packed; | ||
51 | } __packed; | ||
33 | __le32 next_tx_desc; | 52 | __le32 next_tx_desc; |
34 | u8 cw; | 53 | u8 cw; |
35 | u8 retry_limit; | 54 | u8 retry_limit; |
36 | u8 agc; | 55 | u8 agc; |
37 | u8 flags2; | 56 | u8 flags2; |
38 | u32 reserved[2]; | 57 | /* rsvd for 8180/8185. |
58 | * valid for 8187se but we dont use it | ||
59 | */ | ||
60 | u32 reserved; | ||
61 | /* all rsvd for 8180/8185 */ | ||
62 | __le16 flags3; | ||
63 | __le16 frag_qsize; | ||
64 | } __packed; | ||
65 | |||
66 | struct rtl818x_rx_cmd_desc { | ||
67 | __le32 flags; | ||
68 | u32 reserved; | ||
69 | __le32 rx_buf; | ||
39 | } __packed; | 70 | } __packed; |
40 | 71 | ||
41 | struct rtl8180_rx_desc { | 72 | struct rtl8180_rx_desc { |
42 | __le32 flags; | 73 | __le32 flags; |
43 | __le32 flags2; | 74 | __le32 flags2; |
44 | union { | 75 | __le64 tsft; |
45 | __le32 rx_buf; | 76 | |
46 | __le64 tsft; | 77 | } __packed; |
47 | }; | 78 | |
79 | struct rtl8187se_rx_desc { | ||
80 | __le32 flags; | ||
81 | __le64 tsft; | ||
82 | __le32 flags2; | ||
83 | __le32 flags3; | ||
84 | u32 reserved[3]; | ||
48 | } __packed; | 85 | } __packed; |
49 | 86 | ||
50 | struct rtl8180_tx_ring { | 87 | struct rtl8180_tx_ring { |
@@ -71,14 +108,16 @@ struct rtl8180_priv { | |||
71 | 108 | ||
72 | /* rtl8180 driver specific */ | 109 | /* rtl8180 driver specific */ |
73 | spinlock_t lock; | 110 | spinlock_t lock; |
74 | struct rtl8180_rx_desc *rx_ring; | 111 | void *rx_ring; |
112 | u8 rx_ring_sz; | ||
75 | dma_addr_t rx_ring_dma; | 113 | dma_addr_t rx_ring_dma; |
76 | unsigned int rx_idx; | 114 | unsigned int rx_idx; |
77 | struct sk_buff *rx_buf[32]; | 115 | struct sk_buff *rx_buf[32]; |
78 | struct rtl8180_tx_ring tx_ring[4]; | 116 | struct rtl8180_tx_ring tx_ring[RTL818X_NR_TX_QUEUES]; |
79 | struct ieee80211_channel channels[14]; | 117 | struct ieee80211_channel channels[14]; |
80 | struct ieee80211_rate rates[12]; | 118 | struct ieee80211_rate rates[12]; |
81 | struct ieee80211_supported_band band; | 119 | struct ieee80211_supported_band band; |
120 | struct ieee80211_tx_queue_params queue_param[4]; | ||
82 | struct pci_dev *pdev; | 121 | struct pci_dev *pdev; |
83 | u32 rx_conf; | 122 | u32 rx_conf; |
84 | u8 slot_time; | 123 | u8 slot_time; |
@@ -87,18 +126,27 @@ struct rtl8180_priv { | |||
87 | enum { | 126 | enum { |
88 | RTL818X_CHIP_FAMILY_RTL8180, | 127 | RTL818X_CHIP_FAMILY_RTL8180, |
89 | RTL818X_CHIP_FAMILY_RTL8185, | 128 | RTL818X_CHIP_FAMILY_RTL8185, |
129 | RTL818X_CHIP_FAMILY_RTL8187SE, | ||
90 | } chip_family; | 130 | } chip_family; |
91 | u32 anaparam; | 131 | u32 anaparam; |
92 | u16 rfparam; | 132 | u16 rfparam; |
93 | u8 csthreshold; | 133 | u8 csthreshold; |
94 | u8 mac_addr[ETH_ALEN]; | 134 | u8 mac_addr[ETH_ALEN]; |
95 | u8 rf_type; | 135 | u8 rf_type; |
136 | u8 xtal_out; | ||
137 | u8 xtal_in; | ||
138 | u8 xtal_cal; | ||
139 | u8 thermal_meter_val; | ||
140 | u8 thermal_meter_en; | ||
141 | u8 antenna_diversity_en; | ||
142 | u8 antenna_diversity_default; | ||
96 | /* sequence # */ | 143 | /* sequence # */ |
97 | u16 seqno; | 144 | u16 seqno; |
98 | }; | 145 | }; |
99 | 146 | ||
100 | void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data); | 147 | void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data); |
101 | void rtl8180_set_anaparam(struct rtl8180_priv *priv, u32 anaparam); | 148 | void rtl8180_set_anaparam(struct rtl8180_priv *priv, u32 anaparam); |
149 | void rtl8180_set_anaparam2(struct rtl8180_priv *priv, u32 anaparam2); | ||
102 | 150 | ||
103 | static inline u8 rtl818x_ioread8(struct rtl8180_priv *priv, u8 __iomem *addr) | 151 | static inline u8 rtl818x_ioread8(struct rtl8180_priv *priv, u8 __iomem *addr) |
104 | { | 152 | { |
diff --git a/drivers/net/wireless/rtl818x/rtl8180/rtl8225.c b/drivers/net/wireless/rtl818x/rtl8180/rtl8225.c index 1c0fe238d995..9bda5bc78eda 100644 --- a/drivers/net/wireless/rtl818x/rtl8180/rtl8225.c +++ b/drivers/net/wireless/rtl818x/rtl8180/rtl8225.c | |||
@@ -282,6 +282,7 @@ static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel) | |||
282 | 282 | ||
283 | msleep(1); /* FIXME: optional? */ | 283 | msleep(1); /* FIXME: optional? */ |
284 | 284 | ||
285 | /* TODO: use set_anaparam2 dev.c_func*/ | ||
285 | /* anaparam2 on */ | 286 | /* anaparam2 on */ |
286 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); | 287 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); |
287 | reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); | 288 | reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); |
diff --git a/drivers/net/wireless/rtl818x/rtl8180/rtl8225se.c b/drivers/net/wireless/rtl818x/rtl8180/rtl8225se.c new file mode 100644 index 000000000000..fde89866fa8d --- /dev/null +++ b/drivers/net/wireless/rtl818x/rtl8180/rtl8225se.c | |||
@@ -0,0 +1,475 @@ | |||
1 | |||
2 | /* Radio tuning for RTL8225 on RTL8187SE | ||
3 | * | ||
4 | * Copyright 2009 Larry Finger <Larry.Finger@lwfinger.net> | ||
5 | * Copyright 2014 Andrea Merello <andrea.merello@gmail.com> | ||
6 | * | ||
7 | * Based on the r8180 and Realtek r8187se drivers, which are: | ||
8 | * Copyright 2004-2005 Andrea Merello <andrea.merello@gmail.com>, et al. | ||
9 | * | ||
10 | * Also based on the rtl8187 driver, which is: | ||
11 | * Copyright 2007 Michael Wu <flamingice@sourmilk.net> | ||
12 | * Copyright 2007 Andrea Merello <andrea.merello@gmail.com> | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or modify | ||
15 | * it under the terms of the GNU General Public License version 2 as | ||
16 | * published by the Free Software Foundation. | ||
17 | */ | ||
18 | |||
19 | #include <net/mac80211.h> | ||
20 | |||
21 | #include "rtl8180.h" | ||
22 | #include "rtl8225se.h" | ||
23 | |||
24 | #define PFX "rtl8225 (se) " | ||
25 | |||
26 | static const u32 RF_GAIN_TABLE[] = { | ||
27 | 0x0096, 0x0076, 0x0056, 0x0036, 0x0016, 0x01f6, 0x01d6, 0x01b6, | ||
28 | 0x0196, 0x0176, 0x00F7, 0x00D7, 0x00B7, 0x0097, 0x0077, 0x0057, | ||
29 | 0x0037, 0x00FB, 0x00DB, 0x00BB, 0x00FF, 0x00E3, 0x00C3, 0x00A3, | ||
30 | 0x0083, 0x0063, 0x0043, 0x0023, 0x0003, 0x01E3, 0x01C3, 0x01A3, | ||
31 | 0x0183, 0x0163, 0x0143, 0x0123, 0x0103 | ||
32 | }; | ||
33 | |||
34 | static const u8 cck_ofdm_gain_settings[] = { | ||
35 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, | ||
36 | 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, | ||
37 | 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, | ||
38 | 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, | ||
39 | 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, | ||
40 | 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, | ||
41 | }; | ||
42 | |||
43 | static const u8 rtl8225se_tx_gain_cck_ofdm[] = { | ||
44 | 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e | ||
45 | }; | ||
46 | |||
47 | static const u8 rtl8225se_tx_power_cck[] = { | ||
48 | 0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02, | ||
49 | 0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02, | ||
50 | 0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02, | ||
51 | 0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02, | ||
52 | 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03, | ||
53 | 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03 | ||
54 | }; | ||
55 | |||
56 | static const u8 rtl8225se_tx_power_cck_ch14[] = { | ||
57 | 0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00, | ||
58 | 0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00, | ||
59 | 0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00, | ||
60 | 0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00, | ||
61 | 0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00, | ||
62 | 0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00 | ||
63 | }; | ||
64 | |||
65 | static const u8 rtl8225se_tx_power_ofdm[] = { | ||
66 | 0x80, 0x90, 0xa2, 0xb5, 0xcb, 0xe4 | ||
67 | }; | ||
68 | |||
69 | static const u32 rtl8225se_chan[] = { | ||
70 | 0x0080, 0x0100, 0x0180, 0x0200, 0x0280, 0x0300, 0x0380, | ||
71 | 0x0400, 0x0480, 0x0500, 0x0580, 0x0600, 0x0680, 0x074A, | ||
72 | }; | ||
73 | |||
74 | static const u8 rtl8225sez2_tx_power_cck_ch14[] = { | ||
75 | 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00 | ||
76 | }; | ||
77 | |||
78 | static const u8 rtl8225sez2_tx_power_cck_B[] = { | ||
79 | 0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x04 | ||
80 | }; | ||
81 | |||
82 | static const u8 rtl8225sez2_tx_power_cck_A[] = { | ||
83 | 0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04 | ||
84 | }; | ||
85 | |||
86 | static const u8 rtl8225sez2_tx_power_cck[] = { | ||
87 | 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04 | ||
88 | }; | ||
89 | |||
90 | static const u8 ZEBRA_AGC[] = { | ||
91 | 0x7E, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, 0x7B, 0x7A, | ||
92 | 0x79, 0x78, 0x77, 0x76, 0x75, 0x74, 0x73, 0x72, | ||
93 | 0x71, 0x70, 0x6F, 0x6E, 0x6D, 0x6C, 0x6B, 0x6A, | ||
94 | 0x69, 0x68, 0x67, 0x66, 0x65, 0x64, 0x63, 0x62, | ||
95 | 0x48, 0x47, 0x46, 0x45, 0x44, 0x29, 0x28, 0x27, | ||
96 | 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x08, 0x07, | ||
97 | 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, | ||
98 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
99 | 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, | ||
100 | 0x0f, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x15, 0x16, | ||
101 | 0x17, 0x17, 0x18, 0x18, 0x19, 0x1a, 0x1a, 0x1b, | ||
102 | 0x1b, 0x1c, 0x1c, 0x1d, 0x1d, 0x1d, 0x1e, 0x1e, | ||
103 | 0x1f, 0x1f, 0x1f, 0x20, 0x20, 0x20, 0x20, 0x21, | ||
104 | 0x21, 0x21, 0x22, 0x22, 0x22, 0x23, 0x23, 0x24, | ||
105 | 0x24, 0x25, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27, | ||
106 | 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F | ||
107 | }; | ||
108 | |||
109 | static const u8 OFDM_CONFIG[] = { | ||
110 | 0x10, 0x0F, 0x0A, 0x0C, 0x14, 0xFA, 0xFF, 0x50, | ||
111 | 0x00, 0x50, 0x00, 0x00, 0x00, 0x5C, 0x00, 0x00, | ||
112 | 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0xA8, 0x26, | ||
113 | 0x32, 0x33, 0x06, 0xA5, 0x6F, 0x55, 0xC8, 0xBB, | ||
114 | 0x0A, 0xE1, 0x2C, 0x4A, 0x86, 0x83, 0x34, 0x00, | ||
115 | 0x4F, 0x24, 0x6F, 0xC2, 0x03, 0x40, 0x80, 0x00, | ||
116 | 0xC0, 0xC1, 0x58, 0xF1, 0x00, 0xC4, 0x90, 0x3e, | ||
117 | 0xD8, 0x3C, 0x7B, 0x10, 0x10 | ||
118 | }; | ||
119 | |||
120 | static void rtl8187se_three_wire_io(struct ieee80211_hw *dev, u8 *data, | ||
121 | u8 len, bool write) | ||
122 | { | ||
123 | struct rtl8180_priv *priv = dev->priv; | ||
124 | int i; | ||
125 | u8 tmp; | ||
126 | |||
127 | do { | ||
128 | for (i = 0; i < 5; i++) { | ||
129 | tmp = rtl818x_ioread8(priv, SW_3W_CMD1); | ||
130 | if (!(tmp & 0x3)) | ||
131 | break; | ||
132 | udelay(10); | ||
133 | } | ||
134 | if (i == 5) | ||
135 | wiphy_err(dev->wiphy, PFX | ||
136 | "CmdReg: 0x%x RE/WE bits aren't clear\n", tmp); | ||
137 | |||
138 | tmp = rtl818x_ioread8(priv, &priv->map->rf_sw_config) | 0x02; | ||
139 | rtl818x_iowrite8(priv, &priv->map->rf_sw_config, tmp); | ||
140 | |||
141 | tmp = rtl818x_ioread8(priv, REG_ADDR1(0x84)) & 0xF7; | ||
142 | rtl818x_iowrite8(priv, REG_ADDR1(0x84), tmp); | ||
143 | if (write) { | ||
144 | if (len == 16) { | ||
145 | rtl818x_iowrite16(priv, SW_3W_DB0, | ||
146 | *(u16 *)data); | ||
147 | } else if (len == 64) { | ||
148 | rtl818x_iowrite32(priv, SW_3W_DB0_4, | ||
149 | *((u32 *)data)); | ||
150 | rtl818x_iowrite32(priv, SW_3W_DB1_4, | ||
151 | *((u32 *)(data + 4))); | ||
152 | } else | ||
153 | wiphy_err(dev->wiphy, PFX | ||
154 | "Unimplemented length\n"); | ||
155 | } else { | ||
156 | rtl818x_iowrite16(priv, SW_3W_DB0, *(u16 *)data); | ||
157 | } | ||
158 | if (write) | ||
159 | tmp = 2; | ||
160 | else | ||
161 | tmp = 1; | ||
162 | rtl818x_iowrite8(priv, SW_3W_CMD1, tmp); | ||
163 | for (i = 0; i < 5; i++) { | ||
164 | tmp = rtl818x_ioread8(priv, SW_3W_CMD1); | ||
165 | if (!(tmp & 0x3)) | ||
166 | break; | ||
167 | udelay(10); | ||
168 | } | ||
169 | rtl818x_iowrite8(priv, SW_3W_CMD1, 0); | ||
170 | if (!write) { | ||
171 | *((u16 *)data) = rtl818x_ioread16(priv, SI_DATA_REG); | ||
172 | *((u16 *)data) &= 0x0FFF; | ||
173 | } | ||
174 | } while (0); | ||
175 | } | ||
176 | |||
177 | static u32 rtl8187se_rf_readreg(struct ieee80211_hw *dev, u8 addr) | ||
178 | { | ||
179 | u32 dataread = addr & 0x0F; | ||
180 | rtl8187se_three_wire_io(dev, (u8 *)&dataread, 16, 0); | ||
181 | return dataread; | ||
182 | } | ||
183 | |||
184 | static void rtl8187se_rf_writereg(struct ieee80211_hw *dev, u8 addr, u32 data) | ||
185 | { | ||
186 | u32 outdata = (data << 4) | (u32)(addr & 0x0F); | ||
187 | rtl8187se_three_wire_io(dev, (u8 *)&outdata, 16, 1); | ||
188 | } | ||
189 | |||
190 | |||
191 | static void rtl8225se_write_zebra_agc(struct ieee80211_hw *dev) | ||
192 | { | ||
193 | int i; | ||
194 | |||
195 | for (i = 0; i < 128; i++) { | ||
196 | rtl8225se_write_phy_ofdm(dev, 0xF, ZEBRA_AGC[i]); | ||
197 | rtl8225se_write_phy_ofdm(dev, 0xE, i+0x80); | ||
198 | rtl8225se_write_phy_ofdm(dev, 0xE, 0); | ||
199 | } | ||
200 | } | ||
201 | |||
202 | static void rtl8187se_write_ofdm_config(struct ieee80211_hw *dev) | ||
203 | { | ||
204 | /* write OFDM_CONFIG table */ | ||
205 | int i; | ||
206 | |||
207 | for (i = 0; i < 60; i++) | ||
208 | rtl8225se_write_phy_ofdm(dev, i, OFDM_CONFIG[i]); | ||
209 | |||
210 | } | ||
211 | |||
212 | static void rtl8225sez2_rf_set_tx_power(struct ieee80211_hw *dev, int channel) | ||
213 | { | ||
214 | struct rtl8180_priv *priv = dev->priv; | ||
215 | u8 cck_power, ofdm_power; | ||
216 | |||
217 | cck_power = priv->channels[channel - 1].hw_value & 0xFF; | ||
218 | if (cck_power > 35) | ||
219 | cck_power = 35; | ||
220 | rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, | ||
221 | cck_ofdm_gain_settings[cck_power]); | ||
222 | |||
223 | usleep_range(1000, 5000); | ||
224 | ofdm_power = priv->channels[channel - 1].hw_value >> 8; | ||
225 | if (ofdm_power > 35) | ||
226 | ofdm_power = 35; | ||
227 | |||
228 | rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, | ||
229 | cck_ofdm_gain_settings[ofdm_power]); | ||
230 | if (ofdm_power < 12) { | ||
231 | rtl8225se_write_phy_ofdm(dev, 7, 0x5C); | ||
232 | rtl8225se_write_phy_ofdm(dev, 9, 0x5C); | ||
233 | } | ||
234 | if (ofdm_power < 18) { | ||
235 | rtl8225se_write_phy_ofdm(dev, 7, 0x54); | ||
236 | rtl8225se_write_phy_ofdm(dev, 9, 0x54); | ||
237 | } else { | ||
238 | rtl8225se_write_phy_ofdm(dev, 7, 0x50); | ||
239 | rtl8225se_write_phy_ofdm(dev, 9, 0x50); | ||
240 | } | ||
241 | |||
242 | usleep_range(1000, 5000); | ||
243 | } | ||
244 | |||
245 | static void rtl8187se_write_rf_gain(struct ieee80211_hw *dev) | ||
246 | { | ||
247 | int i; | ||
248 | |||
249 | for (i = 0; i <= 36; i++) { | ||
250 | rtl8187se_rf_writereg(dev, 0x01, i); mdelay(1); | ||
251 | rtl8187se_rf_writereg(dev, 0x02, RF_GAIN_TABLE[i]); mdelay(1); | ||
252 | } | ||
253 | } | ||
254 | |||
255 | static void rtl8187se_write_initial_gain(struct ieee80211_hw *dev, | ||
256 | int init_gain) | ||
257 | { | ||
258 | switch (init_gain) { | ||
259 | default: | ||
260 | rtl8225se_write_phy_ofdm(dev, 0x17, 0x26); mdelay(1); | ||
261 | rtl8225se_write_phy_ofdm(dev, 0x24, 0x86); mdelay(1); | ||
262 | rtl8225se_write_phy_ofdm(dev, 0x05, 0xFA); mdelay(1); | ||
263 | break; | ||
264 | case 2: | ||
265 | rtl8225se_write_phy_ofdm(dev, 0x17, 0x36); mdelay(1); | ||
266 | rtl8225se_write_phy_ofdm(dev, 0x24, 0x86); mdelay(1); | ||
267 | rtl8225se_write_phy_ofdm(dev, 0x05, 0xFA); mdelay(1); | ||
268 | break; | ||
269 | case 3: | ||
270 | rtl8225se_write_phy_ofdm(dev, 0x17, 0x36); mdelay(1); | ||
271 | rtl8225se_write_phy_ofdm(dev, 0x24, 0x86); mdelay(1); | ||
272 | rtl8225se_write_phy_ofdm(dev, 0x05, 0xFB); mdelay(1); | ||
273 | break; | ||
274 | case 4: | ||
275 | rtl8225se_write_phy_ofdm(dev, 0x17, 0x46); mdelay(1); | ||
276 | rtl8225se_write_phy_ofdm(dev, 0x24, 0x86); mdelay(1); | ||
277 | rtl8225se_write_phy_ofdm(dev, 0x05, 0xFB); mdelay(1); | ||
278 | break; | ||
279 | case 5: | ||
280 | rtl8225se_write_phy_ofdm(dev, 0x17, 0x46); mdelay(1); | ||
281 | rtl8225se_write_phy_ofdm(dev, 0x24, 0x96); mdelay(1); | ||
282 | rtl8225se_write_phy_ofdm(dev, 0x05, 0xFB); mdelay(1); | ||
283 | break; | ||
284 | case 6: | ||
285 | rtl8225se_write_phy_ofdm(dev, 0x17, 0x56); mdelay(1); | ||
286 | rtl8225se_write_phy_ofdm(dev, 0x24, 0x96); mdelay(1); | ||
287 | rtl8225se_write_phy_ofdm(dev, 0x05, 0xFC); mdelay(1); | ||
288 | break; | ||
289 | case 7: | ||
290 | rtl8225se_write_phy_ofdm(dev, 0x17, 0x56); mdelay(1); | ||
291 | rtl8225se_write_phy_ofdm(dev, 0x24, 0xA6); mdelay(1); | ||
292 | rtl8225se_write_phy_ofdm(dev, 0x05, 0xFC); mdelay(1); | ||
293 | break; | ||
294 | case 8: | ||
295 | rtl8225se_write_phy_ofdm(dev, 0x17, 0x66); mdelay(1); | ||
296 | rtl8225se_write_phy_ofdm(dev, 0x24, 0xB6); mdelay(1); | ||
297 | rtl8225se_write_phy_ofdm(dev, 0x05, 0xFC); mdelay(1); | ||
298 | break; | ||
299 | } | ||
300 | } | ||
301 | |||
302 | void rtl8225se_rf_init(struct ieee80211_hw *dev) | ||
303 | { | ||
304 | struct rtl8180_priv *priv = dev->priv; | ||
305 | u32 rf23, rf24; | ||
306 | u8 d_cut = 0; | ||
307 | u8 tmp; | ||
308 | |||
309 | /* Page 1 */ | ||
310 | rtl8187se_rf_writereg(dev, 0x00, 0x013F); mdelay(1); | ||
311 | rf23 = rtl8187se_rf_readreg(dev, 0x08); mdelay(1); | ||
312 | rf24 = rtl8187se_rf_readreg(dev, 0x09); mdelay(1); | ||
313 | if (rf23 == 0x0818 && rf24 == 0x070C) | ||
314 | d_cut = 1; | ||
315 | |||
316 | wiphy_info(dev->wiphy, "RTL8225-SE version %s\n", | ||
317 | d_cut ? "D" : "not-D"); | ||
318 | |||
319 | /* Page 0: reg 0 - 15 */ | ||
320 | rtl8187se_rf_writereg(dev, 0x00, 0x009F); mdelay(1); | ||
321 | rtl8187se_rf_writereg(dev, 0x01, 0x06E0); mdelay(1); | ||
322 | rtl8187se_rf_writereg(dev, 0x02, 0x004D); mdelay(1); | ||
323 | rtl8187se_rf_writereg(dev, 0x03, 0x07F1); mdelay(1); | ||
324 | rtl8187se_rf_writereg(dev, 0x04, 0x0975); mdelay(1); | ||
325 | rtl8187se_rf_writereg(dev, 0x05, 0x0C72); mdelay(1); | ||
326 | rtl8187se_rf_writereg(dev, 0x06, 0x0AE6); mdelay(1); | ||
327 | rtl8187se_rf_writereg(dev, 0x07, 0x00CA); mdelay(1); | ||
328 | rtl8187se_rf_writereg(dev, 0x08, 0x0E1C); mdelay(1); | ||
329 | rtl8187se_rf_writereg(dev, 0x09, 0x02F0); mdelay(1); | ||
330 | rtl8187se_rf_writereg(dev, 0x0A, 0x09D0); mdelay(1); | ||
331 | rtl8187se_rf_writereg(dev, 0x0B, 0x01BA); mdelay(1); | ||
332 | rtl8187se_rf_writereg(dev, 0x0C, 0x0640); mdelay(1); | ||
333 | rtl8187se_rf_writereg(dev, 0x0D, 0x08DF); mdelay(1); | ||
334 | rtl8187se_rf_writereg(dev, 0x0E, 0x0020); mdelay(1); | ||
335 | rtl8187se_rf_writereg(dev, 0x0F, 0x0990); mdelay(1); | ||
336 | /* page 1: reg 16-30 */ | ||
337 | rtl8187se_rf_writereg(dev, 0x00, 0x013F); mdelay(1); | ||
338 | rtl8187se_rf_writereg(dev, 0x03, 0x0806); mdelay(1); | ||
339 | rtl8187se_rf_writereg(dev, 0x04, 0x03A7); mdelay(1); | ||
340 | rtl8187se_rf_writereg(dev, 0x05, 0x059B); mdelay(1); | ||
341 | rtl8187se_rf_writereg(dev, 0x06, 0x0081); mdelay(1); | ||
342 | rtl8187se_rf_writereg(dev, 0x07, 0x01A0); mdelay(1); | ||
343 | rtl8187se_rf_writereg(dev, 0x0A, 0x0001); mdelay(1); | ||
344 | rtl8187se_rf_writereg(dev, 0x0B, 0x0418); mdelay(1); | ||
345 | rtl8187se_rf_writereg(dev, 0x0C, 0x0FBE); mdelay(1); | ||
346 | rtl8187se_rf_writereg(dev, 0x0D, 0x0008); mdelay(1); | ||
347 | if (d_cut) | ||
348 | rtl8187se_rf_writereg(dev, 0x0E, 0x0807); | ||
349 | else | ||
350 | rtl8187se_rf_writereg(dev, 0x0E, 0x0806); | ||
351 | mdelay(1); | ||
352 | rtl8187se_rf_writereg(dev, 0x0F, 0x0ACC); mdelay(1); | ||
353 | rtl8187se_rf_writereg(dev, 0x00, 0x01D7); mdelay(1); | ||
354 | rtl8187se_rf_writereg(dev, 0x03, 0x0E00); mdelay(1); | ||
355 | rtl8187se_rf_writereg(dev, 0x04, 0x0E50); mdelay(1); | ||
356 | |||
357 | rtl8187se_write_rf_gain(dev); | ||
358 | |||
359 | rtl8187se_rf_writereg(dev, 0x05, 0x0203); mdelay(1); | ||
360 | rtl8187se_rf_writereg(dev, 0x06, 0x0200); mdelay(1); | ||
361 | rtl8187se_rf_writereg(dev, 0x00, 0x0137); mdelay(11); | ||
362 | rtl8187se_rf_writereg(dev, 0x0D, 0x0008); mdelay(11); | ||
363 | rtl8187se_rf_writereg(dev, 0x00, 0x0037); mdelay(11); | ||
364 | rtl8187se_rf_writereg(dev, 0x04, 0x0160); mdelay(11); | ||
365 | rtl8187se_rf_writereg(dev, 0x07, 0x0080); mdelay(11); | ||
366 | rtl8187se_rf_writereg(dev, 0x02, 0x088D); mdelay(221); | ||
367 | rtl8187se_rf_writereg(dev, 0x00, 0x0137); mdelay(11); | ||
368 | rtl8187se_rf_writereg(dev, 0x07, 0x0000); mdelay(1); | ||
369 | rtl8187se_rf_writereg(dev, 0x07, 0x0180); mdelay(1); | ||
370 | rtl8187se_rf_writereg(dev, 0x07, 0x0220); mdelay(1); | ||
371 | rtl8187se_rf_writereg(dev, 0x07, 0x03E0); mdelay(1); | ||
372 | rtl8187se_rf_writereg(dev, 0x06, 0x00C1); mdelay(1); | ||
373 | rtl8187se_rf_writereg(dev, 0x0A, 0x0001); mdelay(1); | ||
374 | if (priv->xtal_cal) { | ||
375 | tmp = (priv->xtal_in << 4) | (priv->xtal_out << 1) | | ||
376 | (1 << 11) | (1 << 9); | ||
377 | rtl8187se_rf_writereg(dev, 0x0F, tmp); | ||
378 | wiphy_info(dev->wiphy, "Xtal cal\n"); | ||
379 | mdelay(1); | ||
380 | } else { | ||
381 | wiphy_info(dev->wiphy, "NO Xtal cal\n"); | ||
382 | rtl8187se_rf_writereg(dev, 0x0F, 0x0ACC); | ||
383 | mdelay(1); | ||
384 | } | ||
385 | /* page 0 */ | ||
386 | rtl8187se_rf_writereg(dev, 0x00, 0x00BF); mdelay(1); | ||
387 | rtl8187se_rf_writereg(dev, 0x0D, 0x08DF); mdelay(1); | ||
388 | rtl8187se_rf_writereg(dev, 0x02, 0x004D); mdelay(1); | ||
389 | rtl8187se_rf_writereg(dev, 0x04, 0x0975); mdelay(31); | ||
390 | rtl8187se_rf_writereg(dev, 0x00, 0x0197); mdelay(1); | ||
391 | rtl8187se_rf_writereg(dev, 0x05, 0x05AB); mdelay(1); | ||
392 | |||
393 | rtl8187se_rf_writereg(dev, 0x00, 0x009F); mdelay(1); | ||
394 | rtl8187se_rf_writereg(dev, 0x01, 0x0000); mdelay(1); | ||
395 | rtl8187se_rf_writereg(dev, 0x02, 0x0000); mdelay(1); | ||
396 | /* power save parameters */ | ||
397 | /* TODO: move to dev.c */ | ||
398 | rtl818x_iowrite8(priv, REG_ADDR1(0x024E), | ||
399 | rtl818x_ioread8(priv, REG_ADDR1(0x24E)) & 0x9F); | ||
400 | rtl8225se_write_phy_cck(dev, 0x00, 0xC8); | ||
401 | rtl8225se_write_phy_cck(dev, 0x06, 0x1C); | ||
402 | rtl8225se_write_phy_cck(dev, 0x10, 0x78); | ||
403 | rtl8225se_write_phy_cck(dev, 0x2E, 0xD0); | ||
404 | rtl8225se_write_phy_cck(dev, 0x2F, 0x06); | ||
405 | rtl8225se_write_phy_cck(dev, 0x01, 0x46); | ||
406 | |||
407 | /* power control */ | ||
408 | rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, 0x10); | ||
409 | rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, 0x1B); | ||
410 | |||
411 | rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03); | ||
412 | rtl8225se_write_phy_ofdm(dev, 0x00, 0x12); | ||
413 | |||
414 | rtl8225se_write_zebra_agc(dev); | ||
415 | |||
416 | rtl8225se_write_phy_ofdm(dev, 0x10, 0x00); | ||
417 | |||
418 | rtl8187se_write_ofdm_config(dev); | ||
419 | |||
420 | /* turn on RF */ | ||
421 | rtl8187se_rf_writereg(dev, 0x00, 0x009F); udelay(500); | ||
422 | rtl8187se_rf_writereg(dev, 0x04, 0x0972); udelay(500); | ||
423 | /* turn on RF again */ | ||
424 | rtl8187se_rf_writereg(dev, 0x00, 0x009F); udelay(500); | ||
425 | rtl8187se_rf_writereg(dev, 0x04, 0x0972); udelay(500); | ||
426 | /* turn on BB */ | ||
427 | rtl8225se_write_phy_ofdm(dev, 0x10, 0x40); | ||
428 | rtl8225se_write_phy_ofdm(dev, 0x12, 0x40); | ||
429 | |||
430 | rtl8187se_write_initial_gain(dev, 4); | ||
431 | } | ||
432 | |||
433 | void rtl8225se_rf_stop(struct ieee80211_hw *dev) | ||
434 | { | ||
435 | /* checked for 8187se */ | ||
436 | struct rtl8180_priv *priv = dev->priv; | ||
437 | |||
438 | /* turn off BB RXIQ matrix to cut off rx signal */ | ||
439 | rtl8225se_write_phy_ofdm(dev, 0x10, 0x00); | ||
440 | rtl8225se_write_phy_ofdm(dev, 0x12, 0x00); | ||
441 | /* turn off RF */ | ||
442 | rtl8187se_rf_writereg(dev, 0x04, 0x0000); | ||
443 | rtl8187se_rf_writereg(dev, 0x00, 0x0000); | ||
444 | |||
445 | usleep_range(1000, 5000); | ||
446 | /* turn off A/D and D/A */ | ||
447 | rtl8180_set_anaparam(priv, RTL8225SE_ANAPARAM_OFF); | ||
448 | rtl8180_set_anaparam2(priv, RTL8225SE_ANAPARAM2_OFF); | ||
449 | } | ||
450 | |||
451 | void rtl8225se_rf_set_channel(struct ieee80211_hw *dev, | ||
452 | struct ieee80211_conf *conf) | ||
453 | { | ||
454 | int chan = | ||
455 | ieee80211_frequency_to_channel(conf->chandef.chan->center_freq); | ||
456 | |||
457 | rtl8225sez2_rf_set_tx_power(dev, chan); | ||
458 | rtl8187se_rf_writereg(dev, 0x7, rtl8225se_chan[chan - 1]); | ||
459 | if ((rtl8187se_rf_readreg(dev, 0x7) & 0x0F80) != | ||
460 | rtl8225se_chan[chan - 1]) | ||
461 | rtl8187se_rf_writereg(dev, 0x7, rtl8225se_chan[chan - 1]); | ||
462 | usleep_range(10000, 20000); | ||
463 | } | ||
464 | |||
465 | static const struct rtl818x_rf_ops rtl8225se_ops = { | ||
466 | .name = "rtl8225-se", | ||
467 | .init = rtl8225se_rf_init, | ||
468 | .stop = rtl8225se_rf_stop, | ||
469 | .set_chan = rtl8225se_rf_set_channel, | ||
470 | }; | ||
471 | |||
472 | const struct rtl818x_rf_ops *rtl8187se_detect_rf(struct ieee80211_hw *dev) | ||
473 | { | ||
474 | return &rtl8225se_ops; | ||
475 | } | ||
diff --git a/drivers/net/wireless/rtl818x/rtl8180/rtl8225se.h b/drivers/net/wireless/rtl818x/rtl8180/rtl8225se.h new file mode 100644 index 000000000000..229400264088 --- /dev/null +++ b/drivers/net/wireless/rtl818x/rtl8180/rtl8225se.h | |||
@@ -0,0 +1,61 @@ | |||
1 | |||
2 | /* Definitions for RTL8187SE hardware | ||
3 | * | ||
4 | * Copyright 2009 Larry Finger <Larry.Finger@lwfinger.net> | ||
5 | * Copyright 2014 Andrea Merello <andrea.merello@gmail.com> | ||
6 | * | ||
7 | * Based on the r8180 and Realtek r8187se drivers, which are: | ||
8 | * Copyright 2004-2005 Andrea Merello <andrea.merello@gmail.com>, et al. | ||
9 | * | ||
10 | * Also based on the rtl8187 driver, which is: | ||
11 | * Copyright 2007 Michael Wu <flamingice@sourmilk.net> | ||
12 | * Copyright 2007 Andrea Merello <andrea.merello@gmail.com> | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or modify | ||
15 | * it under the terms of the GNU General Public License version 2 as | ||
16 | * published by the Free Software Foundation. | ||
17 | */ | ||
18 | |||
19 | #ifndef RTL8187SE_RTL8225_H | ||
20 | #define RTL8187SE_RTL8225_H | ||
21 | |||
22 | #define RTL8225SE_ANAPARAM_ON 0xb0054d00 | ||
23 | #define RTL8225SE_ANAPARAM2_ON 0x000004c6 | ||
24 | |||
25 | /* all off except PLL */ | ||
26 | #define RTL8225SE_ANAPARAM_OFF 0xb0054dec | ||
27 | /* all on including PLL */ | ||
28 | #define RTL8225SE_ANAPARAM_OFF2 0xb0054dfc | ||
29 | |||
30 | #define RTL8225SE_ANAPARAM2_OFF 0x00ff04c6 | ||
31 | |||
32 | #define RTL8225SE_ANAPARAM3 0x10 | ||
33 | |||
34 | enum rtl8187se_power_state { | ||
35 | RTL8187SE_POWER_ON, | ||
36 | RTL8187SE_POWER_OFF, | ||
37 | RTL8187SE_POWER_SLEEP | ||
38 | }; | ||
39 | |||
40 | static inline void rtl8225se_write_phy_ofdm(struct ieee80211_hw *dev, | ||
41 | u8 addr, u8 data) | ||
42 | { | ||
43 | rtl8180_write_phy(dev, addr, data); | ||
44 | } | ||
45 | |||
46 | static inline void rtl8225se_write_phy_cck(struct ieee80211_hw *dev, | ||
47 | u8 addr, u8 data) | ||
48 | { | ||
49 | rtl8180_write_phy(dev, addr, data | 0x10000); | ||
50 | } | ||
51 | |||
52 | |||
53 | const struct rtl818x_rf_ops *rtl8187se_detect_rf(struct ieee80211_hw *); | ||
54 | void rtl8225se_rf_stop(struct ieee80211_hw *dev); | ||
55 | void rtl8225se_rf_set_channel(struct ieee80211_hw *dev, | ||
56 | struct ieee80211_conf *conf); | ||
57 | void rtl8225se_rf_conf_erp(struct ieee80211_hw *dev, | ||
58 | struct ieee80211_bss_conf *info); | ||
59 | void rtl8225se_rf_init(struct ieee80211_hw *dev); | ||
60 | |||
61 | #endif /* RTL8187SE_RTL8225_H */ | ||
diff --git a/drivers/net/wireless/rtl818x/rtl8187/dev.c b/drivers/net/wireless/rtl818x/rtl8187/dev.c index c981bcfb6cef..0ca17cda48fa 100644 --- a/drivers/net/wireless/rtl818x/rtl8187/dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187/dev.c | |||
@@ -592,7 +592,7 @@ static void rtl8187_set_anaparam(struct rtl8187_priv *priv, bool rfon) | |||
592 | rtl818x_iowrite32(priv, &priv->map->ANAPARAM, anaparam); | 592 | rtl818x_iowrite32(priv, &priv->map->ANAPARAM, anaparam); |
593 | rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, anaparam2); | 593 | rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, anaparam2); |
594 | if (priv->is_rtl8187b) | 594 | if (priv->is_rtl8187b) |
595 | rtl818x_iowrite8(priv, &priv->map->ANAPARAM3, anaparam3); | 595 | rtl818x_iowrite8(priv, &priv->map->ANAPARAM3A, anaparam3); |
596 | reg &= ~RTL818X_CONFIG3_ANAPARAM_WRITE; | 596 | reg &= ~RTL818X_CONFIG3_ANAPARAM_WRITE; |
597 | rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg); | 597 | rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg); |
598 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, | 598 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, |
@@ -1636,10 +1636,10 @@ static int rtl8187_probe(struct usb_interface *intf, | |||
1636 | 1636 | ||
1637 | err_free_dmabuf: | 1637 | err_free_dmabuf: |
1638 | kfree(priv->io_dmabuf); | 1638 | kfree(priv->io_dmabuf); |
1639 | err_free_dev: | ||
1640 | ieee80211_free_hw(dev); | ||
1641 | usb_set_intfdata(intf, NULL); | 1639 | usb_set_intfdata(intf, NULL); |
1642 | usb_put_dev(udev); | 1640 | usb_put_dev(udev); |
1641 | err_free_dev: | ||
1642 | ieee80211_free_hw(dev); | ||
1643 | return err; | 1643 | return err; |
1644 | } | 1644 | } |
1645 | 1645 | ||
diff --git a/drivers/net/wireless/rtl818x/rtl818x.h b/drivers/net/wireless/rtl818x/rtl818x.h index 1815b15d03b1..45ea4e1c4abe 100644 --- a/drivers/net/wireless/rtl818x/rtl818x.h +++ b/drivers/net/wireless/rtl818x/rtl818x.h | |||
@@ -16,30 +16,82 @@ | |||
16 | #define RTL818X_H | 16 | #define RTL818X_H |
17 | 17 | ||
18 | struct rtl818x_csr { | 18 | struct rtl818x_csr { |
19 | |||
19 | u8 MAC[6]; | 20 | u8 MAC[6]; |
20 | u8 reserved_0[2]; | 21 | u8 reserved_0[2]; |
21 | __le32 MAR[2]; | 22 | |
22 | u8 RX_FIFO_COUNT; | 23 | union { |
23 | u8 reserved_1; | 24 | __le32 MAR[2]; /* 0x8 */ |
24 | u8 TX_FIFO_COUNT; | 25 | |
25 | u8 BQREQ; | 26 | struct{ /* rtl8187se */ |
26 | u8 reserved_2[4]; | 27 | u8 rf_sw_config; /* 0x8 */ |
28 | u8 reserved_01[3]; | ||
29 | __le32 TMGDA; /* 0xc */ | ||
30 | } __packed; | ||
31 | } __packed; | ||
32 | |||
33 | union { /* 0x10 */ | ||
34 | struct { | ||
35 | u8 RX_FIFO_COUNT; | ||
36 | u8 reserved_1; | ||
37 | u8 TX_FIFO_COUNT; | ||
38 | u8 BQREQ; | ||
39 | } __packed; | ||
40 | |||
41 | __le32 TBKDA; /* for 8187se */ | ||
42 | } __packed; | ||
43 | |||
44 | __le32 TBEDA; /* 0x14 - for rtl8187se */ | ||
45 | |||
27 | __le32 TSFT[2]; | 46 | __le32 TSFT[2]; |
28 | __le32 TLPDA; | 47 | |
29 | __le32 TNPDA; | 48 | union { /* 0x20 */ |
30 | __le32 THPDA; | 49 | __le32 TLPDA; |
31 | __le16 BRSR; | 50 | __le32 TVIDA; /* for 8187se */ |
32 | u8 BSSID[6]; | 51 | } __packed; |
33 | u8 RESP_RATE; | 52 | |
34 | u8 EIFS; | 53 | union { /* 0x24 */ |
35 | u8 reserved_3[1]; | 54 | __le32 TNPDA; |
36 | u8 CMD; | 55 | __le32 TVODA; /* for 8187se */ |
56 | } __packed; | ||
57 | |||
58 | /* hi pri ring for all cards */ | ||
59 | __le32 THPDA; /* 0x28 */ | ||
60 | |||
61 | union { /* 0x2c */ | ||
62 | struct { | ||
63 | u8 reserved_2a; | ||
64 | u8 EIFS_8187SE; | ||
65 | } __packed; | ||
66 | |||
67 | __le16 BRSR; | ||
68 | } __packed; | ||
69 | |||
70 | u8 BSSID[6]; /* 0x2e */ | ||
71 | |||
72 | union { /* 0x34 */ | ||
73 | struct { | ||
74 | u8 RESP_RATE; | ||
75 | u8 EIFS; | ||
76 | } __packed; | ||
77 | __le16 BRSR_8187SE; | ||
78 | } __packed; | ||
79 | |||
80 | u8 reserved_3[1]; /* 0x36 */ | ||
81 | u8 CMD; /* 0x37 */ | ||
37 | #define RTL818X_CMD_TX_ENABLE (1 << 2) | 82 | #define RTL818X_CMD_TX_ENABLE (1 << 2) |
38 | #define RTL818X_CMD_RX_ENABLE (1 << 3) | 83 | #define RTL818X_CMD_RX_ENABLE (1 << 3) |
39 | #define RTL818X_CMD_RESET (1 << 4) | 84 | #define RTL818X_CMD_RESET (1 << 4) |
40 | u8 reserved_4[4]; | 85 | u8 reserved_4[4]; /* 0x38 */ |
41 | __le16 INT_MASK; | 86 | union { |
42 | __le16 INT_STATUS; | 87 | struct { |
88 | __le16 INT_MASK; | ||
89 | __le16 INT_STATUS; | ||
90 | } __packed; | ||
91 | |||
92 | __le32 INT_STATUS_SE; /* 0x3c */ | ||
93 | } __packed; | ||
94 | /* status bits for rtl8187 and rtl8180/8185 */ | ||
43 | #define RTL818X_INT_RX_OK (1 << 0) | 95 | #define RTL818X_INT_RX_OK (1 << 0) |
44 | #define RTL818X_INT_RX_ERR (1 << 1) | 96 | #define RTL818X_INT_RX_ERR (1 << 1) |
45 | #define RTL818X_INT_TXL_OK (1 << 2) | 97 | #define RTL818X_INT_TXL_OK (1 << 2) |
@@ -56,7 +108,34 @@ struct rtl818x_csr { | |||
56 | #define RTL818X_INT_BEACON (1 << 13) | 108 | #define RTL818X_INT_BEACON (1 << 13) |
57 | #define RTL818X_INT_TIME_OUT (1 << 14) | 109 | #define RTL818X_INT_TIME_OUT (1 << 14) |
58 | #define RTL818X_INT_TX_FO (1 << 15) | 110 | #define RTL818X_INT_TX_FO (1 << 15) |
59 | __le32 TX_CONF; | 111 | /* status bits for rtl8187se */ |
112 | #define RTL818X_INT_SE_TIMER3 (1 << 0) | ||
113 | #define RTL818X_INT_SE_TIMER2 (1 << 1) | ||
114 | #define RTL818X_INT_SE_RQ0SOR (1 << 2) | ||
115 | #define RTL818X_INT_SE_TXBED_OK (1 << 3) | ||
116 | #define RTL818X_INT_SE_TXBED_ERR (1 << 4) | ||
117 | #define RTL818X_INT_SE_TXBE_OK (1 << 5) | ||
118 | #define RTL818X_INT_SE_TXBE_ERR (1 << 6) | ||
119 | #define RTL818X_INT_SE_RX_OK (1 << 7) | ||
120 | #define RTL818X_INT_SE_RX_ERR (1 << 8) | ||
121 | #define RTL818X_INT_SE_TXL_OK (1 << 9) | ||
122 | #define RTL818X_INT_SE_TXL_ERR (1 << 10) | ||
123 | #define RTL818X_INT_SE_RX_DU (1 << 11) | ||
124 | #define RTL818X_INT_SE_RX_FIFO (1 << 12) | ||
125 | #define RTL818X_INT_SE_TXN_OK (1 << 13) | ||
126 | #define RTL818X_INT_SE_TXN_ERR (1 << 14) | ||
127 | #define RTL818X_INT_SE_TXH_OK (1 << 15) | ||
128 | #define RTL818X_INT_SE_TXH_ERR (1 << 16) | ||
129 | #define RTL818X_INT_SE_TXB_OK (1 << 17) | ||
130 | #define RTL818X_INT_SE_TXB_ERR (1 << 18) | ||
131 | #define RTL818X_INT_SE_ATIM_TO (1 << 19) | ||
132 | #define RTL818X_INT_SE_BK_TO (1 << 20) | ||
133 | #define RTL818X_INT_SE_TIMER1 (1 << 21) | ||
134 | #define RTL818X_INT_SE_TX_FIFO (1 << 22) | ||
135 | #define RTL818X_INT_SE_WAKEUP (1 << 23) | ||
136 | #define RTL818X_INT_SE_BK_DMA (1 << 24) | ||
137 | #define RTL818X_INT_SE_TMGD_OK (1 << 30) | ||
138 | __le32 TX_CONF; /* 0x40 */ | ||
60 | #define RTL818X_TX_CONF_LOOPBACK_MAC (1 << 17) | 139 | #define RTL818X_TX_CONF_LOOPBACK_MAC (1 << 17) |
61 | #define RTL818X_TX_CONF_LOOPBACK_CONT (3 << 17) | 140 | #define RTL818X_TX_CONF_LOOPBACK_CONT (3 << 17) |
62 | #define RTL818X_TX_CONF_NO_ICV (1 << 19) | 141 | #define RTL818X_TX_CONF_NO_ICV (1 << 19) |
@@ -68,6 +147,7 @@ struct rtl818x_csr { | |||
68 | #define RTL818X_TX_CONF_R8185_D (5 << 25) | 147 | #define RTL818X_TX_CONF_R8185_D (5 << 25) |
69 | #define RTL818X_TX_CONF_R8187vD (5 << 25) | 148 | #define RTL818X_TX_CONF_R8187vD (5 << 25) |
70 | #define RTL818X_TX_CONF_R8187vD_B (6 << 25) | 149 | #define RTL818X_TX_CONF_R8187vD_B (6 << 25) |
150 | #define RTL818X_TX_CONF_RTL8187SE (6 << 25) | ||
71 | #define RTL818X_TX_CONF_HWVER_MASK (7 << 25) | 151 | #define RTL818X_TX_CONF_HWVER_MASK (7 << 25) |
72 | #define RTL818X_TX_CONF_DISREQQSIZE (1 << 28) | 152 | #define RTL818X_TX_CONF_DISREQQSIZE (1 << 28) |
73 | #define RTL818X_TX_CONF_PROBE_DTS (1 << 29) | 153 | #define RTL818X_TX_CONF_PROBE_DTS (1 << 29) |
@@ -122,28 +202,64 @@ struct rtl818x_csr { | |||
122 | u8 PGSELECT; | 202 | u8 PGSELECT; |
123 | u8 SECURITY; | 203 | u8 SECURITY; |
124 | __le32 ANAPARAM2; | 204 | __le32 ANAPARAM2; |
125 | u8 reserved_10[12]; | 205 | u8 reserved_10[8]; |
126 | __le16 BEACON_INTERVAL; | 206 | __le32 IMR; /* 0x6c - Interrupt mask reg for 8187se */ |
127 | __le16 ATIM_WND; | 207 | #define IMR_TMGDOK ((1 << 30)) |
128 | __le16 BEACON_INTERVAL_TIME; | 208 | #define IMR_DOT11HINT ((1 << 25)) /* 802.11h Measurement Interrupt */ |
129 | __le16 ATIMTR_INTERVAL; | 209 | #define IMR_BCNDMAINT ((1 << 24)) /* Beacon DMA Interrupt */ |
130 | u8 PHY_DELAY; | 210 | #define IMR_WAKEINT ((1 << 23)) /* Wake Up Interrupt */ |
131 | u8 CARRIER_SENSE_COUNTER; | 211 | #define IMR_TXFOVW ((1 << 22)) /* Tx FIFO Overflow */ |
132 | u8 reserved_11[2]; | 212 | #define IMR_TIMEOUT1 ((1 << 21)) /* Time Out Interrupt 1 */ |
133 | u8 PHY[4]; | 213 | #define IMR_BCNINT ((1 << 20)) /* Beacon Time out */ |
134 | __le16 RFPinsOutput; | 214 | #define IMR_ATIMINT ((1 << 19)) /* ATIM Time Out */ |
135 | __le16 RFPinsEnable; | 215 | #define IMR_TBDER ((1 << 18)) /* Tx Beacon Descriptor Error */ |
136 | __le16 RFPinsSelect; | 216 | #define IMR_TBDOK ((1 << 17)) /* Tx Beacon Descriptor OK */ |
137 | __le16 RFPinsInput; | 217 | #define IMR_THPDER ((1 << 16)) /* Tx High Priority Descriptor Error */ |
138 | __le32 RF_PARA; | 218 | #define IMR_THPDOK ((1 << 15)) /* Tx High Priority Descriptor OK */ |
139 | __le32 RF_TIMING; | 219 | #define IMR_TVODER ((1 << 14)) /* Tx AC_VO Descriptor Error Int */ |
140 | u8 GP_ENABLE; | 220 | #define IMR_TVODOK ((1 << 13)) /* Tx AC_VO Descriptor OK Interrupt */ |
141 | u8 GPIO0; | 221 | #define IMR_FOVW ((1 << 12)) /* Rx FIFO Overflow Interrupt */ |
142 | u8 GPIO1; | 222 | #define IMR_RDU ((1 << 11)) /* Rx Descriptor Unavailable */ |
143 | u8 reserved_12; | 223 | #define IMR_TVIDER ((1 << 10)) /* Tx AC_VI Descriptor Error */ |
144 | __le32 HSSI_PARA; | 224 | #define IMR_TVIDOK ((1 << 9)) /* Tx AC_VI Descriptor OK Interrupt */ |
145 | u8 reserved_13[4]; | 225 | #define IMR_RER ((1 << 8)) /* Rx Error Interrupt */ |
146 | u8 TX_AGC_CTL; | 226 | #define IMR_ROK ((1 << 7)) /* Receive OK Interrupt */ |
227 | #define IMR_TBEDER ((1 << 6)) /* Tx AC_BE Descriptor Error */ | ||
228 | #define IMR_TBEDOK ((1 << 5)) /* Tx AC_BE Descriptor OK */ | ||
229 | #define IMR_TBKDER ((1 << 4)) /* Tx AC_BK Descriptor Error */ | ||
230 | #define IMR_TBKDOK ((1 << 3)) /* Tx AC_BK Descriptor OK */ | ||
231 | #define IMR_RQOSOK ((1 << 2)) /* Rx QoS OK Interrupt */ | ||
232 | #define IMR_TIMEOUT2 ((1 << 1)) /* Time Out Interrupt 2 */ | ||
233 | #define IMR_TIMEOUT3 ((1 << 0)) /* Time Out Interrupt 3 */ | ||
234 | __le16 BEACON_INTERVAL; /* 0x70 */ | ||
235 | __le16 ATIM_WND; /* 0x72 */ | ||
236 | __le16 BEACON_INTERVAL_TIME; /* 0x74 */ | ||
237 | __le16 ATIMTR_INTERVAL; /* 0x76 */ | ||
238 | u8 PHY_DELAY; /* 0x78 */ | ||
239 | u8 CARRIER_SENSE_COUNTER; /* 0x79 */ | ||
240 | u8 reserved_11[2]; /* 0x7a */ | ||
241 | u8 PHY[4]; /* 0x7c */ | ||
242 | __le16 RFPinsOutput; /* 0x80 */ | ||
243 | __le16 RFPinsEnable; /* 0x82 */ | ||
244 | __le16 RFPinsSelect; /* 0x84 */ | ||
245 | __le16 RFPinsInput; /* 0x86 */ | ||
246 | __le32 RF_PARA; /* 0x88 */ | ||
247 | __le32 RF_TIMING; /* 0x8c */ | ||
248 | u8 GP_ENABLE; /* 0x90 */ | ||
249 | u8 GPIO0; /* 0x91 */ | ||
250 | u8 GPIO1; /* 0x92 */ | ||
251 | u8 TPPOLL_STOP; /* 0x93 - rtl8187se only */ | ||
252 | #define RTL818x_TPPOLL_STOP_BQ (1 << 7) | ||
253 | #define RTL818x_TPPOLL_STOP_VI (1 << 4) | ||
254 | #define RTL818x_TPPOLL_STOP_VO (1 << 5) | ||
255 | #define RTL818x_TPPOLL_STOP_BE (1 << 3) | ||
256 | #define RTL818x_TPPOLL_STOP_BK (1 << 2) | ||
257 | #define RTL818x_TPPOLL_STOP_MG (1 << 1) | ||
258 | #define RTL818x_TPPOLL_STOP_HI (1 << 6) | ||
259 | |||
260 | __le32 HSSI_PARA; /* 0x94 */ | ||
261 | u8 reserved_13[4]; /* 0x98 */ | ||
262 | u8 TX_AGC_CTL; /* 0x9c */ | ||
147 | #define RTL818X_TX_AGC_CTL_PERPACKET_GAIN (1 << 0) | 263 | #define RTL818X_TX_AGC_CTL_PERPACKET_GAIN (1 << 0) |
148 | #define RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL (1 << 1) | 264 | #define RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL (1 << 1) |
149 | #define RTL818X_TX_AGC_CTL_FEEDBACK_ANT (1 << 2) | 265 | #define RTL818X_TX_AGC_CTL_FEEDBACK_ANT (1 << 2) |
@@ -167,7 +283,8 @@ struct rtl818x_csr { | |||
167 | u8 reserved_17[24]; | 283 | u8 reserved_17[24]; |
168 | u8 CONFIG5; | 284 | u8 CONFIG5; |
169 | u8 TX_DMA_POLLING; | 285 | u8 TX_DMA_POLLING; |
170 | u8 reserved_18[2]; | 286 | u8 PHY_PR; |
287 | u8 reserved_18; | ||
171 | __le16 CWR; | 288 | __le16 CWR; |
172 | u8 RETRY_CTR; | 289 | u8 RETRY_CTR; |
173 | u8 reserved_19[3]; | 290 | u8 reserved_19[3]; |
@@ -179,14 +296,59 @@ struct rtl818x_csr { | |||
179 | __le32 RDSAR; | 296 | __le32 RDSAR; |
180 | __le16 TID_AC_MAP; | 297 | __le16 TID_AC_MAP; |
181 | u8 reserved_20[4]; | 298 | u8 reserved_20[4]; |
182 | u8 ANAPARAM3; | 299 | union { |
183 | u8 reserved_21[5]; | 300 | __le16 ANAPARAM3; /* 0xee */ |
184 | __le16 FEMR; | 301 | u8 ANAPARAM3A; /* for rtl8187 */ |
185 | u8 reserved_22[4]; | 302 | }; |
186 | __le16 TALLY_CNT; | 303 | |
187 | u8 TALLY_SEL; | 304 | #define AC_PARAM_TXOP_LIMIT_SHIFT 16 |
305 | #define AC_PARAM_ECW_MAX_SHIFT 12 | ||
306 | #define AC_PARAM_ECW_MIN_SHIFT 8 | ||
307 | #define AC_PARAM_AIFS_SHIFT 0 | ||
308 | |||
309 | __le32 AC_VO_PARAM; /* 0xf0 */ | ||
310 | |||
311 | union { /* 0xf4 */ | ||
312 | __le32 AC_VI_PARAM; | ||
313 | __le16 FEMR; | ||
314 | } __packed; | ||
315 | |||
316 | union{ /* 0xf8 */ | ||
317 | __le32 AC_BE_PARAM; /* rtl8187se */ | ||
318 | struct{ | ||
319 | u8 reserved_21[2]; | ||
320 | __le16 TALLY_CNT; /* 0xfa */ | ||
321 | } __packed; | ||
322 | } __packed; | ||
323 | |||
324 | union { | ||
325 | u8 TALLY_SEL; /* 0xfc */ | ||
326 | __le32 AC_BK_PARAM; | ||
327 | |||
328 | } __packed; | ||
329 | |||
188 | } __packed; | 330 | } __packed; |
189 | 331 | ||
332 | /* These are addresses with NON-standard usage. | ||
333 | * They have offsets very far from this struct. | ||
334 | * I don't like to introduce a ton of "reserved".. | ||
335 | * They are for RTL8187SE | ||
336 | */ | ||
337 | #define REG_ADDR1(addr) ((u8 __iomem *)priv->map + addr) | ||
338 | #define REG_ADDR2(addr) ((__le16 __iomem *)priv->map + (addr >> 1)) | ||
339 | #define REG_ADDR4(addr) ((__le32 __iomem *)priv->map + (addr >> 2)) | ||
340 | |||
341 | #define FEMR_SE REG_ADDR2(0x1D4) | ||
342 | #define ARFR REG_ADDR2(0x1E0) | ||
343 | #define RFSW_CTRL REG_ADDR2(0x272) | ||
344 | #define SW_3W_DB0 REG_ADDR2(0x274) | ||
345 | #define SW_3W_DB0_4 REG_ADDR4(0x274) | ||
346 | #define SW_3W_DB1 REG_ADDR2(0x278) | ||
347 | #define SW_3W_DB1_4 REG_ADDR4(0x278) | ||
348 | #define SW_3W_CMD1 REG_ADDR1(0x27D) | ||
349 | #define PI_DATA_REG REG_ADDR2(0x360) | ||
350 | #define SI_DATA_REG REG_ADDR2(0x362) | ||
351 | |||
190 | struct rtl818x_rf_ops { | 352 | struct rtl818x_rf_ops { |
191 | char *name; | 353 | char *name; |
192 | void (*init)(struct ieee80211_hw *); | 354 | void (*init)(struct ieee80211_hw *); |
diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c index ded691f76f2f..4ec424f26672 100644 --- a/drivers/net/wireless/rtlwifi/core.c +++ b/drivers/net/wireless/rtlwifi/core.c | |||
@@ -982,7 +982,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, | |||
982 | u8 keep_alive = 10; | 982 | u8 keep_alive = 10; |
983 | rtlpriv->cfg->ops->set_hw_reg(hw, | 983 | rtlpriv->cfg->ops->set_hw_reg(hw, |
984 | HW_VAR_KEEP_ALIVE, | 984 | HW_VAR_KEEP_ALIVE, |
985 | (u8 *)(&keep_alive)); | 985 | &keep_alive); |
986 | 986 | ||
987 | rtlpriv->cfg->ops->set_hw_reg(hw, | 987 | rtlpriv->cfg->ops->set_hw_reg(hw, |
988 | HW_VAR_H2C_FW_JOINBSSRPT, | 988 | HW_VAR_H2C_FW_JOINBSSRPT, |
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index f26f4ffc771d..dae55257f0e8 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c | |||
@@ -1509,10 +1509,10 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, | |||
1509 | 1509 | ||
1510 | if (rtlpriv->use_new_trx_flow) { | 1510 | if (rtlpriv->use_new_trx_flow) { |
1511 | rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, true, | 1511 | rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, true, |
1512 | HW_DESC_OWN, (u8 *)&hw_queue); | 1512 | HW_DESC_OWN, &hw_queue); |
1513 | } else { | 1513 | } else { |
1514 | rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, true, | 1514 | rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, true, |
1515 | HW_DESC_OWN, (u8 *)&temp_one); | 1515 | HW_DESC_OWN, &temp_one); |
1516 | } | 1516 | } |
1517 | 1517 | ||
1518 | if ((ring->entries - skb_queue_len(&ring->queue)) < 2 && | 1518 | if ((ring->entries - skb_queue_len(&ring->queue)) < 2 && |
@@ -1853,6 +1853,65 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, | |||
1853 | return true; | 1853 | return true; |
1854 | } | 1854 | } |
1855 | 1855 | ||
1856 | static int rtl_pci_intr_mode_msi(struct ieee80211_hw *hw) | ||
1857 | { | ||
1858 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1859 | struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); | ||
1860 | struct rtl_pci *rtlpci = rtl_pcidev(pcipriv); | ||
1861 | int ret; | ||
1862 | |||
1863 | ret = pci_enable_msi(rtlpci->pdev); | ||
1864 | if (ret < 0) | ||
1865 | return ret; | ||
1866 | |||
1867 | ret = request_irq(rtlpci->pdev->irq, &_rtl_pci_interrupt, | ||
1868 | IRQF_SHARED, KBUILD_MODNAME, hw); | ||
1869 | if (ret < 0) { | ||
1870 | pci_disable_msi(rtlpci->pdev); | ||
1871 | return ret; | ||
1872 | } | ||
1873 | |||
1874 | rtlpci->using_msi = true; | ||
1875 | |||
1876 | RT_TRACE(rtlpriv, COMP_INIT|COMP_INTR, DBG_DMESG, | ||
1877 | "MSI Interrupt Mode!\n"); | ||
1878 | return 0; | ||
1879 | } | ||
1880 | |||
1881 | static int rtl_pci_intr_mode_legacy(struct ieee80211_hw *hw) | ||
1882 | { | ||
1883 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1884 | struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); | ||
1885 | struct rtl_pci *rtlpci = rtl_pcidev(pcipriv); | ||
1886 | int ret; | ||
1887 | |||
1888 | ret = request_irq(rtlpci->pdev->irq, &_rtl_pci_interrupt, | ||
1889 | IRQF_SHARED, KBUILD_MODNAME, hw); | ||
1890 | if (ret < 0) | ||
1891 | return ret; | ||
1892 | |||
1893 | rtlpci->using_msi = false; | ||
1894 | RT_TRACE(rtlpriv, COMP_INIT|COMP_INTR, DBG_DMESG, | ||
1895 | "Pin-based Interrupt Mode!\n"); | ||
1896 | return 0; | ||
1897 | } | ||
1898 | |||
1899 | static int rtl_pci_intr_mode_decide(struct ieee80211_hw *hw) | ||
1900 | { | ||
1901 | struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); | ||
1902 | struct rtl_pci *rtlpci = rtl_pcidev(pcipriv); | ||
1903 | int ret; | ||
1904 | |||
1905 | if (rtlpci->msi_support) { | ||
1906 | ret = rtl_pci_intr_mode_msi(hw); | ||
1907 | if (ret < 0) | ||
1908 | ret = rtl_pci_intr_mode_legacy(hw); | ||
1909 | } else { | ||
1910 | ret = rtl_pci_intr_mode_legacy(hw); | ||
1911 | } | ||
1912 | return ret; | ||
1913 | } | ||
1914 | |||
1856 | int rtl_pci_probe(struct pci_dev *pdev, | 1915 | int rtl_pci_probe(struct pci_dev *pdev, |
1857 | const struct pci_device_id *id) | 1916 | const struct pci_device_id *id) |
1858 | { | 1917 | { |
@@ -1995,8 +2054,7 @@ int rtl_pci_probe(struct pci_dev *pdev, | |||
1995 | } | 2054 | } |
1996 | 2055 | ||
1997 | rtlpci = rtl_pcidev(pcipriv); | 2056 | rtlpci = rtl_pcidev(pcipriv); |
1998 | err = request_irq(rtlpci->pdev->irq, &_rtl_pci_interrupt, | 2057 | err = rtl_pci_intr_mode_decide(hw); |
1999 | IRQF_SHARED, KBUILD_MODNAME, hw); | ||
2000 | if (err) { | 2058 | if (err) { |
2001 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | 2059 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, |
2002 | "%s: failed to register IRQ handler\n", | 2060 | "%s: failed to register IRQ handler\n", |
@@ -2064,6 +2122,9 @@ void rtl_pci_disconnect(struct pci_dev *pdev) | |||
2064 | rtlpci->irq_alloc = 0; | 2122 | rtlpci->irq_alloc = 0; |
2065 | } | 2123 | } |
2066 | 2124 | ||
2125 | if (rtlpci->using_msi) | ||
2126 | pci_disable_msi(rtlpci->pdev); | ||
2127 | |||
2067 | list_del(&rtlpriv->list); | 2128 | list_del(&rtlpriv->list); |
2068 | if (rtlpriv->io.pci_mem_start != 0) { | 2129 | if (rtlpriv->io.pci_mem_start != 0) { |
2069 | pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start); | 2130 | pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start); |
diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c index de7f05f848ef..50504942ded1 100644 --- a/drivers/net/wireless/rtlwifi/ps.c +++ b/drivers/net/wireless/rtlwifi/ps.c | |||
@@ -759,7 +759,7 @@ static void rtl_p2p_noa_ie(struct ieee80211_hw *hw, void *data, | |||
759 | unsigned int len) | 759 | unsigned int len) |
760 | { | 760 | { |
761 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 761 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
762 | struct ieee80211_mgmt *mgmt = (void *)data; | 762 | struct ieee80211_mgmt *mgmt = data; |
763 | struct rtl_p2p_ps_info *p2pinfo = &(rtlpriv->psc.p2p_ps_info); | 763 | struct rtl_p2p_ps_info *p2pinfo = &(rtlpriv->psc.p2p_ps_info); |
764 | u8 *pos, *end, *ie; | 764 | u8 *pos, *end, *ie; |
765 | u16 noa_len; | 765 | u16 noa_len; |
@@ -858,7 +858,7 @@ static void rtl_p2p_action_ie(struct ieee80211_hw *hw, void *data, | |||
858 | unsigned int len) | 858 | unsigned int len) |
859 | { | 859 | { |
860 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 860 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
861 | struct ieee80211_mgmt *mgmt = (void *)data; | 861 | struct ieee80211_mgmt *mgmt = data; |
862 | struct rtl_p2p_ps_info *p2pinfo = &(rtlpriv->psc.p2p_ps_info); | 862 | struct rtl_p2p_ps_info *p2pinfo = &(rtlpriv->psc.p2p_ps_info); |
863 | u8 noa_num, index, i, noa_index = 0; | 863 | u8 noa_num, index, i, noa_index = 0; |
864 | u8 *pos, *end, *ie; | 864 | u8 *pos, *end, *ie; |
@@ -950,9 +950,8 @@ void rtl_p2p_ps_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state) | |||
950 | switch (p2p_ps_state) { | 950 | switch (p2p_ps_state) { |
951 | case P2P_PS_DISABLE: | 951 | case P2P_PS_DISABLE: |
952 | p2pinfo->p2p_ps_state = p2p_ps_state; | 952 | p2pinfo->p2p_ps_state = p2p_ps_state; |
953 | rtlpriv->cfg->ops->set_hw_reg(hw, | 953 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_P2P_PS_OFFLOAD, |
954 | HW_VAR_H2C_FW_P2P_PS_OFFLOAD, | 954 | &p2p_ps_state); |
955 | (u8 *)(&p2p_ps_state)); | ||
956 | 955 | ||
957 | p2pinfo->noa_index = 0; | 956 | p2pinfo->noa_index = 0; |
958 | p2pinfo->ctwindow = 0; | 957 | p2pinfo->ctwindow = 0; |
@@ -964,7 +963,7 @@ void rtl_p2p_ps_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state) | |||
964 | rtlps->smart_ps = 2; | 963 | rtlps->smart_ps = 2; |
965 | rtlpriv->cfg->ops->set_hw_reg(hw, | 964 | rtlpriv->cfg->ops->set_hw_reg(hw, |
966 | HW_VAR_H2C_FW_PWRMODE, | 965 | HW_VAR_H2C_FW_PWRMODE, |
967 | (u8 *)(&rtlps->pwr_mode)); | 966 | &rtlps->pwr_mode); |
968 | } | 967 | } |
969 | } | 968 | } |
970 | break; | 969 | break; |
@@ -977,12 +976,12 @@ void rtl_p2p_ps_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state) | |||
977 | rtlps->smart_ps = 0; | 976 | rtlps->smart_ps = 0; |
978 | rtlpriv->cfg->ops->set_hw_reg(hw, | 977 | rtlpriv->cfg->ops->set_hw_reg(hw, |
979 | HW_VAR_H2C_FW_PWRMODE, | 978 | HW_VAR_H2C_FW_PWRMODE, |
980 | (u8 *)(&rtlps->pwr_mode)); | 979 | &rtlps->pwr_mode); |
981 | } | 980 | } |
982 | } | 981 | } |
983 | rtlpriv->cfg->ops->set_hw_reg(hw, | 982 | rtlpriv->cfg->ops->set_hw_reg(hw, |
984 | HW_VAR_H2C_FW_P2P_PS_OFFLOAD, | 983 | HW_VAR_H2C_FW_P2P_PS_OFFLOAD, |
985 | (u8 *)(&p2p_ps_state)); | 984 | &p2p_ps_state); |
986 | } | 985 | } |
987 | break; | 986 | break; |
988 | case P2P_PS_SCAN: | 987 | case P2P_PS_SCAN: |
@@ -992,7 +991,7 @@ void rtl_p2p_ps_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state) | |||
992 | p2pinfo->p2p_ps_state = p2p_ps_state; | 991 | p2pinfo->p2p_ps_state = p2p_ps_state; |
993 | rtlpriv->cfg->ops->set_hw_reg(hw, | 992 | rtlpriv->cfg->ops->set_hw_reg(hw, |
994 | HW_VAR_H2C_FW_P2P_PS_OFFLOAD, | 993 | HW_VAR_H2C_FW_P2P_PS_OFFLOAD, |
995 | (u8 *)(&p2p_ps_state)); | 994 | &p2p_ps_state); |
996 | } | 995 | } |
997 | break; | 996 | break; |
998 | default: | 997 | default: |
@@ -1012,7 +1011,7 @@ void rtl_p2p_info(struct ieee80211_hw *hw, void *data, unsigned int len) | |||
1012 | { | 1011 | { |
1013 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 1012 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
1014 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 1013 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
1015 | struct ieee80211_hdr *hdr = (void *)data; | 1014 | struct ieee80211_hdr *hdr = data; |
1016 | 1015 | ||
1017 | if (!mac->p2p) | 1016 | if (!mac->p2p) |
1018 | return; | 1017 | return; |
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/dm.c b/drivers/net/wireless/rtlwifi/rtl8188ee/dm.c index 97bc9aa5e1d1..f8daa61cf1c3 100644 --- a/drivers/net/wireless/rtlwifi/rtl8188ee/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8188ee/dm.c | |||
@@ -851,9 +851,8 @@ static void rtl88e_dm_check_edca_turbo(struct ieee80211_hw *hw) | |||
851 | } else { | 851 | } else { |
852 | if (rtlpriv->dm.current_turbo_edca) { | 852 | if (rtlpriv->dm.current_turbo_edca) { |
853 | u8 tmp = AC0_BE; | 853 | u8 tmp = AC0_BE; |
854 | rtlpriv->cfg->ops->set_hw_reg(hw, | 854 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, |
855 | HW_VAR_AC_PARAM, | 855 | &tmp); |
856 | (u8 *)(&tmp)); | ||
857 | rtlpriv->dm.current_turbo_edca = false; | 856 | rtlpriv->dm.current_turbo_edca = false; |
858 | } | 857 | } |
859 | } | 858 | } |
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/fw.c b/drivers/net/wireless/rtlwifi/rtl8188ee/fw.c index 557bc5b8327e..4f9376ad4739 100644 --- a/drivers/net/wireless/rtlwifi/rtl8188ee/fw.c +++ b/drivers/net/wireless/rtlwifi/rtl8188ee/fw.c | |||
@@ -119,7 +119,7 @@ static void _rtl88e_write_fw(struct ieee80211_hw *hw, | |||
119 | enum version_8188e version, u8 *buffer, u32 size) | 119 | enum version_8188e version, u8 *buffer, u32 size) |
120 | { | 120 | { |
121 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 121 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
122 | u8 *buf_ptr = (u8 *)buffer; | 122 | u8 *buf_ptr = buffer; |
123 | u32 page_no, remain; | 123 | u32 page_no, remain; |
124 | u32 page, offset; | 124 | u32 page, offset; |
125 | 125 | ||
@@ -213,7 +213,7 @@ int rtl88e_download_fw(struct ieee80211_hw *hw, bool buse_wake_on_wlan_fw) | |||
213 | return 1; | 213 | return 1; |
214 | 214 | ||
215 | pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware; | 215 | pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware; |
216 | pfwdata = (u8 *)rtlhal->pfirmware; | 216 | pfwdata = rtlhal->pfirmware; |
217 | fwsize = rtlhal->fwsize; | 217 | fwsize = rtlhal->fwsize; |
218 | RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, | 218 | RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, |
219 | "normal Firmware SIZE %d\n", fwsize); | 219 | "normal Firmware SIZE %d\n", fwsize); |
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c b/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c index bd2a26bafb69..94cd9df98381 100644 --- a/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c | |||
@@ -147,8 +147,7 @@ static void _rtl88ee_set_fw_clock_on(struct ieee80211_hw *hw, | |||
147 | } | 147 | } |
148 | 148 | ||
149 | if (IS_IN_LOW_POWER_STATE_88E(rtlhal->fw_ps_state)) { | 149 | if (IS_IN_LOW_POWER_STATE_88E(rtlhal->fw_ps_state)) { |
150 | rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_SET_RPWM, | 150 | rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_SET_RPWM, &rpwm_val); |
151 | (u8 *)(&rpwm_val)); | ||
152 | if (FW_PS_IS_ACK(rpwm_val)) { | 151 | if (FW_PS_IS_ACK(rpwm_val)) { |
153 | isr_regaddr = REG_HISR; | 152 | isr_regaddr = REG_HISR; |
154 | content = rtl_read_dword(rtlpriv, isr_regaddr); | 153 | content = rtl_read_dword(rtlpriv, isr_regaddr); |
@@ -225,7 +224,7 @@ static void _rtl88ee_set_fw_clock_off(struct ieee80211_hw *hw, | |||
225 | rtlhal->fw_ps_state = FW_PS_STATE(rpwm_val); | 224 | rtlhal->fw_ps_state = FW_PS_STATE(rpwm_val); |
226 | rtl_write_word(rtlpriv, REG_HISR, 0x0100); | 225 | rtl_write_word(rtlpriv, REG_HISR, 0x0100); |
227 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, | 226 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, |
228 | (u8 *)(&rpwm_val)); | 227 | &rpwm_val); |
229 | spin_lock_bh(&rtlpriv->locks.fw_ps_lock); | 228 | spin_lock_bh(&rtlpriv->locks.fw_ps_lock); |
230 | rtlhal->fw_clk_change_in_progress = false; | 229 | rtlhal->fw_clk_change_in_progress = false; |
231 | spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); | 230 | spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); |
@@ -273,15 +272,14 @@ static void _rtl88ee_fwlps_leave(struct ieee80211_hw *hw) | |||
273 | _rtl88ee_set_fw_clock_on(hw, rpwm_val, false); | 272 | _rtl88ee_set_fw_clock_on(hw, rpwm_val, false); |
274 | rtlhal->allow_sw_to_change_hwclc = false; | 273 | rtlhal->allow_sw_to_change_hwclc = false; |
275 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, | 274 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, |
276 | (u8 *)(&fw_pwrmode)); | 275 | &fw_pwrmode); |
277 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, | 276 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, |
278 | (u8 *)(&fw_current_inps)); | 277 | (u8 *)(&fw_current_inps)); |
279 | } else { | 278 | } else { |
280 | rpwm_val = FW_PS_STATE_ALL_ON_88E; /* RF on */ | 279 | rpwm_val = FW_PS_STATE_ALL_ON_88E; /* RF on */ |
281 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, | 280 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, &rpwm_val); |
282 | (u8 *)(&rpwm_val)); | ||
283 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, | 281 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, |
284 | (u8 *)(&fw_pwrmode)); | 282 | &fw_pwrmode); |
285 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, | 283 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, |
286 | (u8 *)(&fw_current_inps)); | 284 | (u8 *)(&fw_current_inps)); |
287 | } | 285 | } |
@@ -300,7 +298,7 @@ static void _rtl88ee_fwlps_enter(struct ieee80211_hw *hw) | |||
300 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, | 298 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, |
301 | (u8 *)(&fw_current_inps)); | 299 | (u8 *)(&fw_current_inps)); |
302 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, | 300 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, |
303 | (u8 *)(&ppsc->fwctrl_psmode)); | 301 | &ppsc->fwctrl_psmode); |
304 | rtlhal->allow_sw_to_change_hwclc = true; | 302 | rtlhal->allow_sw_to_change_hwclc = true; |
305 | _rtl88ee_set_fw_clock_off(hw, rpwm_val); | 303 | _rtl88ee_set_fw_clock_off(hw, rpwm_val); |
306 | } else { | 304 | } else { |
@@ -308,9 +306,8 @@ static void _rtl88ee_fwlps_enter(struct ieee80211_hw *hw) | |||
308 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, | 306 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, |
309 | (u8 *)(&fw_current_inps)); | 307 | (u8 *)(&fw_current_inps)); |
310 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, | 308 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, |
311 | (u8 *)(&ppsc->fwctrl_psmode)); | 309 | &ppsc->fwctrl_psmode); |
312 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, | 310 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, &rpwm_val); |
313 | (u8 *)(&rpwm_val)); | ||
314 | } | 311 | } |
315 | } | 312 | } |
316 | 313 | ||
@@ -419,12 +416,12 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
419 | 416 | ||
420 | for (e_aci = 0; e_aci < AC_MAX; e_aci++) { | 417 | for (e_aci = 0; e_aci < AC_MAX; e_aci++) { |
421 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, | 418 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, |
422 | (u8 *)(&e_aci)); | 419 | &e_aci); |
423 | } | 420 | } |
424 | break; } | 421 | break; } |
425 | case HW_VAR_ACK_PREAMBLE:{ | 422 | case HW_VAR_ACK_PREAMBLE:{ |
426 | u8 reg_tmp; | 423 | u8 reg_tmp; |
427 | u8 short_preamble = (bool) (*(u8 *)val); | 424 | u8 short_preamble = (bool)*val; |
428 | reg_tmp = rtl_read_byte(rtlpriv, REG_TRXPTCL_CTL+2); | 425 | reg_tmp = rtl_read_byte(rtlpriv, REG_TRXPTCL_CTL+2); |
429 | if (short_preamble) { | 426 | if (short_preamble) { |
430 | reg_tmp |= 0x02; | 427 | reg_tmp |= 0x02; |
@@ -435,13 +432,13 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
435 | } | 432 | } |
436 | break; } | 433 | break; } |
437 | case HW_VAR_WPA_CONFIG: | 434 | case HW_VAR_WPA_CONFIG: |
438 | rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *)val)); | 435 | rtl_write_byte(rtlpriv, REG_SECCFG, *val); |
439 | break; | 436 | break; |
440 | case HW_VAR_AMPDU_MIN_SPACE:{ | 437 | case HW_VAR_AMPDU_MIN_SPACE:{ |
441 | u8 min_spacing_to_set; | 438 | u8 min_spacing_to_set; |
442 | u8 sec_min_space; | 439 | u8 sec_min_space; |
443 | 440 | ||
444 | min_spacing_to_set = *((u8 *)val); | 441 | min_spacing_to_set = *val; |
445 | if (min_spacing_to_set <= 7) { | 442 | if (min_spacing_to_set <= 7) { |
446 | sec_min_space = 0; | 443 | sec_min_space = 0; |
447 | 444 | ||
@@ -464,7 +461,7 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
464 | case HW_VAR_SHORTGI_DENSITY:{ | 461 | case HW_VAR_SHORTGI_DENSITY:{ |
465 | u8 density_to_set; | 462 | u8 density_to_set; |
466 | 463 | ||
467 | density_to_set = *((u8 *)val); | 464 | density_to_set = *val; |
468 | mac->min_space_cfg |= (density_to_set << 3); | 465 | mac->min_space_cfg |= (density_to_set << 3); |
469 | 466 | ||
470 | RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, | 467 | RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, |
@@ -482,7 +479,7 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
482 | 479 | ||
483 | reg = regtoset_normal; | 480 | reg = regtoset_normal; |
484 | 481 | ||
485 | factor = *((u8 *)val); | 482 | factor = *val; |
486 | if (factor <= 3) { | 483 | if (factor <= 3) { |
487 | factor = (1 << (factor + 2)); | 484 | factor = (1 << (factor + 2)); |
488 | if (factor > 0xf) | 485 | if (factor > 0xf) |
@@ -505,15 +502,15 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
505 | } | 502 | } |
506 | break; } | 503 | break; } |
507 | case HW_VAR_AC_PARAM:{ | 504 | case HW_VAR_AC_PARAM:{ |
508 | u8 e_aci = *((u8 *)val); | 505 | u8 e_aci = *val; |
509 | rtl88e_dm_init_edca_turbo(hw); | 506 | rtl88e_dm_init_edca_turbo(hw); |
510 | 507 | ||
511 | if (rtlpci->acm_method != EACMWAY2_SW) | 508 | if (rtlpci->acm_method != EACMWAY2_SW) |
512 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL, | 509 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL, |
513 | (u8 *)(&e_aci)); | 510 | &e_aci); |
514 | break; } | 511 | break; } |
515 | case HW_VAR_ACM_CTRL:{ | 512 | case HW_VAR_ACM_CTRL:{ |
516 | u8 e_aci = *((u8 *)val); | 513 | u8 e_aci = *val; |
517 | union aci_aifsn *p_aci_aifsn = | 514 | union aci_aifsn *p_aci_aifsn = |
518 | (union aci_aifsn *)(&(mac->ac[0].aifs)); | 515 | (union aci_aifsn *)(&(mac->ac[0].aifs)); |
519 | u8 acm = p_aci_aifsn->f.acm; | 516 | u8 acm = p_aci_aifsn->f.acm; |
@@ -566,7 +563,7 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
566 | rtlpci->receive_config = ((u32 *)(val))[0]; | 563 | rtlpci->receive_config = ((u32 *)(val))[0]; |
567 | break; | 564 | break; |
568 | case HW_VAR_RETRY_LIMIT:{ | 565 | case HW_VAR_RETRY_LIMIT:{ |
569 | u8 retry_limit = ((u8 *)(val))[0]; | 566 | u8 retry_limit = *val; |
570 | 567 | ||
571 | rtl_write_word(rtlpriv, REG_RL, | 568 | rtl_write_word(rtlpriv, REG_RL, |
572 | retry_limit << RETRY_LIMIT_SHORT_SHIFT | | 569 | retry_limit << RETRY_LIMIT_SHORT_SHIFT | |
@@ -579,7 +576,7 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
579 | rtlefuse->efuse_usedbytes = *((u16 *)val); | 576 | rtlefuse->efuse_usedbytes = *((u16 *)val); |
580 | break; | 577 | break; |
581 | case HW_VAR_EFUSE_USAGE: | 578 | case HW_VAR_EFUSE_USAGE: |
582 | rtlefuse->efuse_usedpercentage = *((u8 *)val); | 579 | rtlefuse->efuse_usedpercentage = *val; |
583 | break; | 580 | break; |
584 | case HW_VAR_IO_CMD: | 581 | case HW_VAR_IO_CMD: |
585 | rtl88e_phy_set_io_cmd(hw, (*(enum io_type *)val)); | 582 | 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) | |||
591 | udelay(1); | 588 | udelay(1); |
592 | 589 | ||
593 | if (rpwm_val & BIT(7)) { | 590 | if (rpwm_val & BIT(7)) { |
594 | rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, | 591 | rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, *val); |
595 | (*(u8 *)val)); | ||
596 | } else { | 592 | } else { |
597 | rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, | 593 | rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, *val | BIT(7)); |
598 | ((*(u8 *)val) | BIT(7))); | ||
599 | } | 594 | } |
600 | break; } | 595 | break; } |
601 | case HW_VAR_H2C_FW_PWRMODE: | 596 | case HW_VAR_H2C_FW_PWRMODE: |
602 | rtl88e_set_fw_pwrmode_cmd(hw, (*(u8 *)val)); | 597 | rtl88e_set_fw_pwrmode_cmd(hw, *val); |
603 | break; | 598 | break; |
604 | case HW_VAR_FW_PSMODE_STATUS: | 599 | case HW_VAR_FW_PSMODE_STATUS: |
605 | ppsc->fw_current_inpsmode = *((bool *)val); | 600 | ppsc->fw_current_inpsmode = *((bool *)val); |
@@ -616,7 +611,7 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
616 | _rtl88ee_fwlps_leave(hw); | 611 | _rtl88ee_fwlps_leave(hw); |
617 | break; } | 612 | break; } |
618 | case HW_VAR_H2C_FW_JOINBSSRPT:{ | 613 | case HW_VAR_H2C_FW_JOINBSSRPT:{ |
619 | u8 mstatus = (*(u8 *)val); | 614 | u8 mstatus = *val; |
620 | u8 tmp, tmp_reg422, uval; | 615 | u8 tmp, tmp_reg422, uval; |
621 | u8 count = 0, dlbcn_count = 0; | 616 | u8 count = 0, dlbcn_count = 0; |
622 | bool recover = false; | 617 | bool recover = false; |
@@ -667,10 +662,10 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
667 | } | 662 | } |
668 | rtl_write_byte(rtlpriv, REG_CR + 1, (tmp & ~(BIT(0)))); | 663 | rtl_write_byte(rtlpriv, REG_CR + 1, (tmp & ~(BIT(0)))); |
669 | } | 664 | } |
670 | rtl88e_set_fw_joinbss_report_cmd(hw, (*(u8 *)val)); | 665 | rtl88e_set_fw_joinbss_report_cmd(hw, *val); |
671 | break; } | 666 | break; } |
672 | case HW_VAR_H2C_FW_P2P_PS_OFFLOAD: | 667 | case HW_VAR_H2C_FW_P2P_PS_OFFLOAD: |
673 | rtl88e_set_p2p_ps_offload_cmd(hw, (*(u8 *)val)); | 668 | rtl88e_set_p2p_ps_offload_cmd(hw, *val); |
674 | break; | 669 | break; |
675 | case HW_VAR_AID:{ | 670 | case HW_VAR_AID:{ |
676 | u16 u2btmp; | 671 | u16 u2btmp; |
@@ -680,7 +675,7 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
680 | mac->assoc_id)); | 675 | mac->assoc_id)); |
681 | break; } | 676 | break; } |
682 | case HW_VAR_CORRECT_TSF:{ | 677 | case HW_VAR_CORRECT_TSF:{ |
683 | u8 btype_ibss = ((u8 *)(val))[0]; | 678 | u8 btype_ibss = *val; |
684 | 679 | ||
685 | if (btype_ibss == true) | 680 | if (btype_ibss == true) |
686 | _rtl88ee_stop_tx_beacon(hw); | 681 | _rtl88ee_stop_tx_beacon(hw); |
@@ -1828,7 +1823,7 @@ static void _rtl88ee_read_adapter_info(struct ieee80211_hw *hw) | |||
1828 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, | 1823 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, |
1829 | "EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid); | 1824 | "EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid); |
1830 | /*customer ID*/ | 1825 | /*customer ID*/ |
1831 | rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID]; | 1826 | rtlefuse->eeprom_oemid = hwinfo[EEPROM_CUSTOMER_ID]; |
1832 | if (rtlefuse->eeprom_oemid == 0xFF) | 1827 | if (rtlefuse->eeprom_oemid == 0xFF) |
1833 | rtlefuse->eeprom_oemid = 0; | 1828 | rtlefuse->eeprom_oemid = 0; |
1834 | 1829 | ||
@@ -1845,7 +1840,7 @@ static void _rtl88ee_read_adapter_info(struct ieee80211_hw *hw) | |||
1845 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | 1840 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, |
1846 | "dev_addr: %pM\n", rtlefuse->dev_addr); | 1841 | "dev_addr: %pM\n", rtlefuse->dev_addr); |
1847 | /*channel plan */ | 1842 | /*channel plan */ |
1848 | rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN]; | 1843 | rtlefuse->eeprom_channelplan = hwinfo[EEPROM_CHANNELPLAN]; |
1849 | /* set channel paln to world wide 13 */ | 1844 | /* set channel paln to world wide 13 */ |
1850 | rtlefuse->channel_plan = COUNTRY_CODE_WORLD_WIDE_13; | 1845 | rtlefuse->channel_plan = COUNTRY_CODE_WORLD_WIDE_13; |
1851 | /*tx power*/ | 1846 | /*tx power*/ |
@@ -1857,7 +1852,7 @@ static void _rtl88ee_read_adapter_info(struct ieee80211_hw *hw) | |||
1857 | rtlefuse->autoload_failflag, | 1852 | rtlefuse->autoload_failflag, |
1858 | hwinfo); | 1853 | hwinfo); |
1859 | /*board type*/ | 1854 | /*board type*/ |
1860 | rtlefuse->board_type = (((*(u8 *)&hwinfo[jj]) & 0xE0) >> 5); | 1855 | rtlefuse->board_type = (hwinfo[jj] & 0xE0) >> 5; |
1861 | /*Wake on wlan*/ | 1856 | /*Wake on wlan*/ |
1862 | rtlefuse->wowlan_enable = ((hwinfo[kk] & 0x40) >> 6); | 1857 | rtlefuse->wowlan_enable = ((hwinfo[kk] & 0x40) >> 6); |
1863 | /*parse xtal*/ | 1858 | /*parse xtal*/ |
@@ -2223,8 +2218,7 @@ void rtl88ee_update_channel_access_setting(struct ieee80211_hw *hw) | |||
2223 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 2218 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
2224 | u16 sifs_timer; | 2219 | u16 sifs_timer; |
2225 | 2220 | ||
2226 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, | 2221 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, &mac->slot_time); |
2227 | (u8 *)&mac->slot_time); | ||
2228 | if (!mac->ht_enable) | 2222 | if (!mac->ht_enable) |
2229 | sifs_timer = 0x0a0a; | 2223 | sifs_timer = 0x0a0a; |
2230 | else | 2224 | else |
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/sw.c b/drivers/net/wireless/rtlwifi/rtl8188ee/sw.c index 347af1e4f438..1b4101bf9974 100644 --- a/drivers/net/wireless/rtlwifi/rtl8188ee/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8188ee/sw.c | |||
@@ -93,6 +93,7 @@ int rtl88e_init_sw_vars(struct ieee80211_hw *hw) | |||
93 | u8 tid; | 93 | u8 tid; |
94 | 94 | ||
95 | rtl8188ee_bt_reg_init(hw); | 95 | rtl8188ee_bt_reg_init(hw); |
96 | rtlpci->msi_support = true; | ||
96 | 97 | ||
97 | rtlpriv->dm.dm_initialgain_enable = 1; | 98 | rtlpriv->dm.dm_initialgain_enable = 1; |
98 | rtlpriv->dm.dm_flag = 0; | 99 | rtlpriv->dm.dm_flag = 0; |
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c b/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c index 2ba6f510d884..06ef47cd6203 100644 --- a/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c | |||
@@ -497,7 +497,7 @@ void rtl88ee_tx_fill_desc(struct ieee80211_hw *hw, | |||
497 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 497 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
498 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | 498 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); |
499 | struct rtl_hal *rtlhal = rtl_hal(rtlpriv); | 499 | struct rtl_hal *rtlhal = rtl_hal(rtlpriv); |
500 | u8 *pdesc = (u8 *)pdesc_tx; | 500 | u8 *pdesc = pdesc_tx; |
501 | u16 seq_number; | 501 | u16 seq_number; |
502 | __le16 fc = hdr->frame_control; | 502 | __le16 fc = hdr->frame_control; |
503 | unsigned int buf_len = 0; | 503 | unsigned int buf_len = 0; |
@@ -716,7 +716,7 @@ void rtl88ee_tx_fill_cmddesc(struct ieee80211_hw *hw, | |||
716 | 716 | ||
717 | SET_TX_DESC_OWN(pdesc, 1); | 717 | SET_TX_DESC_OWN(pdesc, 1); |
718 | 718 | ||
719 | SET_TX_DESC_PKT_SIZE((u8 *)pdesc, (u16)(skb->len)); | 719 | SET_TX_DESC_PKT_SIZE(pdesc, (u16)(skb->len)); |
720 | 720 | ||
721 | SET_TX_DESC_FIRST_SEG(pdesc, 1); | 721 | SET_TX_DESC_FIRST_SEG(pdesc, 1); |
722 | SET_TX_DESC_LAST_SEG(pdesc, 1); | 722 | SET_TX_DESC_LAST_SEG(pdesc, 1); |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c index 4ae51d5b436f..55adf043aef7 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c | |||
@@ -476,7 +476,7 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
476 | break; | 476 | break; |
477 | } | 477 | } |
478 | case HW_VAR_H2C_FW_P2P_PS_OFFLOAD: | 478 | case HW_VAR_H2C_FW_P2P_PS_OFFLOAD: |
479 | rtl92c_set_p2p_ps_offload_cmd(hw, (*(u8 *)val)); | 479 | rtl92c_set_p2p_ps_offload_cmd(hw, *val); |
480 | break; | 480 | break; |
481 | case HW_VAR_AID:{ | 481 | case HW_VAR_AID:{ |
482 | u16 u2btmp; | 482 | u16 u2btmp; |
@@ -521,21 +521,21 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
521 | (u8 *)(&fw_current_inps)); | 521 | (u8 *)(&fw_current_inps)); |
522 | rtlpriv->cfg->ops->set_hw_reg(hw, | 522 | rtlpriv->cfg->ops->set_hw_reg(hw, |
523 | HW_VAR_H2C_FW_PWRMODE, | 523 | HW_VAR_H2C_FW_PWRMODE, |
524 | (u8 *)(&ppsc->fwctrl_psmode)); | 524 | &ppsc->fwctrl_psmode); |
525 | 525 | ||
526 | rtlpriv->cfg->ops->set_hw_reg(hw, | 526 | rtlpriv->cfg->ops->set_hw_reg(hw, |
527 | HW_VAR_SET_RPWM, | 527 | HW_VAR_SET_RPWM, |
528 | (u8 *)(&rpwm_val)); | 528 | &rpwm_val); |
529 | } else { | 529 | } else { |
530 | rpwm_val = 0x0C; /* RF on */ | 530 | rpwm_val = 0x0C; /* RF on */ |
531 | fw_pwrmode = FW_PS_ACTIVE_MODE; | 531 | fw_pwrmode = FW_PS_ACTIVE_MODE; |
532 | fw_current_inps = false; | 532 | fw_current_inps = false; |
533 | rtlpriv->cfg->ops->set_hw_reg(hw, | 533 | rtlpriv->cfg->ops->set_hw_reg(hw, |
534 | HW_VAR_SET_RPWM, | 534 | HW_VAR_SET_RPWM, |
535 | (u8 *)(&rpwm_val)); | 535 | &rpwm_val); |
536 | rtlpriv->cfg->ops->set_hw_reg(hw, | 536 | rtlpriv->cfg->ops->set_hw_reg(hw, |
537 | HW_VAR_H2C_FW_PWRMODE, | 537 | HW_VAR_H2C_FW_PWRMODE, |
538 | (u8 *)(&fw_pwrmode)); | 538 | &fw_pwrmode); |
539 | 539 | ||
540 | rtlpriv->cfg->ops->set_hw_reg(hw, | 540 | rtlpriv->cfg->ops->set_hw_reg(hw, |
541 | HW_VAR_FW_PSMODE_STATUS, | 541 | HW_VAR_FW_PSMODE_STATUS, |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c index 3015af167b2b..9098558d916d 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c | |||
@@ -413,20 +413,18 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
413 | (u8 *)(&fw_current_inps)); | 413 | (u8 *)(&fw_current_inps)); |
414 | rtlpriv->cfg->ops->set_hw_reg(hw, | 414 | rtlpriv->cfg->ops->set_hw_reg(hw, |
415 | HW_VAR_H2C_FW_PWRMODE, | 415 | HW_VAR_H2C_FW_PWRMODE, |
416 | (u8 *)(&ppsc->fwctrl_psmode)); | 416 | &ppsc->fwctrl_psmode); |
417 | 417 | ||
418 | rtlpriv->cfg->ops->set_hw_reg(hw, | 418 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, |
419 | HW_VAR_SET_RPWM, | 419 | &rpwm_val); |
420 | (u8 *)(&rpwm_val)); | ||
421 | } else { | 420 | } else { |
422 | rpwm_val = 0x0C; /* RF on */ | 421 | rpwm_val = 0x0C; /* RF on */ |
423 | fw_pwrmode = FW_PS_ACTIVE_MODE; | 422 | fw_pwrmode = FW_PS_ACTIVE_MODE; |
424 | fw_current_inps = false; | 423 | fw_current_inps = false; |
425 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, | 424 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, |
426 | (u8 *)(&rpwm_val)); | 425 | &rpwm_val); |
427 | rtlpriv->cfg->ops->set_hw_reg(hw, | 426 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, |
428 | HW_VAR_H2C_FW_PWRMODE, | 427 | &fw_pwrmode); |
429 | (u8 *)(&fw_pwrmode)); | ||
430 | 428 | ||
431 | rtlpriv->cfg->ops->set_hw_reg(hw, | 429 | rtlpriv->cfg->ops->set_hw_reg(hw, |
432 | HW_VAR_FW_PSMODE_STATUS, | 430 | HW_VAR_FW_PSMODE_STATUS, |
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/dm.c b/drivers/net/wireless/rtlwifi/rtl8723ae/dm.c index 863ddb3e2888..25cc83058b01 100644 --- a/drivers/net/wireless/rtlwifi/rtl8723ae/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/dm.c | |||
@@ -647,9 +647,8 @@ static void rtl8723ae_dm_check_edca_turbo(struct ieee80211_hw *hw) | |||
647 | } else { | 647 | } else { |
648 | if (rtlpriv->dm.current_turbo_edca) { | 648 | if (rtlpriv->dm.current_turbo_edca) { |
649 | u8 tmp = AC0_BE; | 649 | u8 tmp = AC0_BE; |
650 | rtlpriv->cfg->ops->set_hw_reg(hw, | 650 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, |
651 | HW_VAR_AC_PARAM, | 651 | &tmp); |
652 | (u8 *) (&tmp)); | ||
653 | rtlpriv->dm.current_turbo_edca = false; | 652 | rtlpriv->dm.current_turbo_edca = false; |
654 | } | 653 | } |
655 | } | 654 | } |
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c b/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c index f4c9852d1e1e..65c9e80e1f78 100644 --- a/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c | |||
@@ -207,14 +207,13 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
207 | rtl_write_byte(rtlpriv, REG_SLOT, val[0]); | 207 | rtl_write_byte(rtlpriv, REG_SLOT, val[0]); |
208 | 208 | ||
209 | for (e_aci = 0; e_aci < AC_MAX; e_aci++) { | 209 | for (e_aci = 0; e_aci < AC_MAX; e_aci++) { |
210 | rtlpriv->cfg->ops->set_hw_reg(hw, | 210 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, |
211 | HW_VAR_AC_PARAM, | 211 | &e_aci); |
212 | (u8 *) (&e_aci)); | ||
213 | } | 212 | } |
214 | break; } | 213 | break; } |
215 | case HW_VAR_ACK_PREAMBLE:{ | 214 | case HW_VAR_ACK_PREAMBLE:{ |
216 | u8 reg_tmp; | 215 | u8 reg_tmp; |
217 | u8 short_preamble = (bool) (*(u8 *) val); | 216 | u8 short_preamble = (bool)*val; |
218 | reg_tmp = (mac->cur_40_prime_sc) << 5; | 217 | reg_tmp = (mac->cur_40_prime_sc) << 5; |
219 | if (short_preamble) | 218 | if (short_preamble) |
220 | reg_tmp |= 0x80; | 219 | reg_tmp |= 0x80; |
@@ -225,7 +224,7 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
225 | u8 min_spacing_to_set; | 224 | u8 min_spacing_to_set; |
226 | u8 sec_min_space; | 225 | u8 sec_min_space; |
227 | 226 | ||
228 | min_spacing_to_set = *((u8 *) val); | 227 | min_spacing_to_set = *val; |
229 | if (min_spacing_to_set <= 7) { | 228 | if (min_spacing_to_set <= 7) { |
230 | sec_min_space = 0; | 229 | sec_min_space = 0; |
231 | 230 | ||
@@ -249,7 +248,7 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
249 | case HW_VAR_SHORTGI_DENSITY:{ | 248 | case HW_VAR_SHORTGI_DENSITY:{ |
250 | u8 density_to_set; | 249 | u8 density_to_set; |
251 | 250 | ||
252 | density_to_set = *((u8 *) val); | 251 | density_to_set = *val; |
253 | mac->min_space_cfg |= (density_to_set << 3); | 252 | mac->min_space_cfg |= (density_to_set << 3); |
254 | 253 | ||
255 | RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, | 254 | RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, |
@@ -273,7 +272,7 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
273 | else | 272 | else |
274 | p_regtoset = regtoset_normal; | 273 | p_regtoset = regtoset_normal; |
275 | 274 | ||
276 | factor_toset = *((u8 *) val); | 275 | factor_toset = *val; |
277 | if (factor_toset <= 3) { | 276 | if (factor_toset <= 3) { |
278 | factor_toset = (1 << (factor_toset + 2)); | 277 | factor_toset = (1 << (factor_toset + 2)); |
279 | if (factor_toset > 0xf) | 278 | if (factor_toset > 0xf) |
@@ -304,16 +303,15 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
304 | } | 303 | } |
305 | break; } | 304 | break; } |
306 | case HW_VAR_AC_PARAM:{ | 305 | case HW_VAR_AC_PARAM:{ |
307 | u8 e_aci = *((u8 *) val); | 306 | u8 e_aci = *val; |
308 | rtl8723_dm_init_edca_turbo(hw); | 307 | rtl8723_dm_init_edca_turbo(hw); |
309 | 308 | ||
310 | if (rtlpci->acm_method != EACMWAY2_SW) | 309 | if (rtlpci->acm_method != EACMWAY2_SW) |
311 | rtlpriv->cfg->ops->set_hw_reg(hw, | 310 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL, |
312 | HW_VAR_ACM_CTRL, | 311 | &e_aci); |
313 | (u8 *) (&e_aci)); | ||
314 | break; } | 312 | break; } |
315 | case HW_VAR_ACM_CTRL:{ | 313 | case HW_VAR_ACM_CTRL:{ |
316 | u8 e_aci = *((u8 *) val); | 314 | u8 e_aci = *val; |
317 | union aci_aifsn *p_aci_aifsn = | 315 | union aci_aifsn *p_aci_aifsn = |
318 | (union aci_aifsn *)(&(mac->ac[0].aifs)); | 316 | (union aci_aifsn *)(&(mac->ac[0].aifs)); |
319 | u8 acm = p_aci_aifsn->f.acm; | 317 | u8 acm = p_aci_aifsn->f.acm; |
@@ -366,7 +364,7 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
366 | rtlpci->receive_config = ((u32 *) (val))[0]; | 364 | rtlpci->receive_config = ((u32 *) (val))[0]; |
367 | break; | 365 | break; |
368 | case HW_VAR_RETRY_LIMIT:{ | 366 | case HW_VAR_RETRY_LIMIT:{ |
369 | u8 retry_limit = ((u8 *) (val))[0]; | 367 | u8 retry_limit = *val; |
370 | 368 | ||
371 | rtl_write_word(rtlpriv, REG_RL, | 369 | rtl_write_word(rtlpriv, REG_RL, |
372 | retry_limit << RETRY_LIMIT_SHORT_SHIFT | | 370 | retry_limit << RETRY_LIMIT_SHORT_SHIFT | |
@@ -379,13 +377,13 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
379 | rtlefuse->efuse_usedbytes = *((u16 *) val); | 377 | rtlefuse->efuse_usedbytes = *((u16 *) val); |
380 | break; | 378 | break; |
381 | case HW_VAR_EFUSE_USAGE: | 379 | case HW_VAR_EFUSE_USAGE: |
382 | rtlefuse->efuse_usedpercentage = *((u8 *) val); | 380 | rtlefuse->efuse_usedpercentage = *val; |
383 | break; | 381 | break; |
384 | case HW_VAR_IO_CMD: | 382 | case HW_VAR_IO_CMD: |
385 | rtl8723ae_phy_set_io_cmd(hw, (*(enum io_type *)val)); | 383 | rtl8723ae_phy_set_io_cmd(hw, (*(enum io_type *)val)); |
386 | break; | 384 | break; |
387 | case HW_VAR_WPA_CONFIG: | 385 | case HW_VAR_WPA_CONFIG: |
388 | rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *) val)); | 386 | rtl_write_byte(rtlpriv, REG_SECCFG, *val); |
389 | break; | 387 | break; |
390 | case HW_VAR_SET_RPWM:{ | 388 | case HW_VAR_SET_RPWM:{ |
391 | u8 rpwm_val; | 389 | u8 rpwm_val; |
@@ -394,27 +392,25 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
394 | udelay(1); | 392 | udelay(1); |
395 | 393 | ||
396 | if (rpwm_val & BIT(7)) { | 394 | if (rpwm_val & BIT(7)) { |
397 | rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, | 395 | rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, *val); |
398 | (*(u8 *) val)); | ||
399 | } else { | 396 | } else { |
400 | rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, | 397 | rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, *val | BIT(7)); |
401 | ((*(u8 *) val) | BIT(7))); | ||
402 | } | 398 | } |
403 | 399 | ||
404 | break; } | 400 | break; } |
405 | case HW_VAR_H2C_FW_PWRMODE:{ | 401 | case HW_VAR_H2C_FW_PWRMODE:{ |
406 | u8 psmode = (*(u8 *) val); | 402 | u8 psmode = *val; |
407 | 403 | ||
408 | if (psmode != FW_PS_ACTIVE_MODE) | 404 | if (psmode != FW_PS_ACTIVE_MODE) |
409 | rtl8723ae_dm_rf_saving(hw, true); | 405 | rtl8723ae_dm_rf_saving(hw, true); |
410 | 406 | ||
411 | rtl8723ae_set_fw_pwrmode_cmd(hw, (*(u8 *) val)); | 407 | rtl8723ae_set_fw_pwrmode_cmd(hw, *val); |
412 | break; } | 408 | break; } |
413 | case HW_VAR_FW_PSMODE_STATUS: | 409 | case HW_VAR_FW_PSMODE_STATUS: |
414 | ppsc->fw_current_inpsmode = *((bool *) val); | 410 | ppsc->fw_current_inpsmode = *((bool *) val); |
415 | break; | 411 | break; |
416 | case HW_VAR_H2C_FW_JOINBSSRPT:{ | 412 | case HW_VAR_H2C_FW_JOINBSSRPT:{ |
417 | u8 mstatus = (*(u8 *) val); | 413 | u8 mstatus = *val; |
418 | u8 tmp_regcr, tmp_reg422; | 414 | u8 tmp_regcr, tmp_reg422; |
419 | bool recover = false; | 415 | bool recover = false; |
420 | 416 | ||
@@ -447,11 +443,11 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
447 | rtl_write_byte(rtlpriv, REG_CR + 1, | 443 | rtl_write_byte(rtlpriv, REG_CR + 1, |
448 | (tmp_regcr & ~(BIT(0)))); | 444 | (tmp_regcr & ~(BIT(0)))); |
449 | } | 445 | } |
450 | rtl8723ae_set_fw_joinbss_report_cmd(hw, (*(u8 *) val)); | 446 | rtl8723ae_set_fw_joinbss_report_cmd(hw, *val); |
451 | 447 | ||
452 | break; } | 448 | break; } |
453 | case HW_VAR_H2C_FW_P2P_PS_OFFLOAD: | 449 | case HW_VAR_H2C_FW_P2P_PS_OFFLOAD: |
454 | rtl8723ae_set_p2p_ps_offload_cmd(hw, (*(u8 *)val)); | 450 | rtl8723ae_set_p2p_ps_offload_cmd(hw, *val); |
455 | break; | 451 | break; |
456 | case HW_VAR_AID:{ | 452 | case HW_VAR_AID:{ |
457 | u16 u2btmp; | 453 | u16 u2btmp; |
@@ -461,7 +457,7 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
461 | mac->assoc_id)); | 457 | mac->assoc_id)); |
462 | break; } | 458 | break; } |
463 | case HW_VAR_CORRECT_TSF:{ | 459 | case HW_VAR_CORRECT_TSF:{ |
464 | u8 btype_ibss = ((u8 *) (val))[0]; | 460 | u8 btype_ibss = *val; |
465 | 461 | ||
466 | if (btype_ibss == true) | 462 | if (btype_ibss == true) |
467 | _rtl8723ae_stop_tx_beacon(hw); | 463 | _rtl8723ae_stop_tx_beacon(hw); |
@@ -491,20 +487,18 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
491 | (u8 *)(&fw_current_inps)); | 487 | (u8 *)(&fw_current_inps)); |
492 | rtlpriv->cfg->ops->set_hw_reg(hw, | 488 | rtlpriv->cfg->ops->set_hw_reg(hw, |
493 | HW_VAR_H2C_FW_PWRMODE, | 489 | HW_VAR_H2C_FW_PWRMODE, |
494 | (u8 *)(&ppsc->fwctrl_psmode)); | 490 | &ppsc->fwctrl_psmode); |
495 | 491 | ||
496 | rtlpriv->cfg->ops->set_hw_reg(hw, | 492 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, |
497 | HW_VAR_SET_RPWM, | 493 | &rpwm_val); |
498 | (u8 *)(&rpwm_val)); | ||
499 | } else { | 494 | } else { |
500 | rpwm_val = 0x0C; /* RF on */ | 495 | rpwm_val = 0x0C; /* RF on */ |
501 | fw_pwrmode = FW_PS_ACTIVE_MODE; | 496 | fw_pwrmode = FW_PS_ACTIVE_MODE; |
502 | fw_current_inps = false; | 497 | fw_current_inps = false; |
503 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, | 498 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, |
504 | (u8 *)(&rpwm_val)); | 499 | &rpwm_val); |
505 | rtlpriv->cfg->ops->set_hw_reg(hw, | 500 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, |
506 | HW_VAR_H2C_FW_PWRMODE, | 501 | &fw_pwrmode); |
507 | (u8 *)(&fw_pwrmode)); | ||
508 | 502 | ||
509 | rtlpriv->cfg->ops->set_hw_reg(hw, | 503 | rtlpriv->cfg->ops->set_hw_reg(hw, |
510 | HW_VAR_FW_PSMODE_STATUS, | 504 | HW_VAR_FW_PSMODE_STATUS, |
@@ -1628,10 +1622,10 @@ static void _rtl8723ae_read_adapter_info(struct ieee80211_hw *hw, | |||
1628 | rtl8723ae_read_bt_coexist_info_from_hwpg(hw, | 1622 | rtl8723ae_read_bt_coexist_info_from_hwpg(hw, |
1629 | rtlefuse->autoload_failflag, hwinfo); | 1623 | rtlefuse->autoload_failflag, hwinfo); |
1630 | 1624 | ||
1631 | rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN]; | 1625 | rtlefuse->eeprom_channelplan = hwinfo[EEPROM_CHANNELPLAN]; |
1632 | rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION]; | 1626 | rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION]; |
1633 | rtlefuse->txpwr_fromeprom = true; | 1627 | rtlefuse->txpwr_fromeprom = true; |
1634 | rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID]; | 1628 | rtlefuse->eeprom_oemid = hwinfo[EEPROM_CUSTOMER_ID]; |
1635 | 1629 | ||
1636 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, | 1630 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, |
1637 | "EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid); | 1631 | "EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid); |
@@ -2051,8 +2045,7 @@ void rtl8723ae_update_channel_access_setting(struct ieee80211_hw *hw) | |||
2051 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 2045 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
2052 | u16 sifs_timer; | 2046 | u16 sifs_timer; |
2053 | 2047 | ||
2054 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, | 2048 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, &mac->slot_time); |
2055 | (u8 *)&mac->slot_time); | ||
2056 | if (!mac->ht_enable) | 2049 | if (!mac->ht_enable) |
2057 | sifs_timer = 0x0a0a; | 2050 | sifs_timer = 0x0a0a; |
2058 | else | 2051 | else |
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c b/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c index 29adf55c6fd3..10b7577b6ae5 100644 --- a/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c | |||
@@ -375,7 +375,7 @@ void rtl8723ae_tx_fill_desc(struct ieee80211_hw *hw, | |||
375 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | 375 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); |
376 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | 376 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); |
377 | bool defaultadapter = true; | 377 | bool defaultadapter = true; |
378 | u8 *pdesc = (u8 *) pdesc_tx; | 378 | u8 *pdesc = pdesc_tx; |
379 | u16 seq_number; | 379 | u16 seq_number; |
380 | __le16 fc = hdr->frame_control; | 380 | __le16 fc = hdr->frame_control; |
381 | u8 fw_qsel = _rtl8723ae_map_hwqueue_to_fwqueue(skb, hw_queue); | 381 | u8 fw_qsel = _rtl8723ae_map_hwqueue_to_fwqueue(skb, hw_queue); |
@@ -577,7 +577,7 @@ void rtl8723ae_tx_fill_cmddesc(struct ieee80211_hw *hw, | |||
577 | 577 | ||
578 | SET_TX_DESC_OWN(pdesc, 1); | 578 | SET_TX_DESC_OWN(pdesc, 1); |
579 | 579 | ||
580 | SET_TX_DESC_PKT_SIZE((u8 *) pdesc, (u16) (skb->len)); | 580 | SET_TX_DESC_PKT_SIZE(pdesc, (u16) (skb->len)); |
581 | 581 | ||
582 | SET_TX_DESC_FIRST_SEG(pdesc, 1); | 582 | SET_TX_DESC_FIRST_SEG(pdesc, 1); |
583 | SET_TX_DESC_LAST_SEG(pdesc, 1); | 583 | SET_TX_DESC_LAST_SEG(pdesc, 1); |
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/dm.c b/drivers/net/wireless/rtlwifi/rtl8723be/dm.c index 736bfcb7938a..13d53a1df789 100644 --- a/drivers/net/wireless/rtlwifi/rtl8723be/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8723be/dm.c | |||
@@ -1083,7 +1083,7 @@ static void rtl8723be_dm_check_edca_turbo(struct ieee80211_hw *hw) | |||
1083 | if (rtlpriv->dm.current_turbo_edca) { | 1083 | if (rtlpriv->dm.current_turbo_edca) { |
1084 | u8 tmp = AC0_BE; | 1084 | u8 tmp = AC0_BE; |
1085 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, | 1085 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, |
1086 | (u8 *)(&tmp)); | 1086 | &tmp); |
1087 | } | 1087 | } |
1088 | rtlpriv->dm.current_turbo_edca = false; | 1088 | rtlpriv->dm.current_turbo_edca = false; |
1089 | } | 1089 | } |
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/hw.c b/drivers/net/wireless/rtlwifi/rtl8723be/hw.c index 7e70c7108d91..0fdf0909321f 100644 --- a/drivers/net/wireless/rtlwifi/rtl8723be/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8723be/hw.c | |||
@@ -147,7 +147,7 @@ static void _rtl8723be_set_fw_clock_on(struct ieee80211_hw *hw, u8 rpwm_val, | |||
147 | } | 147 | } |
148 | if (IS_IN_LOW_POWER_STATE_88E(rtlhal->fw_ps_state)) { | 148 | if (IS_IN_LOW_POWER_STATE_88E(rtlhal->fw_ps_state)) { |
149 | rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_SET_RPWM, | 149 | rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_SET_RPWM, |
150 | (u8 *)(&rpwm_val)); | 150 | &rpwm_val); |
151 | if (FW_PS_IS_ACK(rpwm_val)) { | 151 | if (FW_PS_IS_ACK(rpwm_val)) { |
152 | isr_regaddr = REG_HISR; | 152 | isr_regaddr = REG_HISR; |
153 | content = rtl_read_dword(rtlpriv, isr_regaddr); | 153 | 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) | |||
221 | rtlhal->fw_ps_state = FW_PS_STATE(rpwm_val); | 221 | rtlhal->fw_ps_state = FW_PS_STATE(rpwm_val); |
222 | rtl_write_word(rtlpriv, REG_HISR, 0x0100); | 222 | rtl_write_word(rtlpriv, REG_HISR, 0x0100); |
223 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, | 223 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, |
224 | (u8 *)(&rpwm_val)); | 224 | &rpwm_val); |
225 | spin_lock_bh(&rtlpriv->locks.fw_ps_lock); | 225 | spin_lock_bh(&rtlpriv->locks.fw_ps_lock); |
226 | rtlhal->fw_clk_change_in_progress = false; | 226 | rtlhal->fw_clk_change_in_progress = false; |
227 | spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); | 227 | spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); |
@@ -253,15 +253,14 @@ static void _rtl8723be_fwlps_leave(struct ieee80211_hw *hw) | |||
253 | _rtl8723be_set_fw_clock_on(hw, rpwm_val, false); | 253 | _rtl8723be_set_fw_clock_on(hw, rpwm_val, false); |
254 | rtlhal->allow_sw_to_change_hwclc = false; | 254 | rtlhal->allow_sw_to_change_hwclc = false; |
255 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, | 255 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, |
256 | (u8 *)(&fw_pwrmode)); | 256 | &fw_pwrmode); |
257 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, | 257 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, |
258 | (u8 *)(&fw_current_inps)); | 258 | (u8 *)(&fw_current_inps)); |
259 | } else { | 259 | } else { |
260 | rpwm_val = FW_PS_STATE_ALL_ON_88E; /* RF on */ | 260 | rpwm_val = FW_PS_STATE_ALL_ON_88E; /* RF on */ |
261 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, | 261 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, &rpwm_val); |
262 | (u8 *)(&rpwm_val)); | ||
263 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, | 262 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, |
264 | (u8 *)(&fw_pwrmode)); | 263 | &fw_pwrmode); |
265 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, | 264 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, |
266 | (u8 *)(&fw_current_inps)); | 265 | (u8 *)(&fw_current_inps)); |
267 | } | 266 | } |
@@ -280,7 +279,7 @@ static void _rtl8723be_fwlps_enter(struct ieee80211_hw *hw) | |||
280 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, | 279 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, |
281 | (u8 *)(&fw_current_inps)); | 280 | (u8 *)(&fw_current_inps)); |
282 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, | 281 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, |
283 | (u8 *)(&ppsc->fwctrl_psmode)); | 282 | &ppsc->fwctrl_psmode); |
284 | rtlhal->allow_sw_to_change_hwclc = true; | 283 | rtlhal->allow_sw_to_change_hwclc = true; |
285 | _rtl8723be_set_fw_clock_off(hw, rpwm_val); | 284 | _rtl8723be_set_fw_clock_off(hw, rpwm_val); |
286 | 285 | ||
@@ -289,9 +288,8 @@ static void _rtl8723be_fwlps_enter(struct ieee80211_hw *hw) | |||
289 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, | 288 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, |
290 | (u8 *)(&fw_current_inps)); | 289 | (u8 *)(&fw_current_inps)); |
291 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, | 290 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, |
292 | (u8 *)(&ppsc->fwctrl_psmode)); | 291 | &ppsc->fwctrl_psmode); |
293 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, | 292 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, &rpwm_val); |
294 | (u8 *)(&rpwm_val)); | ||
295 | } | 293 | } |
296 | } | 294 | } |
297 | 295 | ||
@@ -400,12 +398,12 @@ void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
400 | 398 | ||
401 | for (e_aci = 0; e_aci < AC_MAX; e_aci++) { | 399 | for (e_aci = 0; e_aci < AC_MAX; e_aci++) { |
402 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, | 400 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, |
403 | (u8 *)(&e_aci)); | 401 | &e_aci); |
404 | } | 402 | } |
405 | break; } | 403 | break; } |
406 | case HW_VAR_ACK_PREAMBLE: { | 404 | case HW_VAR_ACK_PREAMBLE: { |
407 | u8 reg_tmp; | 405 | u8 reg_tmp; |
408 | u8 short_preamble = (bool) (*(u8 *)val); | 406 | u8 short_preamble = (bool)*val; |
409 | reg_tmp = rtl_read_byte(rtlpriv, REG_TRXPTCL_CTL + 2); | 407 | reg_tmp = rtl_read_byte(rtlpriv, REG_TRXPTCL_CTL + 2); |
410 | if (short_preamble) { | 408 | if (short_preamble) { |
411 | reg_tmp |= 0x02; | 409 | reg_tmp |= 0x02; |
@@ -416,13 +414,13 @@ void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
416 | } | 414 | } |
417 | break; } | 415 | break; } |
418 | case HW_VAR_WPA_CONFIG: | 416 | case HW_VAR_WPA_CONFIG: |
419 | rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *)val)); | 417 | rtl_write_byte(rtlpriv, REG_SECCFG, *val); |
420 | break; | 418 | break; |
421 | case HW_VAR_AMPDU_MIN_SPACE: { | 419 | case HW_VAR_AMPDU_MIN_SPACE: { |
422 | u8 min_spacing_to_set; | 420 | u8 min_spacing_to_set; |
423 | u8 sec_min_space; | 421 | u8 sec_min_space; |
424 | 422 | ||
425 | min_spacing_to_set = *((u8 *)val); | 423 | min_spacing_to_set = *val; |
426 | if (min_spacing_to_set <= 7) { | 424 | if (min_spacing_to_set <= 7) { |
427 | sec_min_space = 0; | 425 | sec_min_space = 0; |
428 | 426 | ||
@@ -445,7 +443,7 @@ void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
445 | case HW_VAR_SHORTGI_DENSITY: { | 443 | case HW_VAR_SHORTGI_DENSITY: { |
446 | u8 density_to_set; | 444 | u8 density_to_set; |
447 | 445 | ||
448 | density_to_set = *((u8 *)val); | 446 | density_to_set = *val; |
449 | mac->min_space_cfg |= (density_to_set << 3); | 447 | mac->min_space_cfg |= (density_to_set << 3); |
450 | 448 | ||
451 | RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, | 449 | RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, |
@@ -463,7 +461,7 @@ void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
463 | 461 | ||
464 | p_regtoset = regtoset_normal; | 462 | p_regtoset = regtoset_normal; |
465 | 463 | ||
466 | factor_toset = *((u8 *)val); | 464 | factor_toset = *val; |
467 | if (factor_toset <= 3) { | 465 | if (factor_toset <= 3) { |
468 | factor_toset = (1 << (factor_toset + 2)); | 466 | factor_toset = (1 << (factor_toset + 2)); |
469 | if (factor_toset > 0xf) | 467 | if (factor_toset > 0xf) |
@@ -491,15 +489,15 @@ void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
491 | } | 489 | } |
492 | break; } | 490 | break; } |
493 | case HW_VAR_AC_PARAM: { | 491 | case HW_VAR_AC_PARAM: { |
494 | u8 e_aci = *((u8 *)val); | 492 | u8 e_aci = *val; |
495 | rtl8723_dm_init_edca_turbo(hw); | 493 | rtl8723_dm_init_edca_turbo(hw); |
496 | 494 | ||
497 | if (rtlpci->acm_method != EACMWAY2_SW) | 495 | if (rtlpci->acm_method != EACMWAY2_SW) |
498 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL, | 496 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL, |
499 | (u8 *)(&e_aci)); | 497 | &e_aci); |
500 | break; } | 498 | break; } |
501 | case HW_VAR_ACM_CTRL: { | 499 | case HW_VAR_ACM_CTRL: { |
502 | u8 e_aci = *((u8 *)val); | 500 | u8 e_aci = *val; |
503 | union aci_aifsn *p_aci_aifsn = | 501 | union aci_aifsn *p_aci_aifsn = |
504 | (union aci_aifsn *)(&(mac->ac[0].aifs)); | 502 | (union aci_aifsn *)(&(mac->ac[0].aifs)); |
505 | u8 acm = p_aci_aifsn->f.acm; | 503 | u8 acm = p_aci_aifsn->f.acm; |
@@ -552,7 +550,7 @@ void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
552 | rtlpci->receive_config = ((u32 *)(val))[0]; | 550 | rtlpci->receive_config = ((u32 *)(val))[0]; |
553 | break; | 551 | break; |
554 | case HW_VAR_RETRY_LIMIT: { | 552 | case HW_VAR_RETRY_LIMIT: { |
555 | u8 retry_limit = ((u8 *)(val))[0]; | 553 | u8 retry_limit = *val; |
556 | 554 | ||
557 | rtl_write_word(rtlpriv, REG_RL, | 555 | rtl_write_word(rtlpriv, REG_RL, |
558 | retry_limit << RETRY_LIMIT_SHORT_SHIFT | | 556 | retry_limit << RETRY_LIMIT_SHORT_SHIFT | |
@@ -565,7 +563,7 @@ void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
565 | rtlefuse->efuse_usedbytes = *((u16 *)val); | 563 | rtlefuse->efuse_usedbytes = *((u16 *)val); |
566 | break; | 564 | break; |
567 | case HW_VAR_EFUSE_USAGE: | 565 | case HW_VAR_EFUSE_USAGE: |
568 | rtlefuse->efuse_usedpercentage = *((u8 *)val); | 566 | rtlefuse->efuse_usedpercentage = *val; |
569 | break; | 567 | break; |
570 | case HW_VAR_IO_CMD: | 568 | case HW_VAR_IO_CMD: |
571 | rtl8723be_phy_set_io_cmd(hw, (*(enum io_type *)val)); | 569 | 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) | |||
577 | udelay(1); | 575 | udelay(1); |
578 | 576 | ||
579 | if (rpwm_val & BIT(7)) { | 577 | if (rpwm_val & BIT(7)) { |
580 | rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, (*(u8 *)val)); | 578 | rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, *val); |
581 | } else { | 579 | } else { |
582 | rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, | 580 | rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, *val | BIT(7)); |
583 | ((*(u8 *)val) | BIT(7))); | ||
584 | } | 581 | } |
585 | break; } | 582 | break; } |
586 | case HW_VAR_H2C_FW_PWRMODE: | 583 | case HW_VAR_H2C_FW_PWRMODE: |
587 | rtl8723be_set_fw_pwrmode_cmd(hw, (*(u8 *)val)); | 584 | rtl8723be_set_fw_pwrmode_cmd(hw, *val); |
588 | break; | 585 | break; |
589 | case HW_VAR_FW_PSMODE_STATUS: | 586 | case HW_VAR_FW_PSMODE_STATUS: |
590 | ppsc->fw_current_inpsmode = *((bool *)val); | 587 | ppsc->fw_current_inpsmode = *((bool *)val); |
@@ -602,7 +599,7 @@ void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
602 | 599 | ||
603 | break; } | 600 | break; } |
604 | case HW_VAR_H2C_FW_JOINBSSRPT: { | 601 | case HW_VAR_H2C_FW_JOINBSSRPT: { |
605 | u8 mstatus = (*(u8 *)val); | 602 | u8 mstatus = *val; |
606 | u8 tmp_regcr, tmp_reg422, bcnvalid_reg; | 603 | u8 tmp_regcr, tmp_reg422, bcnvalid_reg; |
607 | u8 count = 0, dlbcn_count = 0; | 604 | u8 count = 0, dlbcn_count = 0; |
608 | bool recover = false; | 605 | bool recover = false; |
@@ -657,10 +654,10 @@ void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
657 | rtl_write_byte(rtlpriv, REG_CR + 1, | 654 | rtl_write_byte(rtlpriv, REG_CR + 1, |
658 | (tmp_regcr & ~(BIT(0)))); | 655 | (tmp_regcr & ~(BIT(0)))); |
659 | } | 656 | } |
660 | rtl8723be_set_fw_joinbss_report_cmd(hw, (*(u8 *)val)); | 657 | rtl8723be_set_fw_joinbss_report_cmd(hw, *val); |
661 | break; } | 658 | break; } |
662 | case HW_VAR_H2C_FW_P2P_PS_OFFLOAD: | 659 | case HW_VAR_H2C_FW_P2P_PS_OFFLOAD: |
663 | rtl8723be_set_p2p_ps_offload_cmd(hw, (*(u8 *)val)); | 660 | rtl8723be_set_p2p_ps_offload_cmd(hw, *val); |
664 | break; | 661 | break; |
665 | case HW_VAR_AID: { | 662 | case HW_VAR_AID: { |
666 | u16 u2btmp; | 663 | u16 u2btmp; |
@@ -670,7 +667,7 @@ void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
670 | (u2btmp | mac->assoc_id)); | 667 | (u2btmp | mac->assoc_id)); |
671 | break; } | 668 | break; } |
672 | case HW_VAR_CORRECT_TSF: { | 669 | case HW_VAR_CORRECT_TSF: { |
673 | u8 btype_ibss = ((u8 *)(val))[0]; | 670 | u8 btype_ibss = *val; |
674 | 671 | ||
675 | if (btype_ibss) | 672 | if (btype_ibss) |
676 | _rtl8723be_stop_tx_beacon(hw); | 673 | _rtl8723be_stop_tx_beacon(hw); |
@@ -690,7 +687,7 @@ void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
690 | case HW_VAR_KEEP_ALIVE: { | 687 | case HW_VAR_KEEP_ALIVE: { |
691 | u8 array[2]; | 688 | u8 array[2]; |
692 | array[0] = 0xff; | 689 | array[0] = 0xff; |
693 | array[1] = *((u8 *)val); | 690 | array[1] = *val; |
694 | rtl8723be_fill_h2c_cmd(hw, H2C_8723BE_KEEP_ALIVE_CTRL, | 691 | rtl8723be_fill_h2c_cmd(hw, H2C_8723BE_KEEP_ALIVE_CTRL, |
695 | 2, array); | 692 | 2, array); |
696 | break; } | 693 | break; } |
@@ -1783,10 +1780,10 @@ static void _rtl8723be_read_adapter_info(struct ieee80211_hw *hw, | |||
1783 | rtlefuse->autoload_failflag, | 1780 | rtlefuse->autoload_failflag, |
1784 | hwinfo); | 1781 | hwinfo); |
1785 | 1782 | ||
1786 | rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN]; | 1783 | rtlefuse->eeprom_channelplan = hwinfo[EEPROM_CHANNELPLAN]; |
1787 | rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION]; | 1784 | rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION]; |
1788 | rtlefuse->txpwr_fromeprom = true; | 1785 | rtlefuse->txpwr_fromeprom = true; |
1789 | rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID]; | 1786 | rtlefuse->eeprom_oemid = hwinfo[EEPROM_CUSTOMER_ID]; |
1790 | 1787 | ||
1791 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, | 1788 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, |
1792 | "EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid); | 1789 | "EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid); |
@@ -2252,8 +2249,7 @@ void rtl8723be_update_channel_access_setting(struct ieee80211_hw *hw) | |||
2252 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 2249 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
2253 | u16 sifs_timer; | 2250 | u16 sifs_timer; |
2254 | 2251 | ||
2255 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, | 2252 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, &mac->slot_time); |
2256 | (u8 *)&mac->slot_time); | ||
2257 | if (!mac->ht_enable) | 2253 | if (!mac->ht_enable) |
2258 | sifs_timer = 0x0a0a; | 2254 | sifs_timer = 0x0a0a; |
2259 | else | 2255 | else |
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/trx.c b/drivers/net/wireless/rtlwifi/rtl8723be/trx.c index 74a75dceab08..e0a0d8c8fed5 100644 --- a/drivers/net/wireless/rtlwifi/rtl8723be/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8723be/trx.c | |||
@@ -647,7 +647,7 @@ void rtl8723be_tx_fill_desc(struct ieee80211_hw *hw, | |||
647 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 647 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
648 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | 648 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); |
649 | struct rtl_hal *rtlhal = rtl_hal(rtlpriv); | 649 | struct rtl_hal *rtlhal = rtl_hal(rtlpriv); |
650 | u8 *pdesc = (u8 *)pdesc_tx; | 650 | u8 *pdesc = pdesc_tx; |
651 | u16 seq_number; | 651 | u16 seq_number; |
652 | __le16 fc = hdr->frame_control; | 652 | __le16 fc = hdr->frame_control; |
653 | unsigned int buf_len = 0; | 653 | unsigned int buf_len = 0; |
@@ -850,7 +850,7 @@ void rtl8723be_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, | |||
850 | 850 | ||
851 | SET_TX_DESC_OWN(pdesc, 1); | 851 | SET_TX_DESC_OWN(pdesc, 1); |
852 | 852 | ||
853 | SET_TX_DESC_PKT_SIZE((u8 *)pdesc, (u16)(skb->len)); | 853 | SET_TX_DESC_PKT_SIZE(pdesc, (u16)(skb->len)); |
854 | 854 | ||
855 | SET_TX_DESC_FIRST_SEG(pdesc, 1); | 855 | SET_TX_DESC_FIRST_SEG(pdesc, 1); |
856 | SET_TX_DESC_LAST_SEG(pdesc, 1); | 856 | SET_TX_DESC_LAST_SEG(pdesc, 1); |
diff --git a/drivers/net/wireless/rtlwifi/rtl8723com/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8723com/fw_common.c index c12da552b7f7..540278ff462b 100644 --- a/drivers/net/wireless/rtlwifi/rtl8723com/fw_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8723com/fw_common.c | |||
@@ -115,7 +115,7 @@ void rtl8723_write_fw(struct ieee80211_hw *hw, | |||
115 | u8 *buffer, u32 size) | 115 | u8 *buffer, u32 size) |
116 | { | 116 | { |
117 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 117 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
118 | u8 *bufferptr = (u8 *)buffer; | 118 | u8 *bufferptr = buffer; |
119 | u32 pagenums, remainsize; | 119 | u32 pagenums, remainsize; |
120 | u32 page, offset; | 120 | u32 page, offset; |
121 | 121 | ||
@@ -257,7 +257,7 @@ int rtl8723_download_fw(struct ieee80211_hw *hw, | |||
257 | return 1; | 257 | return 1; |
258 | 258 | ||
259 | pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware; | 259 | pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware; |
260 | pfwdata = (u8 *)rtlhal->pfirmware; | 260 | pfwdata = rtlhal->pfirmware; |
261 | fwsize = rtlhal->fwsize; | 261 | fwsize = rtlhal->fwsize; |
262 | RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, | 262 | RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, |
263 | "normal Firmware SIZE %d\n", fwsize); | 263 | "normal Firmware SIZE %d\n", fwsize); |
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index b8cc39a4a9a5..5f8bc05694ac 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h | |||
@@ -189,6 +189,7 @@ struct hci_dev { | |||
189 | __u16 page_scan_window; | 189 | __u16 page_scan_window; |
190 | __u8 page_scan_type; | 190 | __u8 page_scan_type; |
191 | __u8 le_adv_channel_map; | 191 | __u8 le_adv_channel_map; |
192 | __u8 le_scan_type; | ||
192 | __u16 le_scan_interval; | 193 | __u16 le_scan_interval; |
193 | __u16 le_scan_window; | 194 | __u16 le_scan_window; |
194 | __u16 le_conn_min_interval; | 195 | __u16 le_conn_min_interval; |
@@ -1236,7 +1237,7 @@ void mgmt_pin_code_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, | |||
1236 | void mgmt_pin_code_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, | 1237 | void mgmt_pin_code_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, |
1237 | u8 status); | 1238 | u8 status); |
1238 | int mgmt_user_confirm_request(struct hci_dev *hdev, bdaddr_t *bdaddr, | 1239 | int mgmt_user_confirm_request(struct hci_dev *hdev, bdaddr_t *bdaddr, |
1239 | u8 link_type, u8 addr_type, __le32 value, | 1240 | u8 link_type, u8 addr_type, u32 value, |
1240 | u8 confirm_hint); | 1241 | u8 confirm_hint); |
1241 | int mgmt_user_confirm_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, | 1242 | int mgmt_user_confirm_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, |
1242 | u8 link_type, u8 addr_type, u8 status); | 1243 | u8 link_type, u8 addr_type, u8 status); |
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index a6a3d32553c5..49774912cb01 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -199,6 +199,8 @@ static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb) | |||
199 | memset(hdev->scan_rsp_data, 0, sizeof(hdev->scan_rsp_data)); | 199 | memset(hdev->scan_rsp_data, 0, sizeof(hdev->scan_rsp_data)); |
200 | hdev->scan_rsp_data_len = 0; | 200 | hdev->scan_rsp_data_len = 0; |
201 | 201 | ||
202 | hdev->le_scan_type = LE_SCAN_PASSIVE; | ||
203 | |||
202 | hdev->ssp_debug_mode = 0; | 204 | hdev->ssp_debug_mode = 0; |
203 | } | 205 | } |
204 | 206 | ||
@@ -997,6 +999,25 @@ static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb) | |||
997 | hci_dev_unlock(hdev); | 999 | hci_dev_unlock(hdev); |
998 | } | 1000 | } |
999 | 1001 | ||
1002 | static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb) | ||
1003 | { | ||
1004 | struct hci_cp_le_set_scan_param *cp; | ||
1005 | __u8 status = *((__u8 *) skb->data); | ||
1006 | |||
1007 | BT_DBG("%s status 0x%2.2x", hdev->name, status); | ||
1008 | |||
1009 | cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_PARAM); | ||
1010 | if (!cp) | ||
1011 | return; | ||
1012 | |||
1013 | hci_dev_lock(hdev); | ||
1014 | |||
1015 | if (!status) | ||
1016 | hdev->le_scan_type = cp->type; | ||
1017 | |||
1018 | hci_dev_unlock(hdev); | ||
1019 | } | ||
1020 | |||
1000 | static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, | 1021 | static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, |
1001 | struct sk_buff *skb) | 1022 | struct sk_buff *skb) |
1002 | { | 1023 | { |
@@ -1704,6 +1725,36 @@ unlock: | |||
1704 | hci_dev_unlock(hdev); | 1725 | hci_dev_unlock(hdev); |
1705 | } | 1726 | } |
1706 | 1727 | ||
1728 | static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status) | ||
1729 | { | ||
1730 | struct hci_cp_le_start_enc *cp; | ||
1731 | struct hci_conn *conn; | ||
1732 | |||
1733 | BT_DBG("%s status 0x%2.2x", hdev->name, status); | ||
1734 | |||
1735 | if (!status) | ||
1736 | return; | ||
1737 | |||
1738 | hci_dev_lock(hdev); | ||
1739 | |||
1740 | cp = hci_sent_cmd_data(hdev, HCI_OP_LE_START_ENC); | ||
1741 | if (!cp) | ||
1742 | goto unlock; | ||
1743 | |||
1744 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); | ||
1745 | if (!conn) | ||
1746 | goto unlock; | ||
1747 | |||
1748 | if (conn->state != BT_CONNECTED) | ||
1749 | goto unlock; | ||
1750 | |||
1751 | hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE); | ||
1752 | hci_conn_drop(conn); | ||
1753 | |||
1754 | unlock: | ||
1755 | hci_dev_unlock(hdev); | ||
1756 | } | ||
1757 | |||
1707 | static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | 1758 | static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) |
1708 | { | 1759 | { |
1709 | __u8 status = *((__u8 *) skb->data); | 1760 | __u8 status = *((__u8 *) skb->data); |
@@ -2488,6 +2539,10 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
2488 | hci_cc_le_set_adv_enable(hdev, skb); | 2539 | hci_cc_le_set_adv_enable(hdev, skb); |
2489 | break; | 2540 | break; |
2490 | 2541 | ||
2542 | case HCI_OP_LE_SET_SCAN_PARAM: | ||
2543 | hci_cc_le_set_scan_param(hdev, skb); | ||
2544 | break; | ||
2545 | |||
2491 | case HCI_OP_LE_SET_SCAN_ENABLE: | 2546 | case HCI_OP_LE_SET_SCAN_ENABLE: |
2492 | hci_cc_le_set_scan_enable(hdev, skb); | 2547 | hci_cc_le_set_scan_enable(hdev, skb); |
2493 | break; | 2548 | break; |
@@ -2611,6 +2666,10 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
2611 | hci_cs_le_create_conn(hdev, ev->status); | 2666 | hci_cs_le_create_conn(hdev, ev->status); |
2612 | break; | 2667 | break; |
2613 | 2668 | ||
2669 | case HCI_OP_LE_START_ENC: | ||
2670 | hci_cs_le_start_enc(hdev, ev->status); | ||
2671 | break; | ||
2672 | |||
2614 | default: | 2673 | default: |
2615 | BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); | 2674 | BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); |
2616 | break; | 2675 | break; |
@@ -3459,8 +3518,8 @@ static void hci_user_confirm_request_evt(struct hci_dev *hdev, | |||
3459 | } | 3518 | } |
3460 | 3519 | ||
3461 | confirm: | 3520 | confirm: |
3462 | mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey, | 3521 | mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, |
3463 | confirm_hint); | 3522 | le32_to_cpu(ev->passkey), confirm_hint); |
3464 | 3523 | ||
3465 | unlock: | 3524 | unlock: |
3466 | hci_dev_unlock(hdev); | 3525 | hci_dev_unlock(hdev); |
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 33cd5615ff1e..f59e00c2daa9 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c | |||
@@ -360,7 +360,8 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, | |||
360 | 360 | ||
361 | BT_DBG("sock %p, sk %p", sock, sk); | 361 | BT_DBG("sock %p, sk %p", sock, sk); |
362 | 362 | ||
363 | if (peer && sk->sk_state != BT_CONNECTED) | 363 | if (peer && sk->sk_state != BT_CONNECTED && |
364 | sk->sk_state != BT_CONNECT && sk->sk_state != BT_CONNECT2) | ||
364 | return -ENOTCONN; | 365 | return -ENOTCONN; |
365 | 366 | ||
366 | memset(la, 0, sizeof(struct sockaddr_l2)); | 367 | memset(la, 0, sizeof(struct sockaddr_l2)); |
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 96670f581bb0..d2d4e0d5aed0 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -2762,23 +2762,11 @@ static struct pending_cmd *find_pairing(struct hci_conn *conn) | |||
2762 | 2762 | ||
2763 | static void pairing_complete(struct pending_cmd *cmd, u8 status) | 2763 | static void pairing_complete(struct pending_cmd *cmd, u8 status) |
2764 | { | 2764 | { |
2765 | const struct mgmt_cp_pair_device *cp = cmd->param; | ||
2766 | struct mgmt_rp_pair_device rp; | 2765 | struct mgmt_rp_pair_device rp; |
2767 | struct hci_conn *conn = cmd->user_data; | 2766 | struct hci_conn *conn = cmd->user_data; |
2768 | 2767 | ||
2769 | /* If we had a pairing failure we might have already received | 2768 | bacpy(&rp.addr.bdaddr, &conn->dst); |
2770 | * the remote Identity Address Information and updated the | 2769 | rp.addr.type = link_to_bdaddr(conn->type, conn->dst_type); |
2771 | * hci_conn variables with it, however we would not yet have | ||
2772 | * notified user space of the resolved identity. Therefore, use | ||
2773 | * the address given in the Pair Device command in case the | ||
2774 | * pairing failed. | ||
2775 | */ | ||
2776 | if (status) { | ||
2777 | memcpy(&rp.addr, &cp->addr, sizeof(rp.addr)); | ||
2778 | } else { | ||
2779 | bacpy(&rp.addr.bdaddr, &conn->dst); | ||
2780 | rp.addr.type = link_to_bdaddr(conn->type, conn->dst_type); | ||
2781 | } | ||
2782 | 2770 | ||
2783 | cmd_complete(cmd->sk, cmd->index, MGMT_OP_PAIR_DEVICE, status, | 2771 | cmd_complete(cmd->sk, cmd->index, MGMT_OP_PAIR_DEVICE, status, |
2784 | &rp, sizeof(rp)); | 2772 | &rp, sizeof(rp)); |
@@ -5338,7 +5326,7 @@ void mgmt_pin_code_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, | |||
5338 | } | 5326 | } |
5339 | 5327 | ||
5340 | int mgmt_user_confirm_request(struct hci_dev *hdev, bdaddr_t *bdaddr, | 5328 | int mgmt_user_confirm_request(struct hci_dev *hdev, bdaddr_t *bdaddr, |
5341 | u8 link_type, u8 addr_type, __le32 value, | 5329 | u8 link_type, u8 addr_type, u32 value, |
5342 | u8 confirm_hint) | 5330 | u8 confirm_hint) |
5343 | { | 5331 | { |
5344 | struct mgmt_ev_user_confirm_request ev; | 5332 | struct mgmt_ev_user_confirm_request ev; |
@@ -5348,7 +5336,7 @@ int mgmt_user_confirm_request(struct hci_dev *hdev, bdaddr_t *bdaddr, | |||
5348 | bacpy(&ev.addr.bdaddr, bdaddr); | 5336 | bacpy(&ev.addr.bdaddr, bdaddr); |
5349 | ev.addr.type = link_to_bdaddr(link_type, addr_type); | 5337 | ev.addr.type = link_to_bdaddr(link_type, addr_type); |
5350 | ev.confirm_hint = confirm_hint; | 5338 | ev.confirm_hint = confirm_hint; |
5351 | ev.value = value; | 5339 | ev.value = cpu_to_le32(value); |
5352 | 5340 | ||
5353 | return mgmt_event(MGMT_EV_USER_CONFIRM_REQUEST, hdev, &ev, sizeof(ev), | 5341 | return mgmt_event(MGMT_EV_USER_CONFIRM_REQUEST, hdev, &ev, sizeof(ev), |
5354 | NULL); | 5342 | NULL); |
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index c024e715512f..eabd25ab5ad9 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c | |||
@@ -534,7 +534,8 @@ static int rfcomm_sock_getname(struct socket *sock, struct sockaddr *addr, int * | |||
534 | 534 | ||
535 | BT_DBG("sock %p, sk %p", sock, sk); | 535 | BT_DBG("sock %p, sk %p", sock, sk); |
536 | 536 | ||
537 | if (peer && sk->sk_state != BT_CONNECTED) | 537 | if (peer && sk->sk_state != BT_CONNECTED && |
538 | sk->sk_state != BT_CONNECT && sk->sk_state != BT_CONNECT2) | ||
538 | return -ENOTCONN; | 539 | return -ENOTCONN; |
539 | 540 | ||
540 | memset(sa, 0, sizeof(*sa)); | 541 | memset(sa, 0, sizeof(*sa)); |
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 2a7ee7f6cd8b..dfb4e1161c10 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c | |||
@@ -387,6 +387,11 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth, | |||
387 | if (!(auth & SMP_AUTH_BONDING) && method == JUST_CFM) | 387 | if (!(auth & SMP_AUTH_BONDING) && method == JUST_CFM) |
388 | method = JUST_WORKS; | 388 | method = JUST_WORKS; |
389 | 389 | ||
390 | /* Don't confirm locally initiated pairing attempts */ | ||
391 | if (method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR, | ||
392 | &smp->smp_flags)) | ||
393 | method = JUST_WORKS; | ||
394 | |||
390 | /* If Just Works, Continue with Zero TK */ | 395 | /* If Just Works, Continue with Zero TK */ |
391 | if (method == JUST_WORKS) { | 396 | if (method == JUST_WORKS) { |
392 | set_bit(SMP_FLAG_TK_VALID, &smp->smp_flags); | 397 | 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, | |||
422 | if (method == REQ_PASSKEY) | 427 | if (method == REQ_PASSKEY) |
423 | ret = mgmt_user_passkey_request(hcon->hdev, &hcon->dst, | 428 | ret = mgmt_user_passkey_request(hcon->hdev, &hcon->dst, |
424 | hcon->type, hcon->dst_type); | 429 | hcon->type, hcon->dst_type); |
430 | else if (method == JUST_CFM) | ||
431 | ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst, | ||
432 | hcon->type, hcon->dst_type, | ||
433 | passkey, 1); | ||
425 | else | 434 | else |
426 | ret = mgmt_user_passkey_notify(hcon->hdev, &hcon->dst, | 435 | ret = mgmt_user_passkey_notify(hcon->hdev, &hcon->dst, |
427 | hcon->type, hcon->dst_type, | 436 | hcon->type, hcon->dst_type, |
428 | cpu_to_le32(passkey), 0); | 437 | passkey, 0); |
429 | 438 | ||
430 | hci_dev_unlock(hcon->hdev); | 439 | hci_dev_unlock(hcon->hdev); |
431 | 440 | ||
@@ -547,20 +556,6 @@ error: | |||
547 | smp_failure(conn, reason); | 556 | smp_failure(conn, reason); |
548 | } | 557 | } |
549 | 558 | ||
550 | static void smp_reencrypt(struct work_struct *work) | ||
551 | { | ||
552 | struct smp_chan *smp = container_of(work, struct smp_chan, | ||
553 | reencrypt.work); | ||
554 | struct l2cap_conn *conn = smp->conn; | ||
555 | struct hci_conn *hcon = conn->hcon; | ||
556 | struct smp_ltk *ltk = smp->ltk; | ||
557 | |||
558 | BT_DBG(""); | ||
559 | |||
560 | hci_le_start_enc(hcon, ltk->ediv, ltk->rand, ltk->val); | ||
561 | hcon->enc_key_size = ltk->enc_size; | ||
562 | } | ||
563 | |||
564 | static struct smp_chan *smp_chan_create(struct l2cap_conn *conn) | 559 | static struct smp_chan *smp_chan_create(struct l2cap_conn *conn) |
565 | { | 560 | { |
566 | struct smp_chan *smp; | 561 | struct smp_chan *smp; |
@@ -571,7 +566,6 @@ static struct smp_chan *smp_chan_create(struct l2cap_conn *conn) | |||
571 | 566 | ||
572 | INIT_WORK(&smp->confirm, confirm_work); | 567 | INIT_WORK(&smp->confirm, confirm_work); |
573 | INIT_WORK(&smp->random, random_work); | 568 | INIT_WORK(&smp->random, random_work); |
574 | INIT_DELAYED_WORK(&smp->reencrypt, smp_reencrypt); | ||
575 | 569 | ||
576 | smp->conn = conn; | 570 | smp->conn = conn; |
577 | conn->smp_chan = smp; | 571 | conn->smp_chan = smp; |
@@ -589,8 +583,6 @@ void smp_chan_destroy(struct l2cap_conn *conn) | |||
589 | 583 | ||
590 | BUG_ON(!smp); | 584 | BUG_ON(!smp); |
591 | 585 | ||
592 | cancel_delayed_work_sync(&smp->reencrypt); | ||
593 | |||
594 | complete = test_bit(SMP_FLAG_COMPLETE, &smp->smp_flags); | 586 | complete = test_bit(SMP_FLAG_COMPLETE, &smp->smp_flags); |
595 | mgmt_smp_complete(conn->hcon, complete); | 587 | mgmt_smp_complete(conn->hcon, complete); |
596 | 588 | ||
@@ -712,6 +704,8 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb) | |||
712 | if (ret) | 704 | if (ret) |
713 | return SMP_UNSPECIFIED; | 705 | return SMP_UNSPECIFIED; |
714 | 706 | ||
707 | clear_bit(SMP_FLAG_INITIATOR, &smp->smp_flags); | ||
708 | |||
715 | return 0; | 709 | return 0; |
716 | } | 710 | } |
717 | 711 | ||
@@ -867,6 +861,8 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) | |||
867 | 861 | ||
868 | smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp); | 862 | smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp); |
869 | 863 | ||
864 | clear_bit(SMP_FLAG_INITIATOR, &smp->smp_flags); | ||
865 | |||
870 | return 0; | 866 | return 0; |
871 | } | 867 | } |
872 | 868 | ||
@@ -884,11 +880,15 @@ bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level) | |||
884 | int smp_conn_security(struct hci_conn *hcon, __u8 sec_level) | 880 | int smp_conn_security(struct hci_conn *hcon, __u8 sec_level) |
885 | { | 881 | { |
886 | struct l2cap_conn *conn = hcon->l2cap_data; | 882 | struct l2cap_conn *conn = hcon->l2cap_data; |
887 | struct smp_chan *smp = conn->smp_chan; | 883 | struct smp_chan *smp; |
888 | __u8 authreq; | 884 | __u8 authreq; |
889 | 885 | ||
890 | BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level); | 886 | BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level); |
891 | 887 | ||
888 | /* This may be NULL if there's an unexpected disconnection */ | ||
889 | if (!conn) | ||
890 | return 1; | ||
891 | |||
892 | if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) | 892 | if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) |
893 | return 1; | 893 | return 1; |
894 | 894 | ||
@@ -928,6 +928,8 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level) | |||
928 | smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp); | 928 | smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp); |
929 | } | 929 | } |
930 | 930 | ||
931 | set_bit(SMP_FLAG_INITIATOR, &smp->smp_flags); | ||
932 | |||
931 | done: | 933 | done: |
932 | hcon->pending_sec_level = sec_level; | 934 | hcon->pending_sec_level = sec_level; |
933 | 935 | ||
@@ -1058,12 +1060,6 @@ static int smp_cmd_ident_addr_info(struct l2cap_conn *conn, | |||
1058 | smp->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr, | 1060 | smp->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr, |
1059 | smp->id_addr_type, smp->irk, &rpa); | 1061 | smp->id_addr_type, smp->irk, &rpa); |
1060 | 1062 | ||
1061 | /* Track the connection based on the Identity Address from now on */ | ||
1062 | bacpy(&hcon->dst, &smp->id_addr); | ||
1063 | hcon->dst_type = smp->id_addr_type; | ||
1064 | |||
1065 | l2cap_conn_update_id_addr(hcon); | ||
1066 | |||
1067 | smp_distribute_keys(conn); | 1063 | smp_distribute_keys(conn); |
1068 | 1064 | ||
1069 | return 0; | 1065 | return 0; |
@@ -1214,8 +1210,16 @@ static void smp_notify_keys(struct l2cap_conn *conn) | |||
1214 | struct smp_cmd_pairing *rsp = (void *) &smp->prsp[1]; | 1210 | struct smp_cmd_pairing *rsp = (void *) &smp->prsp[1]; |
1215 | bool persistent; | 1211 | bool persistent; |
1216 | 1212 | ||
1217 | if (smp->remote_irk) | 1213 | if (smp->remote_irk) { |
1218 | mgmt_new_irk(hdev, smp->remote_irk); | 1214 | mgmt_new_irk(hdev, smp->remote_irk); |
1215 | /* Now that user space can be considered to know the | ||
1216 | * identity address track the connection based on it | ||
1217 | * from now on. | ||
1218 | */ | ||
1219 | bacpy(&hcon->dst, &smp->remote_irk->bdaddr); | ||
1220 | hcon->dst_type = smp->remote_irk->addr_type; | ||
1221 | l2cap_conn_update_id_addr(hcon); | ||
1222 | } | ||
1219 | 1223 | ||
1220 | /* The LTKs and CSRKs should be persistent only if both sides | 1224 | /* The LTKs and CSRKs should be persistent only if both sides |
1221 | * had the bonding bit set in their authentication requests. | 1225 | * had the bonding bit set in their authentication requests. |
@@ -1253,7 +1257,6 @@ int smp_distribute_keys(struct l2cap_conn *conn) | |||
1253 | struct smp_chan *smp = conn->smp_chan; | 1257 | struct smp_chan *smp = conn->smp_chan; |
1254 | struct hci_conn *hcon = conn->hcon; | 1258 | struct hci_conn *hcon = conn->hcon; |
1255 | struct hci_dev *hdev = hcon->hdev; | 1259 | struct hci_dev *hdev = hcon->hdev; |
1256 | bool ltk_encrypt; | ||
1257 | __u8 *keydist; | 1260 | __u8 *keydist; |
1258 | 1261 | ||
1259 | BT_DBG("conn %p", conn); | 1262 | BT_DBG("conn %p", conn); |
@@ -1353,32 +1356,12 @@ int smp_distribute_keys(struct l2cap_conn *conn) | |||
1353 | if ((smp->remote_key_dist & 0x07)) | 1356 | if ((smp->remote_key_dist & 0x07)) |
1354 | return 0; | 1357 | return 0; |
1355 | 1358 | ||
1356 | /* Check if we should try to re-encrypt the link with the LTK. | 1359 | clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags); |
1357 | * SMP_FLAG_LTK_ENCRYPT flag is used to track whether we've | 1360 | cancel_delayed_work_sync(&conn->security_timer); |
1358 | * already tried this (in which case we shouldn't try again). | 1361 | set_bit(SMP_FLAG_COMPLETE, &smp->smp_flags); |
1359 | * | 1362 | smp_notify_keys(conn); |
1360 | * The request will trigger an encryption key refresh event | ||
1361 | * which will cause a call to auth_cfm and eventually lead to | ||
1362 | * l2cap_core.c calling this smp_distribute_keys function again | ||
1363 | * and thereby completing the process. | ||
1364 | */ | ||
1365 | if (smp->ltk) | ||
1366 | ltk_encrypt = !test_and_set_bit(SMP_FLAG_LTK_ENCRYPT, | ||
1367 | &smp->smp_flags); | ||
1368 | else | ||
1369 | ltk_encrypt = false; | ||
1370 | 1363 | ||
1371 | /* Re-encrypt the link with LTK if possible */ | 1364 | smp_chan_destroy(conn); |
1372 | if (ltk_encrypt && hcon->out) { | ||
1373 | queue_delayed_work(hdev->req_workqueue, &smp->reencrypt, | ||
1374 | SMP_REENCRYPT_TIMEOUT); | ||
1375 | } else { | ||
1376 | clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags); | ||
1377 | cancel_delayed_work_sync(&conn->security_timer); | ||
1378 | set_bit(SMP_FLAG_COMPLETE, &smp->smp_flags); | ||
1379 | smp_notify_keys(conn); | ||
1380 | smp_chan_destroy(conn); | ||
1381 | } | ||
1382 | 1365 | ||
1383 | return 0; | 1366 | return 0; |
1384 | } | 1367 | } |
diff --git a/net/bluetooth/smp.h b/net/bluetooth/smp.h index b6913471815a..1277147a9150 100644 --- a/net/bluetooth/smp.h +++ b/net/bluetooth/smp.h | |||
@@ -118,10 +118,8 @@ struct smp_cmd_security_req { | |||
118 | #define SMP_FLAG_TK_VALID 1 | 118 | #define SMP_FLAG_TK_VALID 1 |
119 | #define SMP_FLAG_CFM_PENDING 2 | 119 | #define SMP_FLAG_CFM_PENDING 2 |
120 | #define SMP_FLAG_MITM_AUTH 3 | 120 | #define SMP_FLAG_MITM_AUTH 3 |
121 | #define SMP_FLAG_LTK_ENCRYPT 4 | 121 | #define SMP_FLAG_COMPLETE 4 |
122 | #define SMP_FLAG_COMPLETE 5 | 122 | #define SMP_FLAG_INITIATOR 5 |
123 | |||
124 | #define SMP_REENCRYPT_TIMEOUT msecs_to_jiffies(500) | ||
125 | 123 | ||
126 | struct smp_chan { | 124 | struct smp_chan { |
127 | struct l2cap_conn *conn; | 125 | struct l2cap_conn *conn; |
@@ -144,7 +142,6 @@ struct smp_chan { | |||
144 | unsigned long smp_flags; | 142 | unsigned long smp_flags; |
145 | struct work_struct confirm; | 143 | struct work_struct confirm; |
146 | struct work_struct random; | 144 | struct work_struct random; |
147 | struct delayed_work reencrypt; | ||
148 | }; | 145 | }; |
149 | 146 | ||
150 | /* SMP Commands */ | 147 | /* SMP Commands */ |