Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0c07bd74 authored by Ping-Ke Shih's avatar Ping-Ke Shih Committed by Kalle Valo
Browse files

rtlwifi: rtl8192ee: Make driver support 64bits DMA.



1. Both 32-bit and 64-bit use the same TX/RX buffer desc layout
2. Extend set_desc() and get_desc() to set and get 64-bit address
3. Remove directive DMA_IS_64BIT
4. Add module parameter to turn on 64-bit dma

Signed-off-by: default avatarPing-Ke Shih <pkshih@realtek.com>
Signed-off-by: default avatarLarry Finger <Larry.Finger@lwfinger.net>
Cc: Yan-Hsuan Chuang <yhchuang@realtek.com>
Cc: Birming Chiu <birming@realtek.com>
Cc: Shaofu <shaofu@realtek.com>
Cc: Steven Ting <steventing@realtek.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent ecf4000e
Loading
Loading
Loading
Loading
+39 −10
Original line number Diff line number Diff line
@@ -586,7 +586,7 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio)
		skb = __skb_dequeue(&ring->queue);
		pci_unmap_single(rtlpci->pdev,
				 rtlpriv->cfg->ops->
					     get_desc((u8 *)entry, true,
					     get_desc(hw, (u8 *)entry, true,
						      HW_DESC_TXBUFF_ADDR),
				 skb->len, PCI_DMA_TODEVICE);

@@ -691,9 +691,10 @@ static int _rtl_pci_init_one_rxdesc(struct ieee80211_hw *hw,
		return 0;
	rtlpci->rx_ring[rxring_idx].rx_buf[desc_idx] = skb;
	if (rtlpriv->use_new_trx_flow) {
		/* skb->cb may be 64 bit address */
		rtlpriv->cfg->ops->set_desc(hw, (u8 *)entry, false,
					    HW_DESC_RX_PREPARE,
					    (u8 *)&bufferaddress);
					    (u8 *)(dma_addr_t *)skb->cb);
	} else {
		rtlpriv->cfg->ops->set_desc(hw, (u8 *)entry, false,
					    HW_DESC_RXBUFF_ADDR,
@@ -798,7 +799,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
			pdesc = &rtlpci->rx_ring[rxring_idx].desc[
				rtlpci->rx_ring[rxring_idx].idx];

			own = (u8)rtlpriv->cfg->ops->get_desc((u8 *)pdesc,
			own = (u8)rtlpriv->cfg->ops->get_desc(hw, (u8 *)pdesc,
							      false,
							      HW_DESC_OWN);
			if (own) /* wait data to be filled by hardware */
@@ -825,7 +826,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
							   (u8 *)buffer_desc,
							   hw_queue);

		len = rtlpriv->cfg->ops->get_desc((u8 *)pdesc, false,
		len = rtlpriv->cfg->ops->get_desc(hw, (u8 *)pdesc, false,
						  HW_DESC_RXPKT_LEN);

		if (skb->end - skb->tail > len) {
@@ -1122,7 +1123,7 @@ static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw)
	if (pskb) {
		pci_unmap_single(rtlpci->pdev,
				 rtlpriv->cfg->ops->get_desc(
				 (u8 *)entry, true, HW_DESC_TXBUFF_ADDR),
				 hw, (u8 *)entry, true, HW_DESC_TXBUFF_ADDR),
				 pskb->len, PCI_DMA_TODEVICE);
		kfree_skb(pskb);
	}
@@ -1378,7 +1379,8 @@ static void _rtl_pci_free_tx_ring(struct ieee80211_hw *hw,

		pci_unmap_single(rtlpci->pdev,
				 rtlpriv->cfg->
					     ops->get_desc((u8 *)entry, true,
					     ops->get_desc(hw, (u8 *)entry,
						   true,
						   HW_DESC_TXBUFF_ADDR),
				 skb->len, PCI_DMA_TODEVICE);
		kfree_skb(skb);
@@ -1507,7 +1509,7 @@ int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw)
			for (i = 0; i < rtlpci->rxringcount; i++) {
				entry = &rtlpci->rx_ring[rxring_idx].desc[i];
				bufferaddress =
				  rtlpriv->cfg->ops->get_desc((u8 *)entry,
				  rtlpriv->cfg->ops->get_desc(hw, (u8 *)entry,
				  false , HW_DESC_RXBUFF_ADDR);
				memset((u8 *)entry , 0 ,
				       sizeof(*rtlpci->rx_ring
@@ -1560,7 +1562,7 @@ int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw)

				pci_unmap_single(rtlpci->pdev,
						 rtlpriv->cfg->ops->
							 get_desc((u8 *)
							 get_desc(hw, (u8 *)
							 entry,
							 true,
							 HW_DESC_TXBUFF_ADDR),
@@ -1673,7 +1675,7 @@ static int rtl_pci_tx(struct ieee80211_hw *hw,
	if (rtlpriv->use_new_trx_flow) {
		ptx_bd_desc = &ring->buffer_desc[idx];
	} else {
		own = (u8) rtlpriv->cfg->ops->get_desc((u8 *)pdesc,
		own = (u8)rtlpriv->cfg->ops->get_desc(hw, (u8 *)pdesc,
				true, HW_DESC_OWN);

		if ((own == 1) && (hw_queue != BEACON_QUEUE)) {
@@ -2163,6 +2165,21 @@ static int rtl_pci_intr_mode_decide(struct ieee80211_hw *hw)
	return ret;
}

static void platform_enable_dma64(struct pci_dev *pdev, bool dma64)
{
	u8	value;

	pci_read_config_byte(pdev, 0x719, &value);

	/* 0x719 Bit5 is DMA64 bit fetch. */
	if (dma64)
		value |= BIT(5);
	else
		value &= ~BIT(5);

	pci_write_config_byte(pdev, 0x719, value);
}

int rtl_pci_probe(struct pci_dev *pdev,
			    const struct pci_device_id *id)
{
@@ -2181,13 +2198,25 @@ int rtl_pci_probe(struct pci_dev *pdev,
		return err;
	}

	if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
	if (((struct rtl_hal_cfg *)id->driver_data)->mod_params->dma64 &&
	    !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
		if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) {
			WARN_ONCE(true,
				  "Unable to obtain 64bit DMA for consistent allocations\n");
			err = -ENOMEM;
			goto fail1;
		}

		platform_enable_dma64(pdev, true);
	} else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
		if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
			WARN_ONCE(true,
				  "rtlwifi: Unable to obtain 32bit DMA for consistent allocations\n");
			err = -ENOMEM;
			goto fail1;
		}

		platform_enable_dma64(pdev, false);
	}

	pci_set_master(pdev);
+2 −8
Original line number Diff line number Diff line
@@ -143,13 +143,7 @@ struct rtl_pci_capabilities_header {
 * RX wifi info == RX descriptor in old flow
 */
struct rtl_tx_buffer_desc {
#if (RTL8192EE_SEG_NUM == 2)
	u32 dword[2*(DMA_IS_64BIT + 1)*8]; /*seg = 8*/
#elif (RTL8192EE_SEG_NUM == 1)
	u32 dword[2*(DMA_IS_64BIT + 1)*4]; /*seg = 4*/
#elif (RTL8192EE_SEG_NUM == 0)
	u32 dword[2*(DMA_IS_64BIT + 1)*2]; /*seg = 2*/
#endif
	u32 dword[4 * (1 << (BUFDESC_SEG_NUM + 1))];
} __packed;

struct rtl_tx_desc {
@@ -157,7 +151,7 @@ struct rtl_tx_desc {
} __packed;

struct rtl_rx_buffer_desc { /*rx buffer desc*/
	u32 dword[2];
	u32 dword[4];
} __packed;

struct rtl_rx_desc { /*old: rx desc new: rx wifi info*/
+1 −0
Original line number Diff line number Diff line
@@ -99,6 +99,7 @@ static void _rtl88ee_return_beacon_queue_skb(struct ieee80211_hw *hw)

		pci_unmap_single(rtlpci->pdev,
				 rtlpriv->cfg->ops->get_desc(
				 hw,
				 (u8 *)entry, true, HW_DESC_TXBUFF_ADDR),
				 skb->len, PCI_DMA_TODEVICE);
		kfree_skb(skb);
+3 −2
Original line number Diff line number Diff line
@@ -786,7 +786,8 @@ void rtl88ee_set_desc(struct ieee80211_hw *hw, u8 *pdesc,
	}
}

u32 rtl88ee_get_desc(u8 *pdesc, bool istx, u8 desc_name)
u64 rtl88ee_get_desc(struct ieee80211_hw *hw,
		     u8 *pdesc, bool istx, u8 desc_name)
{
	u32 ret = 0;

@@ -828,7 +829,7 @@ bool rtl88ee_is_tx_desc_closed(struct ieee80211_hw *hw, u8 hw_queue, u16 index)
	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
	struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[hw_queue];
	u8 *entry = (u8 *)(&ring->desc[ring->idx]);
	u8 own = (u8)rtl88ee_get_desc(entry, true, HW_DESC_OWN);
	u8 own = (u8)rtl88ee_get_desc(hw, entry, true, HW_DESC_OWN);

	/*beacon packet will only use the first
	 *descriptor defautly,and the own may not
+2 −1
Original line number Diff line number Diff line
@@ -782,7 +782,8 @@ bool rtl88ee_rx_query_desc(struct ieee80211_hw *hw,
			   u8 *pdesc, struct sk_buff *skb);
void rtl88ee_set_desc(struct ieee80211_hw *hw, u8 *pdesc,
		      bool istx, u8 desc_name, u8 *val);
u32 rtl88ee_get_desc(u8 *pdesc, bool istx, u8 desc_name);
u64 rtl88ee_get_desc(struct ieee80211_hw *hw,
		     u8 *pdesc, bool istx, u8 desc_name);
bool rtl88ee_is_tx_desc_closed(struct ieee80211_hw *hw,
			       u8 hw_queue, u16 index);
void rtl88ee_tx_polling(struct ieee80211_hw *hw, u8 hw_queue);
Loading