BigW Consortium Gitlab

Commit a5979a95 by David Clark

Speed optimizations:

- reduced delay check of interrupt - fixed order issue in driver Tx - removed status register checks in SPI queue read/write
parent 2c3d3032
......@@ -38,7 +38,7 @@ int mt7697_irq_run(struct mt7697q_info *qinfo)
if (s2m_mbox) {
if (!queue_delayed_work(qinfo->irq_workq,
&qinfo->irq_delayed_work, usecs_to_jiffies(100))) {
&qinfo->irq_delayed_work, usecs_to_jiffies(10))) {
dev_err(qinfo->dev,
"%s(): queue_delayed_work() failed\n",
__func__);
......
......@@ -242,13 +242,6 @@ int mt7697io_wr(struct mt7697q_info *qinfo, u32 addr, const u32 *data, size_t nu
WARN_ON(num == 0);
ret = mt7697io_slave_wait(qinfo);
if (ret < 0) {
dev_err(qinfo->dev, "%s(): mt7697io_slave_wait() failed(%d)\n",
__func__, ret);
goto cleanup;
}
ret = mt7697io_write32(qinfo, MT7697_IO_SLAVE_REG_BUS_ADDR_LOW, addr);
if (ret < 0) {
dev_err(qinfo->dev, "%s(): mt7697io_write32() failed(%d)\n",
......@@ -278,14 +271,6 @@ int mt7697io_wr(struct mt7697q_info *qinfo, u32 addr, const u32 *data, size_t nu
__func__, ret);
goto cleanup;
}
ret = mt7697io_slave_wait(qinfo);
if (ret < 0) {
dev_err(qinfo->dev,
"%s(): mt7697io_slave_wait() failed(%d)\n",
__func__, ret);
goto cleanup;
}
}
cleanup:
......@@ -299,13 +284,6 @@ int mt7697io_rd(struct mt7697q_info *qinfo, u32 addr, u32 *data, size_t num)
WARN_ON(num == 0);
ret = mt7697io_slave_wait(qinfo);
if (ret < 0) {
dev_err(qinfo->dev, "%s(): mt7697io_slave_wait() failed(%d)\n",
__func__, ret);
goto cleanup;
}
ret = mt7697io_write32(qinfo, MT7697_IO_SLAVE_REG_BUS_ADDR_LOW, addr);
if (ret < 0) {
dev_err(qinfo->dev, "%s(): mt7697io_write32() failed(%d)\n",
......
......@@ -1189,6 +1189,8 @@ struct wireless_dev* mt7697_interface_add(struct mt7697_cfg80211_info *cfg,
INIT_LIST_HEAD(&vif->sta_list);
vif->sta_max = MT7697_MAX_STA;
// INIT_LIST_HEAD(&vif->rx_pkt_list);
ndev->addr_assign_type = NET_ADDR_PERM;
ndev->addr_len = ETH_ALEN;
ndev->dev_addr = cfg->mac_addr.addr;
......
......@@ -38,6 +38,7 @@
#define MT7697_MAX_MC_FILTERS_PER_LIST 7
#define MT7697_MAX_COOKIE_NUM 180
#define MT7697_TX_TIMEOUT 10
#define MT7697_TX_PKT_POOL_LEN 64
/* TODO update below */
#define MT7697_DISCON_TIMER_INTVAL_MSEC (300 * 1000)
......@@ -78,9 +79,9 @@ enum mt7697_vif_state {
SCHED_SCANNING,
};
struct mt7697_cookie {
struct mt7697_tx_pkt {
struct sk_buff *skb;
struct mt7697_cookie *arc_list_next;
struct list_head next;
};
struct mt7697_cfg80211_info {
......@@ -96,13 +97,14 @@ struct mt7697_cfg80211_info {
struct work_struct init_work;
struct mt7697_cookie *cookie_list;
u32 cookie_count;
struct mt7697_cookie cookie_mem[MT7697_MAX_COOKIE_NUM];
atomic_t tx_skb_pool_idx;
struct mt7697_tx_pkt tx_skb_pool[MT7697_TX_PKT_POOL_LEN];
struct sk_buff_head tx_skb_queue;
struct list_head tx_skb_list;
struct workqueue_struct *tx_workq;
struct work_struct tx_work;
struct mt7697_tx_raw_packet tx_req;
u8 rx_data[LEN32_ALIGNED(IEEE80211_MAX_FRAME_LEN)];
u8 probe_data[LEN32_ALIGNED(IEEE80211_MAX_DATA_LEN)];
......@@ -220,7 +222,4 @@ int mt7697_proc_80211cmd(const struct mt7697q_rsp_hdr*, void*);
void mt7697_disconnect_timer_hndlr(unsigned long);
int mt7697_disconnect(struct mt7697_vif*);
struct mt7697_cookie *mt7697_alloc_cookie(struct mt7697_cfg80211_info*);
void mt7697_free_cookie(struct mt7697_cfg80211_info*, struct mt7697_cookie*);
#endif
......@@ -188,25 +188,6 @@ static const struct mt7697q_if_ops if_ops = {
.write = mt7697q_write,
};
static void mt7697_cookie_init(struct mt7697_cfg80211_info *cfg)
{
u32 i;
cfg->cookie_list = NULL;
cfg->cookie_count = 0;
memset(cfg->cookie_mem, 0, sizeof(cfg->cookie_mem));
for (i = 0; i < MT7697_MAX_COOKIE_NUM; i++)
mt7697_free_cookie(cfg, &cfg->cookie_mem[i]);
}
static void mt7697_cookie_cleanup(struct mt7697_cfg80211_info *cfg)
{
cfg->cookie_list = NULL;
cfg->cookie_count = 0;
}
static int mt7697_probe(struct platform_device *pdev)
{
struct wiphy *wiphy;
......@@ -224,10 +205,10 @@ static int mt7697_probe(struct platform_device *pdev)
}
sema_init(&cfg->sem, 1);
cfg->tx_workq = create_singlethread_workqueue(DRVNAME);
cfg->tx_workq = create_workqueue(DRVNAME);
if (!cfg->tx_workq) {
dev_err(&pdev->dev,
"%s(): mt7697_cfg80211_create() failed()\n",
"%s(): create_workqueue() failed()\n",
__func__);
err = -ENOMEM;
goto failed;
......@@ -239,9 +220,13 @@ static int mt7697_probe(struct platform_device *pdev)
spin_lock_init(&cfg->vif_list_lock);
INIT_LIST_HEAD(&cfg->vif_list);
INIT_LIST_HEAD(&cfg->tx_skb_list);
atomic_set(&cfg->tx_skb_pool_idx, 0);
memset(cfg->tx_skb_pool, 0, sizeof(cfg->tx_skb_pool));
cfg->hif_ops = &if_ops;
cfg->dev = &pdev->dev;
mt7697_cookie_init(cfg);
skb_queue_head_init(&cfg->tx_skb_queue);
cfg->vif_start = itf_idx_start;
cfg->vif_max = MT7697_MAX_STA;
......@@ -270,7 +255,6 @@ static int mt7697_remove(struct platform_device *pdev)
{
struct mt7697_cfg80211_info *cfg = platform_get_drvdata(pdev);
mt7697_cookie_cleanup(cfg);
mt7697_cfg80211_cleanup(cfg);
mt7697_cfg80211_destroy(cfg);
pr_info(DRVNAME" %s(): removed.\n", __func__);
......@@ -435,32 +419,6 @@ cleanup:
return ret;
}
struct mt7697_cookie *mt7697_alloc_cookie(struct mt7697_cfg80211_info *cfg)
{
struct mt7697_cookie *cookie;
cookie = cfg->cookie_list;
if (cookie != NULL) {
cfg->cookie_list = cookie->arc_list_next;
cfg->cookie_count--;
}
return cookie;
}
void mt7697_free_cookie(struct mt7697_cfg80211_info *cfg,
struct mt7697_cookie *cookie)
{
/* Insert first */
if (!cfg || !cookie)
return;
cookie->skb = NULL;
cookie->arc_list_next = cfg->cookie_list;
cfg->cookie_list = cookie;
cfg->cookie_count++;
}
MODULE_AUTHOR("Sierra Wireless Corporation");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("MediaTek7697 WiFi 80211");
......
......@@ -22,12 +22,10 @@ int mt7697_data_tx(struct sk_buff *skb, struct net_device *ndev)
{
struct mt7697_cfg80211_info *cfg = mt7697_priv(ndev);
struct mt7697_vif *vif = netdev_priv(ndev);
struct mt7697_cookie *cookie;
struct mt7697_tx_pkt *tx_skb;
int ret = 0;
dev_dbg(cfg->dev,
"%s(): tx cookie cnt(%u) skb(0x%p), data(0x%p), len(%u)\n",
__func__, cfg->cookie_count, skb, skb->data, skb->len);
dev_dbg(cfg->dev, "%s(): tx len(%u)\n", __func__, skb->len);
if (!test_bit(CONNECTED, &vif->flags)) {
dev_warn(cfg->dev, "%s(): interface not associated\n",
......@@ -49,15 +47,22 @@ int mt7697_data_tx(struct sk_buff *skb, struct net_device *ndev)
}
}
cookie = mt7697_alloc_cookie(cfg);
if (cookie == NULL) {
ret = -ENOMEM;
tx_skb = &cfg->tx_skb_pool[atomic_read(&cfg->tx_skb_pool_idx)];
if (tx_skb->skb) {
dev_warn(cfg->dev, "%s(): tx pool full\n",
__func__);
ret = -EAGAIN;
goto cleanup;
}
}
dev_dbg(cfg->dev, "%s(): tx cookie/cnt(0x%p/%u)\n",
__func__, cookie, cfg->cookie_count);
cookie->skb = skb;
tx_skb->skb = skb;
dev_dbg(cfg->dev, "%s(): tx pkt(%u/%p)\n",
__func__, atomic_read(&cfg->tx_skb_pool_idx), tx_skb->skb);
atomic_inc(&cfg->tx_skb_pool_idx);
if (atomic_read(&cfg->tx_skb_pool_idx) >= MT7697_TX_PKT_POOL_LEN)
atomic_set(&cfg->tx_skb_pool_idx, 0);
list_add_tail(&tx_skb->next, &cfg->tx_skb_list);
ret = queue_work(cfg->tx_workq, &cfg->tx_work);
if (ret < 0) {
......@@ -80,35 +85,26 @@ void mt7697_tx_work(struct work_struct *work)
{
struct mt7697_cfg80211_info *cfg = container_of(work,
struct mt7697_cfg80211_info, tx_work);
struct sk_buff_head skb_queue;
struct mt7697_tx_pkt *tx_pkt, *tx_pkt_next = NULL;
struct ieee80211_hdr *hdr;
int ret;
skb_queue_head_init(&skb_queue);
dev_dbg(cfg->dev, "%s(): tx cookie cnt(%u)\n",
__func__, cfg->cookie_count);
while (cfg->cookie_count < MT7697_MAX_COOKIE_NUM) {
struct mt7697_vif *vif;
struct mt7697_cookie *cookie = &cfg->cookie_mem[cfg->cookie_count];
if (!cookie->skb)
break;
vif = netdev_priv(cookie->skb->dev);
list_for_each_entry_safe(tx_pkt, tx_pkt_next, &cfg->tx_skb_list, next) {
struct mt7697_vif *vif = netdev_priv(tx_pkt->skb->dev);
WARN_ON(!vif);
/* validate length for ether packet */
if (cookie->skb->len < sizeof(*hdr)) {
if (tx_pkt->skb->len < sizeof(*hdr)) {
dev_err(cfg->dev, "%s(): invalid skb len(%u < %u)\n",
__func__, cookie->skb->len, sizeof(*hdr));
__func__, tx_pkt->skb->len, sizeof(*hdr));
vif->net_stats.tx_errors++;
ret = -EINVAL;
goto cleanup;
}
ret = mt7697_wr_tx_raw_packet(cfg, cookie->skb->data,
cookie->skb->len);
ret = mt7697_wr_tx_raw_packet(cfg, tx_pkt->skb->data,
tx_pkt->skb->len);
if (ret < 0) {
dev_err(cfg->dev,
"%s(): mt7697_wr_tx_raw_packet() failed(%d)\n",
......@@ -117,19 +113,16 @@ void mt7697_tx_work(struct work_struct *work)
goto cleanup;
}
dev_dbg(cfg->dev, "%s(): tx complete pkt(%p)\n", __func__, tx_pkt->skb);
vif->net_stats.tx_packets++;
vif->net_stats.tx_bytes += cookie->skb->len;
__skb_queue_tail(&skb_queue, cookie->skb);
mt7697_free_cookie(cfg, cookie);
vif->net_stats.tx_bytes += tx_pkt->skb->len;
list_del(&tx_pkt->next);
dev_dbg(cfg->dev, "%s(): tx cookie cnt(%u)\n",
__func__, cfg->cookie_count);
if (cfg->cookie_count < MT7697_MAX_COOKIE_NUM)
cookie = &cfg->cookie_mem[cfg->cookie_count];
__skb_queue_tail(&cfg->tx_skb_queue, tx_pkt->skb);
tx_pkt->skb = NULL;
}
__skb_queue_purge(&skb_queue);
__skb_queue_purge(&cfg->tx_skb_queue);
cleanup:
return;
......@@ -180,6 +173,7 @@ int mt7697_rx_data(struct mt7697_cfg80211_info *cfg, u32 len, u32 if_idx)
vif->net_stats.rx_bytes += len;
skb->protocol = eth_type_trans(skb, skb->dev);
skb->ip_summed = CHECKSUM_UNNECESSARY;
dev_dbg(cfg->dev, "%s(): rx frame protocol(%u) type(%u)\n",
__func__, skb->protocol, skb->pkt_type);
......
......@@ -792,8 +792,8 @@ static int mt7697_rx_raw(const struct mt7697q_rsp_hdr* rsp,
goto cleanup;
}
print_hex_dump(KERN_DEBUG, DRVNAME" RX ", DUMP_PREFIX_OFFSET,
16, 1, cfg->rx_data, rsp->result, 0);
// print_hex_dump(KERN_DEBUG, DRVNAME" RX ", DUMP_PREFIX_OFFSET,
// 16, 1, cfg->rx_data, rsp->result, 0);
if (list_empty(&cfg->vif_list)) {
dev_dbg(cfg->dev, "%s(): no interfaces\n", __func__);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment