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

Commit 9a9053c3 authored by Xinming Hu's avatar Xinming Hu Committed by Kalle Valo
Browse files

mwifiex: fix driver init failure under memory pressure



64k Tx and Rx buffers are allocated during driver initialization
for SDIO level data aggregations. When host is under memory
pressure situation, kzalloc() request for 64k may fail.

We will try allocating 32k buffers and disable our rx single port
aggreagation feature in this situation.

If the allocation still fails, we will disable our sdio multport
aggregation feature as well. In this way, we will transmit and
receive packets one by one, thus reduce the demand for big
memory.

Signed-off-by: default avatarXinming Hu <huxm@marvell.com>
Signed-off-by: default avatarAmitkumar Karwar <akarwar@marvell.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent e3ad3d5b
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -860,6 +860,8 @@ struct mwifiex_adapter {
	u8 more_task_flag;
	u16 tx_buf_size;
	u16 curr_tx_buf_size;
	/* sdio single port rx aggregation capability */
	bool host_disable_sdio_rx_aggr;
	bool sdio_rx_aggr_enable;
	u16 sdio_rx_block_size;
	u32 ioport;
+16 −6
Original line number Diff line number Diff line
@@ -2058,16 +2058,26 @@ static int mwifiex_init_sdio(struct mwifiex_adapter *adapter)
	ret = mwifiex_alloc_sdio_mpa_buffers(adapter,
					     card->mp_tx_agg_buf_size,
					     card->mp_rx_agg_buf_size);

	/* Allocate 32k MPA Tx/Rx buffers if 64k memory allocation fails */
	if (ret && (card->mp_tx_agg_buf_size == MWIFIEX_MP_AGGR_BUF_SIZE_MAX ||
		    card->mp_rx_agg_buf_size == MWIFIEX_MP_AGGR_BUF_SIZE_MAX)) {
		/* Disable rx single port aggregation */
		adapter->host_disable_sdio_rx_aggr = true;

		ret = mwifiex_alloc_sdio_mpa_buffers
			(adapter, MWIFIEX_MP_AGGR_BUF_SIZE_32K,
			 MWIFIEX_MP_AGGR_BUF_SIZE_32K);
		if (ret) {
		mwifiex_dbg(adapter, ERROR,
			    "failed to alloc sdio mp-a buffers\n");
		kfree(card->mp_regs);
		return -1;
			/* Disable multi port aggregation */
			card->mpa_tx.enabled = 0;
			card->mpa_rx.enabled = 0;
		}
	}

	adapter->auto_tdls = card->can_auto_tdls;
	adapter->ext_scan = card->can_ext_scan;
	return ret;
	return 0;
}

/*
+2 −1
Original line number Diff line number Diff line
@@ -2125,7 +2125,8 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta, bool init)

		/** Set SDIO Single Port RX Aggr Info */
		if (priv->adapter->iface_type == MWIFIEX_SDIO &&
		    ISSUPP_SDIO_SPA_ENABLED(priv->adapter->fw_cap_info)) {
		    ISSUPP_SDIO_SPA_ENABLED(priv->adapter->fw_cap_info) &&
		    !priv->adapter->host_disable_sdio_rx_aggr) {
			sdio_sp_rx_aggr_enable = true;
			ret = mwifiex_send_cmd(priv,
					       HostCmd_CMD_SDIO_SP_RX_AGGR_CFG,