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

Commit e644b88e authored by Kalle Valo's avatar Kalle Valo
Browse files
ath.git patches for 4.10. Major changes:

ath9k

* add device tree bindings
* switch to use mac80211 intermediate software queues to reduce
  latency and fix bufferbloat
parents 97489c28 31b23982
Loading
Loading
Loading
Loading
+48 −0
Original line number Diff line number Diff line
* Qualcomm Atheros ath9k wireless devices

This node provides properties for configuring the ath9k wireless device. The
node is expected to be specified as a child node of the PCI controller to
which the wireless chip is connected.

Required properties:
- compatible: For PCI and PCIe devices this should be an identifier following
		the format as defined in "PCI Bus Binding to Open Firmware"
		Revision 2.1. One of the possible formats is "pciVVVV,DDDD"
		where VVVV is the PCI vendor ID and DDDD is PCI device ID.
		Typically QCA's PCI vendor ID 168c is used while the PCI device
		ID depends on the chipset - see the following (possibly
		incomplete) list:
			- 0023 for AR5416
			- 0024 for AR5418
			- 0027 for AR9160
			- 0029 for AR9220 and AR9223
			- 002a for AR9280 and AR9283
			- 002b for AR9285
			- 002c for AR2427
			- 002d for AR9227
			- 002e for AR9287
			- 0030 for AR9380, AR9381 and AR9382
			- 0032 for AR9485
			- 0033 for AR9580 and AR9590
			- 0034 for AR9462
			- 0036 for AR9565
			- 0037 for AR9485
- reg: Address and length of the register set for the device.

Optional properties:
- qca,no-eeprom: Indicates that there is no physical EEPROM connected to the
			ath9k wireless chip (in this case the calibration /
			EEPROM data will be loaded from userspace using the
			kernel firmware loader).
- mac-address: See ethernet.txt in the parent directory
- local-mac-address: See ethernet.txt in the parent directory


In this example, the node is defined as child node of the PCI controller:
&pci0 {
	wifi@168c,002d {
		compatible = "pci168c,002d";
		reg = <0x7000 0 0 0 0x1000>;
		qca,no-eeprom;
	};
};
+6 −0
Original line number Diff line number Diff line
@@ -327,4 +327,10 @@ static inline const char *ath_opmode_to_string(enum nl80211_iftype opmode)
}
#endif

extern const char *ath_bus_type_strings[];
static inline const char *ath_bus_type_to_string(enum ath_bus_type bustype)
{
	return ath_bus_type_strings[bustype];
}

#endif /* ATH_H */
+2 −4
Original line number Diff line number Diff line
@@ -556,10 +556,8 @@ enum ath10k_fw_features {
	 */
	ATH10K_FW_FEATURE_BTCOEX_PARAM = 14,

	/* Older firmware with HTT delivers incorrect tx status for null func
	 * frames to driver, but this fixed in 10.2 and 10.4 firmware versions.
	 * Also this workaround results in reporting of incorrect null func
	 * status for 10.4. This flag is used to skip the workaround.
	/* Unused flag and proven to be not working, enable this if you want
	 * to experiment sending NULL func data frames in HTT TX
	 */
	ATH10K_FW_FEATURE_SKIP_NULL_FUNC_WAR = 15,

+51 −28
Original line number Diff line number Diff line
@@ -229,6 +229,32 @@ void ath10k_htt_tx_free_msdu_id(struct ath10k_htt *htt, u16 msdu_id)
	idr_remove(&htt->pending_tx, msdu_id);
}

static void ath10k_htt_tx_free_cont_txbuf(struct ath10k_htt *htt)
{
	struct ath10k *ar = htt->ar;
	size_t size;

	if (!htt->txbuf.vaddr)
		return;

	size = htt->max_num_pending_tx * sizeof(struct ath10k_htt_txbuf);
	dma_free_coherent(ar->dev, size, htt->txbuf.vaddr, htt->txbuf.paddr);
}

static int ath10k_htt_tx_alloc_cont_txbuf(struct ath10k_htt *htt)
{
	struct ath10k *ar = htt->ar;
	size_t size;

	size = htt->max_num_pending_tx * sizeof(struct ath10k_htt_txbuf);
	htt->txbuf.vaddr = dma_alloc_coherent(ar->dev, size, &htt->txbuf.paddr,
					      GFP_KERNEL);
	if (!htt->txbuf.vaddr)
		return -ENOMEM;

	return 0;
}

static void ath10k_htt_tx_free_cont_frag_desc(struct ath10k_htt *htt)
{
	size_t size;
@@ -256,10 +282,8 @@ static int ath10k_htt_tx_alloc_cont_frag_desc(struct ath10k_htt *htt)
	htt->frag_desc.vaddr = dma_alloc_coherent(ar->dev, size,
						  &htt->frag_desc.paddr,
						  GFP_KERNEL);
	if (!htt->frag_desc.vaddr) {
		ath10k_err(ar, "failed to alloc fragment desc memory\n");
	if (!htt->frag_desc.vaddr)
		return -ENOMEM;
	}

	return 0;
}
@@ -310,10 +334,26 @@ static int ath10k_htt_tx_alloc_txq(struct ath10k_htt *htt)
	return 0;
}

