diff options
Diffstat (limited to 'drivers/net/wireless/rtlwifi/pci.c')
-rw-r--r-- | drivers/net/wireless/rtlwifi/pci.c | 131 |
1 files changed, 102 insertions, 29 deletions
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index d7aa165fe677..dae55257f0e8 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c | |||
@@ -811,19 +811,19 @@ done: | |||
811 | if (pci_dma_mapping_error(rtlpci->pdev, bufferaddress)) | 811 | if (pci_dma_mapping_error(rtlpci->pdev, bufferaddress)) |
812 | return; | 812 | return; |
813 | tmp_one = 1; | 813 | tmp_one = 1; |
814 | rtlpriv->cfg->ops->set_desc((u8 *) pdesc, false, | 814 | rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, false, |
815 | HW_DESC_RXBUFF_ADDR, | 815 | HW_DESC_RXBUFF_ADDR, |
816 | (u8 *)&bufferaddress); | 816 | (u8 *)&bufferaddress); |
817 | rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false, | 817 | rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, false, |
818 | HW_DESC_RXPKT_LEN, | 818 | HW_DESC_RXPKT_LEN, |
819 | (u8 *)&rtlpci->rxbuffersize); | 819 | (u8 *)&rtlpci->rxbuffersize); |
820 | 820 | ||
821 | if (index == rtlpci->rxringcount - 1) | 821 | if (index == rtlpci->rxringcount - 1) |
822 | rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false, | 822 | rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, false, |
823 | HW_DESC_RXERO, | 823 | HW_DESC_RXERO, |
824 | &tmp_one); | 824 | &tmp_one); |
825 | 825 | ||
826 | rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false, HW_DESC_RXOWN, | 826 | rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, false, HW_DESC_RXOWN, |
827 | &tmp_one); | 827 | &tmp_one); |
828 | 828 | ||
829 | index = (index + 1) % rtlpci->rxringcount; | 829 | index = (index + 1) % rtlpci->rxringcount; |
@@ -983,6 +983,8 @@ static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw) | |||
983 | struct sk_buff *pskb = NULL; | 983 | struct sk_buff *pskb = NULL; |
984 | struct rtl_tx_desc *pdesc = NULL; | 984 | struct rtl_tx_desc *pdesc = NULL; |
985 | struct rtl_tcb_desc tcb_desc; | 985 | struct rtl_tcb_desc tcb_desc; |
986 | /*This is for new trx flow*/ | ||
987 | struct rtl_tx_buffer_desc *pbuffer_desc = NULL; | ||
986 | u8 temp_one = 1; | 988 | u8 temp_one = 1; |
987 | 989 | ||
988 | memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc)); | 990 | memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc)); |
@@ -1004,11 +1006,12 @@ static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw) | |||
1004 | info = IEEE80211_SKB_CB(pskb); | 1006 | info = IEEE80211_SKB_CB(pskb); |
1005 | pdesc = &ring->desc[0]; | 1007 | pdesc = &ring->desc[0]; |
1006 | rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *) pdesc, | 1008 | rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *) pdesc, |
1007 | info, NULL, pskb, BEACON_QUEUE, &tcb_desc); | 1009 | (u8 *)pbuffer_desc, info, NULL, pskb, |
1010 | BEACON_QUEUE, &tcb_desc); | ||
1008 | 1011 | ||
1009 | __skb_queue_tail(&ring->queue, pskb); | 1012 | __skb_queue_tail(&ring->queue, pskb); |
1010 | 1013 | ||
1011 | rtlpriv->cfg->ops->set_desc((u8 *) pdesc, true, HW_DESC_OWN, | 1014 | rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, true, HW_DESC_OWN, |
1012 | &temp_one); | 1015 | &temp_one); |
1013 | 1016 | ||
1014 | return; | 1017 | return; |
@@ -1066,7 +1069,7 @@ static void _rtl_pci_init_struct(struct ieee80211_hw *hw, | |||
1066 | mac->current_ampdu_factor = 3; | 1069 | mac->current_ampdu_factor = 3; |
1067 | 1070 | ||
1068 | /*QOS*/ | 1071 | /*QOS*/ |
1069 | rtlpci->acm_method = eAcmWay2_SW; | 1072 | rtlpci->acm_method = EACMWAY2_SW; |
1070 | 1073 | ||
1071 | /*task */ | 1074 | /*task */ |
1072 | tasklet_init(&rtlpriv->works.irq_tasklet, | 1075 | tasklet_init(&rtlpriv->works.irq_tasklet, |
@@ -1113,7 +1116,7 @@ static int _rtl_pci_init_tx_ring(struct ieee80211_hw *hw, | |||
1113 | ((i + 1) % entries) * | 1116 | ((i + 1) % entries) * |
1114 | sizeof(*ring); | 1117 | sizeof(*ring); |
1115 | 1118 | ||
1116 | rtlpriv->cfg->ops->set_desc((u8 *)&(ring[i]), | 1119 | rtlpriv->cfg->ops->set_desc(hw, (u8 *)&(ring[i]), |
1117 | true, HW_DESC_TX_NEXTDESC_ADDR, | 1120 | true, HW_DESC_TX_NEXTDESC_ADDR, |
1118 | (u8 *)&nextdescaddress); | 1121 | (u8 *)&nextdescaddress); |
1119 | } | 1122 | } |
@@ -1188,19 +1191,19 @@ static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw) | |||
1188 | dev_kfree_skb_any(skb); | 1191 | dev_kfree_skb_any(skb); |
1189 | return 1; | 1192 | return 1; |
1190 | } | 1193 | } |
1191 | rtlpriv->cfg->ops->set_desc((u8 *)entry, false, | 1194 | rtlpriv->cfg->ops->set_desc(hw, (u8 *)entry, false, |
1192 | HW_DESC_RXBUFF_ADDR, | 1195 | HW_DESC_RXBUFF_ADDR, |
1193 | (u8 *)&bufferaddress); | 1196 | (u8 *)&bufferaddress); |
1194 | rtlpriv->cfg->ops->set_desc((u8 *)entry, false, | 1197 | rtlpriv->cfg->ops->set_desc(hw, (u8 *)entry, false, |
1195 | HW_DESC_RXPKT_LEN, | 1198 | HW_DESC_RXPKT_LEN, |
1196 | (u8 *)&rtlpci-> | 1199 | (u8 *)&rtlpci-> |
1197 | rxbuffersize); | 1200 | rxbuffersize); |
1198 | rtlpriv->cfg->ops->set_desc((u8 *) entry, false, | 1201 | rtlpriv->cfg->ops->set_desc(hw, (u8 *)entry, false, |
1199 | HW_DESC_RXOWN, | 1202 | HW_DESC_RXOWN, |
1200 | &tmp_one); | 1203 | &tmp_one); |
1201 | } | 1204 | } |
1202 | 1205 | ||
1203 | rtlpriv->cfg->ops->set_desc((u8 *) entry, false, | 1206 | rtlpriv->cfg->ops->set_desc(hw, (u8 *)entry, false, |
1204 | HW_DESC_RXERO, &tmp_one); | 1207 | HW_DESC_RXERO, &tmp_one); |
1205 | } | 1208 | } |
1206 | return 0; | 1209 | return 0; |
@@ -1331,7 +1334,7 @@ int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw) | |||
1331 | 1334 | ||
1332 | for (i = 0; i < rtlpci->rxringcount; i++) { | 1335 | for (i = 0; i < rtlpci->rxringcount; i++) { |
1333 | entry = &rtlpci->rx_ring[rx_queue_idx].desc[i]; | 1336 | entry = &rtlpci->rx_ring[rx_queue_idx].desc[i]; |
1334 | rtlpriv->cfg->ops->set_desc((u8 *) entry, | 1337 | rtlpriv->cfg->ops->set_desc(hw, (u8 *)entry, |
1335 | false, | 1338 | false, |
1336 | HW_DESC_RXOWN, | 1339 | HW_DESC_RXOWN, |
1337 | &tmp_one); | 1340 | &tmp_one); |
@@ -1424,6 +1427,7 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, | |||
1424 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 1427 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
1425 | struct rtl8192_tx_ring *ring; | 1428 | struct rtl8192_tx_ring *ring; |
1426 | struct rtl_tx_desc *pdesc; | 1429 | struct rtl_tx_desc *pdesc; |
1430 | struct rtl_tx_buffer_desc *ptx_bd_desc = NULL; | ||
1427 | u8 idx; | 1431 | u8 idx; |
1428 | u8 hw_queue = _rtl_mac_to_hwqueue(hw, skb); | 1432 | u8 hw_queue = _rtl_mac_to_hwqueue(hw, skb); |
1429 | unsigned long flags; | 1433 | unsigned long flags; |
@@ -1464,17 +1468,22 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, | |||
1464 | idx = 0; | 1468 | idx = 0; |
1465 | 1469 | ||
1466 | pdesc = &ring->desc[idx]; | 1470 | pdesc = &ring->desc[idx]; |
1467 | own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, | 1471 | if (rtlpriv->use_new_trx_flow) { |
1468 | true, HW_DESC_OWN); | 1472 | ptx_bd_desc = &ring->buffer_desc[idx]; |
1473 | } else { | ||
1474 | own = (u8) rtlpriv->cfg->ops->get_desc((u8 *)pdesc, | ||
1475 | true, HW_DESC_OWN); | ||
1469 | 1476 | ||
1470 | if ((own == 1) && (hw_queue != BEACON_QUEUE)) { | 1477 | if ((own == 1) && (hw_queue != BEACON_QUEUE)) { |
1471 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, | 1478 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, |
1472 | "No more TX desc@%d, ring->idx = %d, idx = %d, skb_queue_len = 0x%d\n", | 1479 | "No more TX desc@%d, ring->idx = %d, idx = %d, skb_queue_len = 0x%d\n", |
1473 | hw_queue, ring->idx, idx, | 1480 | hw_queue, ring->idx, idx, |
1474 | skb_queue_len(&ring->queue)); | 1481 | skb_queue_len(&ring->queue)); |
1475 | 1482 | ||
1476 | spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); | 1483 | spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, |
1477 | return skb->len; | 1484 | flags); |
1485 | return skb->len; | ||
1486 | } | ||
1478 | } | 1487 | } |
1479 | 1488 | ||
1480 | if (ieee80211_is_data_qos(fc)) { | 1489 | if (ieee80211_is_data_qos(fc)) { |
@@ -1494,17 +1503,20 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, | |||
1494 | rtlpriv->cfg->ops->led_control(hw, LED_CTL_TX); | 1503 | rtlpriv->cfg->ops->led_control(hw, LED_CTL_TX); |
1495 | 1504 | ||
1496 | rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *)pdesc, | 1505 | rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *)pdesc, |
1497 | info, sta, skb, hw_queue, ptcb_desc); | 1506 | (u8 *)ptx_bd_desc, info, sta, skb, hw_queue, ptcb_desc); |
1498 | 1507 | ||
1499 | __skb_queue_tail(&ring->queue, skb); | 1508 | __skb_queue_tail(&ring->queue, skb); |
1500 | 1509 | ||
1501 | rtlpriv->cfg->ops->set_desc((u8 *)pdesc, true, | 1510 | if (rtlpriv->use_new_trx_flow) { |
1502 | HW_DESC_OWN, &temp_one); | 1511 | rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, true, |
1503 | 1512 | HW_DESC_OWN, &hw_queue); | |
1513 | } else { | ||
1514 | rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, true, | ||
1515 | HW_DESC_OWN, &temp_one); | ||
1516 | } | ||
1504 | 1517 | ||
1505 | if ((ring->entries - skb_queue_len(&ring->queue)) < 2 && | 1518 | if ((ring->entries - skb_queue_len(&ring->queue)) < 2 && |
1506 | hw_queue != BEACON_QUEUE) { | 1519 | hw_queue != BEACON_QUEUE) { |
1507 | |||
1508 | RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, | 1520 | RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, |
1509 | "less desc left, stop skb_queue@%d, ring->idx = %d, idx = %d, skb_queue_len = 0x%d\n", | 1521 | "less desc left, stop skb_queue@%d, ring->idx = %d, idx = %d, skb_queue_len = 0x%d\n", |
1510 | hw_queue, ring->idx, idx, | 1522 | hw_queue, ring->idx, idx, |
@@ -1841,6 +1853,65 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, | |||
1841 | return true; | 1853 | return true; |
1842 | } | 1854 | } |
1843 | 1855 | ||
1856 | static int rtl_pci_intr_mode_msi(struct ieee80211_hw *hw) | ||
1857 | { | ||
1858 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1859 | struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); | ||
1860 | struct rtl_pci *rtlpci = rtl_pcidev(pcipriv); | ||
1861 | int ret; | ||
1862 | |||
1863 | ret = pci_enable_msi(rtlpci->pdev); | ||
1864 | if (ret < 0) | ||
1865 | return ret; | ||
1866 | |||
1867 | ret = request_irq(rtlpci->pdev->irq, &_rtl_pci_interrupt, | ||
1868 | IRQF_SHARED, KBUILD_MODNAME, hw); | ||
1869 | if (ret < 0) { | ||
1870 | pci_disable_msi(rtlpci->pdev); | ||
1871 | return ret; | ||
1872 | } | ||
1873 | |||
1874 | rtlpci->using_msi = true; | ||
1875 | |||
1876 | RT_TRACE(rtlpriv, COMP_INIT|COMP_INTR, DBG_DMESG, | ||
1877 | "MSI Interrupt Mode!\n"); | ||
1878 | return 0; | ||
1879 | } | ||
1880 | |||
1881 | static int rtl_pci_intr_mode_legacy(struct ieee80211_hw *hw) | ||
1882 | { | ||
1883 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1884 | struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); | ||
1885 | struct rtl_pci *rtlpci = rtl_pcidev(pcipriv); | ||
1886 | int ret; | ||
1887 | |||
1888 | ret = request_irq(rtlpci->pdev->irq, &_rtl_pci_interrupt, | ||
1889 | IRQF_SHARED, KBUILD_MODNAME, hw); | ||
1890 | if (ret < 0) | ||
1891 | return ret; | ||
1892 | |||
1893 | rtlpci->using_msi = false; | ||
1894 | RT_TRACE(rtlpriv, COMP_INIT|COMP_INTR, DBG_DMESG, | ||
1895 | "Pin-based Interrupt Mode!\n"); | ||
1896 | return 0; | ||
1897 | } | ||
1898 | |||
1899 | static int rtl_pci_intr_mode_decide(struct ieee80211_hw *hw) | ||
1900 | { | ||
1901 | struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); | ||
1902 | struct rtl_pci *rtlpci = rtl_pcidev(pcipriv); | ||
1903 | int ret; | ||
1904 | |||
1905 | if (rtlpci->msi_support) { | ||
1906 | ret = rtl_pci_intr_mode_msi(hw); | ||
1907 | if (ret < 0) | ||
1908 | ret = rtl_pci_intr_mode_legacy(hw); | ||
1909 | } else { | ||
1910 | ret = rtl_pci_intr_mode_legacy(hw); | ||
1911 | } | ||
1912 | return ret; | ||
1913 | } | ||
1914 | |||
1844 | int rtl_pci_probe(struct pci_dev *pdev, | 1915 | int rtl_pci_probe(struct pci_dev *pdev, |
1845 | const struct pci_device_id *id) | 1916 | const struct pci_device_id *id) |
1846 | { | 1917 | { |
@@ -1983,8 +2054,7 @@ int rtl_pci_probe(struct pci_dev *pdev, | |||
1983 | } | 2054 | } |
1984 | 2055 | ||
1985 | rtlpci = rtl_pcidev(pcipriv); | 2056 | rtlpci = rtl_pcidev(pcipriv); |
1986 | err = request_irq(rtlpci->pdev->irq, &_rtl_pci_interrupt, | 2057 | err = rtl_pci_intr_mode_decide(hw); |
1987 | IRQF_SHARED, KBUILD_MODNAME, hw); | ||
1988 | if (err) { | 2058 | if (err) { |
1989 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | 2059 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, |
1990 | "%s: failed to register IRQ handler\n", | 2060 | "%s: failed to register IRQ handler\n", |
@@ -2052,6 +2122,9 @@ void rtl_pci_disconnect(struct pci_dev *pdev) | |||
2052 | rtlpci->irq_alloc = 0; | 2122 | rtlpci->irq_alloc = 0; |
2053 | } | 2123 | } |
2054 | 2124 | ||
2125 | if (rtlpci->using_msi) | ||
2126 | pci_disable_msi(rtlpci->pdev); | ||
2127 | |||
2055 | list_del(&rtlpriv->list); | 2128 | list_del(&rtlpriv->list); |
2056 | if (rtlpriv->io.pci_mem_start != 0) { | 2129 | if (rtlpriv->io.pci_mem_start != 0) { |
2057 | pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start); | 2130 | pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start); |