Skip to content

Commit

Permalink
mwifiex: flush TX ring for PCIe after disconnect or bss stop
Browse files Browse the repository at this point in the history
This patch adds handler to clean PCIe TX rings after disconnect
or bss stop is called for PCIe based mwifiex driver.

Signed-off-by: Avinash Patil <patila@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Avinash Patil authored and John W. Linville committed Jan 7, 2013
1 parent fc33146 commit fbd7e7a
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 0 deletions.
1 change: 1 addition & 0 deletions drivers/net/wireless/mwifiex/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -602,6 +602,7 @@ struct mwifiex_if_ops {
int (*init_fw_port) (struct mwifiex_adapter *);
int (*dnld_fw) (struct mwifiex_adapter *, struct mwifiex_fw_image *);
void (*card_reset) (struct mwifiex_adapter *);
int (*clean_pcie_ring) (struct mwifiex_adapter *adapter);
};

struct mwifiex_adapter {
Expand Down
32 changes: 32 additions & 0 deletions drivers/net/wireless/mwifiex/pcie.c
Original file line number Diff line number Diff line change
Expand Up @@ -764,6 +764,37 @@ static int mwifiex_pcie_delete_sleep_cookie_buf(struct mwifiex_adapter *adapter)
return 0;
}

/* This function flushes the TX buffer descriptor ring
* This function defined as handler is also called while cleaning TXRX
* during disconnect/ bss stop.
*/
static int mwifiex_clean_pcie_ring_buf(struct mwifiex_adapter *adapter)
{
struct pcie_service_card *card = adapter->card;
u32 rdptr;

/* Read the TX ring read pointer set by firmware */
if (mwifiex_read_reg(adapter, REG_TXBD_RDPTR, &rdptr)) {
dev_err(adapter->dev,
"Flush TXBD: failed to read REG_TXBD_RDPTR\n");
return -1;
}

if (!mwifiex_pcie_txbd_empty(card, rdptr)) {
card->txbd_flush = 1;
/* write pointer already set at last send
* send dnld-rdy intr again, wait for completion.
*/
if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
CPU_INTR_DNLD_RDY)) {
dev_err(adapter->dev,
"failed to assert dnld-rdy interrupt.\n");
return -1;
}
}
return 0;
}

/*
* This function sends data buffer to device
*/
Expand Down Expand Up @@ -1995,6 +2026,7 @@ static struct mwifiex_if_ops pcie_ops = {
.update_mp_end_port = NULL,
.cleanup_mpa_buf = NULL,
.init_fw_port = mwifiex_pcie_init_fw_port,
.clean_pcie_ring = mwifiex_clean_pcie_ring_buf,
};

/*
Expand Down
13 changes: 13 additions & 0 deletions drivers/net/wireless/mwifiex/pcie.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ struct pcie_service_card {
struct pci_dev *dev;
struct mwifiex_adapter *adapter;

u8 txbd_flush;
u32 txbd_wrptr;
u32 txbd_rdptr;
u32 txbd_ring_size;
Expand Down Expand Up @@ -146,4 +147,16 @@ struct pcie_service_card {
void __iomem *pci_mmap1;
};

static inline int
mwifiex_pcie_txbd_empty(struct pcie_service_card *card, u32 rdptr)
{
if (((card->txbd_wrptr & MWIFIEX_TXBD_MASK) ==
(rdptr & MWIFIEX_TXBD_MASK)) &&
((card->txbd_wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) !=
(rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND)))
return 1;

return 0;
}

#endif /* _MWIFIEX_PCIE_H */
2 changes: 2 additions & 0 deletions drivers/net/wireless/mwifiex/wmm.c
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,8 @@ mwifiex_clean_txrx(struct mwifiex_private *priv)
mwifiex_wmm_delete_all_ralist(priv);
memcpy(tos_to_tid, ac_to_tid, sizeof(tos_to_tid));

if (priv->adapter->if_ops.clean_pcie_ring)
priv->adapter->if_ops.clean_pcie_ring(priv->adapter);
spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
}

Expand Down

0 comments on commit fbd7e7a

Please sign in to comment.