diff options
Diffstat (limited to 'drivers/net/wireless/mwifiex/pcie.c')
-rw-r--r-- | drivers/net/wireless/mwifiex/pcie.c | 180 |
1 files changed, 93 insertions, 87 deletions
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c index 7fe7b53fb17a..a7e8b96b2d90 100644 --- a/drivers/net/wireless/mwifiex/pcie.c +++ b/drivers/net/wireless/mwifiex/pcie.c @@ -39,20 +39,31 @@ static struct semaphore add_remove_card_sem; static int mwifiex_map_pci_memory(struct mwifiex_adapter *adapter, struct sk_buff *skb, - int size, int flags) + size_t size, int flags) { struct pcie_service_card *card = adapter->card; - dma_addr_t buf_pa; + struct mwifiex_dma_mapping mapping; - buf_pa = pci_map_single(card->dev, skb->data, size, flags); - if (pci_dma_mapping_error(card->dev, buf_pa)) { + mapping.addr = pci_map_single(card->dev, skb->data, size, flags); + if (pci_dma_mapping_error(card->dev, mapping.addr)) { dev_err(adapter->dev, "failed to map pci memory!\n"); return -1; } - memcpy(skb->cb, &buf_pa, sizeof(dma_addr_t)); + mapping.len = size; + memcpy(skb->cb, &mapping, sizeof(mapping)); return 0; } +static void mwifiex_unmap_pci_memory(struct mwifiex_adapter *adapter, + struct sk_buff *skb, int flags) +{ + struct pcie_service_card *card = adapter->card; + struct mwifiex_dma_mapping mapping; + + MWIFIEX_SKB_PACB(skb, &mapping); + pci_unmap_single(card->dev, mapping.addr, mapping.len, flags); +} + /* * This function reads sleep cookie and checks if FW is ready */ @@ -109,6 +120,7 @@ static int mwifiex_pcie_suspend(struct device *dev) /* Indicate device suspended */ adapter->is_suspended = true; + adapter->hs_enabling = false; return 0; } @@ -179,6 +191,7 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev, card->pcie.firmware = data->firmware; card->pcie.reg = data->reg; card->pcie.blksz_fw_dl = data->blksz_fw_dl; + card->pcie.tx_buf_size = data->tx_buf_size; } if (mwifiex_add_card(card, &add_remove_card_sem, &pcie_ops, @@ -199,7 +212,6 @@ static void mwifiex_pcie_remove(struct pci_dev *pdev) struct pcie_service_card *card; struct mwifiex_adapter *adapter; struct mwifiex_private *priv; - int i; card = pci_get_drvdata(pdev); if (!card) @@ -218,11 +230,7 @@ static void mwifiex_pcie_remove(struct pci_dev *pdev) mwifiex_pcie_resume(&pdev->dev); #endif - for (i = 0; i < adapter->priv_num; i++) - if ((GET_BSS_ROLE(adapter->priv[i]) == - MWIFIEX_BSS_ROLE_STA) && - adapter->priv[i]->media_connected) - mwifiex_deauthenticate(adapter->priv[i], NULL); + mwifiex_deauthenticate_all(adapter); priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); @@ -320,6 +328,30 @@ static void mwifiex_pcie_dev_wakeup_delay(struct mwifiex_adapter *adapter) return; } +static void mwifiex_delay_for_sleep_cookie(struct mwifiex_adapter *adapter, + u32 max_delay_loop_cnt) +{ + struct pcie_service_card *card = adapter->card; + u8 *buffer; + u32 sleep_cookie, count; + + for (count = 0; count < max_delay_loop_cnt; count++) { + buffer = card->cmdrsp_buf->data - INTF_HEADER_LEN; + sleep_cookie = *(u32 *)buffer; + + if (sleep_cookie == MWIFIEX_DEF_SLEEP_COOKIE) { + dev_dbg(adapter->dev, + "sleep cookie found at count %d\n", count); + break; + } + usleep_range(20, 30); + } + + if (count >= max_delay_loop_cnt) + dev_dbg(adapter->dev, + "max count reached while accessing sleep cookie\n"); +} + /* This function wakes up the card by reading fw_status register. */ static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter) { @@ -456,7 +488,7 @@ static int mwifiex_init_rxq_ring(struct mwifiex_adapter *adapter) PCI_DMA_FROMDEVICE)) return -1; - MWIFIEX_SKB_PACB(skb, &buf_pa); + buf_pa = MWIFIEX_SKB_DMA_ADDR(skb); dev_dbg(adapter->dev, "info: RX ring: skb=%p len=%d data=%p buf_pa=%#x:%x\n", @@ -513,7 +545,7 @@ static int mwifiex_pcie_init_evt_ring(struct mwifiex_adapter *adapter) PCI_DMA_FROMDEVICE)) return -1; - MWIFIEX_SKB_PACB(skb, &buf_pa); + buf_pa = MWIFIEX_SKB_DMA_ADDR(skb); dev_dbg(adapter->dev, "info: EVT ring: skb=%p len=%d data=%p buf_pa=%#x:%x\n", @@ -549,8 +581,8 @@ static void mwifiex_cleanup_txq_ring(struct mwifiex_adapter *adapter) 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); + mwifiex_unmap_pci_memory(adapter, skb, + PCI_DMA_TODEVICE); dev_kfree_skb_any(skb); } memset(desc2, 0, sizeof(*desc2)); @@ -558,8 +590,8 @@ static void mwifiex_cleanup_txq_ring(struct mwifiex_adapter *adapter) desc = card->txbd_ring[i]; if (card->tx_buf_list[i]) { skb = card->tx_buf_list[i]; - pci_unmap_single(card->dev, desc->paddr, - skb->len, PCI_DMA_TODEVICE); + mwifiex_unmap_pci_memory(adapter, skb, + PCI_DMA_TODEVICE); dev_kfree_skb_any(skb); } memset(desc, 0, sizeof(*desc)); @@ -587,8 +619,8 @@ static void mwifiex_cleanup_rxq_ring(struct mwifiex_adapter *adapter) 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_FROMDEVICE); + mwifiex_unmap_pci_memory(adapter, skb, + PCI_DMA_FROMDEVICE); dev_kfree_skb_any(skb); } memset(desc2, 0, sizeof(*desc2)); @@ -596,8 +628,8 @@ static void mwifiex_cleanup_rxq_ring(struct mwifiex_adapter *adapter) desc = card->rxbd_ring[i]; if (card->rx_buf_list[i]) { skb = card->rx_buf_list[i]; - pci_unmap_single(card->dev, desc->paddr, - skb->len, PCI_DMA_FROMDEVICE); + mwifiex_unmap_pci_memory(adapter, skb, + PCI_DMA_FROMDEVICE); dev_kfree_skb_any(skb); } memset(desc, 0, sizeof(*desc)); @@ -622,8 +654,8 @@ static void mwifiex_cleanup_evt_ring(struct mwifiex_adapter *adapter) desc = card->evtbd_ring[i]; if (card->evt_buf_list[i]) { skb = card->evt_buf_list[i]; - pci_unmap_single(card->dev, desc->paddr, MAX_EVENT_SIZE, - PCI_DMA_FROMDEVICE); + mwifiex_unmap_pci_memory(adapter, skb, + PCI_DMA_FROMDEVICE); dev_kfree_skb_any(skb); } card->evt_buf_list[i] = NULL; @@ -861,7 +893,6 @@ static int mwifiex_pcie_alloc_cmdrsp_buf(struct mwifiex_adapter *adapter) static int mwifiex_pcie_delete_cmdrsp_buf(struct mwifiex_adapter *adapter) { struct pcie_service_card *card; - dma_addr_t buf_pa; if (!adapter) return 0; @@ -869,16 +900,14 @@ static int mwifiex_pcie_delete_cmdrsp_buf(struct mwifiex_adapter *adapter) card = adapter->card; if (card && card->cmdrsp_buf) { - MWIFIEX_SKB_PACB(card->cmdrsp_buf, &buf_pa); - pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE, - PCI_DMA_FROMDEVICE); + mwifiex_unmap_pci_memory(adapter, card->cmdrsp_buf, + PCI_DMA_FROMDEVICE); dev_kfree_skb_any(card->cmdrsp_buf); } if (card && card->cmd_buf) { - MWIFIEX_SKB_PACB(card->cmd_buf, &buf_pa); - pci_unmap_single(card->dev, buf_pa, card->cmd_buf->len, - PCI_DMA_TODEVICE); + mwifiex_unmap_pci_memory(adapter, card->cmd_buf, + PCI_DMA_TODEVICE); } return 0; } @@ -956,7 +985,6 @@ static int mwifiex_clean_pcie_ring_buf(struct mwifiex_adapter *adapter) static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter) { struct sk_buff *skb; - dma_addr_t buf_pa; u32 wrdoneidx, rdptr, num_tx_buffs, unmap_count = 0; struct mwifiex_pcie_buf_desc *desc; struct mwifiex_pfu_buf_desc *desc2; @@ -986,13 +1014,13 @@ static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter) reg->tx_start_ptr; skb = card->tx_buf_list[wrdoneidx]; + if (skb) { dev_dbg(adapter->dev, "SEND COMP: Detach skb %p at txbd_rdidx=%d\n", skb, wrdoneidx); - MWIFIEX_SKB_PACB(skb, &buf_pa); - pci_unmap_single(card->dev, buf_pa, skb->len, - PCI_DMA_TODEVICE); + mwifiex_unmap_pci_memory(adapter, skb, + PCI_DMA_TODEVICE); unmap_count++; @@ -1006,7 +1034,7 @@ static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter) card->tx_buf_list[wrdoneidx] = NULL; if (reg->pfu_enabled) { - desc2 = (void *)card->txbd_ring[wrdoneidx]; + desc2 = card->txbd_ring[wrdoneidx]; memset(desc2, 0, sizeof(*desc2)); } else { desc = card->txbd_ring[wrdoneidx]; @@ -1082,16 +1110,16 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb, tmp = (__le16 *)&payload[2]; *tmp = cpu_to_le16(MWIFIEX_TYPE_DATA); - if (mwifiex_map_pci_memory(adapter, skb, skb->len , + if (mwifiex_map_pci_memory(adapter, skb, skb->len, PCI_DMA_TODEVICE)) return -1; wrindx = (card->txbd_wrptr & reg->tx_mask) >> reg->tx_start_ptr; - MWIFIEX_SKB_PACB(skb, &buf_pa); + buf_pa = MWIFIEX_SKB_DMA_ADDR(skb); card->tx_buf_list[wrindx] = skb; if (reg->pfu_enabled) { - desc2 = (void *)card->txbd_ring[wrindx]; + desc2 = card->txbd_ring[wrindx]; desc2->paddr = buf_pa; desc2->len = (u16)skb->len; desc2->frag_len = (u16)skb->len; @@ -1162,8 +1190,7 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb, return -EINPROGRESS; done_unmap: - MWIFIEX_SKB_PACB(skb, &buf_pa); - pci_unmap_single(card->dev, buf_pa, skb->len, PCI_DMA_TODEVICE); + mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE); card->tx_buf_list[wrindx] = NULL; if (reg->pfu_enabled) memset(desc2, 0, sizeof(*desc2)); @@ -1217,9 +1244,7 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) if (!skb_data) return -ENOMEM; - MWIFIEX_SKB_PACB(skb_data, &buf_pa); - pci_unmap_single(card->dev, buf_pa, MWIFIEX_RX_DATA_BUF_SIZE, - PCI_DMA_FROMDEVICE); + mwifiex_unmap_pci_memory(adapter, skb_data, PCI_DMA_FROMDEVICE); card->rx_buf_list[rd_index] = NULL; /* Get data length from interface header - @@ -1246,7 +1271,7 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) PCI_DMA_FROMDEVICE)) return -1; - MWIFIEX_SKB_PACB(skb_tmp, &buf_pa); + buf_pa = MWIFIEX_SKB_DMA_ADDR(skb_tmp); dev_dbg(adapter->dev, "RECV DATA: Attach new sk_buff %p at rxbd_rdidx=%d\n", @@ -1254,7 +1279,7 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) card->rx_buf_list[rd_index] = skb_tmp; if (reg->pfu_enabled) { - desc2 = (void *)card->rxbd_ring[rd_index]; + desc2 = card->rxbd_ring[rd_index]; desc2->paddr = buf_pa; desc2->len = skb_tmp->len; desc2->frag_len = skb_tmp->len; @@ -1322,7 +1347,7 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) if (mwifiex_map_pci_memory(adapter, skb, skb->len , PCI_DMA_TODEVICE)) return -1; - MWIFIEX_SKB_PACB(skb, &buf_pa); + buf_pa = MWIFIEX_SKB_DMA_ADDR(skb); /* Write the lower 32bits of the physical address to low command * address scratch register @@ -1331,8 +1356,7 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) dev_err(adapter->dev, "%s: failed to write download command to boot code.\n", __func__); - pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE, - PCI_DMA_TODEVICE); + mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE); return -1; } @@ -1344,8 +1368,7 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) dev_err(adapter->dev, "%s: failed to write download command to boot code.\n", __func__); - pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE, - PCI_DMA_TODEVICE); + mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE); return -1; } @@ -1354,8 +1377,7 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) dev_err(adapter->dev, "%s: failed to write command len to cmd_size scratch reg\n", __func__); - pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE, - PCI_DMA_TODEVICE); + mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE); return -1; } @@ -1364,8 +1386,7 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) CPU_INTR_DOOR_BELL)) { dev_err(adapter->dev, "%s: failed to assert door-bell intr\n", __func__); - pci_unmap_single(card->dev, buf_pa, - MWIFIEX_UPLD_SIZE, PCI_DMA_TODEVICE); + mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE); return -1; } @@ -1439,7 +1460,7 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) */ if (card->cmdrsp_buf) { - MWIFIEX_SKB_PACB(card->cmdrsp_buf, &cmdrsp_buf_pa); + cmdrsp_buf_pa = MWIFIEX_SKB_DMA_ADDR(card->cmdrsp_buf); /* Write the lower 32bits of the cmdrsp buffer physical address */ if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_lo, @@ -1460,7 +1481,7 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) } } - MWIFIEX_SKB_PACB(card->cmd_buf, &cmd_buf_pa); + cmd_buf_pa = MWIFIEX_SKB_DMA_ADDR(card->cmd_buf); /* Write the lower 32bits of the physical address to reg->cmd_addr_lo */ if (mwifiex_write_reg(adapter, reg->cmd_addr_lo, (u32)cmd_buf_pa)) { @@ -1514,13 +1535,17 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter) int count = 0; u16 rx_len; __le16 pkt_len; - dma_addr_t buf_pa; dev_dbg(adapter->dev, "info: Rx CMD Response\n"); - MWIFIEX_SKB_PACB(skb, &buf_pa); - pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE, - PCI_DMA_FROMDEVICE); + mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_FROMDEVICE); + + /* Unmap the command as a response has been received. */ + if (card->cmd_buf) { + mwifiex_unmap_pci_memory(adapter, card->cmd_buf, + PCI_DMA_TODEVICE); + card->cmd_buf = NULL; + } pkt_len = *((__le16 *)skb->data); rx_len = le16_to_cpu(pkt_len); @@ -1539,6 +1564,8 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter) "Write register failed\n"); return -1; } + mwifiex_delay_for_sleep_cookie(adapter, + MWIFIEX_MAX_DELAY_COUNT); while (reg->sleep_cookie && (count++ < 10) && mwifiex_pcie_ok_to_access_hw(adapter)) usleep_range(50, 60); @@ -1552,8 +1579,6 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter) if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE, PCI_DMA_FROMDEVICE)) return -1; - - MWIFIEX_SKB_PACB(skb, &buf_pa); } else if (mwifiex_pcie_ok_to_access_hw(adapter)) { adapter->curr_cmd->resp_skb = skb; adapter->cmd_resp_received = true; @@ -1588,8 +1613,6 @@ static int mwifiex_pcie_cmdrsp_complete(struct mwifiex_adapter *adapter, struct sk_buff *skb) { struct pcie_service_card *card = adapter->card; - dma_addr_t buf_pa; - struct sk_buff *skb_tmp; if (skb) { card->cmdrsp_buf = skb; @@ -1599,14 +1622,6 @@ static int mwifiex_pcie_cmdrsp_complete(struct mwifiex_adapter *adapter, return -1; } - skb_tmp = card->cmd_buf; - if (skb_tmp) { - MWIFIEX_SKB_PACB(skb_tmp, &buf_pa); - pci_unmap_single(card->dev, buf_pa, skb_tmp->len, - PCI_DMA_FROMDEVICE); - card->cmd_buf = NULL; - } - return 0; } @@ -1619,7 +1634,6 @@ static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter) const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK; u32 wrptr, event; - dma_addr_t buf_pa; struct mwifiex_evt_buf_desc *desc; if (!mwifiex_pcie_ok_to_access_hw(adapter)) @@ -1655,9 +1669,7 @@ static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter) dev_dbg(adapter->dev, "info: Read Index: %d\n", rdptr); skb_cmd = card->evt_buf_list[rdptr]; - MWIFIEX_SKB_PACB(skb_cmd, &buf_pa); - pci_unmap_single(card->dev, buf_pa, MAX_EVENT_SIZE, - PCI_DMA_FROMDEVICE); + mwifiex_unmap_pci_memory(adapter, skb_cmd, PCI_DMA_FROMDEVICE); /* Take the pointer and set it to event pointer in adapter and will return back after event handling callback */ @@ -1703,7 +1715,6 @@ static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter, int ret = 0; u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK; u32 wrptr; - dma_addr_t buf_pa; struct mwifiex_evt_buf_desc *desc; if (!skb) @@ -1728,11 +1739,9 @@ static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter, MAX_EVENT_SIZE, PCI_DMA_FROMDEVICE)) return -1; - MWIFIEX_SKB_PACB(skb, &buf_pa); card->evt_buf_list[rdptr] = skb; - MWIFIEX_SKB_PACB(skb, &buf_pa); desc = card->evtbd_ring[rdptr]; - desc->paddr = buf_pa; + desc->paddr = MWIFIEX_SKB_DMA_ADDR(skb); desc->len = (u16)skb->len; desc->flags = 0; skb = NULL; @@ -1782,7 +1791,6 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, struct sk_buff *skb; u32 txlen, tx_blocks = 0, tries, len; u32 block_retry_cnt = 0; - dma_addr_t buf_pa; struct pcie_service_card *card = adapter->card; const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; @@ -1880,8 +1888,6 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, goto done; } - MWIFIEX_SKB_PACB(skb, &buf_pa); - /* Wait for the command done interrupt */ do { if (mwifiex_read_reg(adapter, PCIE_CPU_INT_STATUS, @@ -1889,16 +1895,15 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, dev_err(adapter->dev, "%s: Failed to read " "interrupt status during fw dnld.\n", __func__); - pci_unmap_single(card->dev, buf_pa, skb->len, - PCI_DMA_TODEVICE); + mwifiex_unmap_pci_memory(adapter, skb, + PCI_DMA_TODEVICE); ret = -1; goto done; } } while ((ireg_intr & CPU_INTR_DOOR_BELL) == CPU_INTR_DOOR_BELL); - pci_unmap_single(card->dev, buf_pa, skb->len, - PCI_DMA_TODEVICE); + mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE); offset += txlen; } while (true); @@ -2338,6 +2343,7 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter) } adapter->dev = &pdev->dev; + adapter->tx_buf_size = card->pcie.tx_buf_size; strcpy(adapter->fw_name, card->pcie.firmware); return 0; |