/* * This function prepares command to set/get RF channel. * * Preparation includes - * - Setting command ID, action and proper size * - Setting RF type and current RF channel (for SET only) * - Ensuring correct endian-ness */ static int mwifiex_cmd_802_11_rf_channel(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, u16 cmd_action, u16 *channel) { struct host_cmd_ds_802_11_rf_channel *rf_chan = &cmd->params.rf_channel; uint16_t rf_type = le16_to_cpu(rf_chan->rf_type); cmd->command = cpu_to_le16(HostCmd_CMD_802_11_RF_CHANNEL); cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_rf_channel) + S_DS_GEN); if (cmd_action == HostCmd_ACT_GEN_SET) { if ((priv->adapter->adhoc_start_band & BAND_A) || (priv->adapter->adhoc_start_band & BAND_AN)) rf_chan->rf_type = cpu_to_le16(HostCmd_SCAN_RADIO_TYPE_A); rf_type = le16_to_cpu(rf_chan->rf_type); SET_SECONDARYCHAN(rf_type, priv->adapter->chan_offset); rf_chan->current_channel = cpu_to_le16(*channel); } rf_chan->action = cpu_to_le16(cmd_action); return 0; }
/** * @brief This function append the 802_11N tlv * * @param pmpriv A pointer to mlan_private structure * @param pbss_desc A pointer to BSSDescriptor_t structure * @param ppbuffer A Pointer to command buffer pointer * * @return bytes added to the buffer */ int wlan_cmd_append_11n_tlv(IN mlan_private * pmpriv, IN BSSDescriptor_t * pbss_desc, OUT t_u8 ** ppbuffer) { pmlan_adapter pmadapter = pmpriv->adapter; MrvlIETypes_HTCap_t *pht_cap; MrvlIETypes_HTInfo_t *pht_info; MrvlIEtypes_ChanListParamSet_t *pchan_list; MrvlIETypes_2040BSSCo_t *p2040_bss_co; MrvlIETypes_ExtCap_t *pext_cap; int ret_len = 0; ENTER(); /* Null Checks */ if (ppbuffer == 0) { LEAVE(); return 0; } if (*ppbuffer == 0) { LEAVE(); return 0; } if (pbss_desc->pht_cap) { pht_cap = (MrvlIETypes_HTCap_t *) * ppbuffer; memset(pmadapter, pht_cap, 0, sizeof(MrvlIETypes_HTCap_t)); pht_cap->header.type = wlan_cpu_to_le16(HT_CAPABILITY); pht_cap->header.len = sizeof(HTCap_t); memcpy(pmadapter, (t_u8 *) pht_cap + sizeof(MrvlIEtypesHeader_t), (t_u8 *) pbss_desc->pht_cap + sizeof(IEEEtypes_Header_t), pht_cap->header.len); pht_cap->ht_cap.ht_cap_info = wlan_le16_to_cpu(pht_cap->ht_cap.ht_cap_info); wlan_fill_cap_info(pmpriv, pht_cap); pht_cap->ht_cap.ht_cap_info = wlan_cpu_to_le16(pht_cap->ht_cap.ht_cap_info); HEXDUMP("HT_CAPABILITIES IE", (t_u8 *) pht_cap, sizeof(MrvlIETypes_HTCap_t)); *ppbuffer += sizeof(MrvlIETypes_HTCap_t); ret_len += sizeof(MrvlIETypes_HTCap_t); pht_cap->header.len = wlan_cpu_to_le16(pht_cap->header.len); } if (pbss_desc->pht_info) { if (pmpriv->bss_mode == MLAN_BSS_MODE_IBSS) { pht_info = (MrvlIETypes_HTInfo_t *) * ppbuffer; memset(pmadapter, pht_info, 0, sizeof(MrvlIETypes_HTInfo_t)); pht_info->header.type = wlan_cpu_to_le16(HT_OPERATION); pht_info->header.len = sizeof(HTInfo_t); memcpy(pmadapter, (t_u8 *) pht_info + sizeof(MrvlIEtypesHeader_t), (t_u8 *) pbss_desc->pht_info + sizeof(IEEEtypes_Header_t), pht_info->header.len); if (!ISSUPP_CHANWIDTH40(pmadapter->hw_dot_11n_dev_cap) || !ISSUPP_CHANWIDTH40(pmadapter->usr_dot_11n_dev_cap)) { RESET_CHANWIDTH40(pht_info->ht_info.field2); } *ppbuffer += sizeof(MrvlIETypes_HTInfo_t); ret_len += sizeof(MrvlIETypes_HTInfo_t); pht_info->header.len = wlan_cpu_to_le16(pht_info->header.len); } pchan_list = (MrvlIEtypes_ChanListParamSet_t *) * ppbuffer; memset(pmadapter, pchan_list, 0, sizeof(MrvlIEtypes_ChanListParamSet_t)); pchan_list->header.type = wlan_cpu_to_le16(TLV_TYPE_CHANLIST); pchan_list->header.len = sizeof(MrvlIEtypes_ChanListParamSet_t) - sizeof(MrvlIEtypesHeader_t); pchan_list->chan_scan_param[0].chan_number = pbss_desc->pht_info->ht_info.pri_chan; pchan_list->chan_scan_param[0].radio_type = wlan_band_to_radio_type((t_u8) pbss_desc->bss_band); if ((ISSUPP_CHANWIDTH40(pmadapter->hw_dot_11n_dev_cap) && ISSUPP_CHANWIDTH40(pmadapter->usr_dot_11n_dev_cap)) && ISALLOWED_CHANWIDTH40(pbss_desc->pht_info->ht_info.field2)) SET_SECONDARYCHAN(pchan_list->chan_scan_param[0].radio_type, GET_SECONDARYCHAN(pbss_desc->pht_info->ht_info. field2)); HEXDUMP("ChanList", (t_u8 *) pchan_list, sizeof(MrvlIEtypes_ChanListParamSet_t)); HEXDUMP("pht_info", (t_u8 *) pbss_desc->pht_info, sizeof(MrvlIETypes_HTInfo_t) - 2); *ppbuffer += sizeof(MrvlIEtypes_ChanListParamSet_t); ret_len += sizeof(MrvlIEtypes_ChanListParamSet_t); pchan_list->header.len = wlan_cpu_to_le16(pchan_list->header.len); } if (pbss_desc->pbss_co_2040) { p2040_bss_co = (MrvlIETypes_2040BSSCo_t *) * ppbuffer; memset(pmadapter, p2040_bss_co, 0, sizeof(MrvlIETypes_2040BSSCo_t)); p2040_bss_co->header.type = wlan_cpu_to_le16(BSSCO_2040); p2040_bss_co->header.len = sizeof(BSSCo2040_t); memcpy(pmadapter, (t_u8 *) p2040_bss_co + sizeof(MrvlIEtypesHeader_t), (t_u8 *) pbss_desc->pbss_co_2040 + sizeof(IEEEtypes_Header_t), p2040_bss_co->header.len); HEXDUMP("20/40 BSS Coexistence IE", (t_u8 *) p2040_bss_co, sizeof(MrvlIETypes_2040BSSCo_t)); *ppbuffer += sizeof(MrvlIETypes_2040BSSCo_t); ret_len += sizeof(MrvlIETypes_2040BSSCo_t); p2040_bss_co->header.len = wlan_cpu_to_le16(p2040_bss_co->header.len); } if (pbss_desc->pext_cap) { pext_cap = (MrvlIETypes_ExtCap_t *) * ppbuffer; memset(pmadapter, pext_cap, 0, sizeof(MrvlIETypes_ExtCap_t)); pext_cap->header.type = wlan_cpu_to_le16(EXT_CAPABILITY); pext_cap->header.len = sizeof(ExtCap_t); memcpy(pmadapter, (t_u8 *) pext_cap + sizeof(MrvlIEtypesHeader_t), (t_u8 *) pbss_desc->pext_cap + sizeof(IEEEtypes_Header_t), pext_cap->header.len); HEXDUMP("Extended Capabilities IE", (t_u8 *) pext_cap, sizeof(MrvlIETypes_ExtCap_t)); *ppbuffer += sizeof(MrvlIETypes_ExtCap_t); ret_len += sizeof(MrvlIETypes_ExtCap_t); pext_cap->header.len = wlan_cpu_to_le16(pext_cap->header.len); } LEAVE(); return ret_len; }