diff options
Diffstat (limited to 'drivers/net/wireless/mwifiex')
24 files changed, 346 insertions, 321 deletions
diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c index 916183d39009..34bba5234294 100644 --- a/drivers/net/wireless/mwifiex/11n.c +++ b/drivers/net/wireless/mwifiex/11n.c @@ -185,13 +185,12 @@ int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv, * * Handling includes changing the header fields into CPU format. */ -int mwifiex_ret_11n_cfg(struct host_cmd_ds_command *resp, void *data_buf) +int mwifiex_ret_11n_cfg(struct host_cmd_ds_command *resp, + struct mwifiex_ds_11n_tx_cfg *tx_cfg) { - struct mwifiex_ds_11n_tx_cfg *tx_cfg; struct host_cmd_ds_11n_cfg *htcfg = &resp->params.htcfg; - if (data_buf) { - tx_cfg = (struct mwifiex_ds_11n_tx_cfg *) data_buf; + if (tx_cfg) { tx_cfg->tx_htcap = le16_to_cpu(htcfg->ht_tx_cap); tx_cfg->tx_htinfo = le16_to_cpu(htcfg->ht_tx_info); } @@ -208,11 +207,10 @@ int mwifiex_ret_11n_cfg(struct host_cmd_ds_command *resp, void *data_buf) */ int mwifiex_cmd_recfg_tx_buf(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, int cmd_action, - void *data_buf) + u16 *buf_size) { struct host_cmd_ds_txbuf_cfg *tx_buf = &cmd->params.tx_buf; u16 action = (u16) cmd_action; - u16 buf_size = *((u16 *) data_buf); cmd->command = cpu_to_le16(HostCmd_CMD_RECONFIGURE_TX_BUFF); cmd->size = @@ -220,8 +218,8 @@ int mwifiex_cmd_recfg_tx_buf(struct mwifiex_private *priv, tx_buf->action = cpu_to_le16(action); switch (action) { case HostCmd_ACT_GEN_SET: - dev_dbg(priv->adapter->dev, "cmd: set tx_buf=%d\n", buf_size); - tx_buf->buff_size = cpu_to_le16(buf_size); + dev_dbg(priv->adapter->dev, "cmd: set tx_buf=%d\n", *buf_size); + tx_buf->buff_size = cpu_to_le16(*buf_size); break; case HostCmd_ACT_GEN_GET: default: @@ -240,13 +238,12 @@ int mwifiex_cmd_recfg_tx_buf(struct mwifiex_private *priv, * - Ensuring correct endian-ness */ int mwifiex_cmd_amsdu_aggr_ctrl(struct host_cmd_ds_command *cmd, - int cmd_action, void *data_buf) + int cmd_action, + struct mwifiex_ds_11n_amsdu_aggr_ctrl *aa_ctrl) { struct host_cmd_ds_amsdu_aggr_ctrl *amsdu_ctrl = &cmd->params.amsdu_aggr_ctrl; u16 action = (u16) cmd_action; - struct mwifiex_ds_11n_amsdu_aggr_ctrl *aa_ctrl = - (struct mwifiex_ds_11n_amsdu_aggr_ctrl *) data_buf; cmd->command = cpu_to_le16(HostCmd_CMD_AMSDU_AGGR_CTRL); cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_amsdu_aggr_ctrl) @@ -272,15 +269,13 @@ int mwifiex_cmd_amsdu_aggr_ctrl(struct host_cmd_ds_command *cmd, * Handling includes changing the header fields into CPU format. */ int mwifiex_ret_amsdu_aggr_ctrl(struct host_cmd_ds_command *resp, - void *data_buf) + struct mwifiex_ds_11n_amsdu_aggr_ctrl + *amsdu_aggr_ctrl) { - struct mwifiex_ds_11n_amsdu_aggr_ctrl *amsdu_aggr_ctrl; struct host_cmd_ds_amsdu_aggr_ctrl *amsdu_ctrl = &resp->params.amsdu_aggr_ctrl; - if (data_buf) { - amsdu_aggr_ctrl = - (struct mwifiex_ds_11n_amsdu_aggr_ctrl *) data_buf; + if (amsdu_aggr_ctrl) { amsdu_aggr_ctrl->enable = le16_to_cpu(amsdu_ctrl->enable); amsdu_aggr_ctrl->curr_buf_size = le16_to_cpu(amsdu_ctrl->curr_buf_size); @@ -296,12 +291,10 @@ int mwifiex_ret_amsdu_aggr_ctrl(struct host_cmd_ds_command *resp, * - Setting HT Tx capability and HT Tx information fields * - Ensuring correct endian-ness */ -int mwifiex_cmd_11n_cfg(struct host_cmd_ds_command *cmd, - u16 cmd_action, void *data_buf) +int mwifiex_cmd_11n_cfg(struct host_cmd_ds_command *cmd, u16 cmd_action, + struct mwifiex_ds_11n_tx_cfg *txcfg) { struct host_cmd_ds_11n_cfg *htcfg = &cmd->params.htcfg; - struct mwifiex_ds_11n_tx_cfg *txcfg = - (struct mwifiex_ds_11n_tx_cfg *) data_buf; cmd->command = cpu_to_le16(HostCmd_CMD_11N_CFG); cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_11n_cfg) + S_DS_GEN); diff --git a/drivers/net/wireless/mwifiex/11n.h b/drivers/net/wireless/mwifiex/11n.h index a4390a1a2a9f..90b421e343d4 100644 --- a/drivers/net/wireless/mwifiex/11n.h +++ b/drivers/net/wireless/mwifiex/11n.h @@ -29,9 +29,9 @@ int mwifiex_ret_11n_delba(struct mwifiex_private *priv, int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv, struct host_cmd_ds_command *resp); int mwifiex_ret_11n_cfg(struct host_cmd_ds_command *resp, - void *data_buf); -int mwifiex_cmd_11n_cfg(struct host_cmd_ds_command *cmd, - u16 cmd_action, void *data_buf); + struct mwifiex_ds_11n_tx_cfg *tx_cfg); +int mwifiex_cmd_11n_cfg(struct host_cmd_ds_command *cmd, u16 cmd_action, + struct mwifiex_ds_11n_tx_cfg *txcfg); int mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv, struct mwifiex_bssdescriptor *bss_desc, @@ -62,12 +62,14 @@ int mwifiex_get_rx_reorder_tbl(struct mwifiex_private *priv, int mwifiex_get_tx_ba_stream_tbl(struct mwifiex_private *priv, struct mwifiex_ds_tx_ba_stream_tbl *buf); int mwifiex_ret_amsdu_aggr_ctrl(struct host_cmd_ds_command *resp, - void *data_buf); + struct mwifiex_ds_11n_amsdu_aggr_ctrl + *amsdu_aggr_ctrl); int mwifiex_cmd_recfg_tx_buf(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, - int cmd_action, void *data_buf); + int cmd_action, u16 *buf_size); int mwifiex_cmd_amsdu_aggr_ctrl(struct host_cmd_ds_command *cmd, - int cmd_action, void *data_buf); + int cmd_action, + struct mwifiex_ds_11n_amsdu_aggr_ctrl *aa_ctrl); /* * This function checks whether AMPDU is allowed or not for a particular TID. diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c index f807447e4d99..1a453a605b3f 100644 --- a/drivers/net/wireless/mwifiex/11n_aggr.c +++ b/drivers/net/wireless/mwifiex/11n_aggr.c @@ -164,12 +164,13 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, struct mwifiex_tx_param tx_param; struct txpd *ptx_pd = NULL; - if (skb_queue_empty(&pra_list->skb_head)) { + skb_src = skb_peek(&pra_list->skb_head); + if (!skb_src) { spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags); return 0; } - skb_src = skb_peek(&pra_list->skb_head); + tx_info_src = MWIFIEX_SKB_TXCB(skb_src); skb_aggr = dev_alloc_skb(adapter->tx_buf_size); if (!skb_aggr) { @@ -184,17 +185,15 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, tx_info_aggr->bss_index = tx_info_src->bss_index; skb_aggr->priority = skb_src->priority; - while (skb_src && ((skb_headroom(skb_aggr) + skb_src->len - + LLC_SNAP_LEN) - <= adapter->tx_buf_size)) { + do { + /* Check if AMSDU can accommodate this MSDU */ + if (skb_tailroom(skb_aggr) < (skb_src->len + LLC_SNAP_LEN)) + break; - if (!skb_queue_empty(&pra_list->skb_head)) - skb_src = skb_dequeue(&pra_list->skb_head); - else - skb_src = NULL; + skb_src = skb_dequeue(&pra_list->skb_head); - if (skb_src) - pra_list->total_pkts_size -= skb_src->len; + pra_list->total_pkts_size -= skb_src->len; + pra_list->total_pkts--; atomic_dec(&priv->wmm.tx_pkts_queued); @@ -212,11 +211,15 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, return -1; } - if (!skb_queue_empty(&pra_list->skb_head)) - skb_src = skb_peek(&pra_list->skb_head); - else - skb_src = NULL; - } + if (skb_tailroom(skb_aggr) < pad) { + pad = 0; + break; + } + skb_put(skb_aggr, pad); + + skb_src = skb_peek(&pra_list->skb_head); + + } while (skb_src); spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags); @@ -230,11 +233,19 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, skb_push(skb_aggr, headroom); - tx_param.next_pkt_len = ((pra_list->total_pkts_size) ? - (((pra_list->total_pkts_size) > - adapter->tx_buf_size) ? adapter-> - tx_buf_size : pra_list->total_pkts_size + - LLC_SNAP_LEN + sizeof(struct txpd)) : 0); + /* + * Padding per MSDU will affect the length of next + * packet and hence the exact length of next packet + * is uncertain here. + * + * Also, aggregation of transmission buffer, while + * downloading the data to the card, wont gain much + * on the AMSDU packets as the AMSDU packets utilizes + * the transmission buffer space to the maximum + * (adapter->tx_buf_size). + */ + tx_param.next_pkt_len = 0; + ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_DATA, skb_aggr->data, skb_aggr->len, &tx_param); @@ -258,6 +269,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, skb_queue_tail(&pra_list->skb_head, skb_aggr); pra_list->total_pkts_size += skb_aggr->len; + pra_list->total_pkts++; atomic_inc(&priv->wmm.tx_pkts_queued); diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c index e5dfdc39a921..7aa9aa0ac958 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.c +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c @@ -328,13 +328,12 @@ int mwifiex_cmd_11n_addba_req(struct host_cmd_ds_command *cmd, void *data_buf) */ int mwifiex_cmd_11n_addba_rsp_gen(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, - void *data_buf) + struct host_cmd_ds_11n_addba_req + *cmd_addba_req) { struct host_cmd_ds_11n_addba_rsp *add_ba_rsp = (struct host_cmd_ds_11n_addba_rsp *) &cmd->params.add_ba_rsp; - struct host_cmd_ds_11n_addba_req *cmd_addba_req = - (struct host_cmd_ds_11n_addba_req *) data_buf; u8 tid; int win_size; uint16_t block_ack_param_set; diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.h b/drivers/net/wireless/mwifiex/11n_rxreorder.h index f3ca8c8c18f9..033c8adbdcd4 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.h +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.h @@ -52,8 +52,9 @@ int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv, int mwifiex_cmd_11n_delba(struct host_cmd_ds_command *cmd, void *data_buf); int mwifiex_cmd_11n_addba_rsp_gen(struct mwifiex_private *priv, - struct host_cmd_ds_command - *cmd, void *data_buf); + struct host_cmd_ds_command *cmd, + struct host_cmd_ds_11n_addba_req + *cmd_addba_req); int mwifiex_cmd_11n_addba_req(struct host_cmd_ds_command *cmd, void *data_buf); void mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv); diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 687c1f223497..352d2c5da1fc 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -672,6 +672,59 @@ static const u32 mwifiex_cipher_suites[] = { }; /* + * CFG802.11 operation handler for setting bit rates. + * + * Function selects legacy bang B/G/BG from corresponding bitrates selection. + * Currently only 2.4GHz band is supported. + */ +static int mwifiex_cfg80211_set_bitrate_mask(struct wiphy *wiphy, + struct net_device *dev, + const u8 *peer, + const struct cfg80211_bitrate_mask *mask) +{ + struct mwifiex_ds_band_cfg band_cfg; + struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); + int index = 0, mode = 0, i; + + /* Currently only 2.4GHz is supported */ + for (i = 0; i < mwifiex_band_2ghz.n_bitrates; i++) { + /* + * Rates below 6 Mbps in the table are CCK rates; 802.11b + * and from 6 they are OFDM; 802.11G + */ + if (mwifiex_rates[i].bitrate == 60) { + index = 1 << i; + break; + } + } + + if (mask->control[IEEE80211_BAND_2GHZ].legacy < index) { + mode = BAND_B; + } else { + mode = BAND_G; + if (mask->control[IEEE80211_BAND_2GHZ].legacy % index) + mode |= BAND_B; + } + + memset(&band_cfg, 0, sizeof(band_cfg)); + band_cfg.config_bands = mode; + + if (priv->bss_mode == NL80211_IFTYPE_ADHOC) + band_cfg.adhoc_start_band = mode; + + band_cfg.sec_chan_offset = NO_SEC_CHANNEL; + + if (mwifiex_set_radio_band_cfg(priv, &band_cfg)) + return -EFAULT; + + wiphy_debug(wiphy, "info: device configured in 802.11%s%s mode\n", + (mode & BAND_B) ? "b" : "", + (mode & BAND_G) ? "g" : ""); + + return 0; +} + +/* * CFG802.11 operation handler for disconnection request. * * This function does not work when there is already a disconnection @@ -960,7 +1013,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, ret = mwifiex_set_gen_ie(priv, sme->ie, sme->ie_len); if (sme->key) { - if (mwifiex_is_alg_wep(0) | mwifiex_is_alg_wep(0)) { + if (mwifiex_is_alg_wep(priv->sec_info.encryption_mode)) { dev_dbg(priv->adapter->dev, "info: setting wep encryption" " with key len %d\n", sme->key_len); @@ -1225,6 +1278,7 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = { .set_default_key = mwifiex_cfg80211_set_default_key, .set_power_mgmt = mwifiex_cfg80211_set_power_mgmt, .set_tx_power = mwifiex_cfg80211_set_tx_power, + .set_bitrate_mask = mwifiex_cfg80211_set_bitrate_mask, }; /* diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index cd89fed206ae..b5352afb8714 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c @@ -104,13 +104,11 @@ mwifiex_clean_cmd_node(struct mwifiex_adapter *adapter, * main thread. */ static int mwifiex_cmd_host_cmd(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd, void *data_buf) + struct host_cmd_ds_command *cmd, + struct mwifiex_ds_misc_cmd *pcmd_ptr) { - struct mwifiex_ds_misc_cmd *pcmd_ptr = - (struct mwifiex_ds_misc_cmd *) data_buf; - /* Copy the HOST command to command buffer */ - memcpy((void *) cmd, pcmd_ptr->cmd, pcmd_ptr->len); + memcpy(cmd, pcmd_ptr->cmd, pcmd_ptr->len); dev_dbg(priv->adapter->dev, "cmd: host cmd size = %d\n", pcmd_ptr->len); return 0; } @@ -707,15 +705,14 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) if (adapter->curr_cmd->cmd_flag & CMD_F_HOSTCMD) { /* Copy original response back to response buffer */ - struct mwifiex_ds_misc_cmd *hostcmd = NULL; + struct mwifiex_ds_misc_cmd *hostcmd; uint16_t size = le16_to_cpu(resp->size); dev_dbg(adapter->dev, "info: host cmd resp size = %d\n", size); size = min_t(u16, size, MWIFIEX_SIZE_OF_CMD_BUFFER); if (adapter->curr_cmd->data_buf) { - hostcmd = (struct mwifiex_ds_misc_cmd *) - adapter->curr_cmd->data_buf; + hostcmd = adapter->curr_cmd->data_buf; hostcmd->len = size; - memcpy(hostcmd->cmd, (void *) resp, size); + memcpy(hostcmd->cmd, resp, size); } } orig_cmdresp_no = le16_to_cpu(resp->command); @@ -1155,7 +1152,7 @@ EXPORT_SYMBOL_GPL(mwifiex_process_sleep_confirm_resp); int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, u16 cmd_action, uint16_t ps_bitmap, - void *data_buf) + struct mwifiex_ds_auto_ds *auto_ds) { struct host_cmd_ds_802_11_ps_mode_enh *psmode_enh = &cmd->params.psmode_enh; @@ -1218,9 +1215,8 @@ int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv, sizeof(struct mwifiex_ie_types_header)); cmd_size += sizeof(*auto_ds_tlv); tlv += sizeof(*auto_ds_tlv); - if (data_buf) - idletime = ((struct mwifiex_ds_auto_ds *) - data_buf)->idle_time; + if (auto_ds) + idletime = auto_ds->idle_time; dev_dbg(priv->adapter->dev, "cmd: PS Command: Enter Auto Deep Sleep\n"); auto_ds_tlv->deep_sleep_timeout = cpu_to_le16(idletime); @@ -1239,7 +1235,7 @@ int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv, */ int mwifiex_ret_enh_power_mode(struct mwifiex_private *priv, struct host_cmd_ds_command *resp, - void *data_buf) + struct mwifiex_ds_pm_cfg *pm_cfg) { struct mwifiex_adapter *adapter = priv->adapter; struct host_cmd_ds_802_11_ps_mode_enh *ps_mode = @@ -1282,10 +1278,8 @@ int mwifiex_ret_enh_power_mode(struct mwifiex_private *priv, dev_dbg(adapter->dev, "cmd: ps_bitmap=%#x\n", ps_bitmap); - if (data_buf) { + if (pm_cfg) { /* This section is for get power save mode */ - struct mwifiex_ds_pm_cfg *pm_cfg = - (struct mwifiex_ds_pm_cfg *)data_buf; if (ps_bitmap & BITMAP_STA_PS) pm_cfg->param.ps_mode = 1; else diff --git a/drivers/net/wireless/mwifiex/debugfs.c b/drivers/net/wireless/mwifiex/debugfs.c index 46d65e02c7ba..d26a78b6b3c4 100644 --- a/drivers/net/wireless/mwifiex/debugfs.c +++ b/drivers/net/wireless/mwifiex/debugfs.c @@ -27,8 +27,8 @@ static struct dentry *mwifiex_dfs_dir; static char *bss_modes[] = { "Unknown", - "Managed", "Ad-hoc", + "Managed", "Auto" }; @@ -216,28 +216,19 @@ mwifiex_info_read(struct file *file, char __user *ubuf, p += sprintf(p, "bss_mode=\"%s\"\n", bss_modes[info.bss_mode]); p += sprintf(p, "media_state=\"%s\"\n", (!priv->media_connected ? "Disconnected" : "Connected")); - p += sprintf(p, "mac_address=\"%02x:%02x:%02x:%02x:%02x:%02x\"\n", - netdev->dev_addr[0], netdev->dev_addr[1], - netdev->dev_addr[2], netdev->dev_addr[3], - netdev->dev_addr[4], netdev->dev_addr[5]); + p += sprintf(p, "mac_address=\"%pM\"\n", netdev->dev_addr); if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) { p += sprintf(p, "multicast_count=\"%d\"\n", netdev_mc_count(netdev)); p += sprintf(p, "essid=\"%s\"\n", info.ssid.ssid); - p += sprintf(p, "bssid=\"%02x:%02x:%02x:%02x:%02x:%02x\"\n", - info.bssid[0], info.bssid[1], - info.bssid[2], info.bssid[3], - info.bssid[4], info.bssid[5]); + p += sprintf(p, "bssid=\"%pM\"\n", info.bssid); p += sprintf(p, "channel=\"%d\"\n", (int) info.bss_chan); p += sprintf(p, "region_code = \"%02x\"\n", info.region_code); netdev_for_each_mc_addr(ha, netdev) - p += sprintf(p, "multicast_address[%d]=" - "\"%02x:%02x:%02x:%02x:%02x:%02x\"\n", i++, - ha->addr[0], ha->addr[1], - ha->addr[2], ha->addr[3], - ha->addr[4], ha->addr[5]); + p += sprintf(p, "multicast_address[%d]=\"%pM\"\n", + i++, ha->addr); } p += sprintf(p, "num_tx_bytes = %lu\n", priv->stats.tx_bytes); @@ -451,26 +442,18 @@ mwifiex_debug_read(struct file *file, char __user *ubuf, if (info.tx_tbl_num) { p += sprintf(p, "Tx BA stream table:\n"); for (i = 0; i < info.tx_tbl_num; i++) - p += sprintf(p, "tid = %d, " - "ra = %02x:%02x:%02x:%02x:%02x:%02x\n", - info.tx_tbl[i].tid, info.tx_tbl[i].ra[0], - info.tx_tbl[i].ra[1], info.tx_tbl[i].ra[2], - info.tx_tbl[i].ra[3], info.tx_tbl[i].ra[4], - info.tx_tbl[i].ra[5]); + p += sprintf(p, "tid = %d, ra = %pM\n", + info.tx_tbl[i].tid, info.tx_tbl[i].ra); } if (info.rx_tbl_num) { p += sprintf(p, "Rx reorder table:\n"); for (i = 0; i < info.rx_tbl_num; i++) { - - p += sprintf(p, "tid = %d, " - "ta = %02x:%02x:%02x:%02x:%02x:%02x, " + p += sprintf(p, "tid = %d, ta = %pM, " "start_win = %d, " "win_size = %d, buffer: ", info.rx_tbl[i].tid, - info.rx_tbl[i].ta[0], info.rx_tbl[i].ta[1], - info.rx_tbl[i].ta[2], info.rx_tbl[i].ta[3], - info.rx_tbl[i].ta[4], info.rx_tbl[i].ta[5], + info.rx_tbl[i].ta, info.rx_tbl[i].start_win, info.rx_tbl[i].win_size); diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h index 0e90b0986ed8..94ddc9038cb3 100644 --- a/drivers/net/wireless/mwifiex/decl.h +++ b/drivers/net/wireless/mwifiex/decl.h @@ -30,7 +30,9 @@ #define MWIFIEX_MAX_BSS_NUM (1) -#define MWIFIEX_MIN_DATA_HEADER_LEN 32 /* (sizeof(mwifiex_txpd)) */ +#define MWIFIEX_MIN_DATA_HEADER_LEN 36 /* sizeof(mwifiex_txpd) + * + 4 byte alignment + */ #define MWIFIEX_MAX_TX_BASTREAM_SUPPORTED 2 #define MWIFIEX_MAX_RX_BASTREAM_SUPPORTED 16 diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index afdd145dff0b..4fee0993b186 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -157,6 +157,17 @@ enum MWIFIEX_802_11_WEP_STATUS { #define ISSUPP_RXSTBC(Dot11nDevCap) (Dot11nDevCap & BIT(26)) #define ISSUPP_GREENFIELD(Dot11nDevCap) (Dot11nDevCap & BIT(29)) +/* httxcfg bitmap + * 0 reserved + * 1 20/40 Mhz enable(1)/disable(0) + * 2-3 reserved + * 4 green field enable(1)/disable(0) + * 5 short GI in 20 Mhz enable(1)/disable(0) + * 6 short GI in 40 Mhz enable(1)/disable(0) + * 7-15 reserved + */ +#define MWIFIEX_FW_DEF_HTTXCFG (BIT(1) | BIT(4) | BIT(5) | BIT(6)) + #define GET_RXMCSSUPP(DevMCSSupported) (DevMCSSupported & 0x0f) #define SETHT_MCS32(x) (x[4] |= 1) diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h index 7c1c5ee40eb9..f6bcc868562f 100644 --- a/drivers/net/wireless/mwifiex/ioctl.h +++ b/drivers/net/wireless/mwifiex/ioctl.h @@ -249,6 +249,7 @@ struct mwifiex_ds_hs_cfg { }; #define DEEP_SLEEP_ON 1 +#define DEEP_SLEEP_OFF 0 #define DEEP_SLEEP_IDLE_TIME 100 #define PS_MODE_AUTO 1 diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c index 5eab3dc29b1c..644e2e405cb5 100644 --- a/drivers/net/wireless/mwifiex/join.c +++ b/drivers/net/wireless/mwifiex/join.c @@ -364,10 +364,9 @@ static int mwifiex_append_rsn_ie_wpa_wpa2(struct mwifiex_private *priv, */ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, - void *data_buf) + struct mwifiex_bssdescriptor *bss_desc) { struct host_cmd_ds_802_11_associate *assoc = &cmd->params.associate; - struct mwifiex_bssdescriptor *bss_desc; struct mwifiex_ie_types_ssid_param_set *ssid_tlv; struct mwifiex_ie_types_phy_param_set *phy_tlv; struct mwifiex_ie_types_ss_param_set *ss_tlv; @@ -380,7 +379,6 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, u8 *pos; int rsn_ie_len = 0; - bss_desc = (struct mwifiex_bssdescriptor *) data_buf; pos = (u8 *) assoc; mwifiex_cfg_tx_buf(priv, bss_desc); @@ -748,7 +746,8 @@ done: */ int mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd, void *data_buf) + struct host_cmd_ds_command *cmd, + struct mwifiex_802_11_ssid *req_ssid) { int rsn_ie_len = 0; struct mwifiex_adapter *adapter = priv->adapter; @@ -786,20 +785,15 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, memset(adhoc_start->ssid, 0, IEEE80211_MAX_SSID_LEN); - memcpy(adhoc_start->ssid, - ((struct mwifiex_802_11_ssid *) data_buf)->ssid, - ((struct mwifiex_802_11_ssid *) data_buf)->ssid_len); + memcpy(adhoc_start->ssid, req_ssid->ssid, req_ssid->ssid_len); dev_dbg(adapter->dev, "info: ADHOC_S_CMD: SSID = %s\n", adhoc_start->ssid); memset(bss_desc->ssid.ssid, 0, IEEE80211_MAX_SSID_LEN); - memcpy(bss_desc->ssid.ssid, - ((struct mwifiex_802_11_ssid *) data_buf)->ssid, - ((struct mwifiex_802_11_ssid *) data_buf)->ssid_len); + memcpy(bss_desc->ssid.ssid, req_ssid->ssid, req_ssid->ssid_len); - bss_desc->ssid.ssid_len = - ((struct mwifiex_802_11_ssid *) data_buf)->ssid_len; + bss_desc->ssid.ssid_len = req_ssid->ssid_len; /* Set the BSS mode */ adhoc_start->bss_mode = HostCmd_BSS_MODE_IBSS; @@ -1036,13 +1030,12 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, */ int mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd, void *data_buf) + struct host_cmd_ds_command *cmd, + struct mwifiex_bssdescriptor *bss_desc) { int rsn_ie_len = 0; struct host_cmd_ds_802_11_ad_hoc_join *adhoc_join = &cmd->params.adhoc_join; - struct mwifiex_bssdescriptor *bss_desc = - (struct mwifiex_bssdescriptor *) data_buf; struct mwifiex_ie_types_chan_list_param_set *chan_tlv; u32 cmd_append_size = 0; u16 tmp_cap; diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index f0582259c935..e5fc53dc6887 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c @@ -26,17 +26,12 @@ const char driver_version[] = "mwifiex " VERSION " (%s) "; -struct mwifiex_adapter *g_adapter; -EXPORT_SYMBOL_GPL(g_adapter); - static struct mwifiex_bss_attr mwifiex_bss_sta[] = { {MWIFIEX_BSS_TYPE_STA, MWIFIEX_DATA_FRAME_TYPE_ETH_II, true, 0, 0}, }; static int drv_mode = DRV_MODE_STA; -static char fw_name[32] = DEFAULT_FW_NAME; - /* Supported drv_mode table */ static struct mwifiex_drv_mode mwifiex_drv_mode_tbl[] = { { @@ -62,7 +57,8 @@ static struct mwifiex_drv_mode mwifiex_drv_mode_tbl[] = { * proper cleanup before exiting. */ static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops, - struct mwifiex_drv_mode *drv_mode_ptr) + struct mwifiex_drv_mode *drv_mode_ptr, + void **padapter) { struct mwifiex_adapter *adapter; int i; @@ -71,7 +67,7 @@ static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops, if (!adapter) return -ENOMEM; - g_adapter = adapter; + *padapter = adapter; adapter->card = card; /* Save interface specific operations in adapter */ @@ -326,7 +322,7 @@ exit_main_proc: * and initializing the private structures. */ static int -mwifiex_init_sw(void *card, struct mwifiex_if_ops *if_ops) +mwifiex_init_sw(void *card, struct mwifiex_if_ops *if_ops, void **padapter) { int i; struct mwifiex_drv_mode *drv_mode_ptr; @@ -345,7 +341,7 @@ mwifiex_init_sw(void *card, struct mwifiex_if_ops *if_ops) return -1; } - if (mwifiex_register(card, if_ops, drv_mode_ptr)) + if (mwifiex_register(card, if_ops, drv_mode_ptr, padapter)) return -1; return 0; @@ -384,20 +380,8 @@ static int mwifiex_init_hw_fw(struct mwifiex_adapter *adapter) memset(&fw, 0, sizeof(struct mwifiex_fw_image)); - switch (adapter->revision_id) { - case SD8787_W0: - case SD8787_W1: - strcpy(fw_name, SD8787_W1_FW_NAME); - break; - case SD8787_A0: - case SD8787_A1: - strcpy(fw_name, SD8787_AX_FW_NAME); - break; - default: - break; - } - - err = request_firmware(&adapter->firmware, fw_name, adapter->dev); + err = request_firmware(&adapter->firmware, adapter->fw_name, + adapter->dev); if (err < 0) { dev_err(adapter->dev, "request_firmware() returned" " error code %#x\n", err); @@ -569,7 +553,7 @@ static int mwifiex_set_mac_address(struct net_device *dev, void *addr) { struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); - struct sockaddr *hw_addr = (struct sockaddr *) addr; + struct sockaddr *hw_addr = addr; int ret; memcpy(priv->curr_addr, hw_addr->sa_data, ETH_ALEN); @@ -869,13 +853,11 @@ mwifiex_add_card(void *card, struct semaphore *sem, if (down_interruptible(sem)) goto exit_sem_err; - if (mwifiex_init_sw(card, if_ops)) { + if (mwifiex_init_sw(card, if_ops, (void **)&adapter)) { pr_err("%s: software init failed\n", __func__); goto err_init_sw; } - adapter = g_adapter; - adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING; adapter->surprise_removed = false; init_waitqueue_head(&adapter->init_wait_q); diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 8316b3cd92cd..2215c3c97354 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -39,7 +39,6 @@ #include "fw.h" extern const char driver_version[]; -extern struct mwifiex_adapter *g_adapter; enum { MWIFIEX_ASYNC_CMD, @@ -48,15 +47,6 @@ enum { #define DRV_MODE_STA 0x1 -#define SD8787_W0 0x30 -#define SD8787_W1 0x31 -#define SD8787_A0 0x40 -#define SD8787_A1 0x41 - -#define DEFAULT_FW_NAME "mrvl/sd8787_uapsta.bin" -#define SD8787_W1_FW_NAME "mrvl/sd8787_uapsta_w1.bin" -#define SD8787_AX_FW_NAME "mrvl/sd8787_uapsta.bin" - struct mwifiex_drv_mode { u16 drv_mode; u16 intf_num; @@ -190,6 +180,7 @@ struct mwifiex_ra_list_tbl { struct sk_buff_head skb_head; u8 ra[ETH_ALEN]; u32 total_pkts_size; + u32 total_pkts; u32 is_11n_enabled; }; @@ -576,10 +567,10 @@ struct mwifiex_adapter { u8 priv_num; struct mwifiex_drv_mode *drv_mode; const struct firmware *firmware; + char fw_name[32]; struct device *dev; bool surprise_removed; u32 fw_release_number; - u32 revision_id; u16 init_wait_q_woken; wait_queue_head_t init_wait_q; void *card; @@ -745,10 +736,10 @@ void mwifiex_process_sleep_confirm_resp(struct mwifiex_adapter *, u8 *, int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, u16 cmd_action, uint16_t ps_bitmap, - void *data_buf); + struct mwifiex_ds_auto_ds *auto_ds); int mwifiex_ret_enh_power_mode(struct mwifiex_private *priv, struct host_cmd_ds_command *resp, - void *data_buf); + struct mwifiex_ds_pm_cfg *pm_cfg); void mwifiex_process_hs_config(struct mwifiex_adapter *adapter); void mwifiex_hs_activated_event(struct mwifiex_private *priv, u8 activated); @@ -760,7 +751,7 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *, uint16_t cmd_no, u16 cmd_action, u32 cmd_oid, void *data_buf, void *cmd_buf); int mwifiex_process_sta_cmdresp(struct mwifiex_private *, u16 cmdresp_no, - void *cmd_buf); + struct host_cmd_ds_command *resp); int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *, struct sk_buff *skb); int mwifiex_process_sta_event(struct mwifiex_private *); @@ -769,7 +760,7 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *, u8 first_sta); int mwifiex_scan_networks(struct mwifiex_private *priv, const struct mwifiex_user_scan_cfg *user_scan_in); int mwifiex_cmd_802_11_scan(struct host_cmd_ds_command *cmd, - void *data_buf); + struct mwifiex_scan_cmd_config *scan_cfg); void mwifiex_queue_scan_cmd(struct mwifiex_private *priv, struct cmd_ctrl_node *cmd_node); int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, @@ -786,8 +777,8 @@ s32 mwifiex_ssid_cmp(struct mwifiex_802_11_ssid *ssid1, int mwifiex_associate(struct mwifiex_private *priv, struct mwifiex_bssdescriptor *bss_desc); int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, - struct host_cmd_ds_command - *cmd, void *data_buf); + struct host_cmd_ds_command *cmd, + struct mwifiex_bssdescriptor *bss_desc); int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, struct host_cmd_ds_command *resp); void mwifiex_reset_connect_state(struct mwifiex_private *priv); @@ -800,10 +791,10 @@ int mwifiex_adhoc_join(struct mwifiex_private *priv, struct mwifiex_bssdescriptor *bss_desc); int mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, - void *data_buf); + struct mwifiex_802_11_ssid *req_ssid); int mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, - void *data_buf); + struct mwifiex_bssdescriptor *bss_desc); int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, struct host_cmd_ds_command *resp); int mwifiex_cmd_802_11_bg_scan_query(struct host_cmd_ds_command *cmd); @@ -938,6 +929,7 @@ int mwifiex_set_hs_params(struct mwifiex_private *priv, struct mwifiex_ds_hs_cfg *hscfg); int mwifiex_cancel_hs(struct mwifiex_private *priv, int cmd_type); int mwifiex_enable_hs(struct mwifiex_adapter *adapter); +int mwifiex_disable_auto_ds(struct mwifiex_private *priv); int mwifiex_get_signal_info(struct mwifiex_private *priv, struct mwifiex_ds_get_signal *signal); int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 5c22860fb40a..6f88c8ab5de5 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c @@ -2357,12 +2357,10 @@ int mwifiex_scan_networks(struct mwifiex_private *priv, * - Setting command ID, and proper size * - Ensuring correct endian-ness */ -int mwifiex_cmd_802_11_scan(struct host_cmd_ds_command *cmd, void *data_buf) +int mwifiex_cmd_802_11_scan(struct host_cmd_ds_command *cmd, + struct mwifiex_scan_cmd_config *scan_cfg) { struct host_cmd_ds_802_11_scan *scan_cmd = &cmd->params.scan; - struct mwifiex_scan_cmd_config *scan_cfg; - - scan_cfg = (struct mwifiex_scan_cmd_config *) data_buf; /* Set fixed field variables in scan command */ scan_cmd->bss_mode = scan_cfg->bss_mode; diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c index d425dbd91d19..82098ac483b8 100644 --- a/drivers/net/wireless/mwifiex/sdio.c +++ b/drivers/net/wireless/mwifiex/sdio.c @@ -31,10 +31,27 @@ #define SDIO_VERSION "1.0" +/* The mwifiex_sdio_remove() callback function is called when + * user removes this module from kernel space or ejects + * the card from the slot. The driver handles these 2 cases + * differently. + * If the user is removing the module, the few commands (FUNC_SHUTDOWN, + * HS_CANCEL etc.) are sent to the firmware. + * If the card is removed, there is no need to send these command. + * + * The variable 'user_rmmod' is used to distinguish these two + * scenarios. This flag is initialized as FALSE in case the card + * is removed, and will be set to TRUE for module removal when + * module_exit function is called. + */ +static u8 user_rmmod; + static struct mwifiex_if_ops sdio_ops; static struct semaphore add_remove_card_sem; +static int mwifiex_sdio_resume(struct device *dev); + /* * SDIO probe. * @@ -93,17 +110,39 @@ static void mwifiex_sdio_remove(struct sdio_func *func) { struct sdio_mmc_card *card; + struct mwifiex_adapter *adapter; + int i; pr_debug("info: SDIO func num=%d\n", func->num); - if (func) { - card = sdio_get_drvdata(func); - if (card) { - mwifiex_remove_card(card->adapter, - &add_remove_card_sem); - kfree(card); - } + card = sdio_get_drvdata(func); + if (!card) + return; + + adapter = card->adapter; + if (!adapter || !adapter->priv_num) + return; + + if (user_rmmod) { + if (adapter->is_suspended) + mwifiex_sdio_resume(adapter->dev); + + for (i = 0; i < adapter->priv_num; i++) + if ((GET_BSS_ROLE(adapter->priv[i]) == + MWIFIEX_BSS_ROLE_STA) && + adapter->priv[i]->media_connected) + mwifiex_deauthenticate(adapter->priv[i], NULL); + + mwifiex_disable_auto_ds(mwifiex_get_priv(adapter, + MWIFIEX_BSS_ROLE_ANY)); + + mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter, + MWIFIEX_BSS_ROLE_ANY), + MWIFIEX_FUNC_SHUTDOWN); } + + mwifiex_remove_card(card->adapter, &add_remove_card_sem); + kfree(card); } /* @@ -1283,7 +1322,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, if (!(card->mp_wr_bitmap & (1 << card->curr_wr_port)) || !MP_TX_AGGR_BUF_HAS_ROOM( - card, next_pkt_len)) + card, pkt_len + next_pkt_len)) f_send_aggr_buf = 1; } else { /* No room in Aggr buf, send it */ @@ -1531,6 +1570,7 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter) sdio_set_drvdata(func, card); adapter->dev = &func->dev; + strcpy(adapter->fw_name, SD8787_DEFAULT_FW_NAME); return 0; @@ -1552,7 +1592,6 @@ disable_func: * the first interrupt got from bootloader * - Disable host interrupt mask register * - Get SDIO port - * - Get revision ID * - Initialize SDIO variables in card * - Allocate MP registers * - Allocate MPA Tx and Rx buffers @@ -1576,10 +1615,6 @@ static int mwifiex_init_sdio(struct mwifiex_adapter *adapter) /* Get SDIO ioport */ mwifiex_init_sdio_ioport(adapter); - /* Get revision ID */ -#define REV_ID_REG 0x5c - mwifiex_read_reg(adapter, REV_ID_REG, &adapter->revision_id); - /* Initialize SDIO variables in card */ card->mp_rd_bitmap = 0; card->mp_wr_bitmap = 0; @@ -1700,6 +1735,9 @@ mwifiex_sdio_init_module(void) { sema_init(&add_remove_card_sem, 1); + /* Clear the flag in case user removes the card. */ + user_rmmod = 0; + return sdio_register_driver(&mwifiex_sdio); } @@ -1715,32 +1753,12 @@ mwifiex_sdio_init_module(void) static void mwifiex_sdio_cleanup_module(void) { - struct mwifiex_adapter *adapter = g_adapter; - int i; - - if (down_interruptible(&add_remove_card_sem)) - goto exit_sem_err; - - if (!adapter || !adapter->priv_num) - goto exit; - - if (adapter->is_suspended) - mwifiex_sdio_resume(adapter->dev); - - for (i = 0; i < adapter->priv_num; i++) - if ((GET_BSS_ROLE(adapter->priv[i]) == MWIFIEX_BSS_ROLE_STA) && - adapter->priv[i]->media_connected) - mwifiex_deauthenticate(adapter->priv[i], NULL); - - if (!adapter->surprise_removed) - mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter, - MWIFIEX_BSS_ROLE_ANY), - MWIFIEX_FUNC_SHUTDOWN); + if (!down_interruptible(&add_remove_card_sem)) + up(&add_remove_card_sem); -exit: - up(&add_remove_card_sem); + /* Set the flag as user is removing this module. */ + user_rmmod = 1; -exit_sem_err: sdio_unregister_driver(&mwifiex_sdio); } @@ -1751,4 +1769,4 @@ MODULE_AUTHOR("Marvell International Ltd."); MODULE_DESCRIPTION("Marvell WiFi-Ex SDIO Driver version " SDIO_VERSION); MODULE_VERSION(SDIO_VERSION); MODULE_LICENSE("GPL v2"); -MODULE_FIRMWARE("sd8787.bin"); +MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin"); diff --git a/drivers/net/wireless/mwifiex/sdio.h b/drivers/net/wireless/mwifiex/sdio.h index 4e97e90aa399..524f78f4ee69 100644 --- a/drivers/net/wireless/mwifiex/sdio.h +++ b/drivers/net/wireless/mwifiex/sdio.h @@ -28,6 +28,8 @@ #include "main.h" +#define SD8787_DEFAULT_FW_NAME "mrvl/sd8787_uapsta.bin" + #define BLOCK_MODE 1 #define BYTE_MODE 0 @@ -52,10 +54,10 @@ #define SDIO_MP_AGGR_DEF_PKT_LIMIT 8 -#define SDIO_MP_TX_AGGR_DEF_BUF_SIZE (4096) /* 4K */ +#define SDIO_MP_TX_AGGR_DEF_BUF_SIZE (8192) /* 8K */ /* Multi port RX aggregation buffer size */ -#define SDIO_MP_RX_AGGR_DEF_BUF_SIZE (4096) /* 4K */ +#define SDIO_MP_RX_AGGR_DEF_BUF_SIZE (16384) /* 16K */ /* Misc. Config Register : Auto Re-enable interrupts */ #define AUTO_RE_ENABLE_INT BIT(4) diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c index 8af3a78d2723..c54ee287b878 100644 --- a/drivers/net/wireless/mwifiex/sta_cmd.c +++ b/drivers/net/wireless/mwifiex/sta_cmd.c @@ -67,10 +67,9 @@ mwifiex_cmd_802_11_rssi_info(struct mwifiex_private *priv, */ static int mwifiex_cmd_mac_control(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, - u16 cmd_action, void *data_buf) + u16 cmd_action, u16 *action) { struct host_cmd_ds_mac_control *mac_ctrl = &cmd->params.mac_ctrl; - u16 action = *((u16 *) data_buf); if (cmd_action != HostCmd_ACT_GEN_SET) { dev_err(priv->adapter->dev, @@ -81,7 +80,7 @@ static int mwifiex_cmd_mac_control(struct mwifiex_private *priv, cmd->command = cpu_to_le16(HostCmd_CMD_MAC_CONTROL); cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_mac_control) + S_DS_GEN); - mac_ctrl->action = cpu_to_le16(action); + mac_ctrl->action = cpu_to_le16(*action); return 0; } @@ -104,10 +103,9 @@ static int mwifiex_cmd_mac_control(struct mwifiex_private *priv, static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, u16 cmd_action, u32 cmd_oid, - void *data_buf) + u32 *ul_temp) { struct host_cmd_ds_802_11_snmp_mib *snmp_mib = &cmd->params.smib; - u32 ul_temp; dev_dbg(priv->adapter->dev, "cmd: SNMP_CMD: cmd_oid = 0x%x\n", cmd_oid); cmd->command = cpu_to_le16(HostCmd_CMD_802_11_SNMP_MIB); @@ -127,9 +125,8 @@ static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv, if (cmd_action == HostCmd_ACT_GEN_SET) { snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET); snmp_mib->buf_size = cpu_to_le16(sizeof(u16)); - ul_temp = *((u32 *) data_buf); *((__le16 *) (snmp_mib->value)) = - cpu_to_le16((u16) ul_temp); + cpu_to_le16((u16) *ul_temp); cmd->size = cpu_to_le16(le16_to_cpu(cmd->size) + sizeof(u16)); } @@ -139,9 +136,8 @@ static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv, if (cmd_action == HostCmd_ACT_GEN_SET) { snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET); snmp_mib->buf_size = cpu_to_le16(sizeof(u16)); - ul_temp = *((u32 *) data_buf); *(__le16 *) (snmp_mib->value) = - cpu_to_le16((u16) ul_temp); + cpu_to_le16((u16) *ul_temp); cmd->size = cpu_to_le16(le16_to_cpu(cmd->size) + sizeof(u16)); } @@ -152,9 +148,8 @@ static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv, if (cmd_action == HostCmd_ACT_GEN_SET) { snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET); snmp_mib->buf_size = cpu_to_le16(sizeof(u16)); - ul_temp = (*(u32 *) data_buf); *((__le16 *) (snmp_mib->value)) = - cpu_to_le16((u16) ul_temp); + cpu_to_le16((u16) *ul_temp); cmd->size = cpu_to_le16(le16_to_cpu(cmd->size) + sizeof(u16)); } @@ -164,9 +159,8 @@ static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv, if (cmd_action == HostCmd_ACT_GEN_SET) { snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET); snmp_mib->buf_size = cpu_to_le16(sizeof(u16)); - ul_temp = *(u32 *) data_buf; *((__le16 *) (snmp_mib->value)) = - cpu_to_le16((u16) ul_temp); + cpu_to_le16((u16) *ul_temp); cmd->size = cpu_to_le16(le16_to_cpu(cmd->size) + sizeof(u16)); } @@ -209,13 +203,11 @@ mwifiex_cmd_802_11_get_log(struct host_cmd_ds_command *cmd) */ static int mwifiex_cmd_tx_rate_cfg(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, - u16 cmd_action, void *data_buf) + u16 cmd_action, u16 *pbitmap_rates) { struct host_cmd_ds_tx_rate_cfg *rate_cfg = &cmd->params.tx_rate_cfg; struct mwifiex_rate_scope *rate_scope; struct mwifiex_rate_drop_pattern *rate_drop; - u16 *pbitmap_rates = (u16 *) data_buf; - u32 i; cmd->command = cpu_to_le16(HostCmd_CMD_TX_RATE_CFG); @@ -272,10 +264,10 @@ static int mwifiex_cmd_tx_rate_cfg(struct mwifiex_private *priv, * - Ensuring correct endian-ness */ static int mwifiex_cmd_tx_power_cfg(struct host_cmd_ds_command *cmd, - u16 cmd_action, void *data_buf) + u16 cmd_action, + struct host_cmd_ds_txpwr_cfg *txp) { struct mwifiex_types_power_group *pg_tlv; - struct host_cmd_ds_txpwr_cfg *txp; struct host_cmd_ds_txpwr_cfg *cmd_txp_cfg = &cmd->params.txp_cfg; cmd->command = cpu_to_le16(HostCmd_CMD_TXPWR_CFG); @@ -283,12 +275,11 @@ static int mwifiex_cmd_tx_power_cfg(struct host_cmd_ds_command *cmd, cpu_to_le16(S_DS_GEN + sizeof(struct host_cmd_ds_txpwr_cfg)); switch (cmd_action) { case HostCmd_ACT_GEN_SET: - txp = (struct host_cmd_ds_txpwr_cfg *) data_buf; if (txp->mode) { pg_tlv = (struct mwifiex_types_power_group - *) ((unsigned long) data_buf + + *) ((unsigned long) txp + sizeof(struct host_cmd_ds_txpwr_cfg)); - memmove(cmd_txp_cfg, data_buf, + memmove(cmd_txp_cfg, txp, sizeof(struct host_cmd_ds_txpwr_cfg) + sizeof(struct mwifiex_types_power_group) + pg_tlv->length); @@ -300,8 +291,7 @@ static int mwifiex_cmd_tx_power_cfg(struct host_cmd_ds_command *cmd, sizeof(struct mwifiex_types_power_group) + pg_tlv->length); } else { - memmove(cmd_txp_cfg, data_buf, - sizeof(struct host_cmd_ds_txpwr_cfg)); + memmove(cmd_txp_cfg, txp, sizeof(*txp)); } cmd_txp_cfg->action = cpu_to_le16(cmd_action); break; @@ -322,22 +312,23 @@ static int mwifiex_cmd_tx_power_cfg(struct host_cmd_ds_command *cmd, * (as required) * - Ensuring correct endian-ness */ -static int mwifiex_cmd_802_11_hs_cfg(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd, - u16 cmd_action, - struct mwifiex_hs_config_param *data_buf) +static int +mwifiex_cmd_802_11_hs_cfg(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd, + u16 cmd_action, + struct mwifiex_hs_config_param *hscfg_param) { struct mwifiex_adapter *adapter = priv->adapter; struct host_cmd_ds_802_11_hs_cfg_enh *hs_cfg = &cmd->params.opt_hs_cfg; u16 hs_activate = false; - if (data_buf == NULL) + if (!hscfg_param) /* New Activate command */ hs_activate = true; cmd->command = cpu_to_le16(HostCmd_CMD_802_11_HS_CFG_ENH); if (!hs_activate && - (data_buf->conditions + (hscfg_param->conditions != cpu_to_le32(HOST_SLEEP_CFG_CANCEL)) && ((adapter->arp_filter_size > 0) && (adapter->arp_filter_size <= ARP_FILTER_MAX_BUF_SIZE))) { @@ -359,9 +350,9 @@ static int mwifiex_cmd_802_11_hs_cfg(struct mwifiex_private *priv, hs_cfg->params.hs_activate.resp_ctrl = RESP_NEEDED; } else { hs_cfg->action = cpu_to_le16(HS_CONFIGURE); - hs_cfg->params.hs_config.conditions = data_buf->conditions; - hs_cfg->params.hs_config.gpio = data_buf->gpio; - hs_cfg->params.hs_config.gap = data_buf->gap; + hs_cfg->params.hs_config.conditions = hscfg_param->conditions; + hs_cfg->params.hs_config.gpio = hscfg_param->gpio; + hs_cfg->params.hs_config.gap = hscfg_param->gap; dev_dbg(adapter->dev, "cmd: HS_CFG_CMD: condition:0x%x gpio:0x%x gap:0x%x\n", hs_cfg->params.hs_config.conditions, @@ -405,11 +396,11 @@ static int mwifiex_cmd_802_11_mac_address(struct mwifiex_private *priv, * - Setting MAC multicast address * - Ensuring correct endian-ness */ -static int mwifiex_cmd_mac_multicast_adr(struct host_cmd_ds_command *cmd, - u16 cmd_action, void *data_buf) +static int +mwifiex_cmd_mac_multicast_adr(struct host_cmd_ds_command *cmd, + u16 cmd_action, + struct mwifiex_multicast_list *mcast_list) { - struct mwifiex_multicast_list *mcast_list = - (struct mwifiex_multicast_list *) data_buf; struct host_cmd_ds_mac_multicast_adr *mcast_addr = &cmd->params.mc_addr; cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_mac_multicast_adr) + @@ -435,7 +426,7 @@ static int mwifiex_cmd_mac_multicast_adr(struct host_cmd_ds_command *cmd, */ static int mwifiex_cmd_802_11_deauthenticate(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, - void *data_buf) + u8 *mac) { struct host_cmd_ds_802_11_deauthenticate *deauth = &cmd->params.deauth; @@ -444,7 +435,7 @@ static int mwifiex_cmd_802_11_deauthenticate(struct mwifiex_private *priv, + S_DS_GEN); /* Set AP MAC address */ - memcpy(deauth->mac_addr, (u8 *) data_buf, ETH_ALEN); + memcpy(deauth->mac_addr, mac, ETH_ALEN); dev_dbg(priv->adapter->dev, "cmd: Deauth: %pM\n", deauth->mac_addr); @@ -543,15 +534,14 @@ mwifiex_set_keyparamset_wep(struct mwifiex_private *priv, * encryption (TKIP, AES) (as required) * - Ensuring correct endian-ness */ -static int mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd, - u16 cmd_action, - u32 cmd_oid, void *data_buf) +static int +mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd, + u16 cmd_action, u32 cmd_oid, + struct mwifiex_ds_encrypt_key *enc_key) { struct host_cmd_ds_802_11_key_material *key_material = &cmd->params.key_material; - struct mwifiex_ds_encrypt_key *enc_key = - (struct mwifiex_ds_encrypt_key *) data_buf; u16 key_param_len = 0; int ret = 0; const u8 bc_mac[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; @@ -741,7 +731,7 @@ static int mwifiex_cmd_802_11d_domain_info(struct mwifiex_private *priv, */ static int mwifiex_cmd_802_11_rf_channel(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, - u16 cmd_action, void *data_buf) + u16 cmd_action, u16 *channel) { struct host_cmd_ds_802_11_rf_channel *rf_chan = &cmd->params.rf_channel; @@ -759,7 +749,7 @@ static int mwifiex_cmd_802_11_rf_channel(struct mwifiex_private *priv, rf_type = le16_to_cpu(rf_chan->rf_type); SET_SECONDARYCHAN(rf_type, priv->adapter->chan_offset); - rf_chan->current_channel = cpu_to_le16(*((u16 *) data_buf)); + rf_chan->current_channel = cpu_to_le16(*channel); } rf_chan->action = cpu_to_le16(cmd_action); return 0; @@ -774,11 +764,10 @@ static int mwifiex_cmd_802_11_rf_channel(struct mwifiex_private *priv, * - Ensuring correct endian-ness */ static int mwifiex_cmd_ibss_coalescing_status(struct host_cmd_ds_command *cmd, - u16 cmd_action, void *data_buf) + u16 cmd_action, u16 *enable) { struct host_cmd_ds_802_11_ibss_status *ibss_coal = &(cmd->params.ibss_coalescing); - u16 enable = 0; cmd->command = cpu_to_le16(HostCmd_CMD_802_11_IBSS_COALESCING_STATUS); cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_ibss_status) + @@ -788,9 +777,10 @@ static int mwifiex_cmd_ibss_coalescing_status(struct host_cmd_ds_command *cmd, switch (cmd_action) { case HostCmd_ACT_GEN_SET: - if (data_buf != NULL) - enable = *(u16 *) data_buf; - ibss_coal->enable = cpu_to_le16(enable); + if (enable) + ibss_coal->enable = cpu_to_le16(*enable); + else + ibss_coal->enable = 0; break; /* In other case.. Nothing to do */ @@ -822,9 +812,8 @@ static int mwifiex_cmd_ibss_coalescing_status(struct host_cmd_ds_command *cmd, static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, u16 cmd_action, void *data_buf) { - struct mwifiex_ds_reg_rw *reg_rw; + struct mwifiex_ds_reg_rw *reg_rw = data_buf; - reg_rw = (struct mwifiex_ds_reg_rw *) data_buf; switch (le16_to_cpu(cmd->command)) { case HostCmd_CMD_MAC_REG_ACCESS: { @@ -893,8 +882,7 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, } case HostCmd_CMD_802_11_EEPROM_ACCESS: { - struct mwifiex_ds_read_eeprom *rd_eeprom = - (struct mwifiex_ds_read_eeprom *) data_buf; + struct mwifiex_ds_read_eeprom *rd_eeprom = data_buf; struct host_cmd_ds_802_11_eeprom_access *cmd_eeprom = (struct host_cmd_ds_802_11_eeprom_access *) &cmd->params.eeprom; @@ -923,8 +911,7 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, u16 cmd_action, u32 cmd_oid, void *data_buf, void *cmd_buf) { - struct host_cmd_ds_command *cmd_ptr = - (struct host_cmd_ds_command *) cmd_buf; + struct host_cmd_ds_command *cmd_ptr = cmd_buf; int ret = 0; /* Prepare command */ @@ -1126,6 +1113,7 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta) struct mwifiex_ds_11n_amsdu_aggr_ctrl amsdu_aggr_ctrl; struct mwifiex_ds_auto_ds auto_ds; enum state_11d_t state_11d; + struct mwifiex_ds_11n_tx_cfg tx_cfg; if (first_sta) { @@ -1181,7 +1169,7 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta) /* Send request to firmware */ ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_AMSDU_AGGR_CTRL, HostCmd_ACT_GEN_SET, 0, - (void *) &amsdu_aggr_ctrl); + &amsdu_aggr_ctrl); if (ret) return -1; /* MAC Control must be the last command in init_fw */ @@ -1211,8 +1199,15 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta) if (ret) dev_err(priv->adapter->dev, "11D: failed to enable 11D\n"); + /* Send cmd to FW to configure 11n specific configuration + * (Short GI, Channel BW, Green field support etc.) for transmit + */ + tx_cfg.tx_htcap = MWIFIEX_FW_DEF_HTTXCFG; + ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_CFG, + HostCmd_ACT_GEN_SET, 0, &tx_cfg); + /* set last_init_cmd */ - priv->adapter->last_init_cmd = HostCmd_CMD_802_11_SNMP_MIB; + priv->adapter->last_init_cmd = HostCmd_CMD_11N_CFG; ret = -EINPROGRESS; return ret; diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c index d08f76429a0a..6804239d87bd 100644 --- a/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c @@ -120,11 +120,10 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv, */ static int mwifiex_ret_802_11_rssi_info(struct mwifiex_private *priv, struct host_cmd_ds_command *resp, - void *data_buf) + struct mwifiex_ds_get_signal *signal) { struct host_cmd_ds_802_11_rssi_info_rsp *rssi_info_rsp = &resp->params.rssi_info_rsp; - struct mwifiex_ds_get_signal *signal; priv->data_rssi_last = le16_to_cpu(rssi_info_rsp->data_rssi_last); priv->data_nf_last = le16_to_cpu(rssi_info_rsp->data_nf_last); @@ -139,9 +138,8 @@ static int mwifiex_ret_802_11_rssi_info(struct mwifiex_private *priv, priv->bcn_nf_avg = le16_to_cpu(rssi_info_rsp->bcn_nf_avg); /* Need to indicate IOCTL complete */ - if (data_buf) { - signal = (struct mwifiex_ds_get_signal *) data_buf; - memset(signal, 0, sizeof(struct mwifiex_ds_get_signal)); + if (signal) { + memset(signal, 0, sizeof(*signal)); signal->selector = ALL_RSSI_INFO_MASK; @@ -185,7 +183,7 @@ static int mwifiex_ret_802_11_rssi_info(struct mwifiex_private *priv, */ static int mwifiex_ret_802_11_snmp_mib(struct mwifiex_private *priv, struct host_cmd_ds_command *resp, - void *data_buf) + u32 *data_buf) { struct host_cmd_ds_802_11_snmp_mib *smib = &resp->params.smib; u16 oid = le16_to_cpu(smib->oid); @@ -198,7 +196,7 @@ static int mwifiex_ret_802_11_snmp_mib(struct mwifiex_private *priv, if (query_type == HostCmd_ACT_GEN_GET) { ul_temp = le16_to_cpu(*((__le16 *) (smib->value))); if (data_buf) - *(u32 *)data_buf = ul_temp; + *data_buf = ul_temp; switch (oid) { case FRAG_THRESH_I: dev_dbg(priv->adapter->dev, @@ -228,14 +226,12 @@ static int mwifiex_ret_802_11_snmp_mib(struct mwifiex_private *priv, */ static int mwifiex_ret_get_log(struct mwifiex_private *priv, struct host_cmd_ds_command *resp, - void *data_buf) + struct mwifiex_ds_get_stats *stats) { struct host_cmd_ds_802_11_get_log *get_log = (struct host_cmd_ds_802_11_get_log *) &resp->params.get_log; - struct mwifiex_ds_get_stats *stats; - if (data_buf) { - stats = (struct mwifiex_ds_get_stats *) data_buf; + if (stats) { stats->mcast_tx_frame = le32_to_cpu(get_log->mcast_tx_frame); stats->failed = le32_to_cpu(get_log->failed); stats->retry = le32_to_cpu(get_log->retry); @@ -278,9 +274,8 @@ static int mwifiex_ret_get_log(struct mwifiex_private *priv, */ static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv, struct host_cmd_ds_command *resp, - void *data_buf) + struct mwifiex_rate_cfg *ds_rate) { - struct mwifiex_rate_cfg *ds_rate; struct host_cmd_ds_tx_rate_cfg *rate_cfg = &resp->params.tx_rate_cfg; struct mwifiex_rate_scope *rate_scope; struct mwifiex_ie_types_header *head; @@ -329,8 +324,7 @@ static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv, HostCmd_CMD_802_11_TX_RATE_QUERY, HostCmd_ACT_GEN_GET, 0, NULL); - if (data_buf) { - ds_rate = (struct mwifiex_rate_cfg *) data_buf; + if (ds_rate) { if (le16_to_cpu(rate_cfg->action) == HostCmd_ACT_GEN_GET) { if (priv->is_data_rate_auto) { ds_rate->is_rate_auto = 1; @@ -413,8 +407,7 @@ static int mwifiex_get_power_level(struct mwifiex_private *priv, void *data_buf) * and saving the current Tx power level in driver. */ static int mwifiex_ret_tx_power_cfg(struct mwifiex_private *priv, - struct host_cmd_ds_command *resp, - void *data_buf) + struct host_cmd_ds_command *resp) { struct mwifiex_adapter *adapter = priv->adapter; struct host_cmd_ds_txpwr_cfg *txp_cfg = &resp->params.txp_cfg; @@ -631,7 +624,7 @@ static int mwifiex_ret_802_11d_domain_info(struct mwifiex_private *priv, */ static int mwifiex_ret_802_11_rf_channel(struct mwifiex_private *priv, struct host_cmd_ds_command *resp, - void *data_buf) + u16 *data_buf) { struct host_cmd_ds_802_11_rf_channel *rf_channel = &resp->params.rf_channel; @@ -644,8 +637,9 @@ static int mwifiex_ret_802_11_rf_channel(struct mwifiex_private *priv, /* Update the channel again */ priv->curr_bss_params.bss_descriptor.channel = new_channel; } + if (data_buf) - *((u16 *)data_buf) = new_channel; + *data_buf = new_channel; return 0; } @@ -658,13 +652,11 @@ static int mwifiex_ret_802_11_rf_channel(struct mwifiex_private *priv, */ static int mwifiex_ret_ver_ext(struct mwifiex_private *priv, struct host_cmd_ds_command *resp, - void *data_buf) + struct host_cmd_ds_version_ext *version_ext) { struct host_cmd_ds_version_ext *ver_ext = &resp->params.verext; - struct host_cmd_ds_version_ext *version_ext; - if (data_buf) { - version_ext = (struct host_cmd_ds_version_ext *)data_buf; + if (version_ext) { version_ext->version_str_sel = ver_ext->version_str_sel; memcpy(version_ext->version_str, ver_ext->version_str, sizeof(char) * 128); @@ -686,8 +678,8 @@ static int mwifiex_ret_reg_access(u16 type, struct host_cmd_ds_command *resp, struct mwifiex_ds_read_eeprom *eeprom; if (data_buf) { - reg_rw = (struct mwifiex_ds_reg_rw *) data_buf; - eeprom = (struct mwifiex_ds_read_eeprom *) data_buf; + reg_rw = data_buf; + eeprom = data_buf; switch (type) { case HostCmd_CMD_MAC_REG_ACCESS: { @@ -825,13 +817,11 @@ static int mwifiex_ret_ibss_coalescing_status(struct mwifiex_private *priv, * This is a generic function, which calls command specific * response handlers based on the command ID. */ -int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, - u16 cmdresp_no, void *cmd_buf) +int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no, + struct host_cmd_ds_command *resp) { int ret = 0; struct mwifiex_adapter *adapter = priv->adapter; - struct host_cmd_ds_command *resp = - (struct host_cmd_ds_command *) cmd_buf; void *data_buf = adapter->curr_cmd->data_buf; /* If the command is not successful, cleanup and return failure */ @@ -865,7 +855,7 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, "info: CMD_RESP: BG_SCAN result is ready!\n"); break; case HostCmd_CMD_TXPWR_CFG: - ret = mwifiex_ret_tx_power_cfg(priv, resp, data_buf); + ret = mwifiex_ret_tx_power_cfg(priv, resp); break; case HostCmd_CMD_802_11_PS_MODE_ENH: ret = mwifiex_ret_enh_power_mode(priv, resp, data_buf); diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index d05907d05039..c34ff8c4f4f8 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c @@ -487,6 +487,20 @@ int mwifiex_set_radio_band_cfg(struct mwifiex_private *priv, } /* + * The function disables auto deep sleep mode. + */ +int mwifiex_disable_auto_ds(struct mwifiex_private *priv) +{ + struct mwifiex_ds_auto_ds auto_ds; + + auto_ds.auto_ds = DEEP_SLEEP_OFF; + + return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_PS_MODE_ENH, + DIS_AUTO_PS, BITMAP_AUTO_DS, &auto_ds); +} +EXPORT_SYMBOL_GPL(mwifiex_disable_auto_ds); + +/* * IOCTL request handler to set/get active channel. * * This function performs validity checking on channel/frequency diff --git a/drivers/net/wireless/mwifiex/sta_rx.c b/drivers/net/wireless/mwifiex/sta_rx.c index 1fdddece7479..27430512f7cd 100644 --- a/drivers/net/wireless/mwifiex/sta_rx.c +++ b/drivers/net/wireless/mwifiex/sta_rx.c @@ -187,7 +187,7 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *adapter, ret = mwifiex_11n_rx_reorder_pkt(priv, local_rx_pd->seq_num, local_rx_pd->priority, ta, (u8) local_rx_pd->rx_pkt_type, - (void *) skb); + skb); if (ret || (rx_pkt_type == PKT_TYPE_BAR)) { if (priv && (ret == -1)) diff --git a/drivers/net/wireless/mwifiex/sta_tx.c b/drivers/net/wireless/mwifiex/sta_tx.c index fa6221bc9104..1822bfad8896 100644 --- a/drivers/net/wireless/mwifiex/sta_tx.c +++ b/drivers/net/wireless/mwifiex/sta_tx.c @@ -47,6 +47,7 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv, struct mwifiex_adapter *adapter = priv->adapter; struct txpd *local_tx_pd; struct mwifiex_txinfo *tx_info = MWIFIEX_SKB_TXCB(skb); + u8 pad; if (!skb->len) { dev_err(adapter->dev, "Tx: bad packet length: %d\n", @@ -55,15 +56,19 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv, return skb->data; } - BUG_ON(skb_headroom(skb) < (sizeof(*local_tx_pd) + INTF_HEADER_LEN)); - skb_push(skb, sizeof(*local_tx_pd)); + /* If skb->data is not aligned; add padding */ + pad = (4 - (((void *)skb->data - NULL) & 0x3)) % 4; + + BUG_ON(skb_headroom(skb) < (sizeof(*local_tx_pd) + INTF_HEADER_LEN + + pad)); + skb_push(skb, sizeof(*local_tx_pd) + pad); local_tx_pd = (struct txpd *) skb->data; memset(local_tx_pd, 0, sizeof(struct txpd)); local_tx_pd->bss_num = priv->bss_num; local_tx_pd->bss_type = priv->bss_type; local_tx_pd->tx_pkt_length = cpu_to_le16((u16) (skb->len - - sizeof(struct txpd))); + (sizeof(struct txpd) + pad))); local_tx_pd->priority = (u8) skb->priority; local_tx_pd->pkt_delay_2ms = @@ -88,7 +93,7 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv, } /* Offset of actual data */ - local_tx_pd->tx_pkt_offset = cpu_to_le16(sizeof(struct txpd)); + local_tx_pd->tx_pkt_offset = cpu_to_le16(sizeof(struct txpd) + pad); /* make space for INTF_HEADER_LEN */ skb_push(skb, INTF_HEADER_LEN); diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c index aaa50c074196..6190b2fa57a3 100644 --- a/drivers/net/wireless/mwifiex/txrx.c +++ b/drivers/net/wireless/mwifiex/txrx.c @@ -71,7 +71,7 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb, u8 *head_ptr; struct txpd *local_tx_pd = NULL; - head_ptr = (u8 *) mwifiex_process_sta_txpd(priv, skb); + head_ptr = mwifiex_process_sta_txpd(priv, skb); if (head_ptr) { if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) local_tx_pd = diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index 91634daec306..69e260b41711 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c @@ -121,6 +121,7 @@ mwifiex_wmm_allocate_ralist_node(struct mwifiex_adapter *adapter, u8 *ra) memcpy(ra_list->ra, ra, ETH_ALEN); ra_list->total_pkts_size = 0; + ra_list->total_pkts = 0; dev_dbg(adapter->dev, "info: allocated ra_list %p\n", ra_list); @@ -633,6 +634,8 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_adapter *adapter, ra_list = NULL; } else { memcpy(ra, skb->data, ETH_ALEN); + if (ra[0] & 0x01) + memset(ra, 0xff, ETH_ALEN); ra_list = mwifiex_wmm_get_queue_raptr(priv, tid_down, ra); } @@ -645,6 +648,7 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_adapter *adapter, skb_queue_tail(&ra_list->skb_head, skb); ra_list->total_pkts_size += skb->len; + ra_list->total_pkts++; atomic_inc(&priv->wmm.tx_pkts_queued); @@ -971,28 +975,6 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter, } /* - * This function gets the number of packets in the Tx queue of a - * particular RA list. - */ -static int -mwifiex_num_pkts_in_txq(struct mwifiex_private *priv, - struct mwifiex_ra_list_tbl *ptr, int max_buf_size) -{ - int count = 0, total_size = 0; - struct sk_buff *skb, *tmp; - - skb_queue_walk_safe(&ptr->skb_head, skb, tmp) { - total_size += skb->len; - if (total_size < max_buf_size) - ++count; - else - break; - } - - return count; -} - -/* * This function sends a single packet to firmware for transmission. */ static void @@ -1019,6 +1001,7 @@ mwifiex_send_single_packet(struct mwifiex_private *priv, dev_dbg(adapter->dev, "data: dequeuing the packet %p %p\n", ptr, skb); ptr->total_pkts_size -= skb->len; + ptr->total_pkts--; if (!skb_queue_empty(&ptr->skb_head)) skb_next = skb_peek(&ptr->skb_head); @@ -1044,6 +1027,7 @@ mwifiex_send_single_packet(struct mwifiex_private *priv, skb_queue_tail(&ptr->skb_head, skb); ptr->total_pkts_size += skb->len; + ptr->total_pkts++; tx_info->flags |= MWIFIEX_BUF_FLAG_REQUEUED_PKT; spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags); @@ -1231,9 +1215,9 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter) } /* Minimum number of AMSDU */ #define MIN_NUM_AMSDU 2 + if (mwifiex_is_amsdu_allowed(priv, tid) && - (mwifiex_num_pkts_in_txq(priv, ptr, adapter->tx_buf_size) >= - MIN_NUM_AMSDU)) + (ptr->total_pkts >= MIN_NUM_AMSDU)) mwifiex_11n_aggregate_pkt(priv, ptr, INTF_HEADER_LEN, ptr_index, flags); /* ra_list_spinlock has been freed in |