Commit c5994293 authored by Xinming Hu's avatar Xinming Hu Committed by Kalle Valo

mwifiex: usb: transmit aggregation packets

Instead of using 4KB packet buffer for data transfer, new chipset have
more device memory. This patch try to aggregation packets in an 16KB
buffer. In this way, totally usb transaction cost will be reduced.

Thoughput test on usb 2.0 show both TCP TX and UPD TX promote ~40M,
from ~240M to ~280M.

This feature is default disabled, and can be enabled by module
parameter, like:
insmod mwifiex.ko aggr_ctrl=1
Signed-off-by: default avatarXinming Hu <huxm@marvell.com>
Signed-off-by: default avatarCathy Luo <cluo@marvell.com>
Signed-off-by: default avatarGanapathi Bhat <gbhat@marvell.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent 42d1abb5
......@@ -405,6 +405,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
#define HostCmd_CMD_TDLS_OPER 0x0122
#define HostCmd_CMD_SDIO_SP_RX_AGGR_CFG 0x0223
#define HostCmd_CMD_CHAN_REGION_CFG 0x0242
#define HostCmd_CMD_PACKET_AGGR_CTRL 0x0251
#define PROTOCOL_NO_SECURITY 0x01
#define PROTOCOL_STATIC_WEP 0x02
......@@ -2268,6 +2269,14 @@ struct host_cmd_ds_chan_region_cfg {
__le16 action;
} __packed;
struct host_cmd_ds_pkt_aggr_ctrl {
__le16 action;
__le16 enable;
__le16 tx_aggr_max_size;
__le16 tx_aggr_max_num;
__le16 tx_aggr_align;
} __packed;
struct host_cmd_ds_command {
__le16 command;
__le16 size;
......@@ -2343,6 +2352,7 @@ struct host_cmd_ds_command {
struct host_cmd_ds_wakeup_reason hs_wakeup_reason;
struct host_cmd_ds_gtk_rekey_params rekey;
struct host_cmd_ds_chan_region_cfg reg_cfg;
struct host_cmd_ds_pkt_aggr_ctrl pkt_aggr_ctrl;
} params;
} __packed;
......
......@@ -44,6 +44,10 @@ bool mfg_mode;
module_param(mfg_mode, bool, 0);
MODULE_PARM_DESC(mfg_mode, "manufacturing mode enable:1, disable:0");
bool aggr_ctrl;
module_param(aggr_ctrl, bool, 0000);
MODULE_PARM_DESC(aggr_ctrl, "usb tx aggreataon enable:1, disable:0");
/*
* This function registers the device and performs all the necessary
* initializations.
......
......@@ -60,6 +60,7 @@
extern const char driver_version[];
extern bool mfg_mode;
extern bool aggr_ctrl;
struct mwifiex_adapter;
struct mwifiex_private;
......@@ -798,6 +799,18 @@ struct mwifiex_auto_tdls_peer {
u8 do_setup;
};
#define MWIFIEX_TYPE_AGGR_DATA_V2 11
#define MWIFIEX_BUS_AGGR_MODE_LEN_V2 (2)
#define MWIFIEX_BUS_AGGR_MAX_LEN 16000
#define MWIFIEX_BUS_AGGR_MAX_NUM 10
struct bus_aggr_params {
u16 enable;
u16 mode;
u16 tx_aggr_max_size;
u16 tx_aggr_max_num;
u16 tx_aggr_align;
};
struct mwifiex_if_ops {
int (*init_if) (struct mwifiex_adapter *);
void (*cleanup_if) (struct mwifiex_adapter *);
......@@ -1016,6 +1029,8 @@ struct mwifiex_adapter {
/* Wake-on-WLAN (WoWLAN) */
int irq_wakeup;
bool wake_by_wifi;
/* Aggregation parameters*/
struct bus_aggr_params bus_aggr;
};
void mwifiex_process_tx_queue(struct mwifiex_adapter *adapter);
......
......@@ -2064,6 +2064,15 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
case HostCmd_CMD_11AC_CFG:
ret = mwifiex_cmd_11ac_cfg(priv, cmd_ptr, cmd_action, data_buf);
break;
case HostCmd_CMD_PACKET_AGGR_CTRL:
cmd_ptr->command = cpu_to_le16(cmd_no);
cmd_ptr->params.pkt_aggr_ctrl.action = cpu_to_le16(cmd_action);
cmd_ptr->params.pkt_aggr_ctrl.enable =
cpu_to_le16(*(u16 *)data_buf);
cmd_ptr->size =
cpu_to_le16(sizeof(struct host_cmd_ds_pkt_aggr_ctrl) +
S_DS_GEN);
break;
case HostCmd_CMD_P2P_MODE_CFG:
cmd_ptr->command = cpu_to_le16(cmd_no);
cmd_ptr->params.mode_cfg.action = cpu_to_le16(cmd_action);
......@@ -2241,6 +2250,7 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta, bool init)
enum state_11d_t state_11d;
struct mwifiex_ds_11n_tx_cfg tx_cfg;
u8 sdio_sp_rx_aggr_enable;
u16 packet_aggr_enable;
int data;
if (first_sta) {
......@@ -2387,6 +2397,14 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta, bool init)
"11D: failed to enable 11D\n");
}
/* Pacekt aggregation handshake with firmware */
if (aggr_ctrl) {
packet_aggr_enable = true;
mwifiex_send_cmd(priv, HostCmd_CMD_PACKET_AGGR_CTRL,
HostCmd_ACT_GEN_SET, 0,
&packet_aggr_enable, true);
}
/* Send cmd to FW to configure 11n specific configuration
* (Short GI, Channel BW, Green field support etc.) for transmit
*/
......
......@@ -1154,6 +1154,27 @@ static int mwifiex_ret_chan_region_cfg(struct mwifiex_private *priv,
return 0;
}
int mwifiex_ret_pkt_aggr_ctrl(struct mwifiex_private *priv,
struct host_cmd_ds_command *resp)
{
struct host_cmd_ds_pkt_aggr_ctrl *pkt_aggr_ctrl =
&resp->params.pkt_aggr_ctrl;
struct mwifiex_adapter *adapter = priv->adapter;
adapter->bus_aggr.enable = le16_to_cpu(pkt_aggr_ctrl->enable);
if (adapter->bus_aggr.enable)
adapter->intf_hdr_len = INTF_HEADER_LEN;
adapter->bus_aggr.mode = MWIFIEX_BUS_AGGR_MODE_LEN_V2;
adapter->bus_aggr.tx_aggr_max_size =
le16_to_cpu(pkt_aggr_ctrl->tx_aggr_max_size);
adapter->bus_aggr.tx_aggr_max_num =
le16_to_cpu(pkt_aggr_ctrl->tx_aggr_max_num);
adapter->bus_aggr.tx_aggr_align =
le16_to_cpu(pkt_aggr_ctrl->tx_aggr_align);
return 0;
}
/*
* This function handles the command responses.
*
......@@ -1255,6 +1276,9 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no,
break;
case HostCmd_CMD_11AC_CFG:
break;
case HostCmd_CMD_PACKET_AGGR_CTRL:
ret = mwifiex_ret_pkt_aggr_ctrl(priv, resp);
break;
case HostCmd_CMD_P2P_MODE_CFG:
ret = mwifiex_ret_p2p_mode_cfg(priv, resp, data_buf);
break;
......
This diff is collapsed.
......@@ -64,12 +64,21 @@ struct urb_context {
u8 ep;
};
struct usb_tx_aggr {
struct sk_buff_head aggr_list;
int aggr_len;
int aggr_num;
};
struct usb_tx_data_port {
u8 tx_data_ep;
u8 block_status;
atomic_t tx_data_urb_pending;
int tx_data_ix;
struct urb_context tx_data_list[MWIFIEX_TX_DATA_URB];
/* usb tx aggregation*/
struct usb_tx_aggr tx_aggr;
struct sk_buff *skb_aggr[MWIFIEX_TX_DATA_URB];
};
struct usb_card_rec {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment