1
0
Fork 0

wireless-drivers-next patches for 5.4

Last set of patches for 5.4. wil6210 and rtw88 being most active this
 time, but ath9k also having a new module to load devices without
 EEPROM.
 
 Major changes:
 
 wil6210
 
 * add support for Enhanced Directional Multi-Gigabit (EDMG) channels 9-11
 
 * add debugfs file to show PCM ring content
 
 * report boottime_ns in scan results
 
 ath9k
 
 * add a separate loader for AR92XX (and older) pci(e) without eeprom
 
 brcmfmac
 
 * use the same wiphy after PCIe reset to not confuse the user space
 
 rtw88
 
 * enable interrupt migration
 
 * enable AMSDU in AMPDU aggregation
 
 * report RX power for each antenna
 
 * enable to DPK and IQK calibration methods to improve performance
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQEcBAABAgAGBQJdfLwvAAoJEG4XJFUm622b8N8H/141YVGazqoNC/l0kaMbWZ//
 xbgdS8ujGyEFg86dfXs1DjYPsPG1v+UJwc42GQALcjVrdUacuO7ZEdBKF6q9q0gG
 7WsZrzmgMk2dJsZKSCYZHORbEJ/GE7yCgO1W1hS0iTRNXEV6/6u2s7bx4mPB3uhl
 voYLTLaDvA2n8+pxuJ/Dl0ewWFuGnWqnhgU5CV3f9MGLkB4BXmvMdA5iqhiqq3Bj
 RWfBZCslJj3snh4vsTzRNqnRRvtgTv3Nt/fVV8uH+K5wXBMutlc+MfVQw21kMb7c
 RConz/N87usC+pgY+va2UpyNqLis2rUhb0UH4/Sqc7uBmeCBSyE8JulkRLnce+c=
 =850h
 -----END PGP SIGNATURE-----

Merge tag 'wireless-drivers-next-for-davem-2019-09-14' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next

Kalle Valo says:

====================
wireless-drivers-next patches for 5.4

Last set of patches for 5.4. wil6210 and rtw88 being most active this
time, but ath9k also having a new module to load devices without
EEPROM.

Major changes:

wil6210

* add support for Enhanced Directional Multi-Gigabit (EDMG) channels 9-11

* add debugfs file to show PCM ring content

* report boottime_ns in scan results

ath9k

* add a separate loader for AR92XX (and older) pci(e) without eeprom

brcmfmac

* use the same wiphy after PCIe reset to not confuse the user space

rtw88

* enable interrupt migration

* enable AMSDU in AMPDU aggregation

* report RX power for each antenna

* enable to DPK and IQK calibration methods to improve performance
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
alistair/sunxi64-5.4-dsi
David S. Miller 2019-09-14 15:08:18 +02:00
commit a3d3c74da4
76 changed files with 8446 additions and 3511 deletions

View File

@ -751,7 +751,7 @@ S: Santa Cruz, California
S: USA
N: Luis Correia
E: lfcorreia@users.sf.net
E: luisfcorreia@gmail.com
D: Ralink rt2x00 WLAN driver
S: Belas, Portugal

View File

@ -222,7 +222,7 @@ static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
{
u16 v, o;
int i;
u16 pwr_info_offset[] = {
static const u16 pwr_info_offset[] = {
SSB_SROM8_PWR_INFO_CORE0, SSB_SROM8_PWR_INFO_CORE1,
SSB_SROM8_PWR_INFO_CORE2, SSB_SROM8_PWR_INFO_CORE3
};
@ -578,9 +578,11 @@ int bcma_sprom_get(struct bcma_bus *bus)
{
u16 offset = BCMA_CC_SPROM;
u16 *sprom;
size_t sprom_sizes[] = { SSB_SPROMSIZE_WORDS_R4,
SSB_SPROMSIZE_WORDS_R10,
SSB_SPROMSIZE_WORDS_R11, };
static const size_t sprom_sizes[] = {
SSB_SPROMSIZE_WORDS_R4,
SSB_SPROMSIZE_WORDS_R10,
SSB_SPROMSIZE_WORDS_R11,
};
int i, err = 0;
if (!bus->drv_cc.core)

View File

@ -2151,6 +2151,10 @@ static bool ath10k_htt_rx_proc_rx_ind_hl(struct ath10k_htt *htt,
struct ath10k_peer *peer;
struct htt_rx_indication_mpdu_range *mpdu_ranges;
struct fw_rx_desc_hl *fw_desc;
enum htt_txrx_sec_cast_type sec_index;
enum htt_security_types sec_type;
union htt_rx_pn_t new_pn = {0};
struct htt_hl_rx_desc *rx_desc;
struct ieee80211_hdr *hdr;
struct ieee80211_rx_status *rx_status;
u16 peer_id;
@ -2158,9 +2162,11 @@ static bool ath10k_htt_rx_proc_rx_ind_hl(struct ath10k_htt *htt,
int num_mpdu_ranges;
size_t tot_hdr_len;
struct ieee80211_channel *ch;
bool pn_invalid;
bool pn_invalid, qos, first_msdu;
u32 tid, rx_desc_info;
peer_id = __le16_to_cpu(rx->hdr.peer_id);
tid = MS(rx->hdr.info0, HTT_RX_INDICATION_INFO0_EXT_TID);
spin_lock_bh(&ar->data_lock);
peer = ath10k_peer_find_by_id(ar, peer_id);
@ -2168,6 +2174,9 @@ static bool ath10k_htt_rx_proc_rx_ind_hl(struct ath10k_htt *htt,
if (!peer && peer_id != HTT_INVALID_PEERID)
ath10k_warn(ar, "Got RX ind from invalid peer: %u\n", peer_id);
if (!peer)
return true;
num_mpdu_ranges = MS(__le32_to_cpu(rx->hdr.info1),
HTT_RX_INDICATION_INFO1_NUM_MPDU_RANGES);
mpdu_ranges = htt_rx_ind_get_mpdu_ranges_hl(rx);
@ -2192,10 +2201,24 @@ static bool ath10k_htt_rx_proc_rx_ind_hl(struct ath10k_htt *htt,
goto err;
}
if (check_pn_type == HTT_RX_PN_CHECK) {
rx_desc = (struct htt_hl_rx_desc *)&rx->mpdu_ranges[num_mpdu_ranges];
rx_desc_info = __le32_to_cpu(rx_desc->info);
if (MS(rx_desc_info, HTT_RX_DESC_HL_INFO_MCAST_BCAST))
sec_index = HTT_TXRX_SEC_MCAST;
else
sec_index = HTT_TXRX_SEC_UCAST;
sec_type = peer->rx_pn[sec_index].sec_type;
first_msdu = rx->fw_desc.flags & FW_RX_DESC_FLAGS_FIRST_MSDU;
ath10k_htt_rx_mpdu_desc_pn_hl(rx_desc, &new_pn, peer->rx_pn[sec_index].pn_len);
if (check_pn_type == HTT_RX_PN_CHECK && tid >= IEEE80211_NUM_TIDS) {
spin_lock_bh(&ar->data_lock);
pn_invalid = ath10k_htt_rx_pn_check_replay_hl(ar, peer, rx);
spin_unlock_bh(&ar->data_lock);
if (pn_invalid)
goto err;
}
@ -2211,6 +2234,7 @@ static bool ath10k_htt_rx_proc_rx_ind_hl(struct ath10k_htt *htt,
skb_pull(skb, tot_hdr_len);
hdr = (struct ieee80211_hdr *)skb->data;
qos = ieee80211_is_data_qos(hdr->frame_control);
rx_status = IEEE80211_SKB_RXCB(skb);
rx_status->chains |= BIT(0);
if (rx->ppdu.combined_rssi == 0) {
@ -2254,6 +2278,55 @@ static bool ath10k_htt_rx_proc_rx_ind_hl(struct ath10k_htt *htt,
rx_status->flag |= RX_FLAG_DECRYPTED |
RX_FLAG_IV_STRIPPED |
RX_FLAG_MMIC_STRIPPED;
if (tid < IEEE80211_NUM_TIDS &&
first_msdu &&
check_pn_type == HTT_RX_PN_CHECK &&
(sec_type == HTT_SECURITY_AES_CCMP ||
sec_type == HTT_SECURITY_TKIP ||
sec_type == HTT_SECURITY_TKIP_NOMIC)) {
u8 offset, *ivp, i;
s8 keyidx = 0;
__le64 pn48 = cpu_to_le64(new_pn.pn48);
hdr = (struct ieee80211_hdr *)skb->data;
offset = ieee80211_hdrlen(hdr->frame_control);
hdr->frame_control |= __cpu_to_le16(IEEE80211_FCTL_PROTECTED);
rx_status->flag &= ~RX_FLAG_IV_STRIPPED;
memmove(skb->data - IEEE80211_CCMP_HDR_LEN,
skb->data, offset);
skb_push(skb, IEEE80211_CCMP_HDR_LEN);
ivp = skb->data + offset;
memset(skb->data + offset, 0, IEEE80211_CCMP_HDR_LEN);
/* Ext IV */
ivp[IEEE80211_WEP_IV_LEN - 1] |= ATH10K_IEEE80211_EXTIV;
for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {
if (peer->keys[i] &&
peer->keys[i]->flags & IEEE80211_KEY_FLAG_PAIRWISE)
keyidx = peer->keys[i]->keyidx;
}
/* Key ID */
ivp[IEEE80211_WEP_IV_LEN - 1] |= keyidx << 6;
if (sec_type == HTT_SECURITY_AES_CCMP) {
rx_status->flag |= RX_FLAG_MIC_STRIPPED;
/* pn 0, pn 1 */
memcpy(skb->data + offset, &pn48, 2);
/* pn 1, pn 3 , pn 34 , pn 5 */
memcpy(skb->data + offset + 4, ((u8 *)&pn48) + 2, 4);
} else {
rx_status->flag |= RX_FLAG_ICV_STRIPPED;
/* TSC 0 */
memcpy(skb->data + offset + 2, &pn48, 1);
/* TSC 1 */
memcpy(skb->data + offset, ((u8 *)&pn48) + 1, 1);
/* TSC 2 , TSC 3 , TSC 4 , TSC 5*/
memcpy(skb->data + offset + 4, ((u8 *)&pn48) + 2, 4);
}
}
}
if (tkip_mic_type == HTT_RX_TKIP_MIC)
@ -2263,6 +2336,20 @@ static bool ath10k_htt_rx_proc_rx_ind_hl(struct ath10k_htt *htt,
if (mpdu_ranges->mpdu_range_status == HTT_RX_IND_MPDU_STATUS_TKIP_MIC_ERR)
rx_status->flag |= RX_FLAG_MMIC_ERROR;
if (!qos && tid < IEEE80211_NUM_TIDS) {
u8 offset;
__le16 qos_ctrl = 0;
hdr = (struct ieee80211_hdr *)skb->data;
offset = ieee80211_hdrlen(hdr->frame_control);
hdr->frame_control |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
memmove(skb->data - IEEE80211_QOS_CTL_LEN, skb->data, offset);
skb_push(skb, IEEE80211_QOS_CTL_LEN);
qos_ctrl = cpu_to_le16(tid);
memcpy(skb->data + offset, &qos_ctrl, IEEE80211_QOS_CTL_LEN);
}
ieee80211_rx_ni(ar->hw, skb);
/* We have delivered the skb to the upper layers (mac80211) so we

View File

@ -1237,6 +1237,7 @@ static int ath10k_htt_tx_hl(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txm
struct ath10k *ar = htt->ar;
int res, data_len;
struct htt_cmd_hdr *cmd_hdr;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data;
struct htt_data_tx_desc *tx_desc;
struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu);
struct sk_buff *tmp_skb;
@ -1247,6 +1248,13 @@ static int ath10k_htt_tx_hl(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txm
u16 flags1 = 0;
u16 msdu_id = 0;
if ((ieee80211_is_action(hdr->frame_control) ||
ieee80211_is_deauth(hdr->frame_control) ||
ieee80211_is_disassoc(hdr->frame_control)) &&
ieee80211_has_protected(hdr->frame_control)) {
skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
}
data_len = msdu->len;
switch (txmode) {

View File

@ -5503,10 +5503,6 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw,
mutex_lock(&ar->conf_mutex);
spin_lock_bh(&ar->data_lock);
ath10k_mac_vif_beacon_cleanup(arvif);
spin_unlock_bh(&ar->data_lock);
ret = ath10k_spectral_vif_stop(arvif);
if (ret)
ath10k_warn(ar, "failed to stop spectral for vdev %i: %d\n",
@ -5575,6 +5571,11 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw,
peer->vif = NULL;
}
}
/* Clean this up late, less opportunity for firmware to access
* DMA memory we have deleted.
*/
ath10k_mac_vif_beacon_cleanup(arvif);
spin_unlock_bh(&ar->data_lock);
ath10k_peer_cleanup(ar, arvif->vdev_id);

View File

@ -381,16 +381,11 @@ static int ath10k_sdio_mbox_rx_process_packet(struct ath10k *ar,
struct ath10k_htc_hdr *htc_hdr = (struct ath10k_htc_hdr *)skb->data;
bool trailer_present = htc_hdr->flags & ATH10K_HTC_FLAG_TRAILER_PRESENT;
enum ath10k_htc_ep_id eid;
u16 payload_len;
u8 *trailer;
int ret;
payload_len = le16_to_cpu(htc_hdr->len);
skb->len = payload_len + sizeof(struct ath10k_htc_hdr);
if (trailer_present) {
trailer = skb->data + sizeof(*htc_hdr) +
payload_len - htc_hdr->trailer_len;
trailer = skb->data + skb->len - htc_hdr->trailer_len;
eid = pipe_id_to_eid(htc_hdr->eid);
@ -632,13 +627,31 @@ static int ath10k_sdio_mbox_rx_packet(struct ath10k *ar,
{
struct ath10k_sdio *ar_sdio = ath10k_sdio_priv(ar);
struct sk_buff *skb = pkt->skb;
struct ath10k_htc_hdr *htc_hdr;
int ret;
ret = ath10k_sdio_readsb(ar, ar_sdio->mbox_info.htc_addr,
skb->data, pkt->alloc_len);
if (ret)
goto out;
/* Update actual length. The original length may be incorrect,
* as the FW will bundle multiple packets as long as their sizes
* fit within the same aligned length (pkt->alloc_len).
*/
htc_hdr = (struct ath10k_htc_hdr *)skb->data;
pkt->act_len = le16_to_cpu(htc_hdr->len) + sizeof(*htc_hdr);
if (pkt->act_len > pkt->alloc_len) {
ath10k_warn(ar, "rx packet too large (%zu > %zu)\n",
pkt->act_len, pkt->alloc_len);
ret = -EMSGSIZE;
goto out;
}
skb_put(skb, pkt->act_len);
out:
pkt->status = ret;
if (!ret)
skb_put(skb, pkt->act_len);
return ret;
}

View File

@ -841,7 +841,7 @@ static int ath10k_wmi_tlv_op_pull_ch_info_ev(struct ath10k *ar,
struct wmi_ch_info_ev_arg *arg)
{
const void **tb;
const struct wmi_chan_info_event *ev;
const struct wmi_tlv_chan_info_event *ev;
int ret;
tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);

View File

@ -1615,6 +1615,22 @@ struct chan_info_params {
#define WMI_TLV_FLAG_MGMT_BUNDLE_TX_COMPL BIT(9)
struct wmi_tlv_chan_info_event {
__le32 err_code;
__le32 freq;
__le32 cmd_flags;
__le32 noise_floor;
__le32 rx_clear_count;
__le32 cycle_count;
__le32 chan_tx_pwr_range;
__le32 chan_tx_pwr_tp;
__le32 rx_frame_count;
__le32 my_bss_rx_cycle_count;
__le32 rx_11b_mode_data_duration;
__le32 tx_frame_cnt;
__le32 mac_clk_mhz;
} __packed;
struct wmi_tlv_mgmt_tx_compl_ev {
__le32 desc_id;
__le32 status;

View File

@ -6533,14 +6533,6 @@ struct wmi_chan_info_event {
__le32 noise_floor;
__le32 rx_clear_count;
__le32 cycle_count;
__le32 chan_tx_pwr_range;
__le32 chan_tx_pwr_tp;
__le32 rx_frame_count;
__le32 my_bss_rx_cycle_count;
__le32 rx_11b_mode_data_duration;
__le32 tx_frame_cnt;
__le32 mac_clk_mhz;
} __packed;
struct wmi_10_4_chan_info_event {

View File

@ -2855,8 +2855,8 @@ static void *ath6kl_htc_mbox_create(struct ath6kl *ar)
target->dev = kzalloc(sizeof(*target->dev), GFP_KERNEL);
if (!target->dev) {
ath6kl_err("unable to allocate memory\n");
status = -ENOMEM;
goto err_htc_cleanup;
kfree(target);
return NULL;
}
spin_lock_init(&target->htc_lock);

View File

@ -132,6 +132,10 @@ ath6kl_usb_alloc_urb_from_pipe(struct ath6kl_usb_pipe *pipe)
struct ath6kl_urb_context *urb_context = NULL;
unsigned long flags;
/* bail if this pipe is not initialized */
if (!pipe->ar_usb)
return NULL;
spin_lock_irqsave(&pipe->ar_usb->cs_lock, flags);
if (!list_empty(&pipe->urb_list_head)) {
urb_context =
@ -150,6 +154,10 @@ static void ath6kl_usb_free_urb_to_pipe(struct ath6kl_usb_pipe *pipe,
{
unsigned long flags;
/* bail if this pipe is not initialized */
if (!pipe->ar_usb)
return;
spin_lock_irqsave(&pipe->ar_usb->cs_lock, flags);
pipe->urb_cnt++;

View File

@ -157,6 +157,22 @@ config ATH9K_PCOEM
depends on ATH9K
default y
config ATH9K_PCI_NO_EEPROM
tristate "Atheros ath9k pci loader for EEPROM-less chips"
depends on ATH9K_PCI
default n
help
This separate driver provides a loader in order to support the
AR500X to AR92XX-generation of ath9k PCI(e) WiFi chips, which have
their initialization data (which contains the real PCI Device ID
that ath9k will need) stored together with the calibration data out
of reach for the ath9k chip.
These devices are usually various network appliances, routers or
access Points and such.
If unsure say N.
config ATH9K_HTC
tristate "Atheros HTC based wireless cards support"
depends on USB && MAC80211

View File

@ -77,3 +77,5 @@ ath9k_htc-y += htc_hst.o \
ath9k_htc-$(CONFIG_ATH9K_HTC_DEBUGFS) += htc_drv_debug.o
obj-$(CONFIG_ATH9K_HTC) += ath9k_htc.o
obj-$(CONFIG_ATH9K_PCI_NO_EEPROM) += ath9k_pci_owl_loader.o

View File

@ -0,0 +1,215 @@
// SPDX-License-Identifier: ISC
/* Initialize Owl Emulation Devices
*
* Copyright (C) 2016 Christian Lamparter <chunkeey@gmail.com>
* Copyright (C) 2016 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
*
* Some devices (like the Cisco Meraki Z1 Cloud Managed Teleworker Gateway)
* need to be able to initialize the PCIe wifi device. Normally, this is done
* during the early stages as a pci quirk.
* However, this isn't possible for devices which have the init code for the
* Atheros chip stored on UBI Volume on NAND. Hence, this module can be used to
* initialize the chip when the user-space is ready to extract the init code.
*/
#include <linux/module.h>
#include <linux/version.h>
#include <linux/completion.h>
#include <linux/etherdevice.h>
#include <linux/firmware.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/ath9k_platform.h>
struct owl_ctx {
struct completion eeprom_load;
};
#define EEPROM_FILENAME_LEN 100
#define AR5416_EEPROM_MAGIC 0xa55a
static int ath9k_pci_fixup(struct pci_dev *pdev, const u16 *cal_data,
size_t cal_len)
{
void __iomem *mem;
const void *cal_end = (void *)cal_data + cal_len;
const struct {
u16 reg;
u16 low_val;
u16 high_val;
} __packed * data;
u16 cmd;
u32 bar0;
bool swap_needed = false;
if (*cal_data != AR5416_EEPROM_MAGIC) {
if (*cal_data != swab16(AR5416_EEPROM_MAGIC)) {
dev_err(&pdev->dev, "invalid calibration data\n");
return -EINVAL;
}
dev_dbg(&pdev->dev, "calibration data needs swapping\n");
swap_needed = true;
}
dev_info(&pdev->dev, "fixup device configuration\n");
mem = pcim_iomap(pdev, 0, 0);
if (!mem) {
dev_err(&pdev->dev, "ioremap error\n");
return -EINVAL;
}
pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &bar0);
pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0,
pci_resource_start(pdev, 0));
pci_read_config_word(pdev, PCI_COMMAND, &cmd);
cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
pci_write_config_word(pdev, PCI_COMMAND, cmd);
/* set pointer to first reg address */
for (data = (const void *)(cal_data + 3);
(const void *)data <= cal_end && data->reg != (u16)~0;
data++) {
u32 val;
u16 reg;
reg = data->reg;
val = data->low_val;
val |= ((u32)data->high_val) << 16;
if (swap_needed) {
reg = swab16(reg);
val = swahb32(val);
}
__raw_writel(val, mem + reg);
usleep_range(100, 120);
}
pci_read_config_word(pdev, PCI_COMMAND, &cmd);
cmd &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
pci_write_config_word(pdev, PCI_COMMAND, cmd);
pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, bar0);
pcim_iounmap(pdev, mem);
pci_disable_device(pdev);
return 0;
}
static void owl_fw_cb(const struct firmware *fw, void *context)
{
struct pci_dev *pdev = (struct pci_dev *)context;
struct owl_ctx *ctx = (struct owl_ctx *)pci_get_drvdata(pdev);
struct pci_bus *bus;
complete(&ctx->eeprom_load);
if (!fw) {
dev_err(&pdev->dev, "no eeprom data received.\n");
goto release;
}
/* also note that we are doing *u16 operations on the file */
if (fw->size > 4096 || fw->size < 0x200 || (fw->size & 1) == 1) {
dev_err(&pdev->dev, "eeprom file has an invalid size.\n");
goto release;
}
if (ath9k_pci_fixup(pdev, (const u16 *)fw->data, fw->size))
goto release;
pci_lock_rescan_remove();
bus = pdev->bus;
pci_stop_and_remove_bus_device(pdev);
/* the device should come back with the proper
* ProductId. But we have to initiate a rescan.
*/
pci_rescan_bus(bus);
pci_unlock_rescan_remove();
release:
release_firmware(fw);
}
static const char *owl_get_eeprom_name(struct pci_dev *pdev)
{
struct device *dev = &pdev->dev;
char *eeprom_name;
dev_dbg(dev, "using auto-generated eeprom filename\n");
eeprom_name = devm_kzalloc(dev, EEPROM_FILENAME_LEN, GFP_KERNEL);
if (!eeprom_name)
return NULL;
/* this should match the pattern used in ath9k/init.c */
scnprintf(eeprom_name, EEPROM_FILENAME_LEN, "ath9k-eeprom-pci-%s.bin",
dev_name(dev));
return eeprom_name;
}
static int owl_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
struct owl_ctx *ctx;
const char *eeprom_name;
int err = 0;
if (pcim_enable_device(pdev))
return -EIO;
pcim_pin_device(pdev);
eeprom_name = owl_get_eeprom_name(pdev);
if (!eeprom_name) {
dev_err(&pdev->dev, "no eeprom filename found.\n");
return -ENODEV;
}
ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
if (!ctx)
return -ENOMEM;
init_completion(&ctx->eeprom_load);
pci_set_drvdata(pdev, ctx);
err = request_firmware_nowait(THIS_MODULE, true, eeprom_name,
&pdev->dev, GFP_KERNEL, pdev, owl_fw_cb);
if (err)
dev_err(&pdev->dev, "failed to request caldata (%d).\n", err);
return err;
}
static void owl_remove(struct pci_dev *pdev)
{
struct owl_ctx *ctx = pci_get_drvdata(pdev);
if (ctx) {
wait_for_completion(&ctx->eeprom_load);
pci_set_drvdata(pdev, NULL);
}
}
static const struct pci_device_id owl_pci_table[] = {
{ PCI_VDEVICE(ATHEROS, 0xff1c) }, /* PCIe */
{ PCI_VDEVICE(ATHEROS, 0xff1d) }, /* PCI */
{ },
};
MODULE_DEVICE_TABLE(pci, owl_pci_table);
static struct pci_driver owl_driver = {
.name = KBUILD_MODNAME,
.id_table = owl_pci_table,
.probe = owl_probe,
.remove = owl_remove,
};
module_pci_driver(owl_driver);
MODULE_AUTHOR("Christian Lamparter <chunkeey@gmail.com>");
MODULE_DESCRIPTION("External EEPROM data loader for Atheros AR500X to AR92XX");
MODULE_LICENSE("Dual BSD/GPL");

View File

@ -20,11 +20,30 @@
#define COMPUTE_TO (5 * HZ)
#define LATEACK_DELAY (10 * HZ)
#define LATEACK_TO 256
#define MAX_DELAY 300
#define EWMA_LEVEL 96
#define EWMA_DIV 128
/**
* ath_dynack_get_max_to - set max timeout according to channel width
* @ah: ath hw
*
*/
static u32 ath_dynack_get_max_to(struct ath_hw *ah)
{
const struct ath9k_channel *chan = ah->curchan;
if (!chan)
return 300;
if (IS_CHAN_HT40(chan))
return 300;
if (IS_CHAN_HALF_RATE(chan))
return 750;
if (IS_CHAN_QUARTER_RATE(chan))
return 1500;
return 600;
}
/**
* ath_dynack_ewma - EWMA (Exponentially Weighted Moving Average) calculation
*
@ -78,6 +97,24 @@ static inline bool ath_dynack_bssidmask(struct ath_hw *ah, const u8 *mac)
return true;
}
/**
* ath_dynack_set_timeout - configure timeouts/slottime registers
* @ah: ath hw
* @to: timeout value
*
*/
static void ath_dynack_set_timeout(struct ath_hw *ah, int to)
{
struct ath_common *common = ath9k_hw_common(ah);
int slottime = (to - 3) / 2;
ath_dbg(common, DYNACK, "ACK timeout %u slottime %u\n",
to, slottime);
ath9k_hw_setslottime(ah, slottime);
ath9k_hw_set_ack_timeout(ah, to);
ath9k_hw_set_cts_timeout(ah, to);
}
/**
* ath_dynack_compute_ackto - compute ACK timeout as the maximum STA timeout
* @ah: ath hw
@ -86,7 +123,6 @@ static inline bool ath_dynack_bssidmask(struct ath_hw *ah, const u8 *mac)
*/
static void ath_dynack_compute_ackto(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
struct ath_dynack *da = &ah->dynack;
struct ath_node *an;
int to = 0;
@ -96,15 +132,8 @@ static void ath_dynack_compute_ackto(struct ath_hw *ah)
to = an->ackto;
if (to && da->ackto != to) {
u32 slottime;
slottime = (to - 3) / 2;
ath_dynack_set_timeout(ah, to);
da->ackto = to;
ath_dbg(common, DYNACK, "ACK timeout %u slottime %u\n",
da->ackto, slottime);
ath9k_hw_setslottime(ah, slottime);
ath9k_hw_set_ack_timeout(ah, da->ackto);
ath9k_hw_set_cts_timeout(ah, da->ackto);
}
}
@ -116,15 +145,16 @@ static void ath_dynack_compute_ackto(struct ath_hw *ah)
*/
static void ath_dynack_compute_to(struct ath_hw *ah)
{
u32 ackto, ack_ts;
u8 *dst, *src;
struct ieee80211_sta *sta;
struct ath_node *an;
struct ts_info *st_ts;
struct ath_dynack *da = &ah->dynack;
u32 ackto, ack_ts, max_to;
struct ieee80211_sta *sta;
struct ts_info *st_ts;
struct ath_node *an;
u8 *dst, *src;
rcu_read_lock();
max_to = ath_dynack_get_max_to(ah);
while (da->st_rbf.h_rb != da->st_rbf.t_rb &&
da->ack_rbf.h_rb != da->ack_rbf.t_rb) {
ack_ts = da->ack_rbf.tstamp[da->ack_rbf.h_rb];
@ -140,7 +170,7 @@ static void ath_dynack_compute_to(struct ath_hw *ah)
if (ack_ts > st_ts->tstamp + st_ts->dur) {
ackto = ack_ts - st_ts->tstamp - st_ts->dur;
if (ackto < MAX_DELAY) {
if (ackto < max_to) {
sta = ieee80211_find_sta_by_ifaddr(ah->hw, dst,
src);
if (sta) {
@ -197,11 +227,10 @@ void ath_dynack_sample_tx_ts(struct ath_hw *ah, struct sk_buff *skb,
if (ieee80211_is_assoc_req(hdr->frame_control) ||
ieee80211_is_assoc_resp(hdr->frame_control) ||
ieee80211_is_auth(hdr->frame_control)) {
ath_dbg(common, DYNACK, "late ack\n");
u32 max_to = ath_dynack_get_max_to(ah);
ath9k_hw_setslottime(ah, (LATEACK_TO - 3) / 2);
ath9k_hw_set_ack_timeout(ah, LATEACK_TO);
ath9k_hw_set_cts_timeout(ah, LATEACK_TO);
ath_dbg(common, DYNACK, "late ack\n");
ath_dynack_set_timeout(ah, max_to);
if (sta) {
struct ath_node *an;
@ -292,15 +321,13 @@ EXPORT_SYMBOL(ath_dynack_sample_ack_ts);
*/
void ath_dynack_node_init(struct ath_hw *ah, struct ath_node *an)
{
/* ackto = slottime + sifs + air delay */
u32 ackto = 9 + 16 + 64;
struct ath_dynack *da = &ah->dynack;
an->ackto = ackto;
an->ackto = da->ackto;
spin_lock(&da->qlock);
spin_lock_bh(&da->qlock);
list_add_tail(&an->list, &da->nodes);
spin_unlock(&da->qlock);
spin_unlock_bh(&da->qlock);
}
EXPORT_SYMBOL(ath_dynack_node_init);
@ -314,9 +341,9 @@ void ath_dynack_node_deinit(struct ath_hw *ah, struct ath_node *an)
{
struct ath_dynack *da = &ah->dynack;
spin_lock(&da->qlock);
spin_lock_bh(&da->qlock);
list_del(&an->list);
spin_unlock(&da->qlock);
spin_unlock_bh(&da->qlock);
}
EXPORT_SYMBOL(ath_dynack_node_deinit);
@ -327,22 +354,26 @@ EXPORT_SYMBOL(ath_dynack_node_deinit);
*/
void ath_dynack_reset(struct ath_hw *ah)
{
/* ackto = slottime + sifs + air delay */
u32 ackto = 9 + 16 + 64;
struct ath_dynack *da = &ah->dynack;
struct ath_node *an;
da->lto = jiffies;
da->ackto = ackto;
spin_lock_bh(&da->qlock);
da->lto = jiffies + COMPUTE_TO;
da->st_rbf.t_rb = 0;
da->st_rbf.h_rb = 0;
da->ack_rbf.t_rb = 0;
da->ack_rbf.h_rb = 0;
da->ackto = ath_dynack_get_max_to(ah);
list_for_each_entry(an, &da->nodes, list)
an->ackto = da->ackto;
/* init acktimeout */
ath9k_hw_setslottime(ah, (ackto - 3) / 2);
ath9k_hw_set_ack_timeout(ah, ackto);
ath9k_hw_set_cts_timeout(ah, ackto);
ath_dynack_set_timeout(ah, da->ackto);
spin_unlock_bh(&da->qlock);
}
EXPORT_SYMBOL(ath_dynack_reset);
@ -359,6 +390,8 @@ void ath_dynack_init(struct ath_hw *ah)
spin_lock_init(&da->qlock);
INIT_LIST_HEAD(&da->nodes);
/* ackto = slottime + sifs + air delay */
da->ackto = 9 + 16 + 64;
ah->hw->wiphy->features |= NL80211_FEATURE_ACKTO_ESTIMATION;
}

View File

@ -463,7 +463,7 @@ static void ath9k_enable_rmw_buffer(void *hw_priv)
atomic_inc(&priv->wmi->m_rmw_cnt);
}
static u32 ath9k_reg_rmw_single(void *hw_priv,
static void ath9k_reg_rmw_single(void *hw_priv,
u32 reg_offset, u32 set, u32 clr)
{
struct ath_hw *ah = hw_priv;
@ -471,7 +471,6 @@ static u32 ath9k_reg_rmw_single(void *hw_priv,
struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
struct register_rmw buf, buf_ret;
int ret;
u32 val = 0;
buf.reg = cpu_to_be32(reg_offset);
buf.set = cpu_to_be32(set);
@ -485,7 +484,6 @@ static u32 ath9k_reg_rmw_single(void *hw_priv,
ath_dbg(common, WMI, "REGISTER RMW FAILED:(0x%04x, %d)\n",
reg_offset, ret);
}
return val;
}
static u32 ath9k_reg_rmw(void *hw_priv, u32 reg_offset, u32 set, u32 clr)

View File

@ -170,6 +170,7 @@ static int htc_config_pipe_credits(struct htc_target *target)
time_left = wait_for_completion_timeout(&target->cmd_wait, HZ);
if (!time_left) {
dev_err(target->dev, "HTC credit config timeout\n");
kfree_skb(skb);
return -ETIMEDOUT;
}
@ -205,6 +206,7 @@ static int htc_setup_complete(struct htc_target *target)
time_left = wait_for_completion_timeout(&target->cmd_wait, HZ);
if (!time_left) {
dev_err(target->dev, "HTC start timeout\n");
kfree_skb(skb);
return -ETIMEDOUT;
}
@ -277,6 +279,7 @@ int htc_connect_service(struct htc_target *target,
if (!time_left) {
dev_err(target->dev, "Service connection timeout for: %d\n",
service_connreq->service_id);
kfree_skb(skb);
return -ETIMEDOUT;
}

View File

@ -336,6 +336,7 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
ath_dbg(common, WMI, "Timeout waiting for WMI command: %s\n",
wmi_cmd_to_name(cmd_id));
mutex_unlock(&wmi->op_mutex);
kfree_skb(skb);
return -ETIMEDOUT;
}

View File

@ -1107,12 +1107,10 @@ static int carl9170_usb_probe(struct usb_interface *intf,
static void carl9170_usb_disconnect(struct usb_interface *intf)
{
struct ar9170 *ar = usb_get_intfdata(intf);
struct usb_device *udev;
if (WARN_ON(!ar))
return;
udev = ar->udev;
wait_for_completion(&ar->fw_load_wait);
if (IS_INITIALIZED(ar)) {

View File

@ -641,52 +641,58 @@ int wcn36xx_smd_start_hw_scan(struct wcn36xx *wcn, struct ieee80211_vif *vif,
struct cfg80211_scan_request *req)
{
struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif);
struct wcn36xx_hal_start_scan_offload_req_msg msg_body;
struct wcn36xx_hal_start_scan_offload_req_msg *msg_body;
int ret, i;
if (req->ie_len > WCN36XX_MAX_SCAN_IE_LEN)
return -EINVAL;
mutex_lock(&wcn->hal_mutex);
INIT_HAL_MSG(msg_body, WCN36XX_HAL_START_SCAN_OFFLOAD_REQ);
msg_body.scan_type = WCN36XX_HAL_SCAN_TYPE_ACTIVE;
msg_body.min_ch_time = 30;
msg_body.max_ch_time = 100;
msg_body.scan_hidden = 1;
memcpy(msg_body.mac, vif->addr, ETH_ALEN);
msg_body.bss_type = vif_priv->bss_type;
msg_body.p2p_search = vif->p2p;
msg_body.num_ssid = min_t(u8, req->n_ssids, ARRAY_SIZE(msg_body.ssids));
for (i = 0; i < msg_body.num_ssid; i++) {
msg_body.ssids[i].length = min_t(u8, req->ssids[i].ssid_len,
sizeof(msg_body.ssids[i].ssid));
memcpy(msg_body.ssids[i].ssid, req->ssids[i].ssid,
msg_body.ssids[i].length);
msg_body = kzalloc(sizeof(*msg_body), GFP_KERNEL);
if (!msg_body) {
ret = -ENOMEM;
goto out;
}
msg_body.num_channel = min_t(u8, req->n_channels,
sizeof(msg_body.channels));
for (i = 0; i < msg_body.num_channel; i++)
msg_body.channels[i] = req->channels[i]->hw_value;
INIT_HAL_MSG((*msg_body), WCN36XX_HAL_START_SCAN_OFFLOAD_REQ);
msg_body.header.len -= WCN36XX_MAX_SCAN_IE_LEN;
msg_body->scan_type = WCN36XX_HAL_SCAN_TYPE_ACTIVE;
msg_body->min_ch_time = 30;
msg_body->max_ch_time = 100;
msg_body->scan_hidden = 1;
memcpy(msg_body->mac, vif->addr, ETH_ALEN);
msg_body->bss_type = vif_priv->bss_type;
msg_body->p2p_search = vif->p2p;
msg_body->num_ssid = min_t(u8, req->n_ssids, ARRAY_SIZE(msg_body->ssids));
for (i = 0; i < msg_body->num_ssid; i++) {
msg_body->ssids[i].length = min_t(u8, req->ssids[i].ssid_len,
sizeof(msg_body->ssids[i].ssid));
memcpy(msg_body->ssids[i].ssid, req->ssids[i].ssid,
msg_body->ssids[i].length);
}
msg_body->num_channel = min_t(u8, req->n_channels,
sizeof(msg_body->channels));
for (i = 0; i < msg_body->num_channel; i++)
msg_body->channels[i] = req->channels[i]->hw_value;
msg_body->header.len -= WCN36XX_MAX_SCAN_IE_LEN;
if (req->ie_len > 0) {
msg_body.ie_len = req->ie_len;
msg_body.header.len += req->ie_len;
memcpy(msg_body.ie, req->ie, req->ie_len);
msg_body->ie_len = req->ie_len;
msg_body->header.len += req->ie_len;
memcpy(msg_body->ie, req->ie, req->ie_len);
}
PREPARE_HAL_BUF(wcn->hal_buf, msg_body);
PREPARE_HAL_BUF(wcn->hal_buf, (*msg_body));
wcn36xx_dbg(WCN36XX_DBG_HAL,
"hal start hw-scan (channels: %u; ssids: %u; p2p: %s)\n",
msg_body.num_channel, msg_body.num_ssid,
msg_body.p2p_search ? "yes" : "no");
msg_body->num_channel, msg_body->num_ssid,
msg_body->p2p_search ? "yes" : "no");
ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len);
ret = wcn36xx_smd_send_and_wait(wcn, msg_body->header.len);
if (ret) {
wcn36xx_err("Sending hal_start_scan_offload failed\n");
goto out;
@ -698,6 +704,7 @@ int wcn36xx_smd_start_hw_scan(struct wcn36xx *wcn, struct ieee80211_vif *vif,
goto out;
}
out:
kfree(msg_body);
mutex_unlock(&wcn->hal_mutex);
return ret;
}
@ -1257,96 +1264,104 @@ out:
static int wcn36xx_smd_config_bss_v1(struct wcn36xx *wcn,
const struct wcn36xx_hal_config_bss_req_msg *orig)
{
struct wcn36xx_hal_config_bss_req_msg_v1 msg_body;
struct wcn36xx_hal_config_bss_params_v1 *bss = &msg_body.bss_params;
struct wcn36xx_hal_config_sta_params_v1 *sta = &bss->sta;
struct wcn36xx_hal_config_bss_req_msg_v1 *msg_body;
struct wcn36xx_hal_config_bss_params_v1 *bss;
struct wcn36xx_hal_config_sta_params_v1 *sta;
int ret;
INIT_HAL_MSG(msg_body, WCN36XX_HAL_CONFIG_BSS_REQ);
msg_body = kzalloc(sizeof(*msg_body), GFP_KERNEL);
if (!msg_body)
return -ENOMEM;
INIT_HAL_MSG((*msg_body), WCN36XX_HAL_CONFIG_BSS_REQ);
bss = &msg_body->bss_params;
sta = &bss->sta;
/* convert orig to v1 */
memcpy(&msg_body.bss_params.bssid,
memcpy(&msg_body->bss_params.bssid,
&orig->bss_params.bssid, ETH_ALEN);
memcpy(&msg_body.bss_params.self_mac_addr,
memcpy(&msg_body->bss_params.self_mac_addr,
&orig->bss_params.self_mac_addr, ETH_ALEN);
msg_body.bss_params.bss_type = orig->bss_params.bss_type;
msg_body.bss_params.oper_mode = orig->bss_params.oper_mode;
msg_body.bss_params.nw_type = orig->bss_params.nw_type;
msg_body->bss_params.bss_type = orig->bss_params.bss_type;
msg_body->bss_params.oper_mode = orig->bss_params.oper_mode;
msg_body->bss_params.nw_type = orig->bss_params.nw_type;
msg_body.bss_params.short_slot_time_supported =
msg_body->bss_params.short_slot_time_supported =
orig->bss_params.short_slot_time_supported;
msg_body.bss_params.lla_coexist = orig->bss_params.lla_coexist;
msg_body.bss_params.llb_coexist = orig->bss_params.llb_coexist;
msg_body.bss_params.llg_coexist = orig->bss_params.llg_coexist;
msg_body.bss_params.ht20_coexist = orig->bss_params.ht20_coexist;
msg_body.bss_params.lln_non_gf_coexist =
msg_body->bss_params.lla_coexist = orig->bss_params.lla_coexist;
msg_body->bss_params.llb_coexist = orig->bss_params.llb_coexist;
msg_body->bss_params.llg_coexist = orig->bss_params.llg_coexist;
msg_body->bss_params.ht20_coexist = orig->bss_params.ht20_coexist;
msg_body->bss_params.lln_non_gf_coexist =
orig->bss_params.lln_non_gf_coexist;
msg_body.bss_params.lsig_tx_op_protection_full_support =
msg_body->bss_params.lsig_tx_op_protection_full_support =
orig->bss_params.lsig_tx_op_protection_full_support;
msg_body.bss_params.rifs_mode = orig->bss_params.rifs_mode;
msg_body.bss_params.beacon_interval = orig->bss_params.beacon_interval;
msg_body.bss_params.dtim_period = orig->bss_params.dtim_period;
msg_body.bss_params.tx_channel_width_set =
msg_body->bss_params.rifs_mode = orig->bss_params.rifs_mode;
msg_body->bss_params.beacon_interval = orig->bss_params.beacon_interval;
msg_body->bss_params.dtim_period = orig->bss_params.dtim_period;
msg_body->bss_params.tx_channel_width_set =
orig->bss_params.tx_channel_width_set;
msg_body.bss_params.oper_channel = orig->bss_params.oper_channel;
msg_body.bss_params.ext_channel = orig->bss_params.ext_channel;
msg_body->bss_params.oper_channel = orig->bss_params.oper_channel;
msg_body->bss_params.ext_channel = orig->bss_params.ext_channel;
msg_body.bss_params.reserved = orig->bss_params.reserved;
msg_body->bss_params.reserved = orig->bss_params.reserved;
memcpy(&msg_body.bss_params.ssid,
memcpy(&msg_body->bss_params.ssid,
&orig->bss_params.ssid,
sizeof(orig->bss_params.ssid));
msg_body.bss_params.action = orig->bss_params.action;
msg_body.bss_params.rateset = orig->bss_params.rateset;
msg_body.bss_params.ht = orig->bss_params.ht;
msg_body.bss_params.obss_prot_enabled =
msg_body->bss_params.action = orig->bss_params.action;
msg_body->bss_params.rateset = orig->bss_params.rateset;
msg_body->bss_params.ht = orig->bss_params.ht;
msg_body->bss_params.obss_prot_enabled =
orig->bss_params.obss_prot_enabled;
msg_body.bss_params.rmf = orig->bss_params.rmf;
msg_body.bss_params.ht_oper_mode = orig->bss_params.ht_oper_mode;
msg_body.bss_params.dual_cts_protection =
msg_body->bss_params.rmf = orig->bss_params.rmf;
msg_body->bss_params.ht_oper_mode = orig->bss_params.ht_oper_mode;
msg_body->bss_params.dual_cts_protection =
orig->bss_params.dual_cts_protection;
msg_body.bss_params.max_probe_resp_retry_limit =
msg_body->bss_params.max_probe_resp_retry_limit =
orig->bss_params.max_probe_resp_retry_limit;
msg_body.bss_params.hidden_ssid = orig->bss_params.hidden_ssid;
msg_body.bss_params.proxy_probe_resp =
msg_body->bss_params.hidden_ssid = orig->bss_params.hidden_ssid;
msg_body->bss_params.proxy_probe_resp =
orig->bss_params.proxy_probe_resp;
msg_body.bss_params.edca_params_valid =
msg_body->bss_params.edca_params_valid =
orig->bss_params.edca_params_valid;
memcpy(&msg_body.bss_params.acbe,
memcpy(&msg_body->bss_params.acbe,
&orig->bss_params.acbe,
sizeof(orig->bss_params.acbe));
memcpy(&msg_body.bss_params.acbk,
memcpy(&msg_body->bss_params.acbk,
&orig->bss_params.acbk,
sizeof(orig->bss_params.acbk));
memcpy(&msg_body.bss_params.acvi,
memcpy(&msg_body->bss_params.acvi,
&orig->bss_params.acvi,
sizeof(orig->bss_params.acvi));
memcpy(&msg_body.bss_params.acvo,
memcpy(&msg_body->bss_params.acvo,
&orig->bss_params.acvo,
sizeof(orig->bss_params.acvo));
msg_body.bss_params.ext_set_sta_key_param_valid =
msg_body->bss_params.ext_set_sta_key_param_valid =
orig->bss_params.ext_set_sta_key_param_valid;
memcpy(&msg_body.bss_params.ext_set_sta_key_param,
memcpy(&msg_body->bss_params.ext_set_sta_key_param,
&orig->bss_params.ext_set_sta_key_param,
sizeof(orig->bss_params.acvo));
msg_body.bss_params.wcn36xx_hal_persona =
msg_body->bss_params.wcn36xx_hal_persona =
orig->bss_params.wcn36xx_hal_persona;
msg_body.bss_params.spectrum_mgt_enable =
msg_body->bss_params.spectrum_mgt_enable =
orig->bss_params.spectrum_mgt_enable;
msg_body.bss_params.tx_mgmt_power = orig->bss_params.tx_mgmt_power;
msg_body.bss_params.max_tx_power = orig->bss_params.max_tx_power;
msg_body->bss_params.tx_mgmt_power = orig->bss_params.tx_mgmt_power;
msg_body->bss_params.max_tx_power = orig->bss_params.max_tx_power;
wcn36xx_smd_convert_sta_to_v1(wcn, &orig->bss_params.sta,
&msg_body.bss_params.sta);
&msg_body->bss_params.sta);
PREPARE_HAL_BUF(wcn->hal_buf, msg_body);
PREPARE_HAL_BUF(wcn->hal_buf, (*msg_body));
wcn36xx_dbg(WCN36XX_DBG_HAL,
"hal config bss v1 bssid %pM self_mac_addr %pM bss_type %d oper_mode %d nw_type %d\n",
@ -1358,7 +1373,10 @@ static int wcn36xx_smd_config_bss_v1(struct wcn36xx *wcn,
sta->bssid, sta->action, sta->sta_index,
sta->bssid_index, sta->aid, sta->type, sta->mac);
return wcn36xx_smd_send_and_wait(wcn, msg_body.header.len);
ret = wcn36xx_smd_send_and_wait(wcn, msg_body->header.len);
kfree(msg_body);
return ret;
}
@ -1410,16 +1428,21 @@ int wcn36xx_smd_config_bss(struct wcn36xx *wcn, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, const u8 *bssid,
bool update)
{
struct wcn36xx_hal_config_bss_req_msg msg;
struct wcn36xx_hal_config_bss_req_msg *msg;
struct wcn36xx_hal_config_bss_params *bss;
struct wcn36xx_hal_config_sta_params *sta_params;
struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif);
int ret;
mutex_lock(&wcn->hal_mutex);
INIT_HAL_MSG(msg, WCN36XX_HAL_CONFIG_BSS_REQ);
msg = kzalloc(sizeof(*msg), GFP_KERNEL);
if (!msg) {
ret = -ENOMEM;
goto out;
}
INIT_HAL_MSG((*msg), WCN36XX_HAL_CONFIG_BSS_REQ);
bss = &msg.bss_params;
bss = &msg->bss_params;
sta_params = &bss->sta;
WARN_ON(is_zero_ether_addr(bssid));
@ -1514,11 +1537,11 @@ int wcn36xx_smd_config_bss(struct wcn36xx *wcn, struct ieee80211_vif *vif,
sta_params->mac);
if (!wcn36xx_is_fw_version(wcn, 1, 2, 2, 24)) {
ret = wcn36xx_smd_config_bss_v1(wcn, &msg);
ret = wcn36xx_smd_config_bss_v1(wcn, msg);
} else {
PREPARE_HAL_BUF(wcn->hal_buf, msg);
PREPARE_HAL_BUF(wcn->hal_buf, (*msg));
ret = wcn36xx_smd_send_and_wait(wcn, msg.header.len);
ret = wcn36xx_smd_send_and_wait(wcn, msg->header.len);
}
if (ret) {
wcn36xx_err("Sending hal_config_bss failed\n");
@ -1534,6 +1557,7 @@ int wcn36xx_smd_config_bss(struct wcn36xx *wcn, struct ieee80211_vif *vif,
goto out;
}
out:
kfree(msg);
mutex_unlock(&wcn->hal_mutex);
return ret;
}

View File

@ -25,6 +25,22 @@
#define WIL_MAX_ROC_DURATION_MS 5000
#define WIL_EDMG_CHANNEL_9_SUBCHANNELS (BIT(0) | BIT(1))
#define WIL_EDMG_CHANNEL_10_SUBCHANNELS (BIT(1) | BIT(2))
#define WIL_EDMG_CHANNEL_11_SUBCHANNELS (BIT(2) | BIT(3))
/* WIL_EDMG_BW_CONFIGURATION define the allowed channel bandwidth
* configurations as defined by IEEE 802.11 section 9.4.2.251, Table 13.
* The value 5 allowing CB1 and CB2 of adjacent channels.
*/
#define WIL_EDMG_BW_CONFIGURATION 5
/* WIL_EDMG_CHANNELS is a bitmap that indicates the 2.16 GHz channel(s) that
* are allowed to be used for EDMG transmissions in the BSS as defined by
* IEEE 802.11 section 9.4.2.251.
*/
#define WIL_EDMG_CHANNELS (BIT(0) | BIT(1) | BIT(2) | BIT(3))
bool disable_ap_sme;
module_param(disable_ap_sme, bool, 0444);
MODULE_PARM_DESC(disable_ap_sme, " let user space handle AP mode SME");
@ -51,6 +67,39 @@ static struct ieee80211_channel wil_60ghz_channels[] = {
CHAN60G(4, 0),
};
/* Rx channel bonding mode */
enum wil_rx_cb_mode {
WIL_RX_CB_MODE_DMG,
WIL_RX_CB_MODE_EDMG,
WIL_RX_CB_MODE_WIDE,
};
static int wil_rx_cb_mode_to_n_bonded(u8 cb_mode)
{
switch (cb_mode) {
case WIL_RX_CB_MODE_DMG:
case WIL_RX_CB_MODE_EDMG:
return 1;
case WIL_RX_CB_MODE_WIDE:
return 2;
default:
return 1;
}
}
static int wil_tx_cb_mode_to_n_bonded(u8 cb_mode)
{
switch (cb_mode) {
case WMI_TX_MODE_DMG:
case WMI_TX_MODE_EDMG_CB1:
return 1;
case WMI_TX_MODE_EDMG_CB2:
return 2;
default:
return 1;
}
}
static void
wil_memdup_ie(u8 **pdst, size_t *pdst_len, const u8 *src, size_t src_len)
{
@ -82,6 +131,13 @@ void update_supported_bands(struct wil6210_priv *wil)
wiphy->bands[NL80211_BAND_60GHZ]->n_channels =
wil_num_supported_channels(wil);
if (test_bit(WMI_FW_CAPABILITY_CHANNEL_BONDING, wil->fw_capabilities)) {
wiphy->bands[NL80211_BAND_60GHZ]->edmg_cap.channels =
WIL_EDMG_CHANNELS;
wiphy->bands[NL80211_BAND_60GHZ]->edmg_cap.bw_config =
WIL_EDMG_BW_CONFIGURATION;
}
}
/* Vendor id to be used in vendor specific command and events
@ -275,6 +331,8 @@ static const char * const key_usage_str[] = {
[WMI_KEY_USE_PAIRWISE] = "PTK",
[WMI_KEY_USE_RX_GROUP] = "RX_GTK",
[WMI_KEY_USE_TX_GROUP] = "TX_GTK",
[WMI_KEY_USE_STORE_PTK] = "STORE_PTK",
[WMI_KEY_USE_APPLY_PTK] = "APPLY_PTK",
};
int wil_iftype_nl2wmi(enum nl80211_iftype type)
@ -300,6 +358,86 @@ int wil_iftype_nl2wmi(enum nl80211_iftype type)
return -EOPNOTSUPP;
}
int wil_spec2wmi_ch(u8 spec_ch, u8 *wmi_ch)
{
switch (spec_ch) {
case 1:
*wmi_ch = WMI_CHANNEL_1;
break;
case 2:
*wmi_ch = WMI_CHANNEL_2;
break;
case 3:
*wmi_ch = WMI_CHANNEL_3;
break;
case 4:
*wmi_ch = WMI_CHANNEL_4;
break;
case 5:
*wmi_ch = WMI_CHANNEL_5;
break;
case 6:
*wmi_ch = WMI_CHANNEL_6;
break;
case 9:
*wmi_ch = WMI_CHANNEL_9;
break;
case 10:
*wmi_ch = WMI_CHANNEL_10;
break;
case 11:
*wmi_ch = WMI_CHANNEL_11;
break;
case 12:
*wmi_ch = WMI_CHANNEL_12;
break;
default:
return -EINVAL;
}
return 0;
}
int wil_wmi2spec_ch(u8 wmi_ch, u8 *spec_ch)
{
switch (wmi_ch) {
case WMI_CHANNEL_1:
*spec_ch = 1;
break;
case WMI_CHANNEL_2:
*spec_ch = 2;
break;
case WMI_CHANNEL_3:
*spec_ch = 3;
break;
case WMI_CHANNEL_4:
*spec_ch = 4;
break;
case WMI_CHANNEL_5:
*spec_ch = 5;
break;
case WMI_CHANNEL_6:
*spec_ch = 6;
break;
case WMI_CHANNEL_9:
*spec_ch = 9;
break;
case WMI_CHANNEL_10:
*spec_ch = 10;
break;
case WMI_CHANNEL_11:
*spec_ch = 11;
break;
case WMI_CHANNEL_12:
*spec_ch = 12;
break;
default:
return -EINVAL;
}
return 0;
}
int wil_cid_fill_sinfo(struct wil6210_vif *vif, int cid,
struct station_info *sinfo)
{
@ -314,6 +452,7 @@ int wil_cid_fill_sinfo(struct wil6210_vif *vif, int cid,
} __packed reply;
struct wil_net_stats *stats = &wil->sta[cid].stats;
int rc;
u8 txflag = RATE_INFO_FLAGS_DMG;
memset(&reply, 0, sizeof(reply));
@ -327,7 +466,8 @@ int wil_cid_fill_sinfo(struct wil6210_vif *vif, int cid,
" MCS %d TSF 0x%016llx\n"
" BF status 0x%08x RSSI %d SQI %d%%\n"
" Tx Tpt %d goodput %d Rx goodput %d\n"
" Sectors(rx:tx) my %d:%d peer %d:%d\n""}\n",
" Sectors(rx:tx) my %d:%d peer %d:%d\n"
" Tx mode %d}\n",
cid, vif->mid, le16_to_cpu(reply.evt.bf_mcs),
le64_to_cpu(reply.evt.tsf), reply.evt.status,
reply.evt.rssi,
@ -338,7 +478,8 @@ int wil_cid_fill_sinfo(struct wil6210_vif *vif, int cid,
le16_to_cpu(reply.evt.my_rx_sector),
le16_to_cpu(reply.evt.my_tx_sector),
le16_to_cpu(reply.evt.other_rx_sector),
le16_to_cpu(reply.evt.other_tx_sector));
le16_to_cpu(reply.evt.other_tx_sector),
reply.evt.tx_mode);
sinfo->generation = wil->sinfo_gen;
@ -351,9 +492,16 @@ int wil_cid_fill_sinfo(struct wil6210_vif *vif, int cid,
BIT_ULL(NL80211_STA_INFO_RX_DROP_MISC) |
BIT_ULL(NL80211_STA_INFO_TX_FAILED);
sinfo->txrate.flags = RATE_INFO_FLAGS_DMG;
if (wil->use_enhanced_dma_hw && reply.evt.tx_mode != WMI_TX_MODE_DMG)
txflag = RATE_INFO_FLAGS_EDMG;
sinfo->txrate.flags = txflag;
sinfo->txrate.mcs = le16_to_cpu(reply.evt.bf_mcs);
sinfo->rxrate.mcs = stats->last_mcs_rx;
sinfo->txrate.n_bonded_ch =
wil_tx_cb_mode_to_n_bonded(reply.evt.tx_mode);
sinfo->rxrate.n_bonded_ch =
wil_rx_cb_mode_to_n_bonded(stats->last_cb_mode_rx);
sinfo->rx_bytes = stats->rx_bytes;
sinfo->rx_packets = stats->rx_packets;
sinfo->rx_dropped_misc = stats->rx_dropped;
@ -396,7 +544,7 @@ static int wil_cfg80211_get_station(struct wiphy *wiphy,
/*
* Find @idx-th active STA for specific MID for station dump.
*/
static int wil_find_cid_by_idx(struct wil6210_priv *wil, u8 mid, int idx)
int wil_find_cid_by_idx(struct wil6210_priv *wil, u8 mid, int idx)
{
int i;
@ -1022,6 +1170,33 @@ static int wil_ft_connect(struct wiphy *wiphy,
return rc;
}
static int wil_get_wmi_edmg_channel(struct wil6210_priv *wil, u8 edmg_bw_config,
u8 edmg_channels, u8 *wmi_ch)
{
if (!edmg_bw_config) {
*wmi_ch = 0;
return 0;
} else if (edmg_bw_config == WIL_EDMG_BW_CONFIGURATION) {
/* convert from edmg channel bitmap into edmg channel number */
switch (edmg_channels) {
case WIL_EDMG_CHANNEL_9_SUBCHANNELS:
return wil_spec2wmi_ch(9, wmi_ch);
case WIL_EDMG_CHANNEL_10_SUBCHANNELS:
return wil_spec2wmi_ch(10, wmi_ch);
case WIL_EDMG_CHANNEL_11_SUBCHANNELS:
return wil_spec2wmi_ch(11, wmi_ch);
default:
wil_err(wil, "Unsupported edmg channel bitmap 0x%x\n",
edmg_channels);
return -EINVAL;
}
} else {
wil_err(wil, "Unsupported EDMG BW configuration %d\n",
edmg_bw_config);
return -EINVAL;
}
}
static int wil_cfg80211_connect(struct wiphy *wiphy,
struct net_device *ndev,
struct cfg80211_connect_params *sme)
@ -1167,6 +1342,11 @@ static int wil_cfg80211_connect(struct wiphy *wiphy,
memcpy(conn.ssid, ssid_eid+2, conn.ssid_len);
conn.channel = ch - 1;
rc = wil_get_wmi_edmg_channel(wil, sme->edmg.bw_config,
sme->edmg.channels, &conn.edmg_channel);
if (rc < 0)
return rc;
ether_addr_copy(conn.bssid, bss->bssid);
ether_addr_copy(conn.dst_mac, bss->bssid);
@ -1376,6 +1556,7 @@ void wil_set_crypto_rx(u8 key_index, enum wmi_key_usage key_usage,
return;
switch (key_usage) {
case WMI_KEY_USE_STORE_PTK:
case WMI_KEY_USE_PAIRWISE:
for (tid = 0; tid < WIL_STA_TID_NUM; tid++) {
cc = &cs->tid_crypto_rx[tid].key_id[key_index];
@ -1473,6 +1654,16 @@ static int wil_cfg80211_add_key(struct wiphy *wiphy,
return -EINVAL;
}
spin_lock_bh(&wil->eap_lock);
if (pairwise && wdev->iftype == NL80211_IFTYPE_STATION &&
(vif->ptk_rekey_state == WIL_REKEY_M3_RECEIVED ||
vif->ptk_rekey_state == WIL_REKEY_WAIT_M4_SENT)) {
key_usage = WMI_KEY_USE_STORE_PTK;
vif->ptk_rekey_state = WIL_REKEY_WAIT_M4_SENT;
wil_dbg_misc(wil, "Store EAPOL key\n");
}
spin_unlock_bh(&wil->eap_lock);
rc = wmi_add_cipher_key(vif, key_index, mac_addr, params->key_len,
params->key, key_usage);
if (!rc && !IS_ERR(cs)) {
@ -1728,7 +1919,7 @@ out:
static int _wil_cfg80211_start_ap(struct wiphy *wiphy,
struct net_device *ndev,
const u8 *ssid, size_t ssid_len, u32 privacy,
int bi, u8 chan,
int bi, u8 chan, u8 wmi_edmg_channel,
struct cfg80211_beacon_data *bcon,
u8 hidden_ssid, u32 pbss)
{
@ -1791,6 +1982,7 @@ static int _wil_cfg80211_start_ap(struct wiphy *wiphy,
vif->privacy = privacy;
vif->channel = chan;
vif->wmi_edmg_channel = wmi_edmg_channel;
vif->hidden_ssid = hidden_ssid;
vif->pbss = pbss;
vif->bi = bi;
@ -1801,7 +1993,8 @@ static int _wil_cfg80211_start_ap(struct wiphy *wiphy,
if (!wil_has_other_active_ifaces(wil, ndev, false, true))
wil6210_bus_request(wil, WIL_MAX_BUS_REQUEST_KBPS);
rc = wmi_pcp_start(vif, bi, wmi_nettype, chan, hidden_ssid, is_go);
rc = wmi_pcp_start(vif, bi, wmi_nettype, chan, wmi_edmg_channel,
hidden_ssid, is_go);
if (rc)
goto err_pcp_start;
@ -1853,7 +2046,8 @@ void wil_cfg80211_ap_recovery(struct wil6210_priv *wil)
rc = _wil_cfg80211_start_ap(wiphy, ndev,
vif->ssid, vif->ssid_len,
vif->privacy, vif->bi,
vif->channel, &bcon,
vif->channel,
vif->wmi_edmg_channel, &bcon,
vif->hidden_ssid, vif->pbss);
if (rc) {
wil_err(wil, "vif %d recovery failed (%d)\n", i, rc);
@ -1903,7 +2097,8 @@ static int wil_cfg80211_change_beacon(struct wiphy *wiphy,
rc = _wil_cfg80211_start_ap(wiphy, ndev, vif->ssid,
vif->ssid_len, privacy,
wdev->beacon_interval,
vif->channel, bcon,
vif->channel,
vif->wmi_edmg_channel, bcon,
vif->hidden_ssid,
vif->pbss);
} else {
@ -1922,10 +2117,17 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy,
struct ieee80211_channel *channel = info->chandef.chan;
struct cfg80211_beacon_data *bcon = &info->beacon;
struct cfg80211_crypto_settings *crypto = &info->crypto;
u8 wmi_edmg_channel;
u8 hidden_ssid;
wil_dbg_misc(wil, "start_ap\n");
rc = wil_get_wmi_edmg_channel(wil, info->chandef.edmg.bw_config,
info->chandef.edmg.channels,
&wmi_edmg_channel);
if (rc < 0)
return rc;
if (!channel) {
wil_err(wil, "AP: No channel???\n");
return -EINVAL;
@ -1965,7 +2167,8 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy,
rc = _wil_cfg80211_start_ap(wiphy, ndev,
info->ssid, info->ssid_len, info->privacy,
info->beacon_interval, channel->hw_value,
bcon, hidden_ssid, info->pbss);
wmi_edmg_channel, bcon, hidden_ssid,
info->pbss);
return rc;
}

View File

@ -393,7 +393,8 @@ static int wil_debugfs_iomem_x32_set(void *data, u64 val)
if (ret < 0)
return ret;
writel(val, (void __iomem *)d->offset);
writel_relaxed(val, (void __iomem *)d->offset);
wmb(); /* make sure write propagated to HW */
wil_pm_runtime_put(wil);
@ -959,6 +960,18 @@ static const struct file_operations fops_pmcdata = {
.llseek = wil_pmc_llseek,
};
static int wil_pmcring_seq_open(struct inode *inode, struct file *file)
{
return single_open(file, wil_pmcring_read, inode->i_private);
}
static const struct file_operations fops_pmcring = {
.open = wil_pmcring_seq_open,
.release = single_release,
.read = seq_read,
.llseek = seq_lseek,
};
/*---tx_mgmt---*/
/* Write mgmt frame to this file to send it */
static ssize_t wil_write_file_txmgmt(struct file *file, const char __user *buf,
@ -2371,6 +2384,7 @@ static const struct {
{"back", 0644, &fops_back},
{"pmccfg", 0644, &fops_pmccfg},
{"pmcdata", 0444, &fops_pmcdata},
{"pmcring", 0444, &fops_pmcring},
{"temp", 0444, &temp_fops},
{"freq", 0444, &freq_fops},
{"link", 0444, &link_fops},

View File

@ -373,6 +373,7 @@ static void _wil6210_disconnect_complete(struct wil6210_vif *vif,
}
clear_bit(wil_vif_fwconnecting, vif->status);
clear_bit(wil_vif_ft_roam, vif->status);
vif->ptk_rekey_state = WIL_REKEY_IDLE;
break;
case NL80211_IFTYPE_AP:
@ -724,6 +725,8 @@ int wil_priv_init(struct wil6210_priv *wil)
INIT_LIST_HEAD(&wil->pending_wmi_ev);
spin_lock_init(&wil->wmi_ev_lock);
spin_lock_init(&wil->net_queue_lock);
spin_lock_init(&wil->eap_lock);
init_waitqueue_head(&wil->wq);
init_rwsem(&wil->mem_lock);
@ -1654,6 +1657,7 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
cancel_work_sync(&vif->disconnect_worker);
wil6210_disconnect(vif, NULL,
WLAN_REASON_DEAUTH_LEAVING);
vif->ptk_rekey_state = WIL_REKEY_IDLE;
}
}
wil_bcast_fini_all(wil);

View File

@ -218,6 +218,7 @@ static void wil_vif_deinit(struct wil6210_vif *vif)
cancel_work_sync(&vif->p2p.delayed_listen_work);
wil_probe_client_flush(vif);
cancel_work_sync(&vif->probe_client_worker);
cancel_work_sync(&vif->enable_tx_key_worker);
}
void wil_vif_free(struct wil6210_vif *vif)
@ -283,7 +284,9 @@ static void wil_vif_init(struct wil6210_vif *vif)
INIT_WORK(&vif->probe_client_worker, wil_probe_client_worker);
INIT_WORK(&vif->disconnect_worker, wil_disconnect_worker);
INIT_WORK(&vif->p2p.discovery_expired_work, wil_p2p_listen_expired);
INIT_WORK(&vif->p2p.delayed_listen_work, wil_p2p_delayed_listen_work);
INIT_WORK(&vif->enable_tx_key_worker, wil_enable_tx_key_worker);
INIT_LIST_HEAD(&vif->probe_client_pending);
@ -540,6 +543,7 @@ void wil_vif_remove(struct wil6210_priv *wil, u8 mid)
cancel_work_sync(&vif->disconnect_worker);
wil_probe_client_flush(vif);
cancel_work_sync(&vif->probe_client_worker);
cancel_work_sync(&vif->enable_tx_key_worker);
/* for VIFs, ndev will be freed by destructor after RTNL is unlocked.
* the main interface will be freed in wil_if_free, we need to keep it
* a bit longer so logging macros will work.

View File

@ -435,7 +435,7 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
mutex_unlock(&wil->mutex);
if (rc) {
wil_err(wil, "failed to load WMI only FW\n");
goto if_remove;
/* ignore the error to allow debugging */
}
}
@ -455,8 +455,6 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
return 0;
if_remove:
wil_if_remove(wil);
bus_disable:
wil_if_pcie_disable(wil);
err_iounmap:

View File

@ -18,6 +18,7 @@
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/seq_file.h>
#include "wmi.h"
#include "wil6210.h"
#include "txrx.h"
@ -431,3 +432,28 @@ out:
return newpos;
}
int wil_pmcring_read(struct seq_file *s, void *data)
{
struct wil6210_priv *wil = s->private;
struct pmc_ctx *pmc = &wil->pmc;
size_t pmc_ring_size =
sizeof(struct vring_rx_desc) * pmc->num_descriptors;
mutex_lock(&pmc->lock);
if (!wil_is_pmc_allocated(pmc)) {
wil_err(wil, "error, pmc is not allocated!\n");
pmc->last_cmd_status = -EPERM;
mutex_unlock(&pmc->lock);
return -EPERM;
}
wil_dbg_misc(wil, "pmcring_read: size %zu\n", pmc_ring_size);
seq_write(s, pmc->pring_va, pmc_ring_size);
mutex_unlock(&pmc->lock);
return 0;
}

View File

@ -25,3 +25,4 @@ void wil_pmc_free(struct wil6210_priv *wil, int send_pmc_cmd);
int wil_pmc_last_cmd_status(struct wil6210_priv *wil);
ssize_t wil_pmc_read(struct file *, char __user *, size_t, loff_t *);
loff_t wil_pmc_llseek(struct file *filp, loff_t off, int whence);
int wil_pmcring_read(struct seq_file *s, void *data);

View File

@ -260,7 +260,6 @@ struct wil_tid_ampdu_rx *wil_tid_ampdu_rx_alloc(struct wil6210_priv *wil,
r->reorder_buf =
kcalloc(size, sizeof(struct sk_buff *), GFP_KERNEL);
if (!r->reorder_buf) {
kfree(r->reorder_buf);
kfree(r);
return NULL;
}

View File

@ -724,25 +724,199 @@ static void wil_get_netif_rx_params(struct sk_buff *skb, int *cid,
*security = wil_rxdesc_security(d);
}
/*
* Check if skb is ptk eapol key message
*
* returns a pointer to the start of the eapol key structure, NULL
* if frame is not PTK eapol key
*/
static struct wil_eapol_key *wil_is_ptk_eapol_key(struct wil6210_priv *wil,
struct sk_buff *skb)
{
u8 *buf;
const struct wil_1x_hdr *hdr;
struct wil_eapol_key *key;
u16 key_info;
int len = skb->len;
if (!skb_mac_header_was_set(skb)) {
wil_err(wil, "mac header was not set\n");
return NULL;
}
len -= skb_mac_offset(skb);
if (len < sizeof(struct ethhdr) + sizeof(struct wil_1x_hdr) +
sizeof(struct wil_eapol_key))
return NULL;
buf = skb_mac_header(skb) + sizeof(struct ethhdr);
hdr = (const struct wil_1x_hdr *)buf;
if (hdr->type != WIL_1X_TYPE_EAPOL_KEY)
return NULL;
key = (struct wil_eapol_key *)(buf + sizeof(struct wil_1x_hdr));
if (key->type != WIL_EAPOL_KEY_TYPE_WPA &&
key->type != WIL_EAPOL_KEY_TYPE_RSN)
return NULL;
key_info = be16_to_cpu(key->key_info);
if (!(key_info & WIL_KEY_INFO_KEY_TYPE)) /* check if pairwise */
return NULL;
return key;
}
static bool wil_skb_is_eap_3(struct wil6210_priv *wil, struct sk_buff *skb)
{
struct wil_eapol_key *key;
u16 key_info;
key = wil_is_ptk_eapol_key(wil, skb);
if (!key)
return false;
key_info = be16_to_cpu(key->key_info);
if (key_info & (WIL_KEY_INFO_MIC |
WIL_KEY_INFO_ENCR_KEY_DATA)) {
/* 3/4 of 4-Way Handshake */
wil_dbg_misc(wil, "EAPOL key message 3\n");
return true;
}
/* 1/4 of 4-Way Handshake */
wil_dbg_misc(wil, "EAPOL key message 1\n");
return false;
}
static bool wil_skb_is_eap_4(struct wil6210_priv *wil, struct sk_buff *skb)
{
struct wil_eapol_key *key;
u32 *nonce, i;
key = wil_is_ptk_eapol_key(wil, skb);
if (!key)
return false;
nonce = (u32 *)key->key_nonce;
for (i = 0; i < WIL_EAP_NONCE_LEN / sizeof(u32); i++, nonce++) {
if (*nonce != 0) {
/* message 2/4 */
wil_dbg_misc(wil, "EAPOL key message 2\n");
return false;
}
}
wil_dbg_misc(wil, "EAPOL key message 4\n");
return true;
}
void wil_enable_tx_key_worker(struct work_struct *work)
{
struct wil6210_vif *vif = container_of(work,
struct wil6210_vif, enable_tx_key_worker);
struct wil6210_priv *wil = vif_to_wil(vif);
int rc, cid;
rtnl_lock();
if (vif->ptk_rekey_state != WIL_REKEY_WAIT_M4_SENT) {
wil_dbg_misc(wil, "Invalid rekey state = %d\n",
vif->ptk_rekey_state);
rtnl_unlock();
return;
}
cid = wil_find_cid_by_idx(wil, vif->mid, 0);
if (!wil_cid_valid(wil, cid)) {
wil_err(wil, "Invalid cid = %d\n", cid);
rtnl_unlock();
return;
}
wil_dbg_misc(wil, "Apply PTK key after eapol was sent out\n");
rc = wmi_add_cipher_key(vif, 0, wil->sta[cid].addr, 0, NULL,
WMI_KEY_USE_APPLY_PTK);
vif->ptk_rekey_state = WIL_REKEY_IDLE;
rtnl_unlock();
if (rc)
wil_err(wil, "Apply PTK key failed %d\n", rc);
}
void wil_tx_complete_handle_eapol(struct wil6210_vif *vif, struct sk_buff *skb)
{
struct wil6210_priv *wil = vif_to_wil(vif);
struct wireless_dev *wdev = vif_to_wdev(vif);
bool q = false;
if (wdev->iftype != NL80211_IFTYPE_STATION ||
!test_bit(WMI_FW_CAPABILITY_SPLIT_REKEY, wil->fw_capabilities))
return;
/* check if skb is an EAP message 4/4 */
if (!wil_skb_is_eap_4(wil, skb))
return;
spin_lock_bh(&wil->eap_lock);
switch (vif->ptk_rekey_state) {
case WIL_REKEY_IDLE:
/* ignore idle state, can happen due to M4 retransmission */
break;
case WIL_REKEY_M3_RECEIVED:
vif->ptk_rekey_state = WIL_REKEY_IDLE;
break;
case WIL_REKEY_WAIT_M4_SENT:
q = true;
break;
default:
wil_err(wil, "Unknown rekey state = %d",
vif->ptk_rekey_state);
}
spin_unlock_bh(&wil->eap_lock);
if (q) {
q = queue_work(wil->wmi_wq, &vif->enable_tx_key_worker);
wil_dbg_misc(wil, "queue_work of enable_tx_key_worker -> %d\n",
q);
}
}
static void wil_rx_handle_eapol(struct wil6210_vif *vif, struct sk_buff *skb)
{
struct wil6210_priv *wil = vif_to_wil(vif);
struct wireless_dev *wdev = vif_to_wdev(vif);
if (wdev->iftype != NL80211_IFTYPE_STATION ||
!test_bit(WMI_FW_CAPABILITY_SPLIT_REKEY, wil->fw_capabilities))
return;
/* check if skb is a EAP message 3/4 */
if (!wil_skb_is_eap_3(wil, skb))
return;
if (vif->ptk_rekey_state == WIL_REKEY_IDLE)
vif->ptk_rekey_state = WIL_REKEY_M3_RECEIVED;
}
/*
* Pass Rx packet to the netif. Update statistics.
* Called in softirq context (NAPI poll).
*/
void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev)
void wil_netif_rx(struct sk_buff *skb, struct net_device *ndev, int cid,
struct wil_net_stats *stats, bool gro)
{
gro_result_t rc = GRO_NORMAL;
struct wil6210_vif *vif = ndev_to_vif(ndev);
struct wil6210_priv *wil = ndev_to_wil(ndev);
struct wireless_dev *wdev = vif_to_wdev(vif);
unsigned int len = skb->len;
int cid;
int security;
u8 *sa, *da = wil_skb_get_da(skb);
/* here looking for DA, not A1, thus Rxdesc's 'mcast' indication
* is not suitable, need to look at data
*/
int mcast = is_multicast_ether_addr(da);
struct wil_net_stats *stats;
struct sk_buff *xmit_skb = NULL;
static const char * const gro_res_str[] = {
[GRO_MERGED] = "GRO_MERGED",
@ -753,25 +927,6 @@ void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev)
[GRO_CONSUMED] = "GRO_CONSUMED",
};
wil->txrx_ops.get_netif_rx_params(skb, &cid, &security);
stats = &wil->sta[cid].stats;
skb_orphan(skb);
if (security && (wil->txrx_ops.rx_crypto_check(wil, skb) != 0)) {
rc = GRO_DROP;
dev_kfree_skb(skb);
stats->rx_replay++;
goto stats;
}
/* check errors reported by HW and update statistics */
if (unlikely(wil->txrx_ops.rx_error_check(wil, skb, stats))) {
dev_kfree_skb(skb);
return;
}
if (wdev->iftype == NL80211_IFTYPE_STATION) {
sa = wil_skb_get_sa(skb);
if (mcast && ether_addr_equal(sa, ndev->dev_addr)) {
@ -817,7 +972,14 @@ void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev)
if (skb) { /* deliver to local stack */
skb->protocol = eth_type_trans(skb, ndev);
skb->dev = ndev;
rc = napi_gro_receive(&wil->napi_rx, skb);
if (skb->protocol == cpu_to_be16(ETH_P_PAE))
wil_rx_handle_eapol(vif, skb);
if (gro)
rc = napi_gro_receive(&wil->napi_rx, skb);
else
netif_rx_ni(skb);
wil_dbg_txrx(wil, "Rx complete %d bytes => %s\n",
len, gro_res_str[rc]);
}
@ -837,6 +999,36 @@ stats:
}
}
void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev)
{
int cid, security;
struct wil6210_priv *wil = ndev_to_wil(ndev);
struct wil_net_stats *stats;
wil->txrx_ops.get_netif_rx_params(skb, &cid, &security);
stats = &wil->sta[cid].stats;
skb_orphan(skb);
if (security && (wil->txrx_ops.rx_crypto_check(wil, skb) != 0)) {
dev_kfree_skb(skb);
ndev->stats.rx_dropped++;
stats->rx_replay++;
stats->rx_dropped++;
wil_dbg_txrx(wil, "Rx drop %d bytes\n", skb->len);
return;
}
/* check errors reported by HW and update statistics */
if (unlikely(wil->txrx_ops.rx_error_check(wil, skb, stats))) {
dev_kfree_skb(skb);
return;
}
wil_netif_rx(skb, ndev, cid, stats, true);
}
/**
* Proceed all completed skb's from Rx VRING
*
@ -2320,6 +2512,10 @@ int wil_tx_complete(struct wil6210_vif *vif, int ringid)
if (stats)
stats->tx_errors++;
}
if (skb->protocol == cpu_to_be16(ETH_P_PAE))
wil_tx_complete_handle_eapol(vif, skb);
wil_consume_skb(skb, d->dma.error == 0);
}
memset(ctx, 0, sizeof(*ctx));

View File

@ -423,6 +423,46 @@ struct vring_rx_mac {
#define RX_DMA_STATUS_PHY_INFO BIT(6)
#define RX_DMA_STATUS_FFM BIT(7) /* EtherType Flex Filter Match */
/* IEEE 802.11, 8.5.2 EAPOL-Key frames */
#define WIL_KEY_INFO_KEY_TYPE BIT(3) /* val of 1 = Pairwise, 0 = Group key */
#define WIL_KEY_INFO_MIC BIT(8)
#define WIL_KEY_INFO_ENCR_KEY_DATA BIT(12) /* for rsn only */
#define WIL_EAP_NONCE_LEN 32
#define WIL_EAP_KEY_RSC_LEN 8
#define WIL_EAP_REPLAY_COUNTER_LEN 8
#define WIL_EAP_KEY_IV_LEN 16
#define WIL_EAP_KEY_ID_LEN 8
enum {
WIL_1X_TYPE_EAP_PACKET = 0,
WIL_1X_TYPE_EAPOL_START = 1,
WIL_1X_TYPE_EAPOL_LOGOFF = 2,
WIL_1X_TYPE_EAPOL_KEY = 3,
};
#define WIL_EAPOL_KEY_TYPE_RSN 2
#define WIL_EAPOL_KEY_TYPE_WPA 254
struct wil_1x_hdr {
u8 version;
u8 type;
__be16 length;
/* followed by data */
} __packed;
struct wil_eapol_key {
u8 type;
__be16 key_info;
__be16 key_length;
u8 replay_counter[WIL_EAP_REPLAY_COUNTER_LEN];
u8 key_nonce[WIL_EAP_NONCE_LEN];
u8 key_iv[WIL_EAP_KEY_IV_LEN];
u8 key_rsc[WIL_EAP_KEY_RSC_LEN];
u8 key_id[WIL_EAP_KEY_ID_LEN];
} __packed;
struct vring_rx_dma {
u32 d0;
struct wil_ring_dma_addr addr;
@ -646,6 +686,8 @@ static inline void wil_skb_set_cid(struct sk_buff *skb, u8 cid)
}
void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev);
void wil_netif_rx(struct sk_buff *skb, struct net_device *ndev, int cid,
struct wil_net_stats *stats, bool gro);
void wil_rx_reorder(struct wil6210_priv *wil, struct sk_buff *skb);
void wil_rx_bar(struct wil6210_priv *wil, struct wil6210_vif *vif,
u8 cid, u8 tid, u16 seq);

View File

@ -221,10 +221,17 @@ static int wil_ring_alloc_skb_edma(struct wil6210_priv *wil,
}
static inline
void wil_get_next_rx_status_msg(struct wil_status_ring *sring, void *msg)
void wil_get_next_rx_status_msg(struct wil_status_ring *sring, u8 *dr_bit,
void *msg)
{
memcpy(msg, (void *)(sring->va + (sring->elem_size * sring->swhead)),
sring->elem_size);
struct wil_rx_status_compressed *_msg;
_msg = (struct wil_rx_status_compressed *)
(sring->va + (sring->elem_size * sring->swhead));
*dr_bit = WIL_GET_BITS(_msg->d0, 31, 31);
/* make sure dr_bit is read before the rest of status msg */
rmb();
memcpy(msg, (void *)_msg, sring->elem_size);
}
static inline void wil_sring_advance_swhead(struct wil_status_ring *sring)
@ -587,8 +594,7 @@ static bool wil_is_rx_idle_edma(struct wil6210_priv *wil)
if (!sring->va)
continue;
wil_get_next_rx_status_msg(sring, msg);
dr_bit = wil_rx_status_get_desc_rdy_bit(msg);
wil_get_next_rx_status_msg(sring, &dr_bit, msg);
/* Check if there are unhandled RX status messages */
if (dr_bit == sring->desc_rdy_pol)
@ -878,8 +884,7 @@ static struct sk_buff *wil_sring_reap_rx_edma(struct wil6210_priv *wil,
BUILD_BUG_ON(sizeof(struct wil_rx_status_extended) > sizeof(skb->cb));
again:
wil_get_next_rx_status_msg(sring, msg);
dr_bit = wil_rx_status_get_desc_rdy_bit(msg);
wil_get_next_rx_status_msg(sring, &dr_bit, msg);
/* Completed handling all the ready status messages */
if (dr_bit != sring->desc_rdy_pol)
@ -959,8 +964,8 @@ again:
}
stats = &wil->sta[cid].stats;
if (unlikely(skb->len < ETH_HLEN)) {
wil_dbg_txrx(wil, "Short frame, len = %d\n", skb->len);
if (unlikely(dmalen < ETH_HLEN)) {
wil_dbg_txrx(wil, "Short frame, len = %d\n", dmalen);
stats->rx_short_frame++;
rxdata->skipping = true;
goto skipping;
@ -1023,6 +1028,8 @@ skipping:
stats->last_mcs_rx = wil_rx_status_get_mcs(msg);
if (stats->last_mcs_rx < ARRAY_SIZE(stats->rx_per_mcs))
stats->rx_per_mcs[stats->last_mcs_rx]++;
stats->last_cb_mode_rx = wil_rx_status_get_cb_mode(msg);
}
if (!wil->use_rx_hw_reordering && !wil->use_compressed_rx_status &&
@ -1133,12 +1140,15 @@ static int wil_tx_desc_map_edma(union wil_tx_desc *desc,
}
static inline void
wil_get_next_tx_status_msg(struct wil_status_ring *sring,
wil_get_next_tx_status_msg(struct wil_status_ring *sring, u8 *dr_bit,
struct wil_ring_tx_status *msg)
{
struct wil_ring_tx_status *_msg = (struct wil_ring_tx_status *)
(sring->va + (sring->elem_size * sring->swhead));
*dr_bit = _msg->desc_ready >> TX_STATUS_DESC_READY_POS;
/* make sure dr_bit is read before the rest of status msg */
rmb();
*msg = *_msg;
}
@ -1167,8 +1177,7 @@ int wil_tx_sring_handler(struct wil6210_priv *wil,
int used_before_complete;
int used_new;
wil_get_next_tx_status_msg(sring, &msg);
dr_bit = msg.desc_ready >> TX_STATUS_DESC_READY_POS;
wil_get_next_tx_status_msg(sring, &dr_bit, &msg);
/* Process completion messages while DR bit has the expected polarity */
while (dr_bit == sring->desc_rdy_pol) {
@ -1255,6 +1264,10 @@ int wil_tx_sring_handler(struct wil6210_priv *wil,
if (stats)
stats->tx_errors++;
}
if (skb->protocol == cpu_to_be16(ETH_P_PAE))
wil_tx_complete_handle_eapol(vif, skb);
wil_consume_skb(skb, msg.status == 0);
}
memset(ctx, 0, sizeof(*ctx));
@ -1287,8 +1300,7 @@ again:
wil_sring_advance_swhead(sring);
wil_get_next_tx_status_msg(sring, &msg);
dr_bit = msg.desc_ready >> TX_STATUS_DESC_READY_POS;
wil_get_next_tx_status_msg(sring, &dr_bit, &msg);
}
/* shall we wake net queues? */

View File

@ -366,6 +366,12 @@ static inline u8 wil_rx_status_get_mcs(void *msg)
16, 21);
}
static inline u8 wil_rx_status_get_cb_mode(void *msg)
{
return WIL_GET_BITS(((struct wil_rx_status_compressed *)msg)->d1,
22, 23);
}
static inline u16 wil_rx_status_get_flow_id(void *msg)
{
return WIL_GET_BITS(((struct wil_rx_status_compressed *)msg)->d0,
@ -415,12 +421,6 @@ static inline u8 wil_rx_status_get_tid(void *msg)
return val & WIL_RX_EDMA_DLPF_LU_MISS_CID_TID_MASK;
}
static inline int wil_rx_status_get_desc_rdy_bit(void *msg)
{
return WIL_GET_BITS(((struct wil_rx_status_compressed *)msg)->d0,
31, 31);
}
static inline int wil_rx_status_get_eop(void *msg) /* EoP = End of Packet */
{
return WIL_GET_BITS(((struct wil_rx_status_compressed *)msg)->d0,

View File

@ -590,6 +590,7 @@ struct wil_net_stats {
unsigned long rx_amsdu_error; /* eDMA specific */
unsigned long rx_csum_err;
u16 last_mcs_rx;
u8 last_cb_mode_rx;
u64 rx_per_mcs[WIL_MCS_MAX + 1];
u32 ft_roams; /* relevant in STA mode */
};
@ -730,6 +731,12 @@ enum wil_sta_status {
wil_sta_connected = 2,
};
enum wil_rekey_state {
WIL_REKEY_IDLE = 0,
WIL_REKEY_M3_RECEIVED = 1,
WIL_REKEY_WAIT_M4_SENT = 2,
};
/**
* struct wil_sta_info - data for peer
*
@ -850,6 +857,7 @@ struct wil6210_vif {
DECLARE_BITMAP(status, wil_vif_status_last);
u32 privacy; /* secure connection? */
u16 channel; /* relevant in AP mode */
u8 wmi_edmg_channel; /* relevant in AP mode */
u8 hidden_ssid; /* relevant in AP mode */
u32 ap_isolate; /* no intra-BSS communication */
bool pbss;
@ -877,6 +885,10 @@ struct wil6210_vif {
int net_queue_stopped; /* netif_tx_stop_all_queues invoked */
bool fw_stats_ready; /* per-cid statistics are ready inside sta_info */
u64 fw_stats_tsf; /* measurement timestamp */
/* PTK rekey race prevention, this is relevant to station mode only */
enum wil_rekey_state ptk_rekey_state;
struct work_struct enable_tx_key_worker;
};
/**
@ -977,6 +989,7 @@ struct wil6210_priv {
*/
spinlock_t wmi_ev_lock;
spinlock_t net_queue_lock; /* guarding stop/wake netif queue */
spinlock_t eap_lock; /* guarding access to eap rekey fields */
struct napi_struct napi_rx;
struct napi_struct napi_tx;
struct net_device napi_ndev; /* dummy net_device serving all VIFs */
@ -1144,7 +1157,7 @@ static inline void wil_c(struct wil6210_priv *wil, u32 reg, u32 val)
/**
* wil_cid_valid - check cid is valid
*/
static inline bool wil_cid_valid(struct wil6210_priv *wil, u8 cid)
static inline bool wil_cid_valid(struct wil6210_priv *wil, int cid)
{
return (cid >= 0 && cid < wil->max_assoc_sta);
}
@ -1224,6 +1237,7 @@ int __wil_down(struct wil6210_priv *wil);
void wil_refresh_fw_capabilities(struct wil6210_priv *wil);
void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r);
int wil_find_cid(struct wil6210_priv *wil, u8 mid, const u8 *mac);
int wil_find_cid_by_idx(struct wil6210_priv *wil, u8 mid, int idx);
void wil_set_ethtoolops(struct net_device *ndev);
struct fw_map *wil_find_fw_mapping(const char *section);
@ -1335,7 +1349,7 @@ void wil_p2p_wdev_free(struct wil6210_priv *wil);
int wmi_set_mac_address(struct wil6210_priv *wil, void *addr);
int wmi_pcp_start(struct wil6210_vif *vif, int bi, u8 wmi_nettype, u8 chan,
u8 hidden_ssid, u8 is_go);
u8 edmg_chan, u8 hidden_ssid, u8 is_go);
int wmi_pcp_stop(struct wil6210_vif *vif);
int wmi_led_cfg(struct wil6210_priv *wil, bool enable);
int wmi_abort_scan(struct wil6210_vif *vif);
@ -1349,6 +1363,7 @@ void wil6210_disconnect_complete(struct wil6210_vif *vif, const u8 *bssid,
void wil_probe_client_flush(struct wil6210_vif *vif);
void wil_probe_client_worker(struct work_struct *work);
void wil_disconnect_worker(struct work_struct *work);
void wil_enable_tx_key_worker(struct work_struct *work);
void wil_init_txrx_ops(struct wil6210_priv *wil);
@ -1365,6 +1380,8 @@ void wil_update_net_queues_bh(struct wil6210_priv *wil, struct wil6210_vif *vif,
struct wil_ring *ring, bool check_stop);
netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev);
int wil_tx_complete(struct wil6210_vif *vif, int ringid);
void wil_tx_complete_handle_eapol(struct wil6210_vif *vif,
struct sk_buff *skb);
void wil6210_unmask_irq_tx(struct wil6210_priv *wil);
void wil6210_unmask_irq_tx_edma(struct wil6210_priv *wil);
@ -1412,6 +1429,10 @@ int wmi_mgmt_tx_ext(struct wil6210_vif *vif, const u8 *buf, size_t len,
u8 channel, u16 duration_ms);
int wmi_rbufcap_cfg(struct wil6210_priv *wil, bool enable, u16 threshold);
int wil_wmi2spec_ch(u8 wmi_ch, u8 *spec_ch);
int wil_spec2wmi_ch(u8 spec_ch, u8 *wmi_ch);
void wil_update_supported_bands(struct wil6210_priv *wil);
int reverse_memcmp(const void *cs, const void *ct, size_t count);
/* WMI for enhanced DMA */

View File

@ -878,6 +878,12 @@ static void wmi_evt_rx_mgmt(struct wil6210_vif *vif, int id, void *d, int len)
if (ieee80211_is_beacon(fc) || ieee80211_is_probe_resp(fc)) {
struct cfg80211_bss *bss;
struct cfg80211_inform_bss bss_data = {
.chan = channel,
.scan_width = NL80211_BSS_CHAN_WIDTH_20,
.signal = signal,
.boottime_ns = ktime_to_ns(ktime_get_boottime()),
};
u64 tsf = le64_to_cpu(rx_mgmt_frame->u.beacon.timestamp);
u16 cap = le16_to_cpu(rx_mgmt_frame->u.beacon.capab_info);
u16 bi = le16_to_cpu(rx_mgmt_frame->u.beacon.beacon_int);
@ -892,8 +898,9 @@ static void wmi_evt_rx_mgmt(struct wil6210_vif *vif, int id, void *d, int len)
wil_dbg_wmi(wil, "Capability info : 0x%04x\n", cap);
bss = cfg80211_inform_bss_frame(wiphy, channel, rx_mgmt_frame,
d_len, signal, GFP_KERNEL);
bss = cfg80211_inform_bss_frame_data(wiphy, &bss_data,
rx_mgmt_frame,
d_len, GFP_KERNEL);
if (bss) {
wil_dbg_wmi(wil, "Added BSS %pM\n",
rx_mgmt_frame->bssid);
@ -1332,6 +1339,12 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
cid = evt->cid;
tid = evt->tid;
}
if (!wil_cid_valid(wil, cid)) {
wil_err(wil, "DELBA: Invalid CID %d\n", cid);
return;
}
wil_dbg_wmi(wil, "DELBA MID %d CID %d TID %d from %s reason %d\n",
vif->mid, cid, tid,
evt->from_initiator ? "originator" : "recipient",
@ -1385,6 +1398,10 @@ wmi_evt_sched_scan_result(struct wil6210_vif *vif, int id, void *d, int len)
__le16 fc;
u32 d_len;
struct cfg80211_bss *bss;
struct cfg80211_inform_bss bss_data = {
.scan_width = NL80211_BSS_CHAN_WIDTH_20,
.boottime_ns = ktime_to_ns(ktime_get_boottime()),
};
if (flen < 0) {
wil_err(wil, "sched scan result event too short, len %d\n",
@ -1427,8 +1444,10 @@ wmi_evt_sched_scan_result(struct wil6210_vif *vif, int id, void *d, int len)
return;
}
bss = cfg80211_inform_bss_frame(wiphy, channel, rx_mgmt_frame,
d_len, signal, GFP_KERNEL);
bss_data.signal = signal;
bss_data.chan = channel;
bss = cfg80211_inform_bss_frame_data(wiphy, &bss_data, rx_mgmt_frame,
d_len, GFP_KERNEL);
if (bss) {
wil_dbg_wmi(wil, "Added BSS %pM\n", rx_mgmt_frame->bssid);
cfg80211_put_bss(wiphy, bss);
@ -2163,8 +2182,8 @@ int wmi_rbufcap_cfg(struct wil6210_priv *wil, bool enable, u16 threshold)
return rc;
}
int wmi_pcp_start(struct wil6210_vif *vif,
int bi, u8 wmi_nettype, u8 chan, u8 hidden_ssid, u8 is_go)
int wmi_pcp_start(struct wil6210_vif *vif, int bi, u8 wmi_nettype,
u8 chan, u8 wmi_edmg_chan, u8 hidden_ssid, u8 is_go)
{
struct wil6210_priv *wil = vif_to_wil(vif);
int rc;
@ -2174,6 +2193,7 @@ int wmi_pcp_start(struct wil6210_vif *vif,
.network_type = wmi_nettype,
.disable_sec_offload = 1,
.channel = chan - 1,
.edmg_channel = wmi_edmg_chan,
.pcp_max_assoc_sta = wil->max_assoc_sta,
.hidden_ssid = hidden_ssid,
.is_go = is_go,
@ -2437,10 +2457,17 @@ int wmi_add_cipher_key(struct wil6210_vif *vif, u8 key_index,
.key_len = key_len,
};
if (!key || (key_len > sizeof(cmd.key)))
if (key_len > sizeof(cmd.key))
return -EINVAL;
memcpy(cmd.key, key, key_len);
/* key len = 0 is allowed only for usage of WMI_KEY_USE_APPLY */
if ((key_len == 0 || !key) &&
key_usage != WMI_KEY_USE_APPLY_PTK)
return -EINVAL;
if (key)
memcpy(cmd.key, key, key_len);
if (mac_addr)
memcpy(cmd.mac, mac_addr, WMI_MAC_LEN);

View File

@ -97,6 +97,7 @@ enum wmi_fw_capability {
WMI_FW_CAPABILITY_SET_SILENT_RSSI_TABLE = 13,
WMI_FW_CAPABILITY_LO_POWER_CALIB_FROM_OTP = 14,
WMI_FW_CAPABILITY_PNO = 15,
WMI_FW_CAPABILITY_CHANNEL_BONDING = 17,
WMI_FW_CAPABILITY_REF_CLOCK_CONTROL = 18,
WMI_FW_CAPABILITY_AP_SME_OFFLOAD_NONE = 19,
WMI_FW_CAPABILITY_MULTI_VIFS = 20,
@ -108,6 +109,7 @@ enum wmi_fw_capability {
WMI_FW_CAPABILITY_CHANNEL_4 = 26,
WMI_FW_CAPABILITY_IPA = 27,
WMI_FW_CAPABILITY_TEMPERATURE_ALL_RF = 30,
WMI_FW_CAPABILITY_SPLIT_REKEY = 31,
WMI_FW_CAPABILITY_MAX,
};
@ -361,6 +363,19 @@ enum wmi_connect_ctrl_flag_bits {
#define WMI_MAX_SSID_LEN (32)
enum wmi_channel {
WMI_CHANNEL_1 = 0x00,
WMI_CHANNEL_2 = 0x01,
WMI_CHANNEL_3 = 0x02,
WMI_CHANNEL_4 = 0x03,
WMI_CHANNEL_5 = 0x04,
WMI_CHANNEL_6 = 0x05,
WMI_CHANNEL_9 = 0x06,
WMI_CHANNEL_10 = 0x07,
WMI_CHANNEL_11 = 0x08,
WMI_CHANNEL_12 = 0x09,
};
/* WMI_CONNECT_CMDID */
struct wmi_connect_cmd {
u8 network_type;
@ -372,8 +387,12 @@ struct wmi_connect_cmd {
u8 group_crypto_len;
u8 ssid_len;
u8 ssid[WMI_MAX_SSID_LEN];
/* enum wmi_channel WMI_CHANNEL_1..WMI_CHANNEL_6; for EDMG this is
* the primary channel number
*/
u8 channel;
u8 reserved0;
/* enum wmi_channel WMI_CHANNEL_9..WMI_CHANNEL_12 */
u8 edmg_channel;
u8 bssid[WMI_MAC_LEN];
__le32 ctrl_flags;
u8 dst_mac[WMI_MAC_LEN];
@ -403,6 +422,8 @@ enum wmi_key_usage {
WMI_KEY_USE_PAIRWISE = 0x00,
WMI_KEY_USE_RX_GROUP = 0x01,
WMI_KEY_USE_TX_GROUP = 0x02,
WMI_KEY_USE_STORE_PTK = 0x03,
WMI_KEY_USE_APPLY_PTK = 0x04,
};
struct wmi_add_cipher_key_cmd {
@ -2312,8 +2333,12 @@ struct wmi_notify_req_done_event {
/* WMI_CONNECT_EVENTID */
struct wmi_connect_event {
/* enum wmi_channel WMI_CHANNEL_1..WMI_CHANNEL_6; for EDMG this is
* the primary channel number
*/
u8 channel;
u8 reserved0;
/* enum wmi_channel WMI_CHANNEL_9..WMI_CHANNEL_12 */
u8 edmg_channel;
u8 bssid[WMI_MAC_LEN];
__le16 listen_interval;
__le16 beacon_interval;

View File

@ -253,10 +253,12 @@ void brcmf_rx_frame(struct device *dev, struct sk_buff *rxp, bool handle_event);
/* Receive async event packet from firmware. Callee disposes of rxp. */
void brcmf_rx_event(struct device *dev, struct sk_buff *rxp);
int brcmf_alloc(struct device *dev, struct brcmf_mp_device *settings);
/* Indication from bus module regarding presence/insertion of dongle. */
int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings);
int brcmf_attach(struct device *dev);
/* Indication from bus module regarding removal/absence of dongle */
void brcmf_detach(struct device *dev);
void brcmf_free(struct device *dev);
/* Indication from bus module that dongle should be reset */
void brcmf_dev_reset(struct device *dev);
/* Request from bus module to initiate a coredump */

View File

@ -7202,7 +7202,6 @@ void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
brcmf_pno_detach(cfg);
brcmf_btcoex_detach(cfg);
wiphy_unregister(cfg->wiphy);
kfree(cfg->ops);
wl_deinit_priv(cfg);
brcmf_free_wiphy(cfg->wiphy);
kfree(cfg);

View File

@ -292,7 +292,6 @@ struct brcmf_cfg80211_wowl {
*/
struct brcmf_cfg80211_info {
struct wiphy *wiphy;
struct cfg80211_ops *ops;
struct brcmf_cfg80211_conf *conf;
struct brcmf_p2p_info p2p;
struct brcmf_btcoex_info *btcoex;

View File

@ -1209,13 +1209,11 @@ fail:
return ret;
}
int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings)
int brcmf_alloc(struct device *dev, struct brcmf_mp_device *settings)
{
struct wiphy *wiphy;
struct cfg80211_ops *ops;
struct brcmf_pub *drvr = NULL;
int ret = 0;
int i;
brcmf_dbg(TRACE, "Enter\n");
@ -1224,12 +1222,30 @@ int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings)
return -ENOMEM;
wiphy = wiphy_new(ops, sizeof(*drvr));
if (!wiphy)
if (!wiphy) {
kfree(ops);
return -ENOMEM;
}
set_wiphy_dev(wiphy, dev);
drvr = wiphy_priv(wiphy);
drvr->wiphy = wiphy;
drvr->ops = ops;
drvr->bus_if = dev_get_drvdata(dev);
drvr->bus_if->drvr = drvr;
drvr->settings = settings;
return 0;
}
int brcmf_attach(struct device *dev)
{
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
struct brcmf_pub *drvr = bus_if->drvr;
int ret = 0;
int i;
brcmf_dbg(TRACE, "Enter\n");
for (i = 0; i < ARRAY_SIZE(drvr->if2bss); i++)
drvr->if2bss[i] = BRCMF_BSSIDX_INVALID;
@ -1238,9 +1254,6 @@ int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings)
/* Link to bus module */
drvr->hdrlen = 0;
drvr->bus_if = dev_get_drvdata(dev);
drvr->bus_if->drvr = drvr;
drvr->settings = settings;
/* Attach and link in the protocol */
ret = brcmf_proto_attach(drvr);
@ -1256,18 +1269,16 @@ int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings)
/* attach firmware event handler */
brcmf_fweh_attach(drvr);
ret = brcmf_bus_started(drvr, ops);
ret = brcmf_bus_started(drvr, drvr->ops);
if (ret != 0) {
bphy_err(drvr, "dongle is not responding: err=%d\n", ret);
goto fail;
}
drvr->config->ops = ops;
return 0;
fail:
brcmf_detach(dev);
kfree(ops);
return ret;
}
@ -1350,9 +1361,20 @@ void brcmf_detach(struct device *dev)
brcmf_cfg80211_detach(drvr->config);
drvr->config = NULL;
}
}
void brcmf_free(struct device *dev)
{
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
struct brcmf_pub *drvr = bus_if->drvr;
if (!drvr)
return;
bus_if->drvr = NULL;
kfree(drvr->ops);
wiphy_free(drvr->wiphy);
}

View File

@ -97,6 +97,7 @@ struct brcmf_pub {
struct brcmf_bus *bus_if;
struct brcmf_proto *proto;
struct wiphy *wiphy;
struct cfg80211_ops *ops;
struct brcmf_cfg80211_info *config;
/* Internal brcmf items */

View File

@ -1824,11 +1824,15 @@ static void brcmf_pcie_setup(struct device *dev, int ret,
brcmf_pcie_intr_enable(devinfo);
brcmf_pcie_hostready(devinfo);
if (brcmf_attach(&devinfo->pdev->dev, devinfo->settings) == 0)
return;
ret = brcmf_attach(&devinfo->pdev->dev);
if (ret)
goto fail;
brcmf_pcie_bus_console_read(devinfo, false);
return;
fail:
device_release_driver(dev);
}
@ -1923,6 +1927,10 @@ brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
bus->wowl_supported = pci_pme_capable(pdev, PCI_D3hot);
dev_set_drvdata(&pdev->dev, bus);
ret = brcmf_alloc(&devinfo->pdev->dev, devinfo->settings);
if (ret)
goto fail_bus;
fwreq = brcmf_pcie_prepare_fw_request(devinfo);
if (!fwreq) {
ret = -ENOMEM;
@ -1971,6 +1979,7 @@ brcmf_pcie_remove(struct pci_dev *pdev)
brcmf_pcie_intr_disable(devinfo);
brcmf_detach(&pdev->dev);
brcmf_free(&pdev->dev);
kfree(bus->bus_priv.pcie);
kfree(bus->msgbuf->flowrings);

View File

@ -4247,17 +4247,26 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err,
sdiod->bus_if->chip = bus->ci->chip;
sdiod->bus_if->chiprev = bus->ci->chiprev;
err = brcmf_alloc(sdiod->dev, sdiod->settings);
if (err) {
brcmf_err("brcmf_alloc failed\n");
goto claim;
}
/* Attach to the common layer, reserve hdr space */
err = brcmf_attach(sdiod->dev, sdiod->settings);
err = brcmf_attach(sdiod->dev);
if (err != 0) {
brcmf_err("brcmf_attach failed\n");
sdio_claim_host(sdiod->func1);
goto checkdied;
goto free;
}
/* ready */
return;
free:
brcmf_free(sdiod->dev);
claim:
sdio_claim_host(sdiod->func1);
checkdied:
brcmf_sdio_checkdied(bus);
release:

View File

@ -1178,8 +1178,12 @@ static void brcmf_usb_probe_phase2(struct device *dev, int ret,
if (ret)
goto error;
ret = brcmf_alloc(devinfo->dev, devinfo->settings);
if (ret)
goto error;
/* Attach to the common driver interface */
ret = brcmf_attach(devinfo->dev, devinfo->settings);
ret = brcmf_attach(devinfo->dev);
if (ret)
goto error;
@ -1251,7 +1255,10 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)
}
if (!brcmf_usb_dlneeded(devinfo)) {
ret = brcmf_attach(devinfo->dev, devinfo->settings);
ret = brcmf_alloc(devinfo->dev, devinfo->settings);
if (ret)
goto fail;
ret = brcmf_attach(devinfo->dev);
if (ret)
goto fail;
/* we are done */
@ -1279,6 +1286,7 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)
fail:
/* Release resources in reverse order */
brcmf_free(devinfo->dev);
kfree(bus);
brcmf_usb_detach(devinfo);
return ret;
@ -1292,6 +1300,7 @@ brcmf_usb_disconnect_cb(struct brcmf_usbdev_info *devinfo)
brcmf_dbg(USB, "Enter, bus_pub %p\n", devinfo);
brcmf_detach(devinfo->dev);
brcmf_free(devinfo->dev);
kfree(devinfo->bus_pub.bus);
brcmf_usb_detach(devinfo);
}
@ -1435,10 +1444,12 @@ static int brcmf_usb_suspend(struct usb_interface *intf, pm_message_t state)
brcmf_dbg(USB, "Enter\n");
devinfo->bus_pub.state = BRCMFMAC_USB_STATE_SLEEP;
if (devinfo->wowl_enabled)
if (devinfo->wowl_enabled) {
brcmf_cancel_all_urbs(devinfo);
else
} else {
brcmf_detach(&usb->dev);
brcmf_free(&usb->dev);
}
return 0;
}
@ -1451,8 +1462,19 @@ static int brcmf_usb_resume(struct usb_interface *intf)
struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev);
brcmf_dbg(USB, "Enter\n");
if (!devinfo->wowl_enabled)
return brcmf_attach(devinfo->dev, devinfo->settings);
if (!devinfo->wowl_enabled) {
int err;
err = brcmf_alloc(&usb->dev, devinfo->settings);
if (err)
return err;
err = brcmf_attach(devinfo->dev);
if (err) {
brcmf_free(devinfo->dev);
return err;
}
}
devinfo->bus_pub.state = BRCMFMAC_USB_STATE_UP;
brcmf_usb_rx_fill_all(devinfo);

View File

@ -17748,7 +17748,7 @@ static void wlc_phy_txpwrctrl_pwr_setup_nphy(struct brcms_phy *pi)
num = 8 *
(16 * b0[tbl_id - 26] + b1[tbl_id - 26] * idx);
den = 32768 + a1[tbl_id - 26] * idx;
pwr_est = max(((4 * num + den / 2) / den), -8);
pwr_est = max(DIV_ROUND_CLOSEST(4 * num, den), -8);
if (NREV_LT(pi->pubpi.phy_rev, 3)) {
if (idx <=
(uint) (31 - idle_tssi[tbl_id - 26] + 1))
@ -26990,8 +26990,8 @@ wlc_phy_rxcal_gainctrl_nphy_rev5(struct brcms_phy *pi, u8 rx_core,
NPHY_RXCAL_TONEAMP, 0, cal_type, false);
wlc_phy_rx_iq_est_nphy(pi, est, num_samps, 32, 0);
i_pwr = (est[rx_core].i_pwr + num_samps / 2) / num_samps;
q_pwr = (est[rx_core].q_pwr + num_samps / 2) / num_samps;
i_pwr = DIV_ROUND_CLOSEST(est[rx_core].i_pwr, num_samps);
q_pwr = DIV_ROUND_CLOSEST(est[rx_core].q_pwr, num_samps);
curr_pwr = i_pwr + q_pwr;
switch (gainctrl_dirn) {
@ -27673,10 +27673,10 @@ wlc_phy_cal_rxiq_nphy_rev2(struct brcms_phy *pi,
wlc_phy_rx_iq_est_nphy(pi, est,
num_samps, 32,
0);
i_pwr = (est[rx_core].i_pwr +
num_samps / 2) / num_samps;
q_pwr = (est[rx_core].q_pwr +
num_samps / 2) / num_samps;
i_pwr = DIV_ROUND_CLOSEST(est[rx_core].i_pwr,
num_samps);
q_pwr = DIV_ROUND_CLOSEST(est[rx_core].q_pwr,
num_samps);
tot_pwr[gain_pass] = i_pwr + q_pwr;
} else {

View File

@ -58,8 +58,6 @@ struct lbs_private {
#ifdef CONFIG_LIBERTAS_MESH
struct lbs_mesh_stats mstats;
uint16_t mesh_tlv;
u8 mesh_ssid[IEEE80211_MAX_SSID_LEN + 1];
u8 mesh_ssid_len;
u8 mesh_channel;
#endif

View File

@ -86,6 +86,7 @@ static int lbs_mesh_config_send(struct lbs_private *priv,
static int lbs_mesh_config(struct lbs_private *priv, uint16_t action,
uint16_t chan)
{
struct wireless_dev *mesh_wdev;
struct cmd_ds_mesh_config cmd;
struct mrvl_meshie *ie;
@ -105,10 +106,17 @@ static int lbs_mesh_config(struct lbs_private *priv, uint16_t action,
ie->val.active_protocol_id = MARVELL_MESH_PROTO_ID_HWMP;
ie->val.active_metric_id = MARVELL_MESH_METRIC_ID;
ie->val.mesh_capability = MARVELL_MESH_CAPABILITY;
ie->val.mesh_id_len = priv->mesh_ssid_len;
memcpy(ie->val.mesh_id, priv->mesh_ssid, priv->mesh_ssid_len);
if (priv->mesh_dev) {
mesh_wdev = priv->mesh_dev->ieee80211_ptr;
ie->val.mesh_id_len = mesh_wdev->mesh_id_up_len;
memcpy(ie->val.mesh_id, mesh_wdev->ssid,
mesh_wdev->mesh_id_up_len);
}
ie->len = sizeof(struct mrvl_meshie_val) -
IEEE80211_MAX_SSID_LEN + priv->mesh_ssid_len;
IEEE80211_MAX_SSID_LEN + ie->val.mesh_id_len;
cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie_val));
break;
case CMD_ACT_MESH_CONFIG_STOP:
@ -117,8 +125,8 @@ static int lbs_mesh_config(struct lbs_private *priv, uint16_t action,
return -1;
}
lbs_deb_cmd("mesh config action %d type %x channel %d SSID %*pE\n",
action, priv->mesh_tlv, chan, priv->mesh_ssid_len,
priv->mesh_ssid);
action, priv->mesh_tlv, chan, ie->val.mesh_id_len,
ie->val.mesh_id);
return __lbs_mesh_config_send(priv, &cmd, action, priv->mesh_tlv);
}
@ -863,12 +871,6 @@ int lbs_init_mesh(struct lbs_private *priv)
/* Stop meshing until interface is brought up */
lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_STOP, 1);
if (priv->mesh_tlv) {
sprintf(priv->mesh_ssid, "mesh");
priv->mesh_ssid_len = 4;
ret = 1;
}
return ret;
}
@ -997,6 +999,13 @@ static int lbs_add_mesh(struct lbs_private *priv)
mesh_wdev->iftype = NL80211_IFTYPE_MESH_POINT;
mesh_wdev->wiphy = priv->wdev->wiphy;
if (priv->mesh_tlv) {
sprintf(mesh_wdev->ssid, "mesh");
mesh_wdev->mesh_id_up_len = 4;
ret = 1;
}
mesh_wdev->netdev = mesh_dev;
mesh_dev->ml_priv = priv;

View File

@ -24,8 +24,7 @@ void lbs_remove_mesh(struct lbs_private *priv);
static inline bool lbs_mesh_activated(struct lbs_private *priv)
{
/* Mesh SSID is only programmed after successful init */
return priv->mesh_ssid_len != 0;
return !!priv->mesh_tlv;
}
int lbs_mesh_set_channel(struct lbs_private *priv, u8 channel);

View File

@ -46,15 +46,6 @@ enum ap_peer {
#define MAX_LISTEN_INTERVAL 10
#define MAX_RATE_TRIES 4
#define SET_80211_HDR_FRAME_CONTROL(_hdr, _val) \
WRITEEF2BYTE(_hdr, _val)
#define SET_80211_HDR_TYPE_AND_SUBTYPE(_hdr, _val) \
WRITEEF1BYTE(_hdr, _val)
#define SET_80211_HDR_PWR_MGNT(_hdr, _val) \
SET_BITS_TO_LE_2BYTE(_hdr, 12, 1, _val)
#define SET_80211_HDR_TO_DS(_hdr, _val) \
SET_BITS_TO_LE_2BYTE(_hdr, 8, 1, _val)
#define SET_80211_PS_POLL_AID(_hdr, _val) \
(*(u16 *)((u8 *)(_hdr) + 2) = _val)
#define SET_80211_PS_POLL_BSSID(_hdr, _val) \
@ -62,30 +53,12 @@ enum ap_peer {
#define SET_80211_PS_POLL_TA(_hdr, _val) \
ether_addr_copy(((u8 *)(_hdr))+10, (u8 *)(_val))
#define SET_80211_HDR_DURATION(_hdr, _val) \
(*(u16 *)((u8 *)(_hdr) + FRAME_OFFSET_DURATION) = le16_to_cpu(_val))
#define SET_80211_HDR_ADDRESS1(_hdr, _val) \
CP_MACADDR((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS1, (u8 *)(_val))
#define SET_80211_HDR_ADDRESS2(_hdr, _val) \
CP_MACADDR((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS2, (u8 *)(_val))
#define SET_80211_HDR_ADDRESS3(_hdr, _val) \
CP_MACADDR((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS3, (u8 *)(_val))
#define SET_80211_HDR_FRAGMENT_SEQUENCE(_hdr, _val) \
WRITEEF2BYTE((u8 *)(_hdr)+FRAME_OFFSET_SEQUENCE, _val)
#define SET_BEACON_PROBE_RSP_TIME_STAMP_LOW(__phdr, __val) \
WRITEEF4BYTE(((u8 *)(__phdr)) + 24, __val)
#define SET_BEACON_PROBE_RSP_TIME_STAMP_HIGH(__phdr, __val) \
WRITEEF4BYTE(((u8 *)(__phdr)) + 28, __val)
#define SET_BEACON_PROBE_RSP_BEACON_INTERVAL(__phdr, __val) \
WRITEEF2BYTE(((u8 *)(__phdr)) + 32, __val)
#define GET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr) \
READEF2BYTE(((u8 *)(__phdr)) + 34)
#define SET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, __val) \
WRITEEF2BYTE(((u8 *)(__phdr)) + 34, __val)
#define MASK_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, __val) \
SET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, \
(GET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr) & (~(__val))))
#define SET_TX_DESC_SPE_RPT(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE((__pdesc) + 8, 19, 1, __val)

View File

@ -12,35 +12,6 @@
#define RX_CMD_QUEUE 1
#define C2H_RX_CMD_HDR_LEN 8
#define GET_C2H_CMD_CMD_LEN(__prxhdr) \
LE_BITS_TO_4BYTE((__prxhdr), 0, 16)
#define GET_C2H_CMD_ELEMENT_ID(__prxhdr) \
LE_BITS_TO_4BYTE((__prxhdr), 16, 8)
#define GET_C2H_CMD_CMD_SEQ(__prxhdr) \
LE_BITS_TO_4BYTE((__prxhdr), 24, 7)
#define GET_C2H_CMD_CONTINUE(__prxhdr) \
LE_BITS_TO_4BYTE((__prxhdr), 31, 1)
#define GET_C2H_CMD_CONTENT(__prxhdr) \
((u8 *)(__prxhdr) + C2H_RX_CMD_HDR_LEN)
#define GET_C2H_CMD_FEEDBACK_ELEMENT_ID(__pcmdfbhdr) \
LE_BITS_TO_4BYTE((__pcmdfbhdr), 0, 8)
#define GET_C2H_CMD_FEEDBACK_CCX_LEN(__pcmdfbhdr) \
LE_BITS_TO_4BYTE((__pcmdfbhdr), 8, 8)
#define GET_C2H_CMD_FEEDBACK_CCX_CMD_CNT(__pcmdfbhdr) \
LE_BITS_TO_4BYTE((__pcmdfbhdr), 16, 16)
#define GET_C2H_CMD_FEEDBACK_CCX_MAC_ID(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 0, 5)
#define GET_C2H_CMD_FEEDBACK_CCX_VALID(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 7, 1)
#define GET_C2H_CMD_FEEDBACK_CCX_RETRY_CNT(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 8, 5)
#define GET_C2H_CMD_FEEDBACK_CCX_TOK(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 15, 1)
#define GET_C2H_CMD_FEEDBACK_CCX_QSEL(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 16, 4)
#define GET_C2H_CMD_FEEDBACK_CCX_SEQ(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 20, 12)
#define CHIP_BONDING_IDENTIFIER(_value) (((_value)>>22)&0x3)

View File

@ -17,39 +17,6 @@
#define RX_MPDU_QUEUE 0
#define RX_CMD_QUEUE 1
#define C2H_RX_CMD_HDR_LEN 8
#define GET_C2H_CMD_CMD_LEN(__prxhdr) \
LE_BITS_TO_4BYTE((__prxhdr), 0, 16)
#define GET_C2H_CMD_ELEMENT_ID(__prxhdr) \
LE_BITS_TO_4BYTE((__prxhdr), 16, 8)
#define GET_C2H_CMD_CMD_SEQ(__prxhdr) \
LE_BITS_TO_4BYTE((__prxhdr), 24, 7)
#define GET_C2H_CMD_CONTINUE(__prxhdr) \
LE_BITS_TO_4BYTE((__prxhdr), 31, 1)
#define GET_C2H_CMD_CONTENT(__prxhdr) \
((u8 *)(__prxhdr) + C2H_RX_CMD_HDR_LEN)
#define GET_C2H_CMD_FEEDBACK_ELEMENT_ID(__pcmdfbhdr) \
LE_BITS_TO_4BYTE((__pcmdfbhdr), 0, 8)
#define GET_C2H_CMD_FEEDBACK_CCX_LEN(__pcmdfbhdr) \
LE_BITS_TO_4BYTE((__pcmdfbhdr), 8, 8)
#define GET_C2H_CMD_FEEDBACK_CCX_CMD_CNT(__pcmdfbhdr) \
LE_BITS_TO_4BYTE((__pcmdfbhdr), 16, 16)
#define GET_C2H_CMD_FEEDBACK_CCX_MAC_ID(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 0, 5)
#define GET_C2H_CMD_FEEDBACK_CCX_VALID(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 7, 1)
#define GET_C2H_CMD_FEEDBACK_CCX_RETRY_CNT(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 8, 5)
#define GET_C2H_CMD_FEEDBACK_CCX_TOK(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 15, 1)
#define GET_C2H_CMD_FEEDBACK_CCX_QSEL(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 16, 4)
#define GET_C2H_CMD_FEEDBACK_CCX_SEQ(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 20, 12)
#define GET_RX_STATUS_DESC_BUFF_ADDR(__pdesc) \
SHIFT_AND_MASK_LE(__pdesc + 24, 0, 32)
#define CHIP_VER_B BIT(4)
#define CHIP_BONDING_IDENTIFIER(_value) (((_value) >> 22) & 0x3)
#define CHIP_BONDING_92C_1T2R 0x1

View File

@ -33,27 +33,6 @@ static u8 _rtl92c_query_rxpwrpercentage(s8 antpower)
return 100 + antpower;
}
static u8 _rtl92c_evm_db_to_percentage(s8 value)
{
s8 ret_val;
ret_val = value;
if (ret_val >= 0)
ret_val = 0;
if (ret_val <= -33)
ret_val = -33;
ret_val = 0 - ret_val;
ret_val *= 3;
if (ret_val == 99)
ret_val = 100;
return ret_val;
}
static long _rtl92ce_signal_scale_mapping(struct ieee80211_hw *hw,
long currsig)
{
@ -243,7 +222,7 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw,
max_spatial_stream = 1;
for (i = 0; i < max_spatial_stream; i++) {
evm = _rtl92c_evm_db_to_percentage(p_drvinfo->rxevm[i]);
evm = rtl_evm_db_to_percentage(p_drvinfo->rxevm[i]);
if (packet_match_bssid) {
/* Fill value in RFD, Get the first

View File

@ -577,22 +577,6 @@ static u8 _rtl92c_query_rxpwrpercentage(s8 antpower)
return 100 + antpower;
}
static u8 _rtl92c_evm_db_to_percentage(s8 value)
{
s8 ret_val;
ret_val = value;
if (ret_val >= 0)
ret_val = 0;
if (ret_val <= -33)
ret_val = -33;
ret_val = 0 - ret_val;
ret_val *= 3;
if (ret_val == 99)
ret_val = 100;
return ret_val;
}
static long _rtl92c_signal_scale_mapping(struct ieee80211_hw *hw,
long currsig)
{
@ -743,7 +727,7 @@ static void _rtl92c_query_rxphystatus(struct ieee80211_hw *hw,
else
max_spatial_stream = 1;
for (i = 0; i < max_spatial_stream; i++) {
evm = _rtl92c_evm_db_to_percentage(p_drvinfo->rxevm[i]);
evm = rtl_evm_db_to_percentage(p_drvinfo->rxevm[i]);
if (packet_match_bssid) {
if (i == 0)
pstats->signalquality =

View File

@ -26,37 +26,6 @@
#define RX_MPDU_QUEUE 0
#define RX_CMD_QUEUE 1
#define C2H_RX_CMD_HDR_LEN 8
#define GET_C2H_CMD_CMD_LEN(__prxhdr) \
LE_BITS_TO_4BYTE((__prxhdr), 0, 16)
#define GET_C2H_CMD_ELEMENT_ID(__prxhdr) \
LE_BITS_TO_4BYTE((__prxhdr), 16, 8)
#define GET_C2H_CMD_CMD_SEQ(__prxhdr) \
LE_BITS_TO_4BYTE((__prxhdr), 24, 7)
#define GET_C2H_CMD_CONTINUE(__prxhdr) \
LE_BITS_TO_4BYTE((__prxhdr), 31, 1)
#define GET_C2H_CMD_CONTENT(__prxhdr) \
((u8 *)(__prxhdr) + C2H_RX_CMD_HDR_LEN)
#define GET_C2H_CMD_FEEDBACK_ELEMENT_ID(__pcmdfbhdr) \
LE_BITS_TO_4BYTE((__pcmdfbhdr), 0, 8)
#define GET_C2H_CMD_FEEDBACK_CCX_LEN(__pcmdfbhdr) \
LE_BITS_TO_4BYTE((__pcmdfbhdr), 8, 8)
#define GET_C2H_CMD_FEEDBACK_CCX_CMD_CNT(__pcmdfbhdr) \
LE_BITS_TO_4BYTE((__pcmdfbhdr), 16, 16)
#define GET_C2H_CMD_FEEDBACK_CCX_MAC_ID(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 0, 5)
#define GET_C2H_CMD_FEEDBACK_CCX_VALID(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 7, 1)
#define GET_C2H_CMD_FEEDBACK_CCX_RETRY_CNT(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 8, 5)
#define GET_C2H_CMD_FEEDBACK_CCX_TOK(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 15, 1)
#define GET_C2H_CMD_FEEDBACK_CCX_QSEL(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 16, 4)
#define GET_C2H_CMD_FEEDBACK_CCX_SEQ(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 20, 12)
enum version_8192d {
VERSION_TEST_CHIP_88C = 0x0000,
VERSION_TEST_CHIP_92C = 0x0020,

View File

@ -4,6 +4,7 @@
#include "../wifi.h"
#include "../pci.h"
#include "../base.h"
#include "../stats.h"
#include "reg.h"
#include "def.h"
#include "phy.h"
@ -32,21 +33,6 @@ static u8 _rtl92d_query_rxpwrpercentage(s8 antpower)
return 100 + antpower;
}
static u8 _rtl92d_evm_db_to_percentage(s8 value)
{
s8 ret_val = value;
if (ret_val >= 0)
ret_val = 0;
if (ret_val <= -33)
ret_val = -33;
ret_val = 0 - ret_val;
ret_val *= 3;
if (ret_val == 99)
ret_val = 100;
return ret_val;
}
static long _rtl92de_translate_todbm(struct ieee80211_hw *hw,
u8 signal_strength_index)
{
@ -215,7 +201,7 @@ static void _rtl92de_query_rxphystatus(struct ieee80211_hw *hw,
else
max_spatial_stream = 1;
for (i = 0; i < max_spatial_stream; i++) {
evm = _rtl92d_evm_db_to_percentage(p_drvinfo->rxevm[i]);
evm = rtl_evm_db_to_percentage(p_drvinfo->rxevm[i]);
if (packet_match_bssid) {
if (i == 0)
pstats->signalquality =

View File

@ -11,37 +11,6 @@
#define RX_MPDU_QUEUE 0
#define RX_CMD_QUEUE 1
#define C2H_RX_CMD_HDR_LEN 8
#define GET_C2H_CMD_CMD_LEN(__prxhdr) \
LE_BITS_TO_4BYTE((__prxhdr), 0, 16)
#define GET_C2H_CMD_ELEMENT_ID(__prxhdr) \
LE_BITS_TO_4BYTE((__prxhdr), 16, 8)
#define GET_C2H_CMD_CMD_SEQ(__prxhdr) \
LE_BITS_TO_4BYTE((__prxhdr), 24, 7)
#define GET_C2H_CMD_CONTINUE(__prxhdr) \
LE_BITS_TO_4BYTE((__prxhdr), 31, 1)
#define GET_C2H_CMD_CONTENT(__prxhdr) \
((u8 *)(__prxhdr) + C2H_RX_CMD_HDR_LEN)
#define GET_C2H_CMD_FEEDBACK_ELEMENT_ID(__pcmdfbhdr) \
LE_BITS_TO_4BYTE((__pcmdfbhdr), 0, 8)
#define GET_C2H_CMD_FEEDBACK_CCX_LEN(__pcmdfbhdr) \
LE_BITS_TO_4BYTE((__pcmdfbhdr), 8, 8)
#define GET_C2H_CMD_FEEDBACK_CCX_CMD_CNT(__pcmdfbhdr) \
LE_BITS_TO_4BYTE((__pcmdfbhdr), 16, 16)
#define GET_C2H_CMD_FEEDBACK_CCX_MAC_ID(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 0, 5)
#define GET_C2H_CMD_FEEDBACK_CCX_VALID(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 7, 1)
#define GET_C2H_CMD_FEEDBACK_CCX_RETRY_CNT(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 8, 5)
#define GET_C2H_CMD_FEEDBACK_CCX_TOK(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 15, 1)
#define GET_C2H_CMD_FEEDBACK_CCX_QSEL(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 16, 4)
#define GET_C2H_CMD_FEEDBACK_CCX_SEQ(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 20, 12)
#define CHIP_BONDING_IDENTIFIER(_value) (((_value)>>22)&0x3)
#define CHIP_BONDING_92C_1T2R 0x1

View File

@ -260,28 +260,29 @@ static void translate_rx_signal_stuff(struct ieee80211_hw *hw,
bool rtl8723e_rx_query_desc(struct ieee80211_hw *hw,
struct rtl_stats *status,
struct ieee80211_rx_status *rx_status,
u8 *pdesc, struct sk_buff *skb)
u8 *pdesc8, struct sk_buff *skb)
{
struct rx_fwinfo_8723e *p_drvinfo;
struct ieee80211_hdr *hdr;
u32 phystatus = GET_RX_DESC_PHYST(pdesc);
__le32 *pdesc = (__le32 *)pdesc8;
u32 phystatus = get_rx_desc_physt(pdesc);
status->length = (u16)GET_RX_DESC_PKT_LEN(pdesc);
status->rx_drvinfo_size = (u8)GET_RX_DESC_DRV_INFO_SIZE(pdesc) *
status->length = (u16)get_rx_desc_pkt_len(pdesc);
status->rx_drvinfo_size = (u8)get_rx_desc_drv_info_size(pdesc) *
RX_DRV_INFO_SIZE_UNIT;
status->rx_bufshift = (u8)(GET_RX_DESC_SHIFT(pdesc) & 0x03);
status->icv = (u16)GET_RX_DESC_ICV(pdesc);
status->crc = (u16)GET_RX_DESC_CRC32(pdesc);
status->rx_bufshift = (u8)(get_rx_desc_shift(pdesc) & 0x03);
status->icv = (u16)get_rx_desc_icv(pdesc);
status->crc = (u16)get_rx_desc_crc32(pdesc);
status->hwerror = (status->crc | status->icv);
status->decrypted = !GET_RX_DESC_SWDEC(pdesc);
status->rate = (u8)GET_RX_DESC_RXMCS(pdesc);
status->shortpreamble = (u16)GET_RX_DESC_SPLCP(pdesc);
status->isampdu = (bool)(GET_RX_DESC_PAGGR(pdesc) == 1);
status->isfirst_ampdu = (bool)((GET_RX_DESC_PAGGR(pdesc) == 1) &&
(GET_RX_DESC_FAGGR(pdesc) == 1));
status->timestamp_low = GET_RX_DESC_TSFL(pdesc);
status->rx_is40mhzpacket = (bool)GET_RX_DESC_BW(pdesc);
status->is_ht = (bool)GET_RX_DESC_RXHT(pdesc);
status->decrypted = !get_rx_desc_swdec(pdesc);
status->rate = (u8)get_rx_desc_rxmcs(pdesc);
status->shortpreamble = (u16)get_rx_desc_splcp(pdesc);
status->isampdu = (bool)(get_rx_desc_paggr(pdesc) == 1);
status->isfirst_ampdu = (bool)((get_rx_desc_paggr(pdesc) == 1) &&
(get_rx_desc_faggr(pdesc) == 1));
status->timestamp_low = get_rx_desc_tsfl(pdesc);
status->rx_is40mhzpacket = (bool)get_rx_desc_bw(pdesc);
status->is_ht = (bool)get_rx_desc_rxht(pdesc);
status->is_cck = RX_HAL_IS_CCK_RATE(status->rate);
@ -331,7 +332,7 @@ bool rtl8723e_rx_query_desc(struct ieee80211_hw *hw,
p_drvinfo = (struct rx_fwinfo_8723e *)(skb->data +
status->rx_bufshift);
translate_rx_signal_stuff(hw, skb, status, pdesc, p_drvinfo);
translate_rx_signal_stuff(hw, skb, status, pdesc8, p_drvinfo);
}
rx_status->signal = status->recvsignalpower + 10;
return true;
@ -350,7 +351,8 @@ void rtl8723e_tx_fill_desc(struct ieee80211_hw *hw,
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
bool b_defaultadapter = true;
/* bool b_trigger_ac = false; */
u8 *pdesc = (u8 *)pdesc_tx;
u8 *pdesc8 = (u8 *)pdesc_tx;
__le32 *pdesc = (__le32 *)pdesc8;
u16 seq_number;
__le16 fc = hdr->frame_control;
u8 fw_qsel = _rtl8723e_map_hwqueue_to_fwqueue(skb, hw_queue);
@ -383,7 +385,7 @@ void rtl8723e_tx_fill_desc(struct ieee80211_hw *hw,
rtl_get_tcb_desc(hw, info, sta, skb, ptcb_desc);
CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_8723e));
clear_pci_tx_desc_content(pdesc, sizeof(struct tx_desc_8723e));
if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) {
firstseg = true;
@ -391,58 +393,58 @@ void rtl8723e_tx_fill_desc(struct ieee80211_hw *hw,
}
if (firstseg) {
SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
set_tx_desc_offset(pdesc, USB_HWDESC_HEADER_LEN);
SET_TX_DESC_TX_RATE(pdesc, ptcb_desc->hw_rate);
set_tx_desc_tx_rate(pdesc, ptcb_desc->hw_rate);
if (ptcb_desc->use_shortgi || ptcb_desc->use_shortpreamble)
SET_TX_DESC_DATA_SHORTGI(pdesc, 1);
set_tx_desc_data_shortgi(pdesc, 1);
if (info->flags & IEEE80211_TX_CTL_AMPDU) {
SET_TX_DESC_AGG_BREAK(pdesc, 1);
SET_TX_DESC_MAX_AGG_NUM(pdesc, 0x14);
set_tx_desc_agg_break(pdesc, 1);
set_tx_desc_max_agg_num(pdesc, 0x14);
}
SET_TX_DESC_SEQ(pdesc, seq_number);
set_tx_desc_seq(pdesc, seq_number);
SET_TX_DESC_RTS_ENABLE(pdesc,
set_tx_desc_rts_enable(pdesc,
((ptcb_desc->rts_enable &&
!ptcb_desc->cts_enable) ? 1 : 0));
SET_TX_DESC_HW_RTS_ENABLE(pdesc,
set_tx_desc_hw_rts_enable(pdesc,
((ptcb_desc->rts_enable ||
ptcb_desc->cts_enable) ? 1 : 0));
SET_TX_DESC_CTS2SELF(pdesc,
set_tx_desc_cts2self(pdesc,
((ptcb_desc->cts_enable) ? 1 : 0));
SET_TX_DESC_RTS_STBC(pdesc,
set_tx_desc_rts_stbc(pdesc,
((ptcb_desc->rts_stbc) ? 1 : 0));
SET_TX_DESC_RTS_RATE(pdesc, ptcb_desc->rts_rate);
SET_TX_DESC_RTS_BW(pdesc, 0);
SET_TX_DESC_RTS_SC(pdesc, ptcb_desc->rts_sc);
SET_TX_DESC_RTS_SHORT(pdesc,
set_tx_desc_rts_rate(pdesc, ptcb_desc->rts_rate);
set_tx_desc_rts_bw(pdesc, 0);
set_tx_desc_rts_sc(pdesc, ptcb_desc->rts_sc);
set_tx_desc_rts_short(pdesc,
((ptcb_desc->rts_rate <= DESC92C_RATE54M) ?
(ptcb_desc->rts_use_shortpreamble ? 1 : 0)
: (ptcb_desc->rts_use_shortgi ? 1 : 0)));
if (bw_40) {
if (ptcb_desc->packet_bw == HT_CHANNEL_WIDTH_20_40) {
SET_TX_DESC_DATA_BW(pdesc, 1);
SET_TX_DESC_TX_SUB_CARRIER(pdesc, 3);
set_tx_desc_data_bw(pdesc, 1);
set_tx_desc_tx_sub_carrier(pdesc, 3);
} else {
SET_TX_DESC_DATA_BW(pdesc, 0);
SET_TX_DESC_TX_SUB_CARRIER(pdesc,
set_tx_desc_data_bw(pdesc, 0);
set_tx_desc_tx_sub_carrier(pdesc,
mac->cur_40_prime_sc);
}
} else {
SET_TX_DESC_DATA_BW(pdesc, 0);
SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0);
set_tx_desc_data_bw(pdesc, 0);
set_tx_desc_tx_sub_carrier(pdesc, 0);
}
SET_TX_DESC_LINIP(pdesc, 0);
SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb->len);
set_tx_desc_linip(pdesc, 0);
set_tx_desc_pkt_size(pdesc, (u16)skb->len);
if (sta) {
u8 ampdu_density = sta->ht_cap.ampdu_density;
SET_TX_DESC_AMPDU_DENSITY(pdesc, ampdu_density);
set_tx_desc_ampdu_density(pdesc, ampdu_density);
}
if (info->control.hw_key) {
@ -453,78 +455,79 @@ void rtl8723e_tx_fill_desc(struct ieee80211_hw *hw,
case WLAN_CIPHER_SUITE_WEP40:
case WLAN_CIPHER_SUITE_WEP104:
case WLAN_CIPHER_SUITE_TKIP:
SET_TX_DESC_SEC_TYPE(pdesc, 0x1);
set_tx_desc_sec_type(pdesc, 0x1);
break;
case WLAN_CIPHER_SUITE_CCMP:
SET_TX_DESC_SEC_TYPE(pdesc, 0x3);
set_tx_desc_sec_type(pdesc, 0x3);
break;
default:
SET_TX_DESC_SEC_TYPE(pdesc, 0x0);
set_tx_desc_sec_type(pdesc, 0x0);
break;
}
}
SET_TX_DESC_PKT_ID(pdesc, 0);
SET_TX_DESC_QUEUE_SEL(pdesc, fw_qsel);
set_tx_desc_pkt_id(pdesc, 0);
set_tx_desc_queue_sel(pdesc, fw_qsel);
SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F);
SET_TX_DESC_RTS_RATE_FB_LIMIT(pdesc, 0xF);
SET_TX_DESC_DISABLE_FB(pdesc, 0);
SET_TX_DESC_USE_RATE(pdesc, ptcb_desc->use_driver_rate ? 1 : 0);
set_tx_desc_data_rate_fb_limit(pdesc, 0x1F);
set_tx_desc_rts_rate_fb_limit(pdesc, 0xF);
set_tx_desc_disable_fb(pdesc, 0);
set_tx_desc_use_rate(pdesc, ptcb_desc->use_driver_rate ? 1 : 0);
if (ieee80211_is_data_qos(fc)) {
if (mac->rdg_en) {
RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
"Enable RDG function.\n");
SET_TX_DESC_RDG_ENABLE(pdesc, 1);
SET_TX_DESC_HTC(pdesc, 1);
set_tx_desc_rdg_enable(pdesc, 1);
set_tx_desc_htc(pdesc, 1);
}
}
}
SET_TX_DESC_FIRST_SEG(pdesc, (firstseg ? 1 : 0));
SET_TX_DESC_LAST_SEG(pdesc, (lastseg ? 1 : 0));
set_tx_desc_first_seg(pdesc, (firstseg ? 1 : 0));
set_tx_desc_last_seg(pdesc, (lastseg ? 1 : 0));
SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) skb->len);
set_tx_desc_tx_buffer_size(pdesc, (u16)skb->len);
SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
set_tx_desc_tx_buffer_address(pdesc, mapping);
if (rtlpriv->dm.useramask) {
SET_TX_DESC_RATE_ID(pdesc, ptcb_desc->ratr_index);
SET_TX_DESC_MACID(pdesc, ptcb_desc->mac_id);
set_tx_desc_rate_id(pdesc, ptcb_desc->ratr_index);
set_tx_desc_macid(pdesc, ptcb_desc->mac_id);
} else {
SET_TX_DESC_RATE_ID(pdesc, 0xC + ptcb_desc->ratr_index);
SET_TX_DESC_MACID(pdesc, ptcb_desc->ratr_index);
set_tx_desc_rate_id(pdesc, 0xC + ptcb_desc->ratr_index);
set_tx_desc_macid(pdesc, ptcb_desc->ratr_index);
}
if ((!ieee80211_is_data_qos(fc)) && ppsc->fwctrl_lps) {
SET_TX_DESC_HWSEQ_EN_8723(pdesc, 1);
/* SET_TX_DESC_HWSEQ_EN(pdesc, 1); */
/* SET_TX_DESC_PKT_ID(pdesc, 8); */
set_tx_desc_hwseq_en_8723(pdesc, 1);
/* set_tx_desc_hwseq_en(pdesc, 1); */
/* set_tx_desc_pkt_id(pdesc, 8); */
if (!b_defaultadapter)
SET_TX_DESC_HWSEQ_SEL_8723(pdesc, 1);
/* SET_TX_DESC_QOS(pdesc, 1); */
set_tx_desc_hwseq_sel_8723(pdesc, 1);
/* set_tx_desc_qos(pdesc, 1); */
}
SET_TX_DESC_MORE_FRAG(pdesc, (lastseg ? 0 : 1));
set_tx_desc_more_frag(pdesc, (lastseg ? 0 : 1));
if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) ||
is_broadcast_ether_addr(ieee80211_get_DA(hdr))) {
SET_TX_DESC_BMC(pdesc, 1);
set_tx_desc_bmc(pdesc, 1);
}
RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "\n");
}
void rtl8723e_tx_fill_cmddesc(struct ieee80211_hw *hw,
u8 *pdesc, bool firstseg,
u8 *pdesc8, bool firstseg,
bool lastseg, struct sk_buff *skb)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
u8 fw_queue = QSLT_BEACON;
__le32 *pdesc = (__le32 *)pdesc8;
dma_addr_t mapping = pci_map_single(rtlpci->pdev,
skb->data, skb->len,
@ -538,44 +541,44 @@ void rtl8723e_tx_fill_cmddesc(struct ieee80211_hw *hw,
"DMA mapping error\n");
return;
}
CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE);
clear_pci_tx_desc_content(pdesc, TX_DESC_SIZE);
if (firstseg)
SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
set_tx_desc_offset(pdesc, USB_HWDESC_HEADER_LEN);
SET_TX_DESC_TX_RATE(pdesc, DESC92C_RATE1M);
set_tx_desc_tx_rate(pdesc, DESC92C_RATE1M);
SET_TX_DESC_SEQ(pdesc, 0);
set_tx_desc_seq(pdesc, 0);
SET_TX_DESC_LINIP(pdesc, 0);
set_tx_desc_linip(pdesc, 0);
SET_TX_DESC_QUEUE_SEL(pdesc, fw_queue);
set_tx_desc_queue_sel(pdesc, fw_queue);
SET_TX_DESC_FIRST_SEG(pdesc, 1);
SET_TX_DESC_LAST_SEG(pdesc, 1);
set_tx_desc_first_seg(pdesc, 1);
set_tx_desc_last_seg(pdesc, 1);
SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) (skb->len));
set_tx_desc_tx_buffer_size(pdesc, (u16)(skb->len));
SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
set_tx_desc_tx_buffer_address(pdesc, mapping);
SET_TX_DESC_RATE_ID(pdesc, 7);
SET_TX_DESC_MACID(pdesc, 0);
set_tx_desc_rate_id(pdesc, 7);
set_tx_desc_macid(pdesc, 0);
SET_TX_DESC_OWN(pdesc, 1);
set_tx_desc_own(pdesc, 1);
SET_TX_DESC_PKT_SIZE((u8 *)pdesc, (u16)(skb->len));
set_tx_desc_pkt_size(pdesc, (u16)(skb->len));
SET_TX_DESC_FIRST_SEG(pdesc, 1);
SET_TX_DESC_LAST_SEG(pdesc, 1);
set_tx_desc_first_seg(pdesc, 1);
set_tx_desc_last_seg(pdesc, 1);
SET_TX_DESC_OFFSET(pdesc, 0x20);
set_tx_desc_offset(pdesc, 0x20);
SET_TX_DESC_USE_RATE(pdesc, 1);
set_tx_desc_use_rate(pdesc, 1);
if (!ieee80211_is_data_qos(fc)) {
SET_TX_DESC_HWSEQ_EN_8723(pdesc, 1);
/* SET_TX_DESC_HWSEQ_EN(pdesc, 1); */
/* SET_TX_DESC_PKT_ID(pdesc, 8); */
set_tx_desc_hwseq_en_8723(pdesc, 1);
/* set_tx_desc_hwseq_en(pdesc, 1); */
/* set_tx_desc_pkt_id(pdesc, 8); */
}
RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
@ -583,16 +586,18 @@ void rtl8723e_tx_fill_cmddesc(struct ieee80211_hw *hw,
pdesc, TX_DESC_SIZE);
}
void rtl8723e_set_desc(struct ieee80211_hw *hw, u8 *pdesc,
void rtl8723e_set_desc(struct ieee80211_hw *hw, u8 *pdesc8,
bool istx, u8 desc_name, u8 *val)
{
__le32 *pdesc = (__le32 *)pdesc8;
if (istx == true) {
switch (desc_name) {
case HW_DESC_OWN:
SET_TX_DESC_OWN(pdesc, 1);
set_tx_desc_own(pdesc, 1);
break;
case HW_DESC_TX_NEXTDESC_ADDR:
SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val);
set_tx_desc_next_desc_address(pdesc, *(u32 *)val);
break;
default:
WARN_ONCE(true, "rtl8723ae: ERR txdesc :%d not processed\n",
@ -602,16 +607,16 @@ void rtl8723e_set_desc(struct ieee80211_hw *hw, u8 *pdesc,
} else {
switch (desc_name) {
case HW_DESC_RXOWN:
SET_RX_DESC_OWN(pdesc, 1);
set_rx_desc_own(pdesc, 1);
break;
case HW_DESC_RXBUFF_ADDR:
SET_RX_DESC_BUFF_ADDR(pdesc, *(u32 *) val);
set_rx_desc_buff_addr(pdesc, *(u32 *)val);
break;
case HW_DESC_RXPKT_LEN:
SET_RX_DESC_PKT_LEN(pdesc, *(u32 *) val);
set_rx_desc_pkt_len(pdesc, *(u32 *)val);
break;
case HW_DESC_RXERO:
SET_RX_DESC_EOR(pdesc, 1);
set_rx_desc_eor(pdesc, 1);
break;
default:
WARN_ONCE(true, "rtl8723ae: ERR rxdesc :%d not processed\n",
@ -622,17 +627,18 @@ void rtl8723e_set_desc(struct ieee80211_hw *hw, u8 *pdesc,
}
u64 rtl8723e_get_desc(struct ieee80211_hw *hw,
u8 *pdesc, bool istx, u8 desc_name)
u8 *pdesc8, bool istx, u8 desc_name)
{
u32 ret = 0;
__le32 *pdesc = (__le32 *)pdesc8;
if (istx == true) {
switch (desc_name) {
case HW_DESC_OWN:
ret = GET_TX_DESC_OWN(pdesc);
ret = get_tx_desc_own(pdesc);
break;
case HW_DESC_TXBUFF_ADDR:
ret = GET_TX_DESC_TX_BUFFER_ADDRESS(pdesc);
ret = get_tx_desc_tx_buffer_address(pdesc);
break;
default:
WARN_ONCE(true, "rtl8723ae: ERR txdesc :%d not processed\n",
@ -642,13 +648,13 @@ u64 rtl8723e_get_desc(struct ieee80211_hw *hw,
} else {
switch (desc_name) {
case HW_DESC_OWN:
ret = GET_RX_DESC_OWN(pdesc);
ret = get_rx_desc_own(pdesc);
break;
case HW_DESC_RXPKT_LEN:
ret = GET_RX_DESC_PKT_LEN(pdesc);
ret = get_rx_desc_pkt_len(pdesc);
break;
case HW_DESC_RXBUFF_ADDR:
ret = GET_RX_DESC_BUFF_ADDR(pdesc);
ret = get_rx_desc_buff_addr(pdesc);
break;
default:
WARN_ONCE(true, "rtl8723ae: ERR rxdesc :%d not processed\n",

View File

@ -14,486 +14,324 @@
#define USB_HWDESC_HEADER_LEN 32
#define CRCLENGTH 4
#define SET_TX_DESC_PKT_SIZE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 0, 16, __val)
#define SET_TX_DESC_OFFSET(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 16, 8, __val)
#define SET_TX_DESC_BMC(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 24, 1, __val)
#define SET_TX_DESC_HTC(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 25, 1, __val)
#define SET_TX_DESC_LAST_SEG(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 26, 1, __val)
#define SET_TX_DESC_FIRST_SEG(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 27, 1, __val)
#define SET_TX_DESC_LINIP(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 28, 1, __val)
#define SET_TX_DESC_NO_ACM(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 29, 1, __val)
#define SET_TX_DESC_GF(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 30, 1, __val)
#define SET_TX_DESC_OWN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val)
static inline void set_tx_desc_pkt_size(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits(__pdesc, __val, GENMASK(15, 0));
}
#define GET_TX_DESC_PKT_SIZE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 0, 16)
#define GET_TX_DESC_OFFSET(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 16, 8)
#define GET_TX_DESC_BMC(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 24, 1)
#define GET_TX_DESC_HTC(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 25, 1)
#define GET_TX_DESC_LAST_SEG(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 26, 1)
#define GET_TX_DESC_FIRST_SEG(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 27, 1)
#define GET_TX_DESC_LINIP(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 28, 1)
#define GET_TX_DESC_NO_ACM(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 29, 1)
#define GET_TX_DESC_GF(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 30, 1)
#define GET_TX_DESC_OWN(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 31, 1)
static inline void set_tx_desc_offset(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits(__pdesc, __val, GENMASK(23, 16));
}
#define SET_TX_DESC_MACID(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+4, 0, 5, __val)
#define SET_TX_DESC_AGG_BREAK(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+4, 5, 1, __val)
#define SET_TX_DESC_BK(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+4, 6, 1, __val)
#define SET_TX_DESC_RDG_ENABLE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+4, 7, 1, __val)
#define SET_TX_DESC_QUEUE_SEL(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+4, 8, 5, __val)
#define SET_TX_DESC_RDG_NAV_EXT(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+4, 13, 1, __val)
#define SET_TX_DESC_LSIG_TXOP_EN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+4, 14, 1, __val)
#define SET_TX_DESC_PIFS(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+4, 15, 1, __val)
#define SET_TX_DESC_RATE_ID(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+4, 16, 4, __val)
#define SET_TX_DESC_NAV_USE_HDR(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+4, 20, 1, __val)
#define SET_TX_DESC_EN_DESC_ID(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+4, 21, 1, __val)
#define SET_TX_DESC_SEC_TYPE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+4, 22, 2, __val)
#define SET_TX_DESC_PKT_OFFSET(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+4, 24, 8, __val)
static inline void set_tx_desc_bmc(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits(__pdesc, __val, BIT(24));
}
#define GET_TX_DESC_MACID(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 0, 5)
#define GET_TX_DESC_AGG_ENABLE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 5, 1)
#define GET_TX_DESC_AGG_BREAK(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 6, 1)
#define GET_TX_DESC_RDG_ENABLE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 7, 1)
#define GET_TX_DESC_QUEUE_SEL(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 8, 5)
#define GET_TX_DESC_RDG_NAV_EXT(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 13, 1)
#define GET_TX_DESC_LSIG_TXOP_EN(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 14, 1)
#define GET_TX_DESC_PIFS(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 15, 1)
#define GET_TX_DESC_RATE_ID(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 16, 4)
#define GET_TX_DESC_NAV_USE_HDR(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 20, 1)
#define GET_TX_DESC_EN_DESC_ID(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 21, 1)
#define GET_TX_DESC_SEC_TYPE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 22, 2)
#define GET_TX_DESC_PKT_OFFSET(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 24, 8)
static inline void set_tx_desc_htc(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits(__pdesc, __val, BIT(25));
}
#define SET_TX_DESC_RTS_RC(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 0, 6, __val)
#define SET_TX_DESC_DATA_RC(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 6, 6, __val)
#define SET_TX_DESC_BAR_RTY_TH(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 14, 2, __val)
#define SET_TX_DESC_MORE_FRAG(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 17, 1, __val)
#define SET_TX_DESC_RAW(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 18, 1, __val)
#define SET_TX_DESC_CCX(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 19, 1, __val)
#define SET_TX_DESC_AMPDU_DENSITY(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 20, 3, __val)
#define SET_TX_DESC_ANTSEL_A(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 24, 1, __val)
#define SET_TX_DESC_ANTSEL_B(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 25, 1, __val)
#define SET_TX_DESC_TX_ANT_CCK(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 26, 2, __val)
#define SET_TX_DESC_TX_ANTL(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 28, 2, __val)
#define SET_TX_DESC_TX_ANT_HT(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 30, 2, __val)
static inline void set_tx_desc_last_seg(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits(__pdesc, __val, BIT(26));
}
#define GET_TX_DESC_RTS_RC(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 0, 6)
#define GET_TX_DESC_DATA_RC(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 6, 6)
#define GET_TX_DESC_BAR_RTY_TH(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 14, 2)
#define GET_TX_DESC_MORE_FRAG(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 17, 1)
#define GET_TX_DESC_RAW(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 18, 1)
#define GET_TX_DESC_CCX(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 19, 1)
#define GET_TX_DESC_AMPDU_DENSITY(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 20, 3)
#define GET_TX_DESC_ANTSEL_A(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 24, 1)
#define GET_TX_DESC_ANTSEL_B(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 25, 1)
#define GET_TX_DESC_TX_ANT_CCK(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 26, 2)
#define GET_TX_DESC_TX_ANTL(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 28, 2)
#define GET_TX_DESC_TX_ANT_HT(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 30, 2)
static inline void set_tx_desc_first_seg(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits(__pdesc, __val, BIT(27));
}
#define SET_TX_DESC_NEXT_HEAP_PAGE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+12, 0, 8, __val)
#define SET_TX_DESC_TAIL_PAGE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+12, 8, 8, __val)
#define SET_TX_DESC_SEQ(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+12, 16, 12, __val)
#define SET_TX_DESC_PKT_ID(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+12, 28, 4, __val)
static inline void set_tx_desc_linip(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits(__pdesc, __val, BIT(28));
}
#define GET_TX_DESC_NEXT_HEAP_PAGE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 0, 8)
#define GET_TX_DESC_TAIL_PAGE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 8, 8)
#define GET_TX_DESC_SEQ(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 16, 12)
#define GET_TX_DESC_PKT_ID(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 28, 4)
static inline void set_tx_desc_own(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits(__pdesc, __val, BIT(31));
}
static inline u32 get_tx_desc_own(__le32 *__pdesc)
{
return le32_get_bits(*__pdesc, BIT(31));
}
static inline void set_tx_desc_macid(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 1), __val, GENMASK(4, 0));
}
static inline void set_tx_desc_agg_break(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 1), __val, BIT(5));
}
static inline void set_tx_desc_rdg_enable(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 1), __val, BIT(7));
}
static inline void set_tx_desc_queue_sel(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 1), __val, GENMASK(12, 8));
}
static inline void set_tx_desc_rate_id(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 1), __val, GENMASK(19, 16));
}
static inline void set_tx_desc_sec_type(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 1), __val, GENMASK(23, 22));
}
static inline void set_tx_desc_more_frag(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 2), __val, BIT(17));
}
static inline void set_tx_desc_ampdu_density(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 2), __val, GENMASK(22, 20));
}
static inline void set_tx_desc_seq(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 3), __val, GENMASK(27, 16));
}
static inline void set_tx_desc_pkt_id(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 3), __val, GENMASK(31, 28));
}
/* For RTL8723 */
#define SET_TX_DESC_TRIGGER_INT(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+12, 30, 1, __val)
#define SET_TX_DESC_HWSEQ_EN_8723(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+12, 31, 1, __val)
#define SET_TX_DESC_HWSEQ_SEL_8723(__txdesc, __value) \
SET_BITS_TO_LE_4BYTE(__txdesc+16, 6, 2, __value)
static inline void set_tx_desc_hwseq_en_8723(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 3), __val, BIT(31));
}
#define SET_TX_DESC_RTS_RATE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 0, 5, __val)
#define SET_TX_DESC_AP_DCFE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 5, 1, __val)
#define SET_TX_DESC_QOS(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 6, 1, __val)
#define SET_TX_DESC_HWSEQ_EN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 7, 1, __val)
#define SET_TX_DESC_USE_RATE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 8, 1, __val)
#define SET_TX_DESC_DISABLE_RTS_FB(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 9, 1, __val)
#define SET_TX_DESC_DISABLE_FB(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 10, 1, __val)
#define SET_TX_DESC_CTS2SELF(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 11, 1, __val)
#define SET_TX_DESC_RTS_ENABLE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 12, 1, __val)
#define SET_TX_DESC_HW_RTS_ENABLE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 13, 1, __val)
#define SET_TX_DESC_PORT_ID(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 14, 1, __val)
#define SET_TX_DESC_WAIT_DCTS(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 18, 1, __val)
#define SET_TX_DESC_CTS2AP_EN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 19, 1, __val)
#define SET_TX_DESC_TX_SUB_CARRIER(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 20, 2, __val)
#define SET_TX_DESC_TX_STBC(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 22, 2, __val)
#define SET_TX_DESC_DATA_SHORT(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 24, 1, __val)
#define SET_TX_DESC_DATA_BW(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 25, 1, __val)
#define SET_TX_DESC_RTS_SHORT(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 26, 1, __val)
#define SET_TX_DESC_RTS_BW(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 27, 1, __val)
#define SET_TX_DESC_RTS_SC(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 28, 2, __val)
#define SET_TX_DESC_RTS_STBC(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 30, 2, __val)
static inline void set_tx_desc_hwseq_sel_8723(__le32 *__txdesc, u32 __value)
{
le32p_replace_bits((__txdesc + 4), __value, GENMASK(7, 6));
}
#define GET_TX_DESC_RTS_RATE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 0, 5)
#define GET_TX_DESC_AP_DCFE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 5, 1)
#define GET_TX_DESC_QOS(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 6, 1)
#define GET_TX_DESC_HWSEQ_EN(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 7, 1)
#define GET_TX_DESC_USE_RATE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 8, 1)
#define GET_TX_DESC_DISABLE_RTS_FB(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 9, 1)
#define GET_TX_DESC_DISABLE_FB(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 10, 1)
#define GET_TX_DESC_CTS2SELF(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 11, 1)
#define GET_TX_DESC_RTS_ENABLE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 12, 1)
#define GET_TX_DESC_HW_RTS_ENABLE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 13, 1)
#define GET_TX_DESC_PORT_ID(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 14, 1)
#define GET_TX_DESC_WAIT_DCTS(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 18, 1)
#define GET_TX_DESC_CTS2AP_EN(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 19, 1)
#define GET_TX_DESC_TX_SUB_CARRIER(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 20, 2)
#define GET_TX_DESC_TX_STBC(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 22, 2)
#define GET_TX_DESC_DATA_SHORT(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 24, 1)
#define GET_TX_DESC_DATA_BW(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 25, 1)
#define GET_TX_DESC_RTS_SHORT(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 26, 1)
#define GET_TX_DESC_RTS_BW(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 27, 1)
#define GET_TX_DESC_RTS_SC(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 28, 2)
#define GET_TX_DESC_RTS_STBC(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 30, 2)
static inline void set_tx_desc_rts_rate(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 4), __val, GENMASK(4, 0));
}
#define SET_TX_DESC_TX_RATE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+20, 0, 6, __val)
#define SET_TX_DESC_DATA_SHORTGI(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+20, 6, 1, __val)
#define SET_TX_DESC_CCX_TAG(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+20, 7, 1, __val)
#define SET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+20, 8, 5, __val)
#define SET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+20, 13, 4, __val)
#define SET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+20, 17, 1, __val)
#define SET_TX_DESC_DATA_RETRY_LIMIT(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+20, 18, 6, __val)
#define SET_TX_DESC_USB_TXAGG_NUM(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+20, 24, 8, __val)
static inline void set_tx_desc_use_rate(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 4), __val, BIT(8));
}
#define GET_TX_DESC_TX_RATE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+20, 0, 6)
#define GET_TX_DESC_DATA_SHORTGI(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+20, 6, 1)
#define GET_TX_DESC_CCX_TAG(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+20, 7, 1)
#define GET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+20, 8, 5)
#define GET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+20, 13, 4)
#define GET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+20, 17, 1)
#define GET_TX_DESC_DATA_RETRY_LIMIT(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+20, 18, 6)
#define GET_TX_DESC_USB_TXAGG_NUM(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+20, 24, 8)
static inline void set_tx_desc_disable_fb(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 4), __val, BIT(10));
}
#define SET_TX_DESC_TXAGC_A(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+24, 0, 5, __val)
#define SET_TX_DESC_TXAGC_B(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+24, 5, 5, __val)
#define SET_TX_DESC_USE_MAX_LEN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+24, 10, 1, __val)
#define SET_TX_DESC_MAX_AGG_NUM(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+24, 11, 5, __val)
#define SET_TX_DESC_MCSG1_MAX_LEN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+24, 16, 4, __val)
#define SET_TX_DESC_MCSG2_MAX_LEN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+24, 20, 4, __val)
#define SET_TX_DESC_MCSG3_MAX_LEN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+24, 24, 4, __val)
#define SET_TX_DESC_MCS7_SGI_MAX_LEN(__pdesc, __val)\
SET_BITS_TO_LE_4BYTE(__pdesc+24, 28, 4, __val)
static inline void set_tx_desc_cts2self(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 4), __val, BIT(11));
}
#define GET_TX_DESC_TXAGC_A(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+24, 0, 5)
#define GET_TX_DESC_TXAGC_B(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+24, 5, 5)
#define GET_TX_DESC_USE_MAX_LEN(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+24, 10, 1)
#define GET_TX_DESC_MAX_AGG_NUM(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+24, 11, 5)
#define GET_TX_DESC_MCSG1_MAX_LEN(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+24, 16, 4)
#define GET_TX_DESC_MCSG2_MAX_LEN(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+24, 20, 4)
#define GET_TX_DESC_MCSG3_MAX_LEN(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+24, 24, 4)
#define GET_TX_DESC_MCS7_SGI_MAX_LEN(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+24, 28, 4)
static inline void set_tx_desc_rts_enable(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 4), __val, BIT(12));
}
#define SET_TX_DESC_TX_BUFFER_SIZE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+28, 0, 16, __val)
#define SET_TX_DESC_MCSG4_MAX_LEN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+28, 16, 4, __val)
#define SET_TX_DESC_MCSG5_MAX_LEN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+28, 20, 4, __val)
#define SET_TX_DESC_MCSG6_MAX_LEN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+28, 24, 4, __val)
#define SET_TX_DESC_MCS15_SGI_MAX_LEN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+28, 28, 4, __val)
static inline void set_tx_desc_hw_rts_enable(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 4), __val, BIT(13));
}
#define GET_TX_DESC_TX_BUFFER_SIZE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+28, 0, 16)
#define GET_TX_DESC_MCSG4_MAX_LEN(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+28, 16, 4)
#define GET_TX_DESC_MCSG5_MAX_LEN(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+28, 20, 4)
#define GET_TX_DESC_MCSG6_MAX_LEN(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+28, 24, 4)
#define GET_TX_DESC_MCS15_SGI_MAX_LEN(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+28, 28, 4)
static inline void set_tx_desc_tx_sub_carrier(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 4), __val, GENMASK(21, 20));
}
#define SET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+32, 0, 32, __val)
#define SET_TX_DESC_TX_BUFFER_ADDRESS64(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+36, 0, 32, __val)
static inline void set_tx_desc_data_bw(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 4), __val, BIT(25));
}
#define GET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+32, 0, 32)
#define GET_TX_DESC_TX_BUFFER_ADDRESS64(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+36, 0, 32)
static inline void set_tx_desc_rts_short(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 4), __val, BIT(26));
}
#define SET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+40, 0, 32, __val)
#define SET_TX_DESC_NEXT_DESC_ADDRESS64(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+44, 0, 32, __val)
static inline void set_tx_desc_rts_bw(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 4), __val, BIT(27));
}
#define GET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+40, 0, 32)
#define GET_TX_DESC_NEXT_DESC_ADDRESS64(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+44, 0, 32)
static inline void set_tx_desc_rts_sc(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 4), __val, GENMASK(29, 28));
}
#define GET_RX_DESC_PKT_LEN(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 0, 14)
#define GET_RX_DESC_CRC32(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 14, 1)
#define GET_RX_DESC_ICV(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 15, 1)
#define GET_RX_DESC_DRV_INFO_SIZE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 16, 4)
#define GET_RX_DESC_SECURITY(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 20, 3)
#define GET_RX_DESC_QOS(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 23, 1)
#define GET_RX_DESC_SHIFT(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 24, 2)
#define GET_RX_DESC_PHYST(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 26, 1)
#define GET_RX_DESC_SWDEC(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 27, 1)
#define GET_RX_DESC_LS(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 28, 1)
#define GET_RX_DESC_FS(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 29, 1)
#define GET_RX_DESC_EOR(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 30, 1)
#define GET_RX_DESC_OWN(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 31, 1)
static inline void set_tx_desc_rts_stbc(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 4), __val, GENMASK(31, 30));
}
#define SET_RX_DESC_PKT_LEN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 0, 14, __val)
#define SET_RX_DESC_EOR(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 30, 1, __val)
#define SET_RX_DESC_OWN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val)
static inline void set_tx_desc_tx_rate(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 5), __val, GENMASK(5, 0));
}
#define GET_RX_DESC_MACID(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 0, 5)
#define GET_RX_DESC_TID(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 5, 4)
#define GET_RX_DESC_HWRSVD(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 9, 5)
#define GET_RX_DESC_PAGGR(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 14, 1)
#define GET_RX_DESC_FAGGR(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 15, 1)
#define GET_RX_DESC_A1_FIT(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 16, 4)
#define GET_RX_DESC_A2_FIT(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 20, 4)
#define GET_RX_DESC_PAM(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 24, 1)
#define GET_RX_DESC_PWR(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 25, 1)
#define GET_RX_DESC_MD(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 26, 1)
#define GET_RX_DESC_MF(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 27, 1)
#define GET_RX_DESC_TYPE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 28, 2)
#define GET_RX_DESC_MC(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 30, 1)
#define GET_RX_DESC_BC(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 31, 1)
#define GET_RX_DESC_SEQ(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 0, 12)
#define GET_RX_DESC_FRAG(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 12, 4)
#define GET_RX_DESC_NEXT_PKT_LEN(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 16, 14)
#define GET_RX_DESC_NEXT_IND(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 30, 1)
#define GET_RX_DESC_RSVD(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 31, 1)
static inline void set_tx_desc_data_shortgi(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 5), __val, BIT(6));
}
#define GET_RX_DESC_RXMCS(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 0, 6)
#define GET_RX_DESC_RXHT(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 6, 1)
#define GET_RX_DESC_SPLCP(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 8, 1)
#define GET_RX_DESC_BW(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 9, 1)
#define GET_RX_DESC_HTC(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 10, 1)
#define GET_RX_DESC_HWPC_ERR(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 14, 1)
#define GET_RX_DESC_HWPC_IND(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 15, 1)
#define GET_RX_DESC_IV0(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 16, 16)
static inline void set_tx_desc_data_rate_fb_limit(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 5), __val, GENMASK(12, 8));
}
#define GET_RX_DESC_IV1(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 0, 32)
#define GET_RX_DESC_TSFL(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+20, 0, 32)
static inline void set_tx_desc_rts_rate_fb_limit(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 5), __val, GENMASK(16, 13));
}
#define GET_RX_DESC_BUFF_ADDR(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+24, 0, 32)
#define GET_RX_DESC_BUFF_ADDR64(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+28, 0, 32)
static inline void set_tx_desc_max_agg_num(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 6), __val, GENMASK(15, 11));
}
#define SET_RX_DESC_BUFF_ADDR(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+24, 0, 32, __val)
#define SET_RX_DESC_BUFF_ADDR64(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+28, 0, 32, __val)
static inline void set_tx_desc_tx_buffer_size(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 7), __val, GENMASK(15, 0));
}
#define CLEAR_PCI_TX_DESC_CONTENT(__pdesc, _size) \
do { \
if (_size > TX_DESC_NEXT_DESC_OFFSET) \
memset(__pdesc, 0, TX_DESC_NEXT_DESC_OFFSET); \
else \
memset(__pdesc, 0, _size); \
} while (0)
static inline void set_tx_desc_tx_buffer_address(__le32 *__pdesc, u32 __val)
{
*(__pdesc + 8) = cpu_to_le32(__val);
}
static inline u32 get_tx_desc_tx_buffer_address(__le32 *__pdesc)
{
return le32_to_cpu(*(__pdesc + 8));
}
static inline void set_tx_desc_next_desc_address(__le32 *__pdesc, u32 __val)
{
*(__pdesc + 10) = cpu_to_le32(__val);
}
static inline u32 get_rx_desc_pkt_len(__le32 *__pdesc)
{
return le32_get_bits(*__pdesc, GENMASK(13, 0));
}
static inline u32 get_rx_desc_crc32(__le32 *__pdesc)
{
return le32_get_bits(*__pdesc, BIT(14));
}
static inline u32 get_rx_desc_icv(__le32 *__pdesc)
{
return le32_get_bits(*__pdesc, BIT(15));
}
static inline u32 get_rx_desc_drv_info_size(__le32 *__pdesc)
{
return le32_get_bits(*__pdesc, GENMASK(19, 16));
}
static inline u32 get_rx_desc_shift(__le32 *__pdesc)
{
return le32_get_bits(*__pdesc, GENMASK(25, 24));
}
static inline u32 get_rx_desc_physt(__le32 *__pdesc)
{
return le32_get_bits(*__pdesc, BIT(26));
}
static inline u32 get_rx_desc_swdec(__le32 *__pdesc)
{
return le32_get_bits(*__pdesc, BIT(27));
}
static inline u32 get_rx_desc_own(__le32 *__pdesc)
{
return le32_get_bits(*__pdesc, BIT(31));
}
static inline void set_rx_desc_pkt_len(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits(__pdesc, __val, GENMASK(13, 0));
}
static inline void set_rx_desc_eor(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits(__pdesc, __val, BIT(30));
}
static inline void set_rx_desc_own(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits(__pdesc, __val, BIT(31));
}
static inline u32 get_rx_desc_paggr(__le32 *__pdesc)
{
return le32_get_bits(*(__pdesc + 1), BIT(14));
}
static inline u32 get_rx_desc_faggr(__le32 *__pdesc)
{
return le32_get_bits(*(__pdesc + 1), BIT(15));
}
static inline u32 get_rx_desc_rxmcs(__le32 *__pdesc)
{
return le32_get_bits(*(__pdesc + 3), GENMASK(5, 0));
}
static inline u32 get_rx_desc_rxht(__le32 *__pdesc)
{
return le32_get_bits(*(__pdesc + 3), BIT(6));
}
static inline u32 get_rx_desc_splcp(__le32 *__pdesc)
{
return le32_get_bits(*(__pdesc + 3), BIT(8));
}
static inline u32 get_rx_desc_bw(__le32 *__pdesc)
{
return le32_get_bits(*(__pdesc + 3), BIT(9));
}
static inline u32 get_rx_desc_tsfl(__le32 *__pdesc)
{
return le32_to_cpu(*(__pdesc + 5));
}
static inline u32 get_rx_desc_buff_addr(__le32 *__pdesc)
{
return le32_to_cpu(*(__pdesc + 6));
}
static inline void set_rx_desc_buff_addr(__le32 *__pdesc, u32 __val)
{
*(__pdesc + 6) = cpu_to_le32(__val);
}
static inline void clear_pci_tx_desc_content(__le32 *__pdesc, u32 _size)
{
if (_size > TX_DESC_NEXT_DESC_OFFSET)
memset(__pdesc, 0, TX_DESC_NEXT_DESC_OFFSET);
else
memset(__pdesc, 0, _size);
}
struct rx_fwinfo_8723e {
u8 gain_trsw[4];

View File

@ -26,7 +26,8 @@ static u8 _rtl8723be_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue)
}
static void _rtl8723be_query_rxphystatus(struct ieee80211_hw *hw,
struct rtl_stats *pstatus, u8 *pdesc,
struct rtl_stats *pstatus,
__le32 *pdesc,
struct rx_fwinfo_8723be *p_drvinfo,
bool bpacket_match_bssid,
bool bpacket_toself,
@ -189,7 +190,7 @@ static void _rtl8723be_query_rxphystatus(struct ieee80211_hw *hw,
static void _rtl8723be_translate_rx_signal_stuff(struct ieee80211_hw *hw,
struct sk_buff *skb,
struct rtl_stats *pstatus,
u8 *pdesc,
__le32 *pdesc,
struct rx_fwinfo_8723be *p_drvinfo)
{
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
@ -242,12 +243,12 @@ static void _rtl8723be_translate_rx_signal_stuff(struct ieee80211_hw *hw,
}
static void _rtl8723be_insert_emcontent(struct rtl_tcb_desc *ptcb_desc,
u8 *virtualaddress)
__le32 *virtualaddress)
{
u32 dwtmp = 0;
memset(virtualaddress, 0, 8);
SET_EARLYMODE_PKTNUM(virtualaddress, ptcb_desc->empkt_num);
set_earlymode_pktnum(virtualaddress, ptcb_desc->empkt_num);
if (ptcb_desc->empkt_num == 1) {
dwtmp = ptcb_desc->empkt_len[0];
} else {
@ -255,7 +256,7 @@ static void _rtl8723be_insert_emcontent(struct rtl_tcb_desc *ptcb_desc,
dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4;
dwtmp += ptcb_desc->empkt_len[1];
}
SET_EARLYMODE_LEN0(virtualaddress, dwtmp);
set_earlymode_len0(virtualaddress, dwtmp);
if (ptcb_desc->empkt_num <= 3) {
dwtmp = ptcb_desc->empkt_len[2];
@ -264,7 +265,7 @@ static void _rtl8723be_insert_emcontent(struct rtl_tcb_desc *ptcb_desc,
dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4;
dwtmp += ptcb_desc->empkt_len[3];
}
SET_EARLYMODE_LEN1(virtualaddress, dwtmp);
set_earlymode_len1(virtualaddress, dwtmp);
if (ptcb_desc->empkt_num <= 5) {
dwtmp = ptcb_desc->empkt_len[4];
} else {
@ -272,8 +273,8 @@ static void _rtl8723be_insert_emcontent(struct rtl_tcb_desc *ptcb_desc,
dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4;
dwtmp += ptcb_desc->empkt_len[5];
}
SET_EARLYMODE_LEN2_1(virtualaddress, dwtmp & 0xF);
SET_EARLYMODE_LEN2_2(virtualaddress, dwtmp >> 4);
set_earlymode_len2_1(virtualaddress, dwtmp & 0xF);
set_earlymode_len2_2(virtualaddress, dwtmp >> 4);
if (ptcb_desc->empkt_num <= 7) {
dwtmp = ptcb_desc->empkt_len[6];
} else {
@ -281,7 +282,7 @@ static void _rtl8723be_insert_emcontent(struct rtl_tcb_desc *ptcb_desc,
dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4;
dwtmp += ptcb_desc->empkt_len[7];
}
SET_EARLYMODE_LEN3(virtualaddress, dwtmp);
set_earlymode_len3(virtualaddress, dwtmp);
if (ptcb_desc->empkt_num <= 9) {
dwtmp = ptcb_desc->empkt_len[8];
} else {
@ -289,51 +290,52 @@ static void _rtl8723be_insert_emcontent(struct rtl_tcb_desc *ptcb_desc,
dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4;
dwtmp += ptcb_desc->empkt_len[9];
}
SET_EARLYMODE_LEN4(virtualaddress, dwtmp);
set_earlymode_len4(virtualaddress, dwtmp);
}
bool rtl8723be_rx_query_desc(struct ieee80211_hw *hw,
struct rtl_stats *status,
struct ieee80211_rx_status *rx_status,
u8 *pdesc, struct sk_buff *skb)
u8 *pdesc8, struct sk_buff *skb)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rx_fwinfo_8723be *p_drvinfo;
struct ieee80211_hdr *hdr;
u8 wake_match;
u32 phystatus = GET_RX_DESC_PHYST(pdesc);
__le32 *pdesc = (__le32 *)pdesc8;
u32 phystatus = get_rx_desc_physt(pdesc);
status->length = (u16)GET_RX_DESC_PKT_LEN(pdesc);
status->rx_drvinfo_size = (u8)GET_RX_DESC_DRV_INFO_SIZE(pdesc) *
status->length = (u16)get_rx_desc_pkt_len(pdesc);
status->rx_drvinfo_size = (u8)get_rx_desc_drv_info_size(pdesc) *
RX_DRV_INFO_SIZE_UNIT;
status->rx_bufshift = (u8)(GET_RX_DESC_SHIFT(pdesc) & 0x03);
status->icv = (u16) GET_RX_DESC_ICV(pdesc);
status->crc = (u16) GET_RX_DESC_CRC32(pdesc);
status->rx_bufshift = (u8)(get_rx_desc_shift(pdesc) & 0x03);
status->icv = (u16)get_rx_desc_icv(pdesc);
status->crc = (u16)get_rx_desc_crc32(pdesc);
status->hwerror = (status->crc | status->icv);
status->decrypted = !GET_RX_DESC_SWDEC(pdesc);
status->rate = (u8)GET_RX_DESC_RXMCS(pdesc);
status->shortpreamble = (u16)GET_RX_DESC_SPLCP(pdesc);
status->isampdu = (bool)(GET_RX_DESC_PAGGR(pdesc) == 1);
status->isfirst_ampdu = (bool)(GET_RX_DESC_PAGGR(pdesc) == 1);
status->timestamp_low = GET_RX_DESC_TSFL(pdesc);
status->rx_is40mhzpacket = (bool)GET_RX_DESC_BW(pdesc);
status->bandwidth = (u8)GET_RX_DESC_BW(pdesc);
status->macid = GET_RX_DESC_MACID(pdesc);
status->is_ht = (bool)GET_RX_DESC_RXHT(pdesc);
status->decrypted = !get_rx_desc_swdec(pdesc);
status->rate = (u8)get_rx_desc_rxmcs(pdesc);
status->shortpreamble = (u16)get_rx_desc_splcp(pdesc);
status->isampdu = (bool)(get_rx_desc_paggr(pdesc) == 1);
status->isfirst_ampdu = (bool)(get_rx_desc_paggr(pdesc) == 1);
status->timestamp_low = get_rx_desc_tsfl(pdesc);
status->rx_is40mhzpacket = (bool)get_rx_desc_bw(pdesc);
status->bandwidth = (u8)get_rx_desc_bw(pdesc);
status->macid = get_rx_desc_macid(pdesc);
status->is_ht = (bool)get_rx_desc_rxht(pdesc);
status->is_cck = RX_HAL_IS_CCK_RATE(status->rate);
if (GET_RX_STATUS_DESC_RPT_SEL(pdesc))
if (get_rx_status_desc_rpt_sel(pdesc))
status->packet_report_type = C2H_PACKET;
else
status->packet_report_type = NORMAL_RX;
if (GET_RX_STATUS_DESC_PATTERN_MATCH(pdesc))
if (get_rx_status_desc_pattern_match(pdesc))
wake_match = BIT(2);
else if (GET_RX_STATUS_DESC_MAGIC_MATCH(pdesc))
else if (get_rx_status_desc_magic_match(pdesc))
wake_match = BIT(1);
else if (GET_RX_STATUS_DESC_UNICAST_MATCH(pdesc))
else if (get_rx_status_desc_unicast_match(pdesc))
wake_match = BIT(0);
else
wake_match = 0;
@ -392,15 +394,15 @@ bool rtl8723be_rx_query_desc(struct ieee80211_hw *hw,
rx_status->signal = status->recvsignalpower + 10;
if (status->packet_report_type == TX_REPORT2) {
status->macid_valid_entry[0] =
GET_RX_RPT2_DESC_MACID_VALID_1(pdesc);
get_rx_rpt2_desc_macid_valid_1(pdesc);
status->macid_valid_entry[1] =
GET_RX_RPT2_DESC_MACID_VALID_2(pdesc);
get_rx_rpt2_desc_macid_valid_2(pdesc);
}
return true;
}
void rtl8723be_tx_fill_desc(struct ieee80211_hw *hw,
struct ieee80211_hdr *hdr, u8 *pdesc_tx,
struct ieee80211_hdr *hdr, u8 *pdesc8,
u8 *txbd, struct ieee80211_tx_info *info,
struct ieee80211_sta *sta, struct sk_buff *skb,
u8 hw_queue, struct rtl_tcb_desc *ptcb_desc)
@ -410,7 +412,7 @@ void rtl8723be_tx_fill_desc(struct ieee80211_hw *hw,
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
struct rtlwifi_tx_info *tx_info = rtl_tx_skb_cb_info(skb);
u8 *pdesc = (u8 *)pdesc_tx;
__le32 *pdesc = (__le32 *)pdesc8;
u16 seq_number;
__le16 fc = hdr->frame_control;
unsigned int buf_len = 0;
@ -446,78 +448,78 @@ void rtl8723be_tx_fill_desc(struct ieee80211_hw *hw,
RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "DMA mapping error\n");
return;
}
CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_8723be));
clear_pci_tx_desc_content(pdesc, sizeof(struct tx_desc_8723be));
if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) {
firstseg = true;
lastseg = true;
}
if (firstseg) {
if (rtlhal->earlymode_enable) {
SET_TX_DESC_PKT_OFFSET(pdesc, 1);
SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN +
set_tx_desc_pkt_offset(pdesc, 1);
set_tx_desc_offset(pdesc, USB_HWDESC_HEADER_LEN +
EM_HDR_LEN);
if (ptcb_desc->empkt_num) {
RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
"Insert 8 byte.pTcb->EMPktNum:%d\n",
ptcb_desc->empkt_num);
_rtl8723be_insert_emcontent(ptcb_desc,
(u8 *)(skb->data));
(__le32 *)(skb->data));
}
} else {
SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
set_tx_desc_offset(pdesc, USB_HWDESC_HEADER_LEN);
}
/* ptcb_desc->use_driver_rate = true; */
SET_TX_DESC_TX_RATE(pdesc, ptcb_desc->hw_rate);
set_tx_desc_tx_rate(pdesc, ptcb_desc->hw_rate);
if (ptcb_desc->hw_rate > DESC92C_RATEMCS0)
short_gi = (ptcb_desc->use_shortgi) ? 1 : 0;
else
short_gi = (ptcb_desc->use_shortpreamble) ? 1 : 0;
SET_TX_DESC_DATA_SHORTGI(pdesc, short_gi);
set_tx_desc_data_shortgi(pdesc, short_gi);
if (info->flags & IEEE80211_TX_CTL_AMPDU) {
SET_TX_DESC_AGG_ENABLE(pdesc, 1);
SET_TX_DESC_MAX_AGG_NUM(pdesc, 0x14);
set_tx_desc_agg_enable(pdesc, 1);
set_tx_desc_max_agg_num(pdesc, 0x14);
}
SET_TX_DESC_SEQ(pdesc, seq_number);
SET_TX_DESC_RTS_ENABLE(pdesc, ((ptcb_desc->rts_enable &&
set_tx_desc_seq(pdesc, seq_number);
set_tx_desc_rts_enable(pdesc, ((ptcb_desc->rts_enable &&
!ptcb_desc->cts_enable) ?
1 : 0));
SET_TX_DESC_HW_RTS_ENABLE(pdesc, 0);
SET_TX_DESC_CTS2SELF(pdesc, ((ptcb_desc->cts_enable) ?
set_tx_desc_hw_rts_enable(pdesc, 0);
set_tx_desc_cts2self(pdesc, ((ptcb_desc->cts_enable) ?
1 : 0));
SET_TX_DESC_RTS_RATE(pdesc, ptcb_desc->rts_rate);
set_tx_desc_rts_rate(pdesc, ptcb_desc->rts_rate);
SET_TX_DESC_RTS_SC(pdesc, ptcb_desc->rts_sc);
SET_TX_DESC_RTS_SHORT(pdesc,
set_tx_desc_rts_sc(pdesc, ptcb_desc->rts_sc);
set_tx_desc_rts_short(pdesc,
((ptcb_desc->rts_rate <= DESC92C_RATE54M) ?
(ptcb_desc->rts_use_shortpreamble ? 1 : 0) :
(ptcb_desc->rts_use_shortgi ? 1 : 0)));
if (ptcb_desc->tx_enable_sw_calc_duration)
SET_TX_DESC_NAV_USE_HDR(pdesc, 1);
set_tx_desc_nav_use_hdr(pdesc, 1);
if (bw_40) {
if (ptcb_desc->packet_bw == HT_CHANNEL_WIDTH_20_40) {
SET_TX_DESC_DATA_BW(pdesc, 1);
SET_TX_DESC_TX_SUB_CARRIER(pdesc, 3);
set_tx_desc_data_bw(pdesc, 1);
set_tx_desc_tx_sub_carrier(pdesc, 3);
} else {
SET_TX_DESC_DATA_BW(pdesc, 0);
SET_TX_DESC_TX_SUB_CARRIER(pdesc, mac->cur_40_prime_sc);
set_tx_desc_data_bw(pdesc, 0);
set_tx_desc_tx_sub_carrier(pdesc, mac->cur_40_prime_sc);
}
} else {
SET_TX_DESC_DATA_BW(pdesc, 0);
SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0);
set_tx_desc_data_bw(pdesc, 0);
set_tx_desc_tx_sub_carrier(pdesc, 0);
}
SET_TX_DESC_LINIP(pdesc, 0);
SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb_len);
set_tx_desc_linip(pdesc, 0);
set_tx_desc_pkt_size(pdesc, (u16)skb_len);
if (sta) {
u8 ampdu_density = sta->ht_cap.ampdu_density;
SET_TX_DESC_AMPDU_DENSITY(pdesc, ampdu_density);
set_tx_desc_ampdu_density(pdesc, ampdu_density);
}
if (info->control.hw_key) {
struct ieee80211_key_conf *keyconf =
@ -526,23 +528,23 @@ void rtl8723be_tx_fill_desc(struct ieee80211_hw *hw,
case WLAN_CIPHER_SUITE_WEP40:
case WLAN_CIPHER_SUITE_WEP104:
case WLAN_CIPHER_SUITE_TKIP:
SET_TX_DESC_SEC_TYPE(pdesc, 0x1);
set_tx_desc_sec_type(pdesc, 0x1);
break;
case WLAN_CIPHER_SUITE_CCMP:
SET_TX_DESC_SEC_TYPE(pdesc, 0x3);
set_tx_desc_sec_type(pdesc, 0x3);
break;
default:
SET_TX_DESC_SEC_TYPE(pdesc, 0x0);
set_tx_desc_sec_type(pdesc, 0x0);
break;
}
}
SET_TX_DESC_QUEUE_SEL(pdesc, fw_qsel);
SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F);
SET_TX_DESC_RTS_RATE_FB_LIMIT(pdesc, 0xF);
SET_TX_DESC_DISABLE_FB(pdesc, ptcb_desc->disable_ratefallback ?
set_tx_desc_queue_sel(pdesc, fw_qsel);
set_tx_desc_data_rate_fb_limit(pdesc, 0x1F);
set_tx_desc_rts_rate_fb_limit(pdesc, 0xF);
set_tx_desc_disable_fb(pdesc, ptcb_desc->disable_ratefallback ?
1 : 0);
SET_TX_DESC_USE_RATE(pdesc, ptcb_desc->use_driver_rate ? 1 : 0);
set_tx_desc_use_rate(pdesc, ptcb_desc->use_driver_rate ? 1 : 0);
/* Set TxRate and RTSRate in TxDesc */
/* This prevent Tx initial rate of new-coming packets */
@ -551,46 +553,47 @@ void rtl8723be_tx_fill_desc(struct ieee80211_hw *hw,
if (mac->rdg_en) {
RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
"Enable RDG function.\n");
SET_TX_DESC_RDG_ENABLE(pdesc, 1);
SET_TX_DESC_HTC(pdesc, 1);
set_tx_desc_rdg_enable(pdesc, 1);
set_tx_desc_htc(pdesc, 1);
}
}
/* tx report */
rtl_set_tx_report(ptcb_desc, pdesc, hw, tx_info);
rtl_set_tx_report(ptcb_desc, pdesc8, hw, tx_info);
}
SET_TX_DESC_FIRST_SEG(pdesc, (firstseg ? 1 : 0));
SET_TX_DESC_LAST_SEG(pdesc, (lastseg ? 1 : 0));
SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) buf_len);
SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
set_tx_desc_first_seg(pdesc, (firstseg ? 1 : 0));
set_tx_desc_last_seg(pdesc, (lastseg ? 1 : 0));
set_tx_desc_tx_buffer_size(pdesc, (u16)buf_len);
set_tx_desc_tx_buffer_address(pdesc, mapping);
/* if (rtlpriv->dm.useramask) { */
if (1) {
SET_TX_DESC_RATE_ID(pdesc, ptcb_desc->ratr_index);
SET_TX_DESC_MACID(pdesc, ptcb_desc->mac_id);
set_tx_desc_rate_id(pdesc, ptcb_desc->ratr_index);
set_tx_desc_macid(pdesc, ptcb_desc->mac_id);
} else {
SET_TX_DESC_RATE_ID(pdesc, 0xC + ptcb_desc->ratr_index);
SET_TX_DESC_MACID(pdesc, ptcb_desc->mac_id);
set_tx_desc_rate_id(pdesc, 0xC + ptcb_desc->ratr_index);
set_tx_desc_macid(pdesc, ptcb_desc->mac_id);
}
if (!ieee80211_is_data_qos(fc)) {
SET_TX_DESC_HWSEQ_EN(pdesc, 1);
SET_TX_DESC_HWSEQ_SEL(pdesc, 0);
set_tx_desc_hwseq_en(pdesc, 1);
set_tx_desc_hwseq_sel(pdesc, 0);
}
SET_TX_DESC_MORE_FRAG(pdesc, (lastseg ? 0 : 1));
set_tx_desc_more_frag(pdesc, (lastseg ? 0 : 1));
if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) ||
is_broadcast_ether_addr(ieee80211_get_DA(hdr))) {
SET_TX_DESC_BMC(pdesc, 1);
set_tx_desc_bmc(pdesc, 1);
}
RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "\n");
}
void rtl8723be_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
void rtl8723be_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc8,
bool firstseg, bool lastseg,
struct sk_buff *skb)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
u8 fw_queue = QSLT_BEACON;
__le32 *pdesc = (__le32 *)pdesc8;
dma_addr_t mapping = pci_map_single(rtlpci->pdev,
skb->data, skb->len,
@ -601,51 +604,53 @@ void rtl8723be_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
"DMA mapping error\n");
return;
}
CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE);
clear_pci_tx_desc_content(pdesc, TX_DESC_SIZE);
SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
set_tx_desc_offset(pdesc, USB_HWDESC_HEADER_LEN);
SET_TX_DESC_TX_RATE(pdesc, DESC92C_RATE1M);
set_tx_desc_tx_rate(pdesc, DESC92C_RATE1M);
SET_TX_DESC_SEQ(pdesc, 0);
set_tx_desc_seq(pdesc, 0);
SET_TX_DESC_LINIP(pdesc, 0);
set_tx_desc_linip(pdesc, 0);
SET_TX_DESC_QUEUE_SEL(pdesc, fw_queue);
set_tx_desc_queue_sel(pdesc, fw_queue);
SET_TX_DESC_FIRST_SEG(pdesc, 1);
SET_TX_DESC_LAST_SEG(pdesc, 1);
set_tx_desc_first_seg(pdesc, 1);
set_tx_desc_last_seg(pdesc, 1);
SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16)(skb->len));
set_tx_desc_tx_buffer_size(pdesc, (u16)(skb->len));
SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
set_tx_desc_tx_buffer_address(pdesc, mapping);
SET_TX_DESC_RATE_ID(pdesc, 0);
SET_TX_DESC_MACID(pdesc, 0);
set_tx_desc_rate_id(pdesc, 0);
set_tx_desc_macid(pdesc, 0);
SET_TX_DESC_OWN(pdesc, 1);
set_tx_desc_own(pdesc, 1);
SET_TX_DESC_PKT_SIZE((u8 *)pdesc, (u16)(skb->len));
set_tx_desc_pkt_size(pdesc, (u16)(skb->len));
SET_TX_DESC_FIRST_SEG(pdesc, 1);
SET_TX_DESC_LAST_SEG(pdesc, 1);
set_tx_desc_first_seg(pdesc, 1);
set_tx_desc_last_seg(pdesc, 1);
SET_TX_DESC_USE_RATE(pdesc, 1);
set_tx_desc_use_rate(pdesc, 1);
RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
"H2C Tx Cmd Content\n", pdesc, TX_DESC_SIZE);
}
void rtl8723be_set_desc(struct ieee80211_hw *hw, u8 *pdesc,
void rtl8723be_set_desc(struct ieee80211_hw *hw, u8 *pdesc8,
bool istx, u8 desc_name, u8 *val)
{
__le32 *pdesc = (__le32 *)pdesc8;
if (istx) {
switch (desc_name) {
case HW_DESC_OWN:
SET_TX_DESC_OWN(pdesc, 1);
set_tx_desc_own(pdesc, 1);
break;
case HW_DESC_TX_NEXTDESC_ADDR:
SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *)val);
set_tx_desc_next_desc_address(pdesc, *(u32 *)val);
break;
default:
WARN_ONCE(true, "rtl8723be: ERR txdesc :%d not processed\n",
@ -655,16 +660,16 @@ void rtl8723be_set_desc(struct ieee80211_hw *hw, u8 *pdesc,
} else {
switch (desc_name) {
case HW_DESC_RXOWN:
SET_RX_DESC_OWN(pdesc, 1);
set_rx_desc_own(pdesc, 1);
break;
case HW_DESC_RXBUFF_ADDR:
SET_RX_DESC_BUFF_ADDR(pdesc, *(u32 *)val);
set_rx_desc_buff_addr(pdesc, *(u32 *)val);
break;
case HW_DESC_RXPKT_LEN:
SET_RX_DESC_PKT_LEN(pdesc, *(u32 *)val);
set_rx_desc_pkt_len(pdesc, *(u32 *)val);
break;
case HW_DESC_RXERO:
SET_RX_DESC_EOR(pdesc, 1);
set_rx_desc_eor(pdesc, 1);
break;
default:
WARN_ONCE(true, "rtl8723be: ERR rxdesc :%d not process\n",
@ -675,17 +680,18 @@ void rtl8723be_set_desc(struct ieee80211_hw *hw, u8 *pdesc,
}
u64 rtl8723be_get_desc(struct ieee80211_hw *hw,
u8 *pdesc, bool istx, u8 desc_name)
u8 *pdesc8, bool istx, u8 desc_name)
{
u32 ret = 0;
__le32 *pdesc = (__le32 *)pdesc8;
if (istx) {
switch (desc_name) {
case HW_DESC_OWN:
ret = GET_TX_DESC_OWN(pdesc);
ret = get_tx_desc_own(pdesc);
break;
case HW_DESC_TXBUFF_ADDR:
ret = GET_TX_DESC_TX_BUFFER_ADDRESS(pdesc);
ret = get_tx_desc_tx_buffer_address(pdesc);
break;
default:
WARN_ONCE(true, "rtl8723be: ERR txdesc :%d not process\n",
@ -695,13 +701,13 @@ u64 rtl8723be_get_desc(struct ieee80211_hw *hw,
} else {
switch (desc_name) {
case HW_DESC_OWN:
ret = GET_RX_DESC_OWN(pdesc);
ret = get_rx_desc_own(pdesc);
break;
case HW_DESC_RXPKT_LEN:
ret = GET_RX_DESC_PKT_LEN(pdesc);
ret = get_rx_desc_pkt_len(pdesc);
break;
case HW_DESC_RXBUFF_ADDR:
ret = GET_RX_DESC_BUFF_ADDR(pdesc);
ret = get_rx_desc_buff_addr(pdesc);
break;
default:
WARN_ONCE(true, "rtl8723be: ERR rxdesc :%d not processed\n",

View File

@ -14,351 +14,385 @@
#define USB_HWDESC_HEADER_LEN 40
#define CRCLENGTH 4
#define SET_TX_DESC_PKT_SIZE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 0, 16, __val)
#define SET_TX_DESC_OFFSET(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 16, 8, __val)
#define SET_TX_DESC_BMC(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 24, 1, __val)
#define SET_TX_DESC_HTC(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 25, 1, __val)
#define SET_TX_DESC_LAST_SEG(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 26, 1, __val)
#define SET_TX_DESC_FIRST_SEG(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 27, 1, __val)
#define SET_TX_DESC_LINIP(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 28, 1, __val)
#define SET_TX_DESC_NO_ACM(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 29, 1, __val)
#define SET_TX_DESC_GF(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 30, 1, __val)
#define SET_TX_DESC_OWN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val)
static inline void set_tx_desc_pkt_size(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits(__pdesc, __val, GENMASK(15, 0));
}
#define GET_TX_DESC_PKT_SIZE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 0, 16)
#define GET_TX_DESC_OFFSET(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 16, 8)
#define GET_TX_DESC_BMC(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 24, 1)
#define GET_TX_DESC_HTC(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 25, 1)
#define GET_TX_DESC_LAST_SEG(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 26, 1)
#define GET_TX_DESC_FIRST_SEG(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 27, 1)
#define GET_TX_DESC_LINIP(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 28, 1)
#define GET_TX_DESC_NO_ACM(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 29, 1)
#define GET_TX_DESC_GF(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 30, 1)
#define GET_TX_DESC_OWN(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 31, 1)
static inline void set_tx_desc_offset(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits(__pdesc, __val, GENMASK(23, 16));
}
#define SET_TX_DESC_MACID(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+4, 0, 7, __val)
#define SET_TX_DESC_QUEUE_SEL(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+4, 8, 5, __val)
#define SET_TX_DESC_RDG_NAV_EXT(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+4, 13, 1, __val)
#define SET_TX_DESC_LSIG_TXOP_EN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+4, 14, 1, __val)
#define SET_TX_DESC_PIFS(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+4, 15, 1, __val)
#define SET_TX_DESC_RATE_ID(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+4, 16, 5, __val)
#define SET_TX_DESC_EN_DESC_ID(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+4, 21, 1, __val)
#define SET_TX_DESC_SEC_TYPE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+4, 22, 2, __val)
#define SET_TX_DESC_PKT_OFFSET(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+4, 24, 5, __val)
static inline void set_tx_desc_bmc(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits(__pdesc, __val, BIT(24));
}
static inline void set_tx_desc_htc(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits(__pdesc, __val, BIT(25));
}
#define SET_TX_DESC_PAID(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 0, 9, __val)
#define SET_TX_DESC_CCA_RTS(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 10, 2, __val)
#define SET_TX_DESC_AGG_ENABLE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 12, 1, __val)
#define SET_TX_DESC_RDG_ENABLE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 13, 1, __val)
#define SET_TX_DESC_BAR_RTY_TH(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE((__pdesc) + 8, 14, 2, __val)
#define SET_TX_DESC_AGG_BREAK(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 16, 1, __val)
#define SET_TX_DESC_MORE_FRAG(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 17, 1, __val)
#define SET_TX_DESC_RAW(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 18, 1, __val)
#define SET_TX_DESC_SPE_RPT(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE((__pdesc) + 8, 19, 1, __val)
#define SET_TX_DESC_AMPDU_DENSITY(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 20, 3, __val)
#define SET_TX_DESC_BT_INT(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 23, 1, __val)
#define SET_TX_DESC_GID(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+8, 24, 6, __val)
static inline void set_tx_desc_last_seg(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits(__pdesc, __val, BIT(26));
}
static inline void set_tx_desc_first_seg(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits(__pdesc, __val, BIT(27));
}
#define SET_TX_DESC_WHEADER_LEN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+12, 0, 4, __val)
#define SET_TX_DESC_CHK_EN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+12, 4, 1, __val)
#define SET_TX_DESC_EARLY_MODE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+12, 5, 1, __val)
#define SET_TX_DESC_HWSEQ_SEL(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+12, 6, 2, __val)
#define SET_TX_DESC_USE_RATE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+12, 8, 1, __val)
#define SET_TX_DESC_DISABLE_RTS_FB(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+12, 9, 1, __val)
#define SET_TX_DESC_DISABLE_FB(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+12, 10, 1, __val)
#define SET_TX_DESC_CTS2SELF(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+12, 11, 1, __val)
#define SET_TX_DESC_RTS_ENABLE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+12, 12, 1, __val)
#define SET_TX_DESC_HW_RTS_ENABLE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+12, 13, 1, __val)
#define SET_TX_DESC_NAV_USE_HDR(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+12, 15, 1, __val)
#define SET_TX_DESC_USE_MAX_LEN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+12, 16, 1, __val)
#define SET_TX_DESC_MAX_AGG_NUM(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+12, 17, 5, __val)
#define SET_TX_DESC_NDPA(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+12, 22, 2, __val)
#define SET_TX_DESC_AMPDU_MAX_TIME(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+12, 24, 8, __val)
static inline void set_tx_desc_linip(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits(__pdesc, __val, BIT(28));
}
static inline void set_tx_desc_own(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits(__pdesc, __val, BIT(31));
}
#define SET_TX_DESC_TX_RATE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 0, 7, __val)
#define SET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 8, 5, __val)
#define SET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 13, 4, __val)
#define SET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 17, 1, __val)
#define SET_TX_DESC_DATA_RETRY_LIMIT(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 18, 6, __val)
#define SET_TX_DESC_RTS_RATE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+16, 24, 5, __val)
static inline u32 get_tx_desc_own(__le32 *__pdesc)
{
return le32_get_bits(*__pdesc, BIT(31));
}
static inline void set_tx_desc_macid(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 1), __val, GENMASK(6, 0));
}
#define SET_TX_DESC_TX_SUB_CARRIER(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+20, 0, 4, __val)
#define SET_TX_DESC_DATA_SHORTGI(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+20, 4, 1, __val)
#define SET_TX_DESC_DATA_BW(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+20, 5, 2, __val)
#define SET_TX_DESC_DATA_LDPC(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+20, 7, 1, __val)
#define SET_TX_DESC_DATA_STBC(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+20, 8, 2, __val)
#define SET_TX_DESC_CTROL_STBC(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+20, 10, 2, __val)
#define SET_TX_DESC_RTS_SHORT(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+20, 12, 1, __val)
#define SET_TX_DESC_RTS_SC(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+20, 13, 4, __val)
static inline void set_tx_desc_queue_sel(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 1), __val, GENMASK(12, 8));
}
#define SET_TX_DESC_SW_DEFINE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE((__pdesc) + 24, 0, 12, __val)
#define SET_TX_DESC_MBSSID(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE((__pdesc) + 24, 12, 4, __val)
#define SET_TX_DESC_ANTSEL_A(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE((__pdesc) + 24, 16, 3, __val)
#define SET_TX_DESC_ANTSEL_B(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE((__pdesc) + 24, 19, 3, __val)
#define SET_TX_DESC_ANTSEL_C(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE((__pdesc) + 24, 22, 3, __val)
#define SET_TX_DESC_ANTSEL_D(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE((__pdesc) + 24, 25, 3, __val)
static inline void set_tx_desc_rate_id(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 1), __val, GENMASK(20, 16));
}
#define SET_TX_DESC_TX_BUFFER_SIZE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+28, 0, 16, __val)
static inline void set_tx_desc_sec_type(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 1), __val, GENMASK(23, 22));
}
#define GET_TX_DESC_TX_BUFFER_SIZE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+28, 0, 16)
static inline void set_tx_desc_pkt_offset(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 1), __val, GENMASK(28, 24));
}
#define SET_TX_DESC_HWSEQ_EN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+32, 15, 1, __val)
static inline void set_tx_desc_agg_enable(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 2), __val, BIT(12));
}
#define SET_TX_DESC_SEQ(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+36, 12, 12, __val)
static inline void set_tx_desc_rdg_enable(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 2), __val, BIT(13));
}
#define SET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+40, 0, 32, __val)
static inline void set_tx_desc_more_frag(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 2), __val, BIT(17));
}
#define GET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+40, 0, 32)
static inline void set_tx_desc_ampdu_density(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 2), __val, GENMASK(22, 20));
}
static inline void set_tx_desc_hwseq_sel(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 3), __val, GENMASK(7, 6));
}
#define SET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+48, 0, 32, __val)
static inline void set_tx_desc_use_rate(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 3), __val, BIT(8));
}
#define GET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+48, 0, 32)
static inline void set_tx_desc_disable_fb(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 3), __val, BIT(10));
}
#define GET_RX_DESC_PKT_LEN(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 0, 14)
#define GET_RX_DESC_CRC32(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 14, 1)
#define GET_RX_DESC_ICV(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 15, 1)
#define GET_RX_DESC_DRV_INFO_SIZE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 16, 4)
#define GET_RX_DESC_SECURITY(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 20, 3)
#define GET_RX_DESC_QOS(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 23, 1)
#define GET_RX_DESC_SHIFT(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 24, 2)
#define GET_RX_DESC_PHYST(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 26, 1)
#define GET_RX_DESC_SWDEC(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 27, 1)
#define GET_RX_DESC_LS(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 28, 1)
#define GET_RX_DESC_FS(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 29, 1)
#define GET_RX_DESC_EOR(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 30, 1)
#define GET_RX_DESC_OWN(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc, 31, 1)
static inline void set_tx_desc_cts2self(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 3), __val, BIT(11));
}
#define SET_RX_DESC_PKT_LEN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 0, 14, __val)
#define SET_RX_DESC_EOR(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 30, 1, __val)
#define SET_RX_DESC_OWN(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val)
static inline void set_tx_desc_rts_enable(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 3), __val, BIT(12));
}
#define GET_RX_DESC_MACID(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 0, 7)
#define GET_RX_DESC_TID(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 8, 4)
#define GET_RX_DESC_AMSDU(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 13, 1)
#define GET_RX_STATUS_DESC_RXID_MATCH(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 14, 1)
#define GET_RX_DESC_PAGGR(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 15, 1)
#define GET_RX_DESC_A1_FIT(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 16, 4)
#define GET_RX_DESC_CHKERR(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 20, 1)
#define GET_RX_DESC_IPVER(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 21, 1)
#define GET_RX_STATUS_DESC_IS_TCPUDP(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 22, 1)
#define GET_RX_STATUS_DESC_CHK_VLD(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 23, 1)
#define GET_RX_DESC_PAM(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 24, 1)
#define GET_RX_DESC_PWR(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 25, 1)
#define GET_RX_DESC_MD(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 26, 1)
#define GET_RX_DESC_MF(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 27, 1)
#define GET_RX_DESC_TYPE(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 28, 2)
#define GET_RX_DESC_MC(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 30, 1)
#define GET_RX_DESC_BC(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+4, 31, 1)
static inline void set_tx_desc_hw_rts_enable(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 3), __val, BIT(13));
}
static inline void set_tx_desc_nav_use_hdr(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 3), __val, BIT(15));
}
#define GET_RX_DESC_SEQ(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 0, 12)
#define GET_RX_DESC_FRAG(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 12, 4)
#define GET_RX_STATUS_DESC_RX_IS_QOS(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 16, 1)
#define GET_RX_STATUS_DESC_WLANHD_IV_LEN(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 18, 6)
#define GET_RX_STATUS_DESC_RPT_SEL(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+8, 28, 1)
static inline void set_tx_desc_max_agg_num(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 3), __val, GENMASK(21, 17));
}
static inline void set_tx_desc_tx_rate(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 4), __val, GENMASK(6, 0));
}
#define GET_RX_DESC_RXMCS(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 0, 7)
#define GET_RX_DESC_RXHT(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 6, 1)
#define GET_RX_STATUS_DESC_RX_GF(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 7, 1)
#define GET_RX_DESC_HTC(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 10, 1)
#define GET_RX_STATUS_DESC_EOSP(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 11, 1)
#define GET_RX_STATUS_DESC_BSSID_FIT(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 12, 2)
static inline void set_tx_desc_data_rate_fb_limit(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 4), __val, GENMASK(12, 8));
}
#define GET_RX_STATUS_DESC_PATTERN_MATCH(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 29, 1)
#define GET_RX_STATUS_DESC_UNICAST_MATCH(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 30, 1)
#define GET_RX_STATUS_DESC_MAGIC_MATCH(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+12, 31, 1)
static inline void set_tx_desc_rts_rate_fb_limit(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 4), __val, GENMASK(16, 13));
}
#define GET_RX_DESC_SPLCP(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 0, 1)
#define GET_RX_STATUS_DESC_LDPC(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 1, 1)
#define GET_RX_STATUS_DESC_STBC(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 2, 1)
#define GET_RX_DESC_BW(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+16, 4, 2)
static inline void set_tx_desc_rts_rate(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 4), __val, GENMASK(28, 24));
}
#define GET_RX_DESC_TSFL(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+20, 0, 32)
static inline void set_tx_desc_tx_sub_carrier(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 5), __val, GENMASK(3, 0));
}
#define GET_RX_DESC_BUFF_ADDR(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+24, 0, 32)
#define GET_RX_DESC_BUFF_ADDR64(__pdesc) \
LE_BITS_TO_4BYTE(__pdesc+28, 0, 32)
static inline void set_tx_desc_data_shortgi(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 5), __val, BIT(4));
}
#define SET_RX_DESC_BUFF_ADDR(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+24, 0, 32, __val)
#define SET_RX_DESC_BUFF_ADDR64(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+28, 0, 32, __val)
static inline void set_tx_desc_data_bw(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 5), __val, GENMASK(6, 5));
}
static inline void set_tx_desc_rts_short(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 5), __val, BIT(12));
}
static inline void set_tx_desc_rts_sc(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 5), __val, GENMASK(16, 13));
}
static inline void set_tx_desc_tx_buffer_size(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 7), __val, GENMASK(15, 0));
}
static inline void set_tx_desc_hwseq_en(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 8), __val, BIT(15));
}
static inline void set_tx_desc_seq(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits((__pdesc + 9), __val, GENMASK(23, 12));
}
static inline void set_tx_desc_tx_buffer_address(__le32 *__pdesc, u32 __val)
{
*(__pdesc + 10) = cpu_to_le32(__val);
}
static inline u32 get_tx_desc_tx_buffer_address(__le32 *__pdesc)
{
return le32_to_cpu(*((__pdesc + 10)));
}
static inline void set_tx_desc_next_desc_address(__le32 *__pdesc, u32 __val)
{
*(__pdesc + 12) = cpu_to_le32(__val);
}
static inline u32 get_rx_desc_pkt_len(__le32 *__pdesc)
{
return le32_get_bits(*__pdesc, GENMASK(13, 0));
}
static inline u32 get_rx_desc_crc32(__le32 *__pdesc)
{
return le32_get_bits(*__pdesc, BIT(14));
}
static inline u32 get_rx_desc_icv(__le32 *__pdesc)
{
return le32_get_bits(*__pdesc, BIT(15));
}
static inline u32 get_rx_desc_drv_info_size(__le32 *__pdesc)
{
return le32_get_bits(*__pdesc, GENMASK(19, 16));
}
static inline u32 get_rx_desc_shift(__le32 *__pdesc)
{
return le32_get_bits(*__pdesc, GENMASK(25, 24));
}
static inline u32 get_rx_desc_physt(__le32 *__pdesc)
{
return le32_get_bits(*__pdesc, BIT(26));
}
static inline u32 get_rx_desc_swdec(__le32 *__pdesc)
{
return le32_get_bits(*__pdesc, BIT(27));
}
static inline u32 get_rx_desc_own(__le32 *__pdesc)
{
return le32_get_bits(*__pdesc, BIT(31));
}
static inline void set_rx_desc_pkt_len(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits(__pdesc, __val, GENMASK(13, 0));
}
static inline void set_rx_desc_eor(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits(__pdesc, __val, BIT(30));
}
static inline void set_rx_desc_own(__le32 *__pdesc, u32 __val)
{
le32p_replace_bits(__pdesc, __val, BIT(31));
}
static inline u32 get_rx_desc_macid(__le32 *__pdesc)
{
return le32_get_bits(*(__pdesc + 1), GENMASK(6, 0));
}
static inline u32 get_rx_desc_paggr(__le32 *__pdesc)
{
return le32_get_bits(*(__pdesc + 1), BIT(15));
}
static inline u32 get_rx_status_desc_rpt_sel(__le32 *__pdesc)
{
return le32_get_bits(*(__pdesc + 2), BIT(28));
}
static inline u32 get_rx_desc_rxmcs(__le32 *__pdesc)
{
return le32_get_bits(*(__pdesc + 3), GENMASK(6, 0));
}
static inline u32 get_rx_desc_rxht(__le32 *__pdesc)
{
return le32_get_bits(*(__pdesc + 3), BIT(6));
}
static inline u32 get_rx_status_desc_pattern_match(__le32 *__pdesc)
{
return le32_get_bits(*(__pdesc + 3), BIT(29));
}
static inline u32 get_rx_status_desc_unicast_match(__le32 *__pdesc)
{
return le32_get_bits(*(__pdesc + 3), BIT(30));
}
static inline u32 get_rx_status_desc_magic_match(__le32 *__pdesc)
{
return le32_get_bits(*(__pdesc + 3), BIT(31));
}
static inline u32 get_rx_desc_splcp(__le32 *__pdesc)
{
return le32_get_bits(*(__pdesc + 4), BIT(0));
}
static inline u32 get_rx_desc_bw(__le32 *__pdesc)
{
return le32_get_bits(*(__pdesc + 4), GENMASK(5, 4));
}
static inline u32 get_rx_desc_tsfl(__le32 *__pdesc)
{
return le32_to_cpu(*((__pdesc + 5)));
}
static inline u32 get_rx_desc_buff_addr(__le32 *__pdesc)
{
return le32_to_cpu(*((__pdesc + 6)));
}
static inline void set_rx_desc_buff_addr(__le32 *__pdesc, u32 __val)
{
*(__pdesc + 6) = cpu_to_le32(__val);
}
/* TX report 2 format in Rx desc*/
#define GET_RX_RPT2_DESC_PKT_LEN(__rxstatusdesc) \
LE_BITS_TO_4BYTE(__rxstatusdesc, 0, 9)
#define GET_RX_RPT2_DESC_MACID_VALID_1(__rxstatusdesc) \
LE_BITS_TO_4BYTE(__rxstatusdesc+16, 0, 32)
#define GET_RX_RPT2_DESC_MACID_VALID_2(__rxstatusdesc) \
LE_BITS_TO_4BYTE(__rxstatusdesc+20, 0, 32)
static inline u32 get_rx_rpt2_desc_macid_valid_1(__le32 *__rxstatusdesc)
{
return le32_to_cpu(*((__rxstatusdesc + 4)));
}
#define SET_EARLYMODE_PKTNUM(__paddr, __value) \
SET_BITS_TO_LE_4BYTE(__paddr, 0, 4, __value)
#define SET_EARLYMODE_LEN0(__paddr, __value) \
SET_BITS_TO_LE_4BYTE(__paddr, 4, 12, __value)
#define SET_EARLYMODE_LEN1(__paddr, __value) \
SET_BITS_TO_LE_4BYTE(__paddr, 16, 12, __value)
#define SET_EARLYMODE_LEN2_1(__paddr, __value) \
SET_BITS_TO_LE_4BYTE(__paddr, 28, 4, __value)
#define SET_EARLYMODE_LEN2_2(__paddr, __value) \
SET_BITS_TO_LE_4BYTE(__paddr+4, 0, 8, __value)
#define SET_EARLYMODE_LEN3(__paddr, __value) \
SET_BITS_TO_LE_4BYTE(__paddr+4, 8, 12, __value)
#define SET_EARLYMODE_LEN4(__paddr, __value) \
SET_BITS_TO_LE_4BYTE(__paddr+4, 20, 12, __value)
static inline u32 get_rx_rpt2_desc_macid_valid_2(__le32 *__rxstatusdesc)
{
return le32_to_cpu(*((__rxstatusdesc + 5)));
}
#define CLEAR_PCI_TX_DESC_CONTENT(__pdesc, _size) \
do { \
if (_size > TX_DESC_NEXT_DESC_OFFSET) \
memset(__pdesc, 0, TX_DESC_NEXT_DESC_OFFSET); \
else \
memset(__pdesc, 0, _size); \
} while (0)
static inline void set_earlymode_pktnum(__le32 *__paddr, u32 __value)
{
le32p_replace_bits(__paddr, __value, GENMASK(3, 0));
}
static inline void set_earlymode_len0(__le32 *__paddr, u32 __value)
{
le32p_replace_bits(__paddr, __value, GENMASK(15, 4));
}
static inline void set_earlymode_len1(__le32 *__paddr, u32 __value)
{
le32p_replace_bits(__paddr, __value, GENMASK(27, 16));
}
static inline void set_earlymode_len2_1(__le32 *__paddr, u32 __value)
{
le32p_replace_bits(__paddr, __value, GENMASK(31, 28));
}
static inline void set_earlymode_len2_2(__le32 *__paddr, u32 __value)
{
le32p_replace_bits((__paddr + 1), __value, GENMASK(7, 0));
}
static inline void set_earlymode_len3(__le32 *__paddr, u32 __value)
{
le32p_replace_bits((__paddr + 1), __value, GENMASK(19, 8));
}
static inline void set_earlymode_len4(__le32 *__paddr, u32 __value)
{
le32p_replace_bits((__paddr + 1), __value, GENMASK(31, 20));
}
static inline void clear_pci_tx_desc_content(__le32 *__pdesc, u32 _size)
{
if (_size > TX_DESC_NEXT_DESC_OFFSET)
memset(__pdesc, 0, TX_DESC_NEXT_DESC_OFFSET);
else
memset(__pdesc, 0, _size);
}
struct phy_rx_agc_info_t {
#ifdef __LITTLE_ENDIAN

View File

@ -107,37 +107,6 @@
#define MAX_RX_DMA_BUFFER_SIZE_8812 0x3E80
#define C2H_RX_CMD_HDR_LEN 8
#define GET_C2H_CMD_CMD_LEN(__prxhdr) \
LE_BITS_TO_4BYTE((__prxhdr), 0, 16)
#define GET_C2H_CMD_ELEMENT_ID(__prxhdr) \
LE_BITS_TO_4BYTE((__prxhdr), 16, 8)
#define GET_C2H_CMD_CMD_SEQ(__prxhdr) \
LE_BITS_TO_4BYTE((__prxhdr), 24, 7)
#define GET_C2H_CMD_CONTINUE(__prxhdr) \
LE_BITS_TO_4BYTE((__prxhdr), 31, 1)
#define GET_C2H_CMD_CONTENT(__prxhdr) \
((u8 *)(__prxhdr) + C2H_RX_CMD_HDR_LEN)
#define GET_C2H_CMD_FEEDBACK_ELEMENT_ID(__pcmdfbhdr) \
LE_BITS_TO_4BYTE((__pcmdfbhdr), 0, 8)
#define GET_C2H_CMD_FEEDBACK_CCX_LEN(__pcmdfbhdr) \
LE_BITS_TO_4BYTE((__pcmdfbhdr), 8, 8)
#define GET_C2H_CMD_FEEDBACK_CCX_CMD_CNT(__pcmdfbhdr) \
LE_BITS_TO_4BYTE((__pcmdfbhdr), 16, 16)
#define GET_C2H_CMD_FEEDBACK_CCX_MAC_ID(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 0, 5)
#define GET_C2H_CMD_FEEDBACK_CCX_VALID(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 7, 1)
#define GET_C2H_CMD_FEEDBACK_CCX_RETRY_CNT(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 8, 5)
#define GET_C2H_CMD_FEEDBACK_CCX_TOK(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 15, 1)
#define GET_C2H_CMD_FEEDBACK_CCX_QSEL(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 16, 4)
#define GET_C2H_CMD_FEEDBACK_CCX_SEQ(__pcmdfbhdr) \
LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 20, 12)
#define CHIP_BONDING_IDENTIFIER(_value) (((_value)>>22)&0x3)
#define CHIP_8812 BIT(2)

