Commit ca8f2112 authored by Avinash Patil's avatar Avinash Patil Committed by John W. Linville

mwifiex: add PCIe8897 support

This patch adds PCIe8897 support to mwifiex.
In PCIe8897 PFU (pre-fetch unit) is enabled by default.
This patch adds support to accommodate this feaure as well.
Signed-off-by: default avatarAvinash Patil <patila@marvell.com>
Signed-off-by: default avatarYogesh Ashok Powar <yogeshp@marvell.com>
Signed-off-by: default avatarNishant Sarmukadam <nishants@marvell.com>
Signed-off-by: default avatarBing Zhao <bzhao@marvell.com>
Signed-off-by: default avatarFrank Huang <frankh@marvell.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent e05dc3e9
...@@ -20,12 +20,12 @@ config MWIFIEX_SDIO ...@@ -20,12 +20,12 @@ config MWIFIEX_SDIO
mwifiex_sdio. mwifiex_sdio.
config MWIFIEX_PCIE config MWIFIEX_PCIE
tristate "Marvell WiFi-Ex Driver for PCIE 8766" tristate "Marvell WiFi-Ex Driver for PCIE 8766/8897"
depends on MWIFIEX && PCI depends on MWIFIEX && PCI
select FW_LOADER select FW_LOADER
---help--- ---help---
This adds support for wireless adapters based on Marvell This adds support for wireless adapters based on Marvell
8766 chipset with PCIe interface. 8766/8897 chipsets with PCIe interface.
If you choose to build it as a module, it will be called If you choose to build it as a module, it will be called
mwifiex_pcie. mwifiex_pcie.
......
...@@ -237,15 +237,17 @@ static int mwifiex_pcie_resume(struct pci_dev *pdev) ...@@ -237,15 +237,17 @@ static int mwifiex_pcie_resume(struct pci_dev *pdev)
return 0; return 0;
} }
#define PCIE_VENDOR_ID_MARVELL (0x11ab)
#define PCIE_DEVICE_ID_MARVELL_88W8766P (0x2b30)
static DEFINE_PCI_DEVICE_TABLE(mwifiex_ids) = { static DEFINE_PCI_DEVICE_TABLE(mwifiex_ids) = {
{ {
PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8766P, PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8766P,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
.driver_data = (unsigned long) &mwifiex_pcie8766, .driver_data = (unsigned long) &mwifiex_pcie8766,
}, },
{
PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8897,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
.driver_data = (unsigned long) &mwifiex_pcie8897,
},
{}, {},
}; };
...@@ -377,16 +379,25 @@ static int mwifiex_pcie_enable_host_int(struct mwifiex_adapter *adapter) ...@@ -377,16 +379,25 @@ static int mwifiex_pcie_enable_host_int(struct mwifiex_adapter *adapter)
static int mwifiex_init_txq_ring(struct mwifiex_adapter *adapter) static int mwifiex_init_txq_ring(struct mwifiex_adapter *adapter)
{ {
struct pcie_service_card *card = adapter->card; struct pcie_service_card *card = adapter->card;
const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
struct mwifiex_pcie_buf_desc *desc; struct mwifiex_pcie_buf_desc *desc;
struct mwifiex_pfu_buf_desc *desc2;
int i; int i;
for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) { for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
card->tx_buf_list[i] = NULL; card->tx_buf_list[i] = NULL;
card->txbd_ring[i] = (void *)(card->txbd_ring_vbase + if (reg->pfu_enabled) {
(sizeof(*desc) * i)); card->txbd_ring[i] = (void *)card->txbd_ring_vbase +
(sizeof(*desc2) * i);
desc2 = card->txbd_ring[i];
memset(desc2, 0, sizeof(*desc2));
} else {
card->txbd_ring[i] = (void *)card->txbd_ring_vbase +
(sizeof(*desc) * i);
desc = card->txbd_ring[i]; desc = card->txbd_ring[i];
memset(desc, 0, sizeof(*desc)); memset(desc, 0, sizeof(*desc));
} }
}
return 0; return 0;
} }
...@@ -398,8 +409,10 @@ static int mwifiex_init_txq_ring(struct mwifiex_adapter *adapter) ...@@ -398,8 +409,10 @@ static int mwifiex_init_txq_ring(struct mwifiex_adapter *adapter)
static int mwifiex_init_rxq_ring(struct mwifiex_adapter *adapter) static int mwifiex_init_rxq_ring(struct mwifiex_adapter *adapter)
{ {
struct pcie_service_card *card = adapter->card; struct pcie_service_card *card = adapter->card;
const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
struct sk_buff *skb; struct sk_buff *skb;
struct mwifiex_pcie_buf_desc *desc; struct mwifiex_pcie_buf_desc *desc;
struct mwifiex_pfu_buf_desc *desc2;
dma_addr_t buf_pa; dma_addr_t buf_pa;
int i; int i;
...@@ -426,6 +439,16 @@ static int mwifiex_init_rxq_ring(struct mwifiex_adapter *adapter) ...@@ -426,6 +439,16 @@ static int mwifiex_init_rxq_ring(struct mwifiex_adapter *adapter)
(u32)((u64)buf_pa >> 32)); (u32)((u64)buf_pa >> 32));
card->rx_buf_list[i] = skb; card->rx_buf_list[i] = skb;
if (reg->pfu_enabled) {
card->rxbd_ring[i] = (void *)card->rxbd_ring_vbase +
(sizeof(*desc2) * i);
desc2 = card->rxbd_ring[i];
desc2->paddr = buf_pa;
desc2->len = (u16)skb->len;
desc2->frag_len = (u16)skb->len;
desc2->flags = reg->ring_flag_eop | reg->ring_flag_sop;
desc2->offset = 0;
} else {
card->rxbd_ring[i] = (void *)(card->rxbd_ring_vbase + card->rxbd_ring[i] = (void *)(card->rxbd_ring_vbase +
(sizeof(*desc) * i)); (sizeof(*desc) * i));
desc = card->rxbd_ring[i]; desc = card->rxbd_ring[i];
...@@ -433,6 +456,7 @@ static int mwifiex_init_rxq_ring(struct mwifiex_adapter *adapter) ...@@ -433,6 +456,7 @@ static int mwifiex_init_rxq_ring(struct mwifiex_adapter *adapter)
desc->len = (u16)skb->len; desc->len = (u16)skb->len;
desc->flags = 0; desc->flags = 0;
} }
}
return 0; return 0;
} }
...@@ -489,21 +513,34 @@ static int mwifiex_pcie_init_evt_ring(struct mwifiex_adapter *adapter) ...@@ -489,21 +513,34 @@ static int mwifiex_pcie_init_evt_ring(struct mwifiex_adapter *adapter)
static void mwifiex_cleanup_txq_ring(struct mwifiex_adapter *adapter) static void mwifiex_cleanup_txq_ring(struct mwifiex_adapter *adapter)
{ {
struct pcie_service_card *card = adapter->card; struct pcie_service_card *card = adapter->card;
const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
struct sk_buff *skb; struct sk_buff *skb;
struct mwifiex_pcie_buf_desc *desc; struct mwifiex_pcie_buf_desc *desc;
struct mwifiex_pfu_buf_desc *desc2;
int i; int i;
for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) { for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
if (reg->pfu_enabled) {
desc2 = card->txbd_ring[i];
if (card->tx_buf_list[i]) {
skb = card->tx_buf_list[i];
pci_unmap_single(card->dev, desc2->paddr,
skb->len, PCI_DMA_TODEVICE);
dev_kfree_skb_any(skb);
}
memset(desc2, 0, sizeof(*desc2));
} else {
desc = card->txbd_ring[i]; desc = card->txbd_ring[i];
if (card->tx_buf_list[i]) { if (card->tx_buf_list[i]) {
skb = card->tx_buf_list[i]; skb = card->tx_buf_list[i];
pci_unmap_single(card->dev, desc->paddr, skb->len, pci_unmap_single(card->dev, desc->paddr,
PCI_DMA_TODEVICE); skb->len, PCI_DMA_TODEVICE);
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
} }
card->tx_buf_list[i] = NULL;
memset(desc, 0, sizeof(*desc)); memset(desc, 0, sizeof(*desc));
} }
card->tx_buf_list[i] = NULL;
}
return; return;
} }
...@@ -514,21 +551,34 @@ static void mwifiex_cleanup_txq_ring(struct mwifiex_adapter *adapter) ...@@ -514,21 +551,34 @@ static void mwifiex_cleanup_txq_ring(struct mwifiex_adapter *adapter)
static void mwifiex_cleanup_rxq_ring(struct mwifiex_adapter *adapter) static void mwifiex_cleanup_rxq_ring(struct mwifiex_adapter *adapter)
{ {
struct pcie_service_card *card = adapter->card; struct pcie_service_card *card = adapter->card;
const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
struct mwifiex_pcie_buf_desc *desc; struct mwifiex_pcie_buf_desc *desc;
struct mwifiex_pfu_buf_desc *desc2;
struct sk_buff *skb; struct sk_buff *skb;
int i; int i;
for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) { for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
if (reg->pfu_enabled) {
desc2 = card->rxbd_ring[i];
if (card->rx_buf_list[i]) {
skb = card->rx_buf_list[i];
pci_unmap_single(card->dev, desc2->paddr,
skb->len, PCI_DMA_TODEVICE);
dev_kfree_skb_any(skb);
}
memset(desc2, 0, sizeof(*desc2));
} else {
desc = card->rxbd_ring[i]; desc = card->rxbd_ring[i];
if (card->rx_buf_list[i]) { if (card->rx_buf_list[i]) {
skb = card->rx_buf_list[i]; skb = card->rx_buf_list[i];
pci_unmap_single(card->dev, desc->paddr, pci_unmap_single(card->dev, desc->paddr,
MWIFIEX_RX_DATA_BUF_SIZE, skb->len, PCI_DMA_TODEVICE);
PCI_DMA_FROMDEVICE);
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
} }
memset(desc, 0, sizeof(*desc)); memset(desc, 0, sizeof(*desc));
} }
card->rx_buf_list[i] = NULL;
}
return; return;
} }
...@@ -571,12 +621,21 @@ static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter) ...@@ -571,12 +621,21 @@ static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter)
* starts at zero with rollover bit set * starts at zero with rollover bit set
*/ */
card->txbd_wrptr = 0; card->txbd_wrptr = 0;
if (reg->pfu_enabled)
card->txbd_rdptr = 0;
else
card->txbd_rdptr |= reg->tx_rollover_ind; card->txbd_rdptr |= reg->tx_rollover_ind;
/* allocate shared memory for the BD ring and divide the same in to /* allocate shared memory for the BD ring and divide the same in to
several descriptors */ several descriptors */
if (reg->pfu_enabled)
card->txbd_ring_size = sizeof(struct mwifiex_pfu_buf_desc) *
MWIFIEX_MAX_TXRX_BD;
else
card->txbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) * card->txbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) *
MWIFIEX_MAX_TXRX_BD; MWIFIEX_MAX_TXRX_BD;
dev_dbg(adapter->dev, "info: txbd_ring: Allocating %d bytes\n", dev_dbg(adapter->dev, "info: txbd_ring: Allocating %d bytes\n",
card->txbd_ring_size); card->txbd_ring_size);
card->txbd_ring_vbase = pci_alloc_consistent(card->dev, card->txbd_ring_vbase = pci_alloc_consistent(card->dev,
...@@ -632,8 +691,13 @@ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter) ...@@ -632,8 +691,13 @@ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter)
card->rxbd_wrptr = 0; card->rxbd_wrptr = 0;
card->rxbd_rdptr = reg->rx_rollover_ind; card->rxbd_rdptr = reg->rx_rollover_ind;
if (reg->pfu_enabled)
card->rxbd_ring_size = sizeof(struct mwifiex_pfu_buf_desc) *
MWIFIEX_MAX_TXRX_BD;
else
card->rxbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) * card->rxbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) *
MWIFIEX_MAX_TXRX_BD; MWIFIEX_MAX_TXRX_BD;
dev_dbg(adapter->dev, "info: rxbd_ring: Allocating %d bytes\n", dev_dbg(adapter->dev, "info: rxbd_ring: Allocating %d bytes\n",
card->rxbd_ring_size); card->rxbd_ring_size);
card->rxbd_ring_vbase = pci_alloc_consistent(card->dev, card->rxbd_ring_vbase = pci_alloc_consistent(card->dev,
...@@ -696,6 +760,7 @@ static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter) ...@@ -696,6 +760,7 @@ static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter)
card->evtbd_ring_size = sizeof(struct mwifiex_evt_buf_desc) * card->evtbd_ring_size = sizeof(struct mwifiex_evt_buf_desc) *
MWIFIEX_MAX_EVT_BD; MWIFIEX_MAX_EVT_BD;
dev_dbg(adapter->dev, "info: evtbd_ring: Allocating %d bytes\n", dev_dbg(adapter->dev, "info: evtbd_ring: Allocating %d bytes\n",
card->evtbd_ring_size); card->evtbd_ring_size);
card->evtbd_ring_vbase = pci_alloc_consistent(card->dev, card->evtbd_ring_vbase = pci_alloc_consistent(card->dev,
...@@ -875,11 +940,11 @@ static int mwifiex_clean_pcie_ring_buf(struct mwifiex_adapter *adapter) ...@@ -875,11 +940,11 @@ static int mwifiex_clean_pcie_ring_buf(struct mwifiex_adapter *adapter)
*/ */
static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter) static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter)
{ {
const u32 num_tx_buffs = MWIFIEX_MAX_TXRX_BD;
struct sk_buff *skb; struct sk_buff *skb;
dma_addr_t buf_pa; dma_addr_t buf_pa;
u32 wrdoneidx, rdptr, unmap_count = 0; u32 wrdoneidx, rdptr, num_tx_buffs, unmap_count = 0;
struct mwifiex_pcie_buf_desc *desc; struct mwifiex_pcie_buf_desc *desc;
struct mwifiex_pfu_buf_desc *desc2;
struct pcie_service_card *card = adapter->card; struct pcie_service_card *card = adapter->card;
const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
...@@ -896,12 +961,14 @@ static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter) ...@@ -896,12 +961,14 @@ static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter)
dev_dbg(adapter->dev, "SEND COMP: rdptr_prev=0x%x, rdptr=0x%x\n", dev_dbg(adapter->dev, "SEND COMP: rdptr_prev=0x%x, rdptr=0x%x\n",
card->txbd_rdptr, rdptr); card->txbd_rdptr, rdptr);
num_tx_buffs = MWIFIEX_MAX_TXRX_BD << reg->tx_start_ptr;
/* free from previous txbd_rdptr to current txbd_rdptr */ /* free from previous txbd_rdptr to current txbd_rdptr */
while (((card->txbd_rdptr & reg->tx_mask) != while (((card->txbd_rdptr & reg->tx_mask) !=
(rdptr & reg->tx_mask)) || (rdptr & reg->tx_mask)) ||
((card->txbd_rdptr & reg->tx_rollover_ind) != ((card->txbd_rdptr & reg->tx_rollover_ind) !=
(rdptr & reg->tx_rollover_ind))) { (rdptr & reg->tx_rollover_ind))) {
wrdoneidx = card->txbd_rdptr & reg->tx_mask; wrdoneidx = (card->txbd_rdptr & reg->tx_mask) >>
reg->tx_start_ptr;
skb = card->tx_buf_list[wrdoneidx]; skb = card->tx_buf_list[wrdoneidx];
if (skb) { if (skb) {
...@@ -922,9 +989,23 @@ static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter) ...@@ -922,9 +989,23 @@ static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter)
} }
card->tx_buf_list[wrdoneidx] = NULL; card->tx_buf_list[wrdoneidx] = NULL;
if (reg->pfu_enabled) {
desc2 = (void *)card->txbd_ring[wrdoneidx];
memset(desc2, 0, sizeof(*desc2));
} else {
desc = card->txbd_ring[wrdoneidx]; desc = card->txbd_ring[wrdoneidx];
memset(desc, 0, sizeof(*desc)); memset(desc, 0, sizeof(*desc));
}
switch (card->dev->device) {
case PCIE_DEVICE_ID_MARVELL_88W8766P:
card->txbd_rdptr++; card->txbd_rdptr++;
break;
case PCIE_DEVICE_ID_MARVELL_88W8897:
card->txbd_rdptr += reg->ring_tx_start_ptr;
break;
}
if ((card->txbd_rdptr & reg->tx_mask) == num_tx_buffs) if ((card->txbd_rdptr & reg->tx_mask) == num_tx_buffs)
card->txbd_rdptr = ((card->txbd_rdptr & card->txbd_rdptr = ((card->txbd_rdptr &
...@@ -960,10 +1041,11 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb, ...@@ -960,10 +1041,11 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb,
{ {
struct pcie_service_card *card = adapter->card; struct pcie_service_card *card = adapter->card;
const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
u32 wrindx; u32 wrindx, num_tx_buffs, rx_val;
int ret; int ret;
dma_addr_t buf_pa; dma_addr_t buf_pa;
struct mwifiex_pcie_buf_desc *desc; struct mwifiex_pcie_buf_desc *desc;
struct mwifiex_pfu_buf_desc *desc2;
__le16 *tmp; __le16 *tmp;
if (!(skb->data && skb->len)) { if (!(skb->data && skb->len)) {
...@@ -975,6 +1057,7 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb, ...@@ -975,6 +1057,7 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb,
if (!mwifiex_pcie_ok_to_access_hw(adapter)) if (!mwifiex_pcie_ok_to_access_hw(adapter))
mwifiex_pm_wakeup_card(adapter); mwifiex_pm_wakeup_card(adapter);
num_tx_buffs = MWIFIEX_MAX_TXRX_BD << reg->tx_start_ptr;
dev_dbg(adapter->dev, "info: SEND DATA: <Rd: %#x, Wr: %#x>\n", dev_dbg(adapter->dev, "info: SEND DATA: <Rd: %#x, Wr: %#x>\n",
card->txbd_rdptr, card->txbd_wrptr); card->txbd_rdptr, card->txbd_wrptr);
if (mwifiex_pcie_txbd_not_full(card)) { if (mwifiex_pcie_txbd_not_full(card)) {
...@@ -991,24 +1074,44 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb, ...@@ -991,24 +1074,44 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb,
PCI_DMA_TODEVICE)) PCI_DMA_TODEVICE))
return -1; return -1;
wrindx = card->txbd_wrptr & reg->tx_mask; wrindx = (card->txbd_wrptr & reg->tx_mask) >> reg->tx_start_ptr;
MWIFIEX_SKB_PACB(skb, &buf_pa); MWIFIEX_SKB_PACB(skb, &buf_pa);
card->tx_buf_list[wrindx] = skb; card->tx_buf_list[wrindx] = skb;
if (reg->pfu_enabled) {
desc2 = (void *)card->txbd_ring[wrindx];
desc2->paddr = buf_pa;
desc2->len = (u16)skb->len;
desc2->frag_len = (u16)skb->len;
desc2->offset = 0;
desc2->flags = MWIFIEX_BD_FLAG_FIRST_DESC |
MWIFIEX_BD_FLAG_LAST_DESC;
} else {
desc = card->txbd_ring[wrindx]; desc = card->txbd_ring[wrindx];
desc->paddr = buf_pa; desc->paddr = buf_pa;
desc->len = (u16)skb->len; desc->len = (u16)skb->len;
desc->flags = MWIFIEX_BD_FLAG_FIRST_DESC | desc->flags = MWIFIEX_BD_FLAG_FIRST_DESC |
MWIFIEX_BD_FLAG_LAST_DESC; MWIFIEX_BD_FLAG_LAST_DESC;
}
if ((++card->txbd_wrptr & reg->tx_mask) == switch (card->dev->device) {
MWIFIEX_MAX_TXRX_BD) case PCIE_DEVICE_ID_MARVELL_88W8766P:
card->txbd_wrptr++;
break;
case PCIE_DEVICE_ID_MARVELL_88W8897:
card->txbd_wrptr += reg->ring_tx_start_ptr;
break;
}
if ((card->txbd_wrptr & reg->tx_mask) == num_tx_buffs)
card->txbd_wrptr = ((card->txbd_wrptr & card->txbd_wrptr = ((card->txbd_wrptr &
reg->tx_rollover_ind) ^ reg->tx_rollover_ind) ^
reg->tx_rollover_ind); reg->tx_rollover_ind);
rx_val = card->rxbd_rdptr & reg->rx_wrap_mask;
/* Write the TX ring write pointer in to reg->tx_wrptr */ /* Write the TX ring write pointer in to reg->tx_wrptr */
if (mwifiex_write_reg(adapter, reg->tx_wrptr, if (mwifiex_write_reg(adapter, reg->tx_wrptr,
card->txbd_wrptr)) { card->txbd_wrptr | rx_val)) {
dev_err(adapter->dev, dev_err(adapter->dev,
"SEND DATA: failed to write reg->tx_wrptr\n"); "SEND DATA: failed to write reg->tx_wrptr\n");
ret = -1; ret = -1;
...@@ -1050,7 +1153,11 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb, ...@@ -1050,7 +1153,11 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb,
MWIFIEX_SKB_PACB(skb, &buf_pa); MWIFIEX_SKB_PACB(skb, &buf_pa);
pci_unmap_single(card->dev, buf_pa, skb->len, PCI_DMA_TODEVICE); pci_unmap_single(card->dev, buf_pa, skb->len, PCI_DMA_TODEVICE);
card->tx_buf_list[wrindx] = NULL; card->tx_buf_list[wrindx] = NULL;
if (reg->pfu_enabled)
memset(desc2, 0, sizeof(*desc2));
else
memset(desc, 0, sizeof(*desc)); memset(desc, 0, sizeof(*desc));
return ret; return ret;
} }
...@@ -1062,11 +1169,12 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) ...@@ -1062,11 +1169,12 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter)
{ {
struct pcie_service_card *card = adapter->card; struct pcie_service_card *card = adapter->card;
const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
u32 wrptr, rd_index; u32 wrptr, rd_index, tx_val;
dma_addr_t buf_pa; dma_addr_t buf_pa;
int ret = 0; int ret = 0;
struct sk_buff *skb_tmp = NULL; struct sk_buff *skb_tmp = NULL;
struct mwifiex_pcie_buf_desc *desc; struct mwifiex_pcie_buf_desc *desc;
struct mwifiex_pfu_buf_desc *desc2;
if (!mwifiex_pcie_ok_to_access_hw(adapter)) if (!mwifiex_pcie_ok_to_access_hw(adapter))
mwifiex_pm_wakeup_card(adapter); mwifiex_pm_wakeup_card(adapter);
...@@ -1126,10 +1234,20 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) ...@@ -1126,10 +1234,20 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter)
"RECV DATA: Attach new sk_buff %p at rxbd_rdidx=%d\n", "RECV DATA: Attach new sk_buff %p at rxbd_rdidx=%d\n",
skb_tmp, rd_index); skb_tmp, rd_index);
card->rx_buf_list[rd_index] = skb_tmp; card->rx_buf_list[rd_index] = skb_tmp;
if (reg->pfu_enabled) {
desc2 = (void *)card->rxbd_ring[rd_index];
desc2->paddr = buf_pa;
desc2->len = skb_tmp->len;
desc2->frag_len = skb_tmp->len;
desc2->offset = 0;
desc2->flags = reg->ring_flag_sop | reg->ring_flag_eop;
} else {
desc = card->rxbd_ring[rd_index]; desc = card->rxbd_ring[rd_index];
desc->paddr = buf_pa; desc->paddr = buf_pa;
desc->len = skb_tmp->len; desc->len = skb_tmp->len;
desc->flags = 0; desc->flags = 0;
}
if ((++card->rxbd_rdptr & reg->rx_mask) == if ((++card->rxbd_rdptr & reg->rx_mask) ==
MWIFIEX_MAX_TXRX_BD) { MWIFIEX_MAX_TXRX_BD) {
...@@ -1140,9 +1258,10 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) ...@@ -1140,9 +1258,10 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter)
dev_dbg(adapter->dev, "info: RECV DATA: <Rd: %#x, Wr: %#x>\n", dev_dbg(adapter->dev, "info: RECV DATA: <Rd: %#x, Wr: %#x>\n",
card->rxbd_rdptr, wrptr); card->rxbd_rdptr, wrptr);
tx_val = card->txbd_wrptr & reg->tx_wrap_mask;
/* Write the RX ring read pointer in to reg->rx_rdptr */ /* Write the RX ring read pointer in to reg->rx_rdptr */
if (mwifiex_write_reg(adapter, reg->rx_rdptr, if (mwifiex_write_reg(adapter, reg->rx_rdptr,
card->rxbd_rdptr)) { card->rxbd_rdptr | tx_val)) {
dev_err(adapter->dev, dev_err(adapter->dev,
"RECV DATA: failed to write reg->rx_rdptr\n"); "RECV DATA: failed to write reg->rx_rdptr\n");
ret = -1; ret = -1;
...@@ -1242,9 +1361,11 @@ static int mwifiex_pcie_init_fw_port(struct mwifiex_adapter *adapter) ...@@ -1242,9 +1361,11 @@ static int mwifiex_pcie_init_fw_port(struct mwifiex_adapter *adapter)
{ {
struct pcie_service_card *card = adapter->card; struct pcie_service_card *card = adapter->card;
const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
int tx_wrap = card->txbd_wrptr & reg->tx_wrap_mask;
/* Write the RX ring read pointer in to reg->rx_rdptr */ /* Write the RX ring read pointer in to reg->rx_rdptr */
if (mwifiex_write_reg(adapter, reg->rx_rdptr, card->rxbd_rdptr)) { if (mwifiex_write_reg(adapter, reg->rx_rdptr, card->rxbd_rdptr |
tx_wrap)) {
dev_err(adapter->dev, dev_err(adapter->dev,
"RECV DATA: failed to write reg->rx_rdptr\n"); "RECV DATA: failed to write reg->rx_rdptr\n");
return -1; return -1;
...@@ -2259,7 +2380,7 @@ static int mwifiex_pcie_init_module(void) ...@@ -2259,7 +2380,7 @@ static int mwifiex_pcie_init_module(void)
{ {
int ret; int ret;
pr_debug("Marvell 8766 PCIe Driver\n"); pr_debug("Marvell PCIe Driver\n");
sema_init(&add_remove_card_sem, 1); sema_init(&add_remove_card_sem, 1);
...@@ -2302,4 +2423,5 @@ MODULE_AUTHOR("Marvell International Ltd."); ...@@ -2302,4 +2423,5 @@ MODULE_AUTHOR("Marvell International Ltd.");
MODULE_DESCRIPTION("Marvell WiFi-Ex PCI-Express Driver version " PCIE_VERSION); MODULE_DESCRIPTION("Marvell WiFi-Ex PCI-Express Driver version " PCIE_VERSION);
MODULE_VERSION(PCIE_VERSION); MODULE_VERSION(PCIE_VERSION);
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");
MODULE_FIRMWARE("mrvl/pcie8766_uapsta.bin"); MODULE_FIRMWARE(PCIE8766_DEFAULT_FW_NAME);
MODULE_FIRMWARE(PCIE8897_DEFAULT_FW_NAME);
...@@ -29,6 +29,11 @@ ...@@ -29,6 +29,11 @@
#include "main.h" #include "main.h"
#define PCIE8766_DEFAULT_FW_NAME "mrvl/pcie8766_uapsta.bin" #define PCIE8766_DEFAULT_FW_NAME "mrvl/pcie8766_uapsta.bin"
#define PCIE8897_DEFAULT_FW_NAME "mrvl/pcie8897_uapsta.bin"
#define PCIE_VENDOR_ID_MARVELL (0x11ab)
#define PCIE_DEVICE_ID_MARVELL_88W8766P (0x2b30)
#define PCIE_DEVICE_ID_MARVELL_88W8897 (0x2b38)
/* Constants for Buffer Descriptor (BD) rings */ /* Constants for Buffer Descriptor (BD) rings */
#define MWIFIEX_MAX_TXRX_BD 0x20 #define MWIFIEX_MAX_TXRX_BD 0x20
...@@ -57,6 +62,8 @@ ...@@ -57,6 +62,8 @@
#define PCIE_SCRATCH_10_REG 0xCE8 #define PCIE_SCRATCH_10_REG 0xCE8
#define PCIE_SCRATCH_11_REG 0xCEC #define PCIE_SCRATCH_11_REG 0xCEC
#define PCIE_SCRATCH_12_REG 0xCF0 #define PCIE_SCRATCH_12_REG 0xCF0
#define PCIE_RD_DATA_PTR_Q0_Q1 0xC08C
#define PCIE_WR_DATA_PTR_Q0_Q1 0xC05C
#define CPU_INTR_DNLD_RDY BIT(0) #define CPU_INTR_DNLD_RDY BIT(0)
#define CPU_INTR_DOOR_BELL BIT(1) #define CPU_INTR_DOOR_BELL BIT(1)
...@@ -75,6 +82,14 @@ ...@@ -75,6 +82,14 @@
#define MWIFIEX_BD_FLAG_ROLLOVER_IND BIT(7) #define MWIFIEX_BD_FLAG_ROLLOVER_IND BIT(7)
#define MWIFIEX_BD_FLAG_FIRST_DESC BIT(0) #define MWIFIEX_BD_FLAG_FIRST_DESC BIT(0)
#define MWIFIEX_BD_FLAG_LAST_DESC BIT(1) #define MWIFIEX_BD_FLAG_LAST_DESC BIT(1)
#define MWIFIEX_BD_FLAG_SOP BIT(0)
#define MWIFIEX_BD_FLAG_EOP BIT(1)
#define MWIFIEX_BD_FLAG_XS_SOP BIT(2)
#define MWIFIEX_BD_FLAG_XS_EOP BIT(3)
#define MWIFIEX_BD_FLAG_EVT_ROLLOVER_IND BIT(7)
#define MWIFIEX_BD_FLAG_RX_ROLLOVER_IND BIT(10)
#define MWIFIEX_BD_FLAG_TX_START_PTR BIT(16)
#define MWIFIEX_BD_FLAG_TX_ROLLOVER_IND BIT(26)
/* Max retry number of command write */ /* Max retry number of command write */
#define MAX_WRITE_IOMEM_RETRY 2 #define MAX_WRITE_IOMEM_RETRY 2
...@@ -143,6 +158,36 @@ static const struct mwifiex_pcie_card_reg mwifiex_reg_8766 = { ...@@ -143,6 +158,36 @@ static const struct mwifiex_pcie_card_reg mwifiex_reg_8766 = {
.pfu_enabled = 0, .pfu_enabled = 0,
}; };
static const struct mwifiex_pcie_card_reg mwifiex_reg_8897 = {
.cmd_addr_lo = PCIE_SCRATCH_0_REG,
.cmd_addr_hi = PCIE_SCRATCH_1_REG,
.cmd_size = PCIE_SCRATCH_2_REG,
.fw_status = PCIE_SCRATCH_3_REG,
.cmdrsp_addr_lo = PCIE_SCRATCH_4_REG,
.cmdrsp_addr_hi = PCIE_SCRATCH_5_REG,
.tx_rdptr = PCIE_RD_DATA_PTR_Q0_Q1,
.tx_wrptr = PCIE_WR_DATA_PTR_Q0_Q1,
.rx_rdptr = PCIE_WR_DATA_PTR_Q0_Q1,
.rx_wrptr = PCIE_RD_DATA_PTR_Q0_Q1,
.evt_rdptr = PCIE_SCRATCH_10_REG,
.evt_wrptr = PCIE_SCRATCH_11_REG,
.drv_rdy = PCIE_SCRATCH_12_REG,
.tx_start_ptr = 16,
.tx_mask = 0x03FF0000,
.tx_wrap_mask = 0x07FF0000,
.rx_mask = 0x000003FF,
.rx_wrap_mask = 0x000007FF,
.tx_rollover_ind = MWIFIEX_BD_FLAG_TX_ROLLOVER_IND,
.rx_rollover_ind = MWIFIEX_BD_FLAG_RX_ROLLOVER_IND,
.evt_rollover_ind = MWIFIEX_BD_FLAG_EVT_ROLLOVER_IND,
.ring_flag_sop = MWIFIEX_BD_FLAG_SOP,
.ring_flag_eop = MWIFIEX_BD_FLAG_EOP,
.ring_flag_xs_sop = MWIFIEX_BD_FLAG_XS_SOP,
.ring_flag_xs_eop = MWIFIEX_BD_FLAG_XS_EOP,
.ring_tx_start_ptr = MWIFIEX_BD_FLAG_TX_START_PTR,
.pfu_enabled = 1,
};
struct mwifiex_pcie_device { struct mwifiex_pcie_device {
const char *firmware; const char *firmware;
const struct mwifiex_pcie_card_reg *reg; const struct mwifiex_pcie_card_reg *reg;
...@@ -155,6 +200,12 @@ static const struct mwifiex_pcie_device mwifiex_pcie8766 = { ...@@ -155,6 +200,12 @@ static const struct mwifiex_pcie_device mwifiex_pcie8766 = {
.blksz_fw_dl = MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD, .blksz_fw_dl = MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD,
}; };
static const struct mwifiex_pcie_device mwifiex_pcie8897 = {
.firmware = PCIE8897_DEFAULT_FW_NAME,
.reg = &mwifiex_reg_8897,
.blksz_fw_dl = MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD,
};
struct mwifiex_evt_buf_desc { struct mwifiex_evt_buf_desc {
u64 paddr; u64 paddr;
u16 len; u16 len;
...@@ -167,6 +218,15 @@ struct mwifiex_pcie_buf_desc { ...@@ -167,6 +218,15 @@ struct mwifiex_pcie_buf_desc {
u16 flags; u16 flags;
} __packed; } __packed;
struct mwifiex_pfu_buf_desc {
u16 flags;
u16 offset;
u16 frag_len;
u16 len;
u64 paddr;
u32 reserved;
} __packed;
struct pcie_service_card { struct pcie_service_card {
struct pci_dev *dev; struct pci_dev *dev;
struct mwifiex_adapter *adapter; struct mwifiex_adapter *adapter;
...@@ -210,10 +270,22 @@ mwifiex_pcie_txbd_empty(struct pcie_service_card *card, u32 rdptr) ...@@ -210,10 +270,22 @@ mwifiex_pcie_txbd_empty(struct pcie_service_card *card, u32 rdptr)
{ {
const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
if (((card->txbd_wrptr & reg->tx_mask) == (rdptr & reg->tx_mask)) && switch (card->dev->device) {
case PCIE_DEVICE_ID_MARVELL_88W8766P:
if (((card->txbd_wrptr & reg->tx_mask) ==
(rdptr & reg->tx_mask)) &&
((card->txbd_wrptr & reg->tx_rollover_ind) != ((card->txbd_wrptr & reg->tx_rollover_ind) !=
(rdptr & reg->tx_rollover_ind))) (rdptr & reg->tx_rollover_ind)))
return 1; return 1;
break;
case PCIE_DEVICE_ID_MARVELL_88W8897:
if (((card->txbd_wrptr & reg->tx_mask) ==
(rdptr & reg->tx_mask)) &&
((card->txbd_wrptr & reg->tx_rollover_ind) ==
(rdptr & reg->tx_rollover_ind)))
return 1;
break;
}
return 0; return 0;
} }
...@@ -223,11 +295,22 @@ mwifiex_pcie_txbd_not_full(struct pcie_service_card *card) ...@@ -223,11 +295,22 @@ mwifiex_pcie_txbd_not_full(struct pcie_service_card *card)
{ {
const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
switch (card->dev->device) {
case PCIE_DEVICE_ID_MARVELL_88W8766P:
if (((card->txbd_wrptr & reg->tx_mask) != if (((card->txbd_wrptr & reg->tx_mask) !=
(card->txbd_rdptr & reg->tx_mask)) || (card->txbd_rdptr & reg->tx_mask)) ||
((card->txbd_wrptr & reg->tx_rollover_ind) != ((card->txbd_wrptr & reg->tx_rollover_ind) !=
(card->txbd_rdptr & reg->tx_rollover_ind))) (card->txbd_rdptr & reg->tx_rollover_ind)))
return 1; return 1;
break;
case PCIE_DEVICE_ID_MARVELL_88W8897:
if (((card->txbd_wrptr & reg->tx_mask) !=
(card->txbd_rdptr & reg->tx_mask)) ||
((card->txbd_wrptr & reg->tx_rollover_ind) ==
(card->txbd_rdptr & reg->tx_rollover_ind)))
return 1;
break;
}
return 0; return 0;
} }
......
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