static void ath10k_htt_tx_free_txdone_fifo(struct ath10k_htt *htt)
{
	WARN_ON(!kfifo_is_empty(&htt->txdone_fifo));
	kfifo_free(&htt->txdone_fifo);
}

static int ath10k_htt_tx_alloc_txdone_fifo(struct ath10k_htt *htt)
{
	int ret;
	size_t size;

	size = roundup_pow_of_two(htt->max_num_pending_tx);
	ret = kfifo_alloc(&htt->txdone_fifo, size, GFP_KERNEL);
	return ret;
}

int ath10k_htt_tx_alloc(struct ath10k_htt *htt)
{
	struct ath10k *ar = htt->ar;
	int ret, size;
	int ret;

	ath10k_dbg(ar, ATH10K_DBG_BOOT, "htt tx max num pending tx %d\n",
		   htt->max_num_pending_tx);
@@ -321,13 +361,9 @@ int ath10k_htt_tx_alloc(struct ath10k_htt *htt)
	spin_lock_init(&htt->tx_lock);
	idr_init(&htt->pending_tx);

	size = htt->max_num_pending_tx * sizeof(struct ath10k_htt_txbuf);
	htt->txbuf.vaddr = dma_alloc_coherent(ar->dev, size,
						  &htt->txbuf.paddr,
						  GFP_KERNEL);
	if (!htt->txbuf.vaddr) {
		ath10k_err(ar, "failed to alloc tx buffer\n");
		ret = -ENOMEM;
	ret = ath10k_htt_tx_alloc_cont_txbuf(htt);
	if (ret) {
		ath10k_err(ar, "failed to alloc cont tx buffer: %d\n", ret);
		goto free_idr_pending_tx;
	}

@@ -343,8 +379,7 @@ int ath10k_htt_tx_alloc(struct ath10k_htt *htt)
		goto free_frag_desc;
	}

	size = roundup_pow_of_two(htt->max_num_pending_tx);
	ret = kfifo_alloc(&htt->txdone_fifo, size, GFP_KERNEL);
	ret = ath10k_htt_tx_alloc_txdone_fifo(htt);
	if (ret) {
		ath10k_err(ar, "failed to alloc txdone fifo: %d\n", ret);
		goto free_txq;
@@ -359,10 +394,7 @@ int ath10k_htt_tx_alloc(struct ath10k_htt *htt)
	ath10k_htt_tx_free_cont_frag_desc(htt);

free_txbuf:
	size = htt->max_num_pending_tx *
			  sizeof(struct ath10k_htt_txbuf);
	dma_free_coherent(htt->ar->dev, size, htt->txbuf.vaddr,
			  htt->txbuf.paddr);
	ath10k_htt_tx_free_cont_txbuf(htt);

free_idr_pending_tx:
	idr_destroy(&htt->pending_tx);
@@ -388,22 +420,13 @@ static int ath10k_htt_tx_clean_up_pending(int msdu_id, void *skb, void *ctx)

void ath10k_htt_tx_free(struct ath10k_htt *htt)
{
	int size;

	idr_for_each(&htt->pending_tx, ath10k_htt_tx_clean_up_pending, htt->ar);
	idr_destroy(&htt->pending_tx);

	if (htt->txbuf.vaddr) {
		size = htt->max_num_pending_tx *
				  sizeof(struct ath10k_htt_txbuf);
		dma_free_coherent(htt->ar->dev, size, htt->txbuf.vaddr,
				  htt->txbuf.paddr);
	}

	ath10k_htt_tx_free_cont_txbuf(htt);
	ath10k_htt_tx_free_txq(htt);
	ath10k_htt_tx_free_cont_frag_desc(htt);
	WARN_ON(!kfifo_is_empty(&htt->txdone_fifo));
	kfifo_free(&htt->txdone_fifo);
	ath10k_htt_tx_free_txdone_fifo(htt);
}

void ath10k_htt_htc_tx_complete(struct ath10k *ar, struct sk_buff *skb)
+0 −2
Original line number Diff line number Diff line
@@ -3257,8 +3257,6 @@ ath10k_mac_tx_h_get_txmode(struct ath10k *ar,
	if (ar->htt.target_version_major < 3 &&
	    (ieee80211_is_nullfunc(fc) || ieee80211_is_qos_nullfunc(fc)) &&
	    !test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
		      ar->running_fw->fw_file.fw_features) &&
	    !test_bit(ATH10K_FW_FEATURE_SKIP_NULL_FUNC_WAR,
		      ar->running_fw->fw_file.fw_features))
		return ATH10K_HW_TXRX_MGMT;

Loading