View File

@ -3613,14 +3613,14 @@ u8 rtl8821ae_phy_sw_chnl(struct ieee80211_hw *hw)
u8 _rtl8812ae_get_right_chnl_place_for_iqk(u8 chnl)
{
u8 channel_all[TARGET_CHNL_NUM_2G_5G_8812] = {
static const u8 channel_all[TARGET_CHNL_NUM_2G_5G_8812] = {
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
14, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54,
56, 58, 60, 62, 64, 100, 102, 104, 106, 108,
110, 112, 114, 116, 118, 120, 122, 124, 126,
128, 130, 132, 134, 136, 138, 140, 149, 151,
153, 155, 157, 159, 161, 163, 165};
u8 place = chnl;
u8 place;
if (chnl > 14) {
for (place = 14; place < sizeof(channel_all); place++)

View File

@ -721,7 +721,7 @@ static void rtw_coex_set_rf_para(struct rtw_dev *rtwdev,
rtw_coex_set_bt_rx_gain(rtwdev, para.bt_lna_lvl);
}
static u32 rtw_coex_read_indirect_reg(struct rtw_dev *rtwdev, u16 addr)
u32 rtw_coex_read_indirect_reg(struct rtw_dev *rtwdev, u16 addr)
{
u32 val;

View File

@ -346,6 +346,7 @@ void rtw_coex_set_wl_rx_gain(struct rtw_dev *rtwdev, bool low_gain)
}
void rtw_coex_info_response(struct rtw_dev *rtwdev, struct sk_buff *skb);
u32 rtw_coex_read_indirect_reg(struct rtw_dev *rtwdev, u16 addr);
void rtw_coex_write_indirect_reg(struct rtw_dev *rtwdev, u16 addr,
u32 mask, u32 val);
void rtw_coex_write_scbd(struct rtw_dev *rtwdev, u16 bitpos, bool set);

View File

@ -256,7 +256,7 @@ static void rtw_ops_bss_info_changed(struct ieee80211_hw *hw,
if (conf->assoc) {
rtw_coex_connect_notify(rtwdev, COEX_ASSOCIATE_FINISH);
net_type = RTW_NET_MGD_LINKED;
chip->ops->do_iqk(rtwdev);
chip->ops->phy_calibration(rtwdev);
rtwvif->aid = conf->aid;
rtw_add_rsvd_page(rtwdev, RSVD_PS_POLL, true);

View File

@ -1236,6 +1236,7 @@ int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw)
ieee80211_hw_set(hw, SUPPORTS_PS);
ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS);
ieee80211_hw_set(hw, SUPPORT_FAST_XMIT);
ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU);
hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_AP) |

View File

@ -640,7 +640,9 @@ struct rtw_chip_ops {
u8 antenna_rx);
void (*cfg_ldo25)(struct rtw_dev *rtwdev, bool enable);
void (*false_alarm_statistics)(struct rtw_dev *rtwdev);
void (*do_iqk)(struct rtw_dev *rtwdev);
void (*phy_calibration)(struct rtw_dev *rtwdev);
void (*dpk_track)(struct rtw_dev *rtwdev);
void (*cck_pd_set)(struct rtw_dev *rtwdev, u8 level);
/* for coex */
void (*coex_set_init)(struct rtw_dev *rtwdev);
@ -864,6 +866,9 @@ struct rtw_chip_info {
const struct rtw_rfe_def *rfe_defs;
u32 rfe_defs_size;
bool en_dis_dpd;
u16 dpd_ratemask;
/* coex paras */
u32 coex_para_ver;
u8 bt_desired_ver;
@ -1075,6 +1080,44 @@ struct rtw_coex {
struct delayed_work defreeze_work;
};
#define DPK_RF_REG_NUM 7
#define DPK_RF_PATH_NUM 2
#define DPK_BB_REG_NUM 18
#define DPK_CHANNEL_WIDTH_80 1
DECLARE_EWMA(thermal, 10, 4);
struct rtw_dpk_info {
bool is_dpk_pwr_on;
bool is_reload;
DECLARE_BITMAP(dpk_path_ok, DPK_RF_PATH_NUM);
u8 thermal_dpk[DPK_RF_PATH_NUM];
struct ewma_thermal avg_thermal[DPK_RF_PATH_NUM];
u32 gnt_control;
u32 gnt_value;
u8 result[RTW_RF_PATH_MAX];
u8 dpk_txagc[RTW_RF_PATH_MAX];
u32 coef[RTW_RF_PATH_MAX][20];
u16 dpk_gs[RTW_RF_PATH_MAX];
u8 thermal_dpk_delta[RTW_RF_PATH_MAX];
u8 pre_pwsf[RTW_RF_PATH_MAX];
u8 dpk_band;
u8 dpk_ch;
u8 dpk_bw;
};
struct rtw_phy_cck_pd_reg {
u32 reg_pd;
u32 mask_pd;
u32 reg_cs;
u32 mask_cs;
};
#define DACK_MSBK_BACKUP_NUM 0xf
#define DACK_DCK_BACKUP_NUM 0x2
@ -1108,6 +1151,12 @@ struct rtw_dm_info {
u32 dack_adck[RTW_RF_PATH_MAX];
u16 dack_msbk[RTW_RF_PATH_MAX][2][DACK_MSBK_BACKUP_NUM];
u8 dack_dck[RTW_RF_PATH_MAX][2][DACK_DCK_BACKUP_NUM];
struct rtw_dpk_info dpk_info;
/* [bandwidth 0:20M/1:40M][number of path] */
u8 cck_pd_lv[2][RTW_RF_PATH_MAX];
u32 cck_fa_avg;
};
struct rtw_efuse {
@ -1344,6 +1393,11 @@ static inline void rtw_flag_set(struct rtw_dev *rtwdev, enum rtw_flags flag)
set_bit(flag, rtwdev->flags);
}
static inline bool rtw_is_assoc(struct rtw_dev *rtwdev)
{
return !!rtwdev->sta_cnt;
}
void rtw_get_channel_params(struct cfg80211_chan_def *chandef,
struct rtw_channel_params *ch_param);
bool check_hw_ready(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 target);

View File

@ -111,6 +111,19 @@ enum rtw_phy_band_type {
PHY_BAND_5G = 1,
};
static void rtw_phy_cck_pd_init(struct rtw_dev *rtwdev)
{
struct rtw_dm_info *dm_info = &rtwdev->dm_info;
u8 i, j;
for (i = 0; i <= RTW_CHANNEL_WIDTH_40; i++) {
for (j = 0; j < RTW_RF_PATH_MAX; j++)
dm_info->cck_pd_lv[i][j] = 0;
}
dm_info->cck_fa_avg = CCK_FA_AVG_RESET;
}
void rtw_phy_init(struct rtw_dev *rtwdev)
{
struct rtw_chip_info *chip = rtwdev->chip;
@ -129,6 +142,7 @@ void rtw_phy_init(struct rtw_dev *rtwdev)
addr = chip->dig[0].addr;
mask = chip->dig[0].mask;
dm_info->igi_history[0] = rtw_read32_mask(rtwdev, addr, mask);
rtw_phy_cck_pd_init(rtwdev);
}
void rtw_phy_dig_write(struct rtw_dev *rtwdev, u8 igi)
@ -439,12 +453,100 @@ static void rtw_phy_ra_info_update(struct rtw_dev *rtwdev)
rtw_iterate_stas_atomic(rtwdev, rtw_phy_ra_info_update_iter, rtwdev);
}
static void rtw_phy_dpk_track(struct rtw_dev *rtwdev)
{
struct rtw_chip_info *chip = rtwdev->chip;
if (chip->ops->dpk_track)
chip->ops->dpk_track(rtwdev);
}
#define CCK_PD_LV_MAX 5
#define CCK_PD_FA_LV1_MIN 1000
#define CCK_PD_FA_LV0_MAX 500
static u8 rtw_phy_cck_pd_lv_unlink(struct rtw_dev *rtwdev)
{
struct rtw_dm_info *dm_info = &rtwdev->dm_info;
u32 cck_fa_avg = dm_info->cck_fa_avg;
if (cck_fa_avg > CCK_PD_FA_LV1_MIN)
return 1;
if (cck_fa_avg < CCK_PD_FA_LV0_MAX)
return 0;
return CCK_PD_LV_MAX;
}
#define CCK_PD_IGI_LV4_VAL 0x38
#define CCK_PD_IGI_LV3_VAL 0x2a
#define CCK_PD_IGI_LV2_VAL 0x24
#define CCK_PD_RSSI_LV4_VAL 32
#define CCK_PD_RSSI_LV3_VAL 32
#define CCK_PD_RSSI_LV2_VAL 24
static u8 rtw_phy_cck_pd_lv_link(struct rtw_dev *rtwdev)
{
struct rtw_dm_info *dm_info = &rtwdev->dm_info;
u8 igi = dm_info->igi_history[0];
u8 rssi = dm_info->min_rssi;
u32 cck_fa_avg = dm_info->cck_fa_avg;
if (igi > CCK_PD_IGI_LV4_VAL && rssi > CCK_PD_RSSI_LV4_VAL)
return 4;
if (igi > CCK_PD_IGI_LV3_VAL && rssi > CCK_PD_RSSI_LV3_VAL)
return 3;
if (igi > CCK_PD_IGI_LV2_VAL || rssi > CCK_PD_RSSI_LV2_VAL)
return 2;
if (cck_fa_avg > CCK_PD_FA_LV1_MIN)
return 1;
if (cck_fa_avg < CCK_PD_FA_LV0_MAX)
return 0;
return CCK_PD_LV_MAX;
}
static u8 rtw_phy_cck_pd_lv(struct rtw_dev *rtwdev)
{
if (!rtw_is_assoc(rtwdev))
return rtw_phy_cck_pd_lv_unlink(rtwdev);
else
return rtw_phy_cck_pd_lv_link(rtwdev);
}
static void rtw_phy_cck_pd(struct rtw_dev *rtwdev)
{
struct rtw_dm_info *dm_info = &rtwdev->dm_info;
struct rtw_chip_info *chip = rtwdev->chip;
u32 cck_fa = dm_info->cck_fa_cnt;
u8 level;
if (rtwdev->hal.current_band_type != RTW_BAND_2G)
return;
if (dm_info->cck_fa_avg == CCK_FA_AVG_RESET)
dm_info->cck_fa_avg = cck_fa;
else
dm_info->cck_fa_avg = (dm_info->cck_fa_avg * 3 + cck_fa) >> 2;
level = rtw_phy_cck_pd_lv(rtwdev);
if (level >= CCK_PD_LV_MAX)
return;
if (chip->ops->cck_pd_set)
chip->ops->cck_pd_set(rtwdev, level);
}
void rtw_phy_dynamic_mechanism(struct rtw_dev *rtwdev)
{
/* for further calculation */
rtw_phy_statistics(rtwdev);
rtw_phy_dig(rtwdev);
rtw_phy_cck_pd(rtwdev);
rtw_phy_ra_info_update(rtwdev);
rtw_phy_dpk_track(rtwdev);
}
#define FRAC_BITS 3
@ -1316,11 +1418,20 @@ void rtw_phy_cfg_rf(struct rtw_dev *rtwdev, const struct rtw_table *tbl,
static void rtw_load_rfk_table(struct rtw_dev *rtwdev)
{
struct rtw_chip_info *chip = rtwdev->chip;
struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info;
if (!chip->rfk_init_tbl)
return;
rtw_write32_mask(rtwdev, 0x1e24, BIT(17), 0x1);
rtw_write32_mask(rtwdev, 0x1cd0, BIT(28), 0x1);
rtw_write32_mask(rtwdev, 0x1cd0, BIT(29), 0x1);
rtw_write32_mask(rtwdev, 0x1cd0, BIT(30), 0x1);
rtw_write32_mask(rtwdev, 0x1cd0, BIT(31), 0x0);
rtw_load_table(rtwdev, chip->rfk_init_tbl);
dpk_info->is_dpk_pwr_on = 1;
}
void rtw_phy_load_tables(struct rtw_dev *rtwdev)
@ -1430,6 +1541,37 @@ static u8 rtw_get_channel_group(u8 channel)
}
}
static s8 rtw_phy_get_dis_dpd_by_rate_diff(struct rtw_dev *rtwdev, u16 rate)
{
struct rtw_chip_info *chip = rtwdev->chip;
s8 dpd_diff = 0;
if (!chip->en_dis_dpd)
return 0;
#define RTW_DPD_RATE_CHECK(_rate) \
case DESC_RATE ## _rate: \
if (DIS_DPD_RATE ## _rate & chip->dpd_ratemask) \
dpd_diff = -6 * chip->txgi_factor; \
break
switch (rate) {
RTW_DPD_RATE_CHECK(6M);
RTW_DPD_RATE_CHECK(9M);
RTW_DPD_RATE_CHECK(MCS0);
RTW_DPD_RATE_CHECK(MCS1);
RTW_DPD_RATE_CHECK(MCS8);
RTW_DPD_RATE_CHECK(MCS9);
RTW_DPD_RATE_CHECK(VHT1SS_MCS0);
RTW_DPD_RATE_CHECK(VHT1SS_MCS1);
RTW_DPD_RATE_CHECK(VHT2SS_MCS0);
RTW_DPD_RATE_CHECK(VHT2SS_MCS1);
}
#undef RTW_DPD_RATE_CHECK
return dpd_diff;
}
static u8 rtw_phy_get_2g_tx_power_index(struct rtw_dev *rtwdev,
struct rtw_2g_txpwr_idx *pwr_idx_2g,
enum rtw_bandwidth bandwidth,
@ -1638,6 +1780,9 @@ rtw_phy_get_tx_power_index(struct rtw_dev *rtwdev, u8 rf_path, u8 rate,
tx_power = pwr_param.pwr_base;
offset = min_t(s8, pwr_param.pwr_offset, pwr_param.pwr_limit);
if (rtwdev->chip->en_dis_dpd)
offset += rtw_phy_get_dis_dpd_by_rate_diff(rtwdev, rate);
tx_power += offset;
if (tx_power > rtwdev->chip->max_power_index)

View File

@ -146,4 +146,6 @@ rtw_get_tx_power_params(struct rtw_dev *rtwdev, u8 path,
#define MASKBYTE3LOWNIBBLE 0x0f000000
#define MASKL3BYTES 0x00ffffff
#define CCK_FA_AVG_RESET 0xffffffff
#endif

View File

@ -193,6 +193,8 @@
#define REG_H2C_READ_ADDR 0x024C
#define REG_H2C_INFO 0x0254
#define REG_INT_MIG 0x0304
#define REG_FWHW_TXQ_CTRL 0x0420
#define BIT_EN_BCNQ_DL BIT(22)
#define BIT_EN_WR_FREE_TAIL BIT(20)
@ -339,6 +341,20 @@
#define REG_RFE_CTRL_E 0x0974
#define REG_DIS_DPD 0x0a70
#define DIS_DPD_MASK GENMASK(9, 0)
#define DIS_DPD_RATE6M BIT(0)
#define DIS_DPD_RATE9M BIT(1)
#define DIS_DPD_RATEMCS0 BIT(2)
#define DIS_DPD_RATEMCS1 BIT(3)
#define DIS_DPD_RATEMCS8 BIT(4)
#define DIS_DPD_RATEMCS9 BIT(5)
#define DIS_DPD_RATEVHT1SS_MCS0 BIT(6)
#define DIS_DPD_RATEVHT1SS_MCS1 BIT(7)
#define DIS_DPD_RATEVHT2SS_MCS0 BIT(8)
#define DIS_DPD_RATEVHT2SS_MCS1 BIT(9)
#define DIS_DPD_RATEALL GENMASK(9, 0)
#define REG_RFE_CTRL8 0x0cb4
#define BIT_MASK_RFE_SEL89 GENMASK(7, 0)
#define REG_RFE_INV8 0x0cbd
@ -469,6 +485,7 @@
#define RF_LUTWA 0x33
#define RF_LUTWD1 0x3e
#define RF_LUTWD0 0x3f
#define RF_T_METER 0x42
#define RF_XTALX2 0xb8
#define RF_MALSEL 0xbe
#define RF_RCKD 0xde

View File

@ -766,6 +766,7 @@ static void query_phy_status_page0(struct rtw_dev *rtwdev, u8 *phy_status,
s8 min_rx_power = -120;
u8 pwdb = GET_PHY_STAT_P0_PWDB(phy_status);
/* 8822B uses only 1 antenna to RX CCK rates */
pkt_stat->rx_power[RF_PATH_A] = pwdb - 110;
pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1);
pkt_stat->bw = RTW_CHANNEL_WIDTH_20;
@ -1001,6 +1002,11 @@ static void rtw8822b_do_iqk(struct rtw_dev *rtwdev)
counter, reload, ++do_iqk_cnt, iqk_fail_mask);
}
static void rtw8822b_phy_calibration(struct rtw_dev *rtwdev)
{
rtw8822b_do_iqk(rtwdev);
}
static void rtw8822b_coex_cfg_init(struct rtw_dev *rtwdev)
{
/* enable TBTT nterrupt */
@ -1794,7 +1800,7 @@ static struct rtw_chip_ops rtw8822b_ops = {
.set_antenna = rtw8822b_set_antenna,
.cfg_ldo25 = rtw8822b_cfg_ldo25,
.false_alarm_statistics = rtw8822b_false_alarm_statistics,
.do_iqk = rtw8822b_do_iqk,
.phy_calibration = rtw8822b_phy_calibration,
.coex_set_init = rtw8822b_coex_cfg_init,
.coex_set_ant_switch = rtw8822b_coex_cfg_ant_switch,

File diff suppressed because it is too large Load Diff

View File

@ -96,6 +96,35 @@ struct rtw8822c_efuse {
};
};
enum rtw8822c_dpk_agc_phase {
RTW_DPK_GAIN_CHECK,
RTW_DPK_GAIN_LARGE,
RTW_DPK_GAIN_LESS,
RTW_DPK_GL_LARGE,
RTW_DPK_GL_LESS,
RTW_DPK_LOSS_CHECK,
RTW_DPK_AGC_OUT,
};
enum rtw8822c_dpk_one_shot_action {
RTW_DPK_CAL_PWR,
RTW_DPK_GAIN_LOSS,
RTW_DPK_DO_DPK,
RTW_DPK_DPK_ON,
RTW_DPK_DAGC,
RTW_DPK_ACTION_MAX
};
void rtw8822c_parse_tbl_dpk(struct rtw_dev *rtwdev,
const struct rtw_table *tbl);
#define RTW_DECL_TABLE_DPK(name) \
const struct rtw_table name ## _tbl = { \
.data = name, \
.size = ARRAY_SIZE(name), \
.parse = rtw8822c_parse_tbl_dpk, \
}
#define DACK_PATH_8822C 2
#define DACK_REG_8822C 16
#define DACK_RF_8822C 1
@ -176,6 +205,7 @@ struct rtw8822c_efuse {
#define REG_TXF7 0x1ab0
#define REG_CCK_SOURCE 0x1abc
#define BIT_NBI_EN BIT(30)
#define REG_IQKSTAT 0x1b10
#define REG_TXANT 0x1c28
#define REG_ENCCK 0x1c3c
#define BIT_CCK_BLK_EN BIT(1)
@ -197,6 +227,7 @@ struct rtw8822c_efuse {
#define REG_OFDM_FACNT3 0x2d0c
#define REG_OFDM_FACNT4 0x2d10
#define REG_OFDM_FACNT5 0x2d20
#define REG_RPT_CIP 0x2d9c
#define REG_OFDM_TXCNT 0x2de0
#define REG_ORITXCODE2 0x4100
#define REG_3WIRE2 0x410c
@ -206,4 +237,59 @@ struct rtw8822c_efuse {
#define REG_DCKB_Q_0 0x41d8
#define REG_DCKB_Q_1 0x41dc
#define RF_MODE_TRXAGC 0x00
#define RF_RXAGC_OFFSET 0x19
#define RF_BW_TRXBB 0x1a
#define RF_TX_GAIN_OFFSET 0x55
#define RF_TX_GAIN 0x56
#define RF_TXA_LB_SW 0x63
#define RF_RXG_GAIN 0x87
#define RF_RXA_MIX_GAIN 0x8a
#define RF_EXT_TIA_BW 0x8f
#define RF_DEBUG 0xde
#define REG_NCTL0 0x1b00
#define REG_DPD_CTL0_S0 0x1b04
#define REG_DPD_CTL1_S0 0x1b08
#define REG_IQK_CTL1 0x1b20
#define REG_DPD_LUT0 0x1b44
#define REG_DPD_CTL0_S1 0x1b5c
#define REG_DPD_LUT3 0x1b60
#define REG_DPD_CTL1_S1 0x1b60
#define REG_DPD_AGC 0x1b67
#define REG_DPD_CTL0 0x1bb4
#define REG_R_CONFIG 0x1bcc
#define REG_RXSRAM_CTL 0x1bd4
#define REG_DPD_CTL11 0x1be4
#define REG_DPD_CTL12 0x1be8
#define REG_DPD_CTL15 0x1bf4
#define REG_DPD_CTL16 0x1bf8
#define REG_STAT_RPT 0x1bfc
#define BIT_EXT_TIA_BW BIT(1)
#define BIT_DE_TRXBW BIT(2)
#define BIT_DE_TX_GAIN BIT(16)
#define BIT_RXG_GAIN BIT(18)
#define BIT_DE_PWR_TRIM BIT(19)
#define BIT_INNER_LB BIT(21)
#define BIT_BYPASS_DPD BIT(25)
#define BIT_DPD_EN BIT(31)
#define BIT_SUBPAGE GENMASK(3, 0)
#define BIT_TXAGC GENMASK(4, 0)
#define BIT_GAIN_TXBB GENMASK(4, 0)
#define BIT_LB_ATT GENMASK(4, 2)
#define BIT_RXA_MIX_GAIN GENMASK(4, 3)
#define BIT_IQ_SWITCH GENMASK(5, 0)
#define BIT_DPD_CLK GENMASK(7, 4)
#define BIT_RXAGC GENMASK(9, 5)
#define BIT_BW_RXBB GENMASK(11, 10)
#define BIT_LB_SW GENMASK(13, 12)
#define BIT_BW_TXBB GENMASK(14, 12)
#define BIT_GLOSS_DB GENMASK(14, 12)
#define BIT_TXA_LB_ATT GENMASK(15, 14)
#define BIT_TX_OFFSET_VAL GENMASK(18, 14)
#define BIT_RPT_SEL GENMASK(20, 16)
#define BIT_GS_PWSF GENMASK(27, 0)
#define BIT_RPT_DGAIN GENMASK(27, 16)
#define BIT_TX_CFIR GENMASK(31, 30)
#endif

File diff suppressed because it is too large Load Diff

View File

@ -12,6 +12,9 @@ extern const struct rtw_table rtw8822c_bb_pg_type0_tbl;
extern const struct rtw_table rtw8822c_rf_a_tbl;
extern const struct rtw_table rtw8822c_rf_b_tbl;
extern const struct rtw_table rtw8822c_txpwr_lmt_type0_tbl;
extern const struct rtw_table rtw8822c_dpk_afe_no_dpk_tbl;
extern const struct rtw_table rtw8822c_dpk_afe_is_dpk_tbl;
extern const struct rtw_table rtw8822c_dpk_mac_bb_tbl;
extern const struct rtw_table rtw8822c_array_mp_cal_init_tbl;
#endif

View File

@ -90,6 +90,7 @@ void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev,
u8 *phy_status)
{
struct ieee80211_hw *hw = rtwdev->hw;
u8 path;
memset(rx_status, 0, sizeof(*rx_status));
rx_status->freq = hw->conf.chandef.chan->center_freq;
@ -146,6 +147,10 @@ void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev,
rx_status->bw = RATE_INFO_BW_20;
rx_status->signal = pkt_stat->signal_power;
for (path = 0; path < rtwdev->hal.rf_path_num; path++) {
rx_status->chains |= BIT(path);
rx_status->chain_signal[path] = pkt_stat->rx_power[path];
}
rtw_rx_addr_match(rtwdev, pkt_stat, hdr);
}

View File

@ -595,7 +595,7 @@ static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in)
{
int i;
u16 o;
u16 pwr_info_offset[] = {
static const u16 pwr_info_offset[] = {
SSB_SROM8_PWR_INFO_CORE0, SSB_SROM8_PWR_INFO_CORE1,
SSB_SROM8_PWR_INFO_CORE2, SSB_SROM8_PWR_INFO_CORE3
};