Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved performance and interoperability #422

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,5 @@ clean:
find . -name ".*.o.cmd" -exec rm -f {} \;
find . -name "*.o" -exec rm -f {} \;
find . -name "*.o.d" -exec rm -f {} \;
find . -name "*.orig" -exec rm -f {} \;
find . -name "*.rej" -exec rm -f {} \;
1 change: 1 addition & 0 deletions core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1028,6 +1028,7 @@ struct ieee80211_hw *mwl_alloc_hw(int bus_type,
priv->hif.ops = ops;
priv->hif.priv = (char *)priv + ALIGN(sizeof(*priv), NETDEV_ALIGN);
priv->debug_ampdu = false;
priv->rx_decrypt = false;
priv->ampdu_num = mwl_hif_get_ampdu_num(hw);
priv->ampdu =
kzalloc(priv->ampdu_num * sizeof(*priv->ampdu), GFP_KERNEL);
Expand Down
2 changes: 1 addition & 1 deletion core.h
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ struct mwl_priv {
u32 ra_tx_attempt[2][6];

bool debug_ampdu;
bool decrypt_rx;
bool rx_decrypt;
bool rate_adapt_mode;
bool dwds_stamode;
bool optimization_level;
Expand Down
54 changes: 54 additions & 0 deletions debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -425,11 +425,63 @@ static ssize_t mwl_debugfs_info_read(struct file *file, char __user *ubuf,
len += scnprintf(p + len, size - len,
"use_short_preamble: %s\n", priv->use_short_preamble ? "enable" : "disable");
len += mwl_hif_get_info(priv->hw, p + len, size - len);
ret = simple_read_from_buffer(ubuf, count, ppos, p, len);
free_page(page);

return ret;
}

static ssize_t mwl_debugfs_rx_decrypt_read(struct file *file, char __user *ubuf,
size_t count, loff_t *ppos) {
struct mwl_priv *priv = (struct mwl_priv *)file->private_data;
unsigned long page = get_zeroed_page(GFP_KERNEL);
char *p = (char *)page;
int len = 0, size = PAGE_SIZE;
ssize_t ret;

if (!p)
return -ENOMEM;

len += scnprintf(p + len, size - len, "%5s\n", priv->rx_decrypt ? "true" : "false");

ret = simple_read_from_buffer(ubuf, count, ppos, p, len);
free_page(page);

return ret;

}

static ssize_t mwl_debugfs_rx_decrypt_write(struct file *file,
const char __user *ubuf,
size_t count, loff_t *ppos)
{
struct mwl_priv *priv = (struct mwl_priv *)file->private_data;
unsigned long addr = get_zeroed_page(GFP_KERNEL);
char *buf = (char *)addr;
size_t buf_size = min_t(size_t, count, PAGE_SIZE - 1);
int value;
ssize_t ret;

if (!buf)
return -ENOMEM;

if (copy_from_user(buf, ubuf, buf_size)) {
ret = -EFAULT;
goto err;
}

if (kstrtoint(buf, 0, &value)) {
ret = -EINVAL;
goto err;
}

priv->rx_decrypt = value ? true : false;

ret = count;

err:
free_page(addr);
return ret;
}

static ssize_t mwl_debugfs_tx_status_read(struct file *file, char __user *ubuf,
Expand Down Expand Up @@ -2105,6 +2157,7 @@ MWLWIFI_DEBUGFS_FILE_READ_OPS(device_pwrtbl);
MWLWIFI_DEBUGFS_FILE_READ_OPS(txpwrlmt);
MWLWIFI_DEBUGFS_FILE_OPS(ampdu);
MWLWIFI_DEBUGFS_FILE_OPS(tx_amsdu);
MWLWIFI_DEBUGFS_FILE_OPS(rx_decrypt);
MWLWIFI_DEBUGFS_FILE_OPS(dump_hostcmd);
MWLWIFI_DEBUGFS_FILE_OPS(heartbeat);
MWLWIFI_DEBUGFS_FILE_OPS(dfs_test);
Expand Down Expand Up @@ -2134,6 +2187,7 @@ void mwl_debugfs_init(struct ieee80211_hw *hw)

MWLWIFI_DEBUGFS_ADD_FILE(info);
MWLWIFI_DEBUGFS_ADD_FILE(tx_status);
MWLWIFI_DEBUGFS_ADD_FILE(rx_decrypt);
MWLWIFI_DEBUGFS_ADD_FILE(rx_status);
MWLWIFI_DEBUGFS_ADD_FILE(vif);
MWLWIFI_DEBUGFS_ADD_FILE(sta);
Expand Down
4 changes: 3 additions & 1 deletion hif/fwcmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1498,8 +1498,10 @@ int mwl_fwcmd_set_cfg_data(struct ieee80211_hw *hw, u16 type)
parsed_len = mwl_fwcmd_parse_cal_cfg(priv->cal_data->data,
priv->cal_data->size,
pcmd->data);
if (parsed_len == -EINVAL)
if (parsed_len == -EINVAL) {
mutex_unlock(&priv->fwcmd_mutex);
return -EIO;
}
pcmd->data_len = parsed_len;
pcmd->cmd_hdr.cmd = cpu_to_le16(HOSTCMD_CMD_SET_CFG);
pcmd->cmd_hdr.len = cpu_to_le16(sizeof(*pcmd) +
Expand Down
93 changes: 50 additions & 43 deletions hif/pcie/8864/rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,39 +240,30 @@ static inline void pcie_rx_status(struct mwl_priv *priv,
}
}

static inline bool pcie_rx_process_mesh_amsdu(struct mwl_priv *priv,
static inline int pcie_rx_process_amsdu(struct mwl_priv *priv,
struct sk_buff *skb,
struct ieee80211_rx_status *status)
{
struct ieee80211_hdr *wh;
struct mwl_sta *sta_info;
struct ieee80211_sta *sta;
u8 *qc;
int wh_len;
int len;
u8 pad;
u8 *data;
u16 frame_len;
struct sk_buff *newskb;
int work_done;
struct pcie_priv *pcie_priv = priv->hif.priv;

wh = (struct ieee80211_hdr *)skb->data;

spin_lock_bh(&priv->sta_lock);
list_for_each_entry(sta_info, &priv->sta_list, list) {
sta = container_of((void *)sta_info, struct ieee80211_sta,
drv_priv[0]);
if (ether_addr_equal(sta->addr, wh->addr2)) {
if (!sta_info->is_mesh_node) {
spin_unlock_bh(&priv->sta_lock);
return false;
}
}
}
spin_unlock_bh(&priv->sta_lock);

qc = ieee80211_get_qos_ctl(wh);
*qc &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT;

if(priv->rx_decrypt)
if(status->flag & RX_FLAG_DECRYPTED)
status->flag |= RX_FLAG_SKIP_MONITOR;

wh_len = ieee80211_hdrlen(wh->frame_control);
len = wh_len;
data = skb->data;
Expand Down Expand Up @@ -302,12 +293,23 @@ static inline bool pcie_rx_process_mesh_amsdu(struct mwl_priv *priv,
else
status->flag &= ~RX_FLAG_AMSDU_MORE;
memcpy(IEEE80211_SKB_RXCB(newskb), status, sizeof(*status));
ieee80211_rx(priv->hw, newskb);
ieee80211_rx_napi(priv->hw, NULL, newskb, &pcie_priv->napi);
work_done++;
}

dev_kfree_skb_any(skb);
if(priv->rx_decrypt) {
if (status->flag & RX_FLAG_DECRYPTED) {

status->flag &= ~RX_FLAG_SKIP_MONITOR;
status->flag |= RX_FLAG_ONLY_MONITOR;
((struct ieee80211_hdr *)skb->data)->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_PROTECTED);
ieee80211_rx_napi(priv->hw, NULL, skb, &pcie_priv->napi);
}
}
else
dev_kfree_skb_any(skb);

return true;
return work_done;
}

static inline int pcie_rx_refill(struct mwl_priv *priv,
Expand Down Expand Up @@ -378,11 +380,11 @@ void pcie_8864_rx_deinit(struct ieee80211_hw *hw)
pcie_rx_ring_free(priv);
}

void pcie_8864_rx_recv(unsigned long data)
int pcie_8864_poll_napi(struct napi_struct *napi, int budget)
{
struct ieee80211_hw *hw = (struct ieee80211_hw *)data;
struct mwl_priv *priv = hw->priv;
struct pcie_priv *pcie_priv = priv->hif.priv;
struct pcie_priv *pcie_priv = container_of(napi, struct pcie_priv, napi);
struct mwl_priv *priv = pcie_priv->mwl_priv;
struct ieee80211_hw *hw = priv->hw;
struct pcie_desc_data *desc;
struct pcie_rx_hndl *curr_hndl;
int work_done = 0;
Expand All @@ -399,30 +401,28 @@ void pcie_8864_rx_recv(unsigned long data)
curr_hndl = desc->pnext_rx_hndl;

if (!curr_hndl) {
pcie_mask_int(pcie_priv, MACREG_A2HRIC_BIT_RX_RDY, true);
pcie_priv->is_rx_schedule = false;
wiphy_warn(hw->wiphy, "busy or no receiving packets\n");
return;
goto end_poll;
}

while ((curr_hndl->pdesc->rx_control == EAGLE_RXD_CTRL_DMA_OWN) &&
(work_done < pcie_priv->recv_limit)) {
(work_done < budget)) {
prx_skb = curr_hndl->psk_buff;
if (!prx_skb)
if (unlikely(!prx_skb))
goto out;
dma_unmap_single(&(pcie_priv->pdev)->dev,
le32_to_cpu(curr_hndl->pdesc->pphys_buff_data),
desc->rx_buf_size,
DMA_FROM_DEVICE);
pkt_len = le16_to_cpu(curr_hndl->pdesc->pkt_len);

if (skb_tailroom(prx_skb) < pkt_len) {
if (unlikely(skb_tailroom(prx_skb) < pkt_len)) {
dev_kfree_skb_any(prx_skb);
goto out;
}

if (curr_hndl->pdesc->channel !=
hw->conf.chandef.chan->hw_value) {
if (unlikely(curr_hndl->pdesc->channel !=
hw->conf.chandef.chan->hw_value)) {
dev_kfree_skb_any(prx_skb);
goto out;
}
Expand Down Expand Up @@ -476,23 +476,25 @@ void pcie_8864_rx_recv(unsigned long data)
*qc |= 7;

if ((*qc & IEEE80211_QOS_CTL_A_MSDU_PRESENT) && (ieee80211_has_a4(wh->frame_control))) {
if (pcie_rx_process_mesh_amsdu(priv, prx_skb, status))
goto out;
work_done += pcie_rx_process_amsdu(priv, prx_skb, status);
goto out;
}
}

if (status->flag & RX_FLAG_DECRYPTED) {
monitor_skb = skb_copy(prx_skb, GFP_ATOMIC);
if (monitor_skb) {
IEEE80211_SKB_RXCB(monitor_skb)->flag |= RX_FLAG_ONLY_MONITOR;
((struct ieee80211_hdr *)monitor_skb->data)->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_PROTECTED);
if(priv->rx_decrypt) {
if (status->flag & RX_FLAG_DECRYPTED) {
monitor_skb = skb_copy(prx_skb, GFP_ATOMIC);
if (monitor_skb) {
IEEE80211_SKB_RXCB(monitor_skb)->flag |= RX_FLAG_ONLY_MONITOR;
((struct ieee80211_hdr *)monitor_skb->data)->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_PROTECTED);

ieee80211_rx(hw, monitor_skb);
ieee80211_rx_napi(hw, NULL, monitor_skb, &pcie_priv->napi);
}
status->flag |= RX_FLAG_SKIP_MONITOR;
}
status->flag |= RX_FLAG_SKIP_MONITOR;
}

ieee80211_rx(hw, prx_skb);
ieee80211_rx_napi(hw, NULL, prx_skb, &pcie_priv->napi);
out:
pcie_rx_refill(priv, curr_hndl);
curr_hndl->pdesc->rx_control = EAGLE_RXD_CTRL_DRIVER_OWN;
Expand All @@ -502,6 +504,11 @@ void pcie_8864_rx_recv(unsigned long data)
}

desc->pnext_rx_hndl = curr_hndl;
pcie_mask_int(pcie_priv, MACREG_A2HRIC_BIT_RX_RDY, true);
pcie_priv->is_rx_schedule = false;

end_poll:
if (work_done < budget) {
napi_complete(napi);
priv->hif.ops->irq_enable(hw);
}
return work_done;
}
2 changes: 1 addition & 1 deletion hif/pcie/8864/rx.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@

int pcie_8864_rx_init(struct ieee80211_hw *hw);
void pcie_8864_rx_deinit(struct ieee80211_hw *hw);
void pcie_8864_rx_recv(unsigned long data);
int pcie_8864_poll_napi(struct napi_struct *napi, int budget);

#endif /* _8864_RX_H_ */
Loading