コード例 #1
0
ファイル: sta_ioctl.c プロジェクト: 513855417/linux
/*
 * IOCTL request handler to set/reset WPA IE.
 *
 * The supplied WPA IE is treated as a opaque buffer. Only the first field
 * is checked to determine WPA version. If buffer length is zero, the existing
 * WPA IE is reset.
 */
static int mwifiex_set_wpa_ie_helper(struct mwifiex_private *priv,
				     u8 *ie_data_ptr, u16 ie_len)
{
	if (ie_len) {
		if (ie_len > sizeof(priv->wpa_ie)) {
			mwifiex_dbg(priv->adapter, ERROR,
				    "failed to copy WPA IE, too big\n");
			return -1;
		}
		memcpy(priv->wpa_ie, ie_data_ptr, ie_len);
		priv->wpa_ie_len = ie_len;
		mwifiex_dbg(priv->adapter, CMD,
			    "cmd: Set Wpa_ie_len=%d IE=%#x\n",
			    priv->wpa_ie_len, priv->wpa_ie[0]);

		if (priv->wpa_ie[0] == WLAN_EID_VENDOR_SPECIFIC) {
			priv->sec_info.wpa_enabled = true;
		} else if (priv->wpa_ie[0] == WLAN_EID_RSN) {
			priv->sec_info.wpa2_enabled = true;
		} else {
			priv->sec_info.wpa_enabled = false;
			priv->sec_info.wpa2_enabled = false;
		}
	} else {
		memset(priv->wpa_ie, 0, sizeof(priv->wpa_ie));
		priv->wpa_ie_len = 0;
		mwifiex_dbg(priv->adapter, INFO,
			    "info: reset wpa_ie_len=%d IE=%#x\n",
			    priv->wpa_ie_len, priv->wpa_ie[0]);
		priv->sec_info.wpa_enabled = false;
		priv->sec_info.wpa2_enabled = false;
	}

	return 0;
}
コード例 #2
0
ファイル: sta_ioctl.c プロジェクト: 513855417/linux
/*
 * IOCTL request handler to set/get generic IE.
 *
 * In addition to various generic IEs, this function can also be
 * used to set the ARP filter.
 */
static int mwifiex_misc_ioctl_gen_ie(struct mwifiex_private *priv,
				     struct mwifiex_ds_misc_gen_ie *gen_ie,
				     u16 action)
{
	struct mwifiex_adapter *adapter = priv->adapter;

	switch (gen_ie->type) {
	case MWIFIEX_IE_TYPE_GEN_IE:
		if (action == HostCmd_ACT_GEN_GET) {
			gen_ie->len = priv->wpa_ie_len;
			memcpy(gen_ie->ie_data, priv->wpa_ie, gen_ie->len);
		} else {
			mwifiex_set_gen_ie_helper(priv, gen_ie->ie_data,
						  (u16) gen_ie->len);
		}
		break;
	case MWIFIEX_IE_TYPE_ARP_FILTER:
		memset(adapter->arp_filter, 0, sizeof(adapter->arp_filter));
		if (gen_ie->len > ARP_FILTER_MAX_BUF_SIZE) {
			adapter->arp_filter_size = 0;
			mwifiex_dbg(adapter, ERROR,
				    "invalid ARP filter size\n");
			return -1;
		} else {
			memcpy(adapter->arp_filter, gen_ie->ie_data,
			       gen_ie->len);
			adapter->arp_filter_size = gen_ie->len;
		}
		break;
	default:
		mwifiex_dbg(adapter, ERROR, "invalid IE type\n");
		return -1;
	}
	return 0;
}
コード例 #3
0
ファイル: sta_ioctl.c プロジェクト: 513855417/linux
/*
 * IOCTL request handler to set/reset WPS IE.
 *
 * The supplied WPS IE is treated as a opaque buffer. Only the first field
 * is checked to internally enable WPS. If buffer length is zero, the existing
 * WPS IE is reset.
 */
static int mwifiex_set_wps_ie(struct mwifiex_private *priv,
			       u8 *ie_data_ptr, u16 ie_len)
{
	if (ie_len) {
		if (ie_len > MWIFIEX_MAX_VSIE_LEN) {
			mwifiex_dbg(priv->adapter, ERROR,
				    "info: failed to copy WPS IE, too big\n");
			return -1;
		}

		priv->wps_ie = kzalloc(MWIFIEX_MAX_VSIE_LEN, GFP_KERNEL);
		if (!priv->wps_ie)
			return -ENOMEM;

		memcpy(priv->wps_ie, ie_data_ptr, ie_len);
		priv->wps_ie_len = ie_len;
		mwifiex_dbg(priv->adapter, CMD,
			    "cmd: Set wps_ie_len=%d IE=%#x\n",
			    priv->wps_ie_len, priv->wps_ie[0]);
	} else {
		kfree(priv->wps_ie);
		priv->wps_ie_len = ie_len;
		mwifiex_dbg(priv->adapter, INFO,
			    "info: Reset wps_ie_len=%d\n", priv->wps_ie_len);
	}
	return 0;
}
コード例 #4
0
ファイル: 11h.c プロジェクト: AlexShiLucky/linux
/* This function prepares channel report request command to FW for
 * starting radar detection.
 */
int mwifiex_cmd_issue_chan_report_request(struct mwifiex_private *priv,
					  struct host_cmd_ds_command *cmd,
					  void *data_buf)
{
	struct host_cmd_ds_chan_rpt_req *cr_req = &cmd->params.chan_rpt_req;
	struct mwifiex_radar_params *radar_params = (void *)data_buf;

	cmd->command = cpu_to_le16(HostCmd_CMD_CHAN_REPORT_REQUEST);
	cmd->size = cpu_to_le16(S_DS_GEN);
	le16_unaligned_add_cpu(&cmd->size,
			       sizeof(struct host_cmd_ds_chan_rpt_req));

	cr_req->chan_desc.start_freq = cpu_to_le16(MWIFIEX_A_BAND_START_FREQ);
	cr_req->chan_desc.chan_num = radar_params->chandef->chan->hw_value;
	cr_req->chan_desc.chan_width = radar_params->chandef->width;
	cr_req->msec_dwell_time = cpu_to_le32(radar_params->cac_time_ms);

	if (radar_params->cac_time_ms)
		mwifiex_dbg(priv->adapter, MSG,
			    "11h: issuing DFS Radar check for channel=%d\n",
			    radar_params->chandef->chan->hw_value);
	else
		mwifiex_dbg(priv->adapter, MSG, "cancelling CAC\n");

	return 0;
}
コード例 #5
0
ファイル: init.c プロジェクト: OSPro/wpj344_compatwireless
/*
 * This function allocates buffers for members of the adapter
 * structure.
 *
 * The memory allocated includes scan table, command buffers, and
 * sleep confirm command buffer. In addition, the queues are
 * also initialized.
 */
static int mwifiex_allocate_adapter(struct mwifiex_adapter *adapter)
{
	int ret;

	/* Allocate command buffer */
	ret = mwifiex_alloc_cmd_buffer(adapter);
	if (ret) {
		mwifiex_dbg(adapter, ERROR,
			    "%s: failed to alloc cmd buffer\n",
			    __func__);
		return -1;
	}

	adapter->sleep_cfm =
		dev_alloc_skb(sizeof(struct mwifiex_opt_sleep_confirm)
			      + INTF_HEADER_LEN);

	if (!adapter->sleep_cfm) {
		mwifiex_dbg(adapter, ERROR,
			    "%s: failed to alloc sleep cfm\t"
			    " cmd buffer\n", __func__);
		return -1;
	}
	skb_reserve(adapter->sleep_cfm, INTF_HEADER_LEN);

	return 0;
}
コード例 #6
0
ファイル: sta_cmdresp.c プロジェクト: mkrufky/linux
/*
 * This function handles the command response of set rf antenna
 */
static int mwifiex_ret_rf_antenna(struct mwifiex_private *priv,
				  struct host_cmd_ds_command *resp)
{
	struct host_cmd_ds_rf_ant_mimo *ant_mimo = &resp->params.ant_mimo;
	struct host_cmd_ds_rf_ant_siso *ant_siso = &resp->params.ant_siso;
	struct mwifiex_adapter *adapter = priv->adapter;

	if (adapter->hw_dev_mcs_support == HT_STREAM_2X2) {
		priv->tx_ant = le16_to_cpu(ant_mimo->tx_ant_mode);
		priv->rx_ant = le16_to_cpu(ant_mimo->rx_ant_mode);
		mwifiex_dbg(adapter, INFO,
			    "RF_ANT_RESP: Tx action = 0x%x, Tx Mode = 0x%04x\t"
			    "Rx action = 0x%x, Rx Mode = 0x%04x\n",
			    le16_to_cpu(ant_mimo->action_tx),
			    le16_to_cpu(ant_mimo->tx_ant_mode),
			    le16_to_cpu(ant_mimo->action_rx),
			    le16_to_cpu(ant_mimo->rx_ant_mode));
	} else {
		priv->tx_ant = le16_to_cpu(ant_siso->ant_mode);
		priv->rx_ant = le16_to_cpu(ant_siso->ant_mode);
		mwifiex_dbg(adapter, INFO,
			    "RF_ANT_RESP: action = 0x%x, Mode = 0x%04x\n",
			    le16_to_cpu(ant_siso->action),
			    le16_to_cpu(ant_siso->ant_mode));
	}
	return 0;
}
コード例 #7
0
ファイル: 11h.c プロジェクト: AlexShiLucky/linux
/* This is work queue function for channel switch handling.
 * This function takes care of updating new channel definitin to
 * bss config structure, restart AP and indicate channel switch success
 * to cfg80211.
 */
void mwifiex_dfs_chan_sw_work_queue(struct work_struct *work)
{
	struct mwifiex_uap_bss_param *bss_cfg;
	struct delayed_work *delayed_work = to_delayed_work(work);
	struct mwifiex_private *priv =
			container_of(delayed_work, struct mwifiex_private,
				     dfs_chan_sw_work);

	bss_cfg = &priv->bss_cfg;
	if (!bss_cfg->beacon_period) {
		mwifiex_dbg(priv->adapter, ERROR,
			    "channel switch: AP already stopped\n");
		return;
	}

	mwifiex_uap_set_channel(priv, bss_cfg, priv->dfs_chandef);

	if (mwifiex_config_start_uap(priv, bss_cfg)) {
		mwifiex_dbg(priv->adapter, ERROR,
			    "Failed to start AP after channel switch\n");
		return;
	}

	mwifiex_dbg(priv->adapter, MSG,
		    "indicating channel switch completion to kernel\n");
	cfg80211_ch_switch_notify(priv->netdev, &priv->dfs_chandef);
}
コード例 #8
0
ファイル: sta_ioctl.c プロジェクト: 513855417/linux
/*
 * IOCTL request handler to set/reset WAPI IE.
 *
 * The supplied WAPI IE is treated as a opaque buffer. Only the first field
 * is checked to internally enable WAPI. If buffer length is zero, the existing
 * WAPI IE is reset.
 */
static int mwifiex_set_wapi_ie(struct mwifiex_private *priv,
			       u8 *ie_data_ptr, u16 ie_len)
{
	if (ie_len) {
		if (ie_len > sizeof(priv->wapi_ie)) {
			mwifiex_dbg(priv->adapter, ERROR,
				    "info: failed to copy WAPI IE, too big\n");
			return -1;
		}
		memcpy(priv->wapi_ie, ie_data_ptr, ie_len);
		priv->wapi_ie_len = ie_len;
		mwifiex_dbg(priv->adapter, CMD,
			    "cmd: Set wapi_ie_len=%d IE=%#x\n",
			    priv->wapi_ie_len, priv->wapi_ie[0]);

		if (priv->wapi_ie[0] == WLAN_EID_BSS_AC_ACCESS_DELAY)
			priv->sec_info.wapi_enabled = true;
	} else {
		memset(priv->wapi_ie, 0, sizeof(priv->wapi_ie));
		priv->wapi_ie_len = ie_len;
		mwifiex_dbg(priv->adapter, INFO,
			    "info: Reset wapi_ie_len=%d IE=%#x\n",
			    priv->wapi_ie_len, priv->wapi_ie[0]);
		priv->sec_info.wapi_enabled = false;
	}
	return 0;
}
コード例 #9
0
ファイル: usb.c プロジェクト: ReneNyffenegger/linux
/* Kernel needs to suspend all functions separately. Therefore all
 * registered functions must have drivers with suspend and resume
 * methods. Failing that the kernel simply removes the whole card.
 *
 * If already not suspended, this function allocates and sends a
 * 'host sleep activate' request to the firmware and turns off the traffic.
 */
static int mwifiex_usb_suspend(struct usb_interface *intf, pm_message_t message)
{
	struct usb_card_rec *card = usb_get_intfdata(intf);
	struct mwifiex_adapter *adapter;
	struct usb_tx_data_port *port;
	int i, j;

	/* Might still be loading firmware */
	wait_for_completion(&card->fw_done);

	adapter = card->adapter;
	if (!adapter) {
		dev_err(&intf->dev, "card is not valid\n");
		return 0;
	}

	if (unlikely(adapter->is_suspended))
		mwifiex_dbg(adapter, WARN,
			    "Device already suspended\n");

	/* Enable the Host Sleep */
	if (!mwifiex_enable_hs(adapter)) {
		mwifiex_dbg(adapter, ERROR,
			    "cmd: failed to suspend\n");
		adapter->hs_enabling = false;
		return -EFAULT;
	}


	/* 'is_suspended' flag indicates device is suspended.
	 * It must be set here before the usb_kill_urb() calls. Reason
	 * is in the complete handlers, urb->status(= -ENOENT) and
	 * this flag is used in combination to distinguish between a
	 * 'suspended' state and a 'disconnect' one.
	 */
	adapter->is_suspended = true;
	adapter->hs_enabling = false;

	if (atomic_read(&card->rx_cmd_urb_pending) && card->rx_cmd.urb)
		usb_kill_urb(card->rx_cmd.urb);

	if (atomic_read(&card->rx_data_urb_pending))
		for (i = 0; i < MWIFIEX_RX_DATA_URB; i++)
			if (card->rx_data_list[i].urb)
				usb_kill_urb(card->rx_data_list[i].urb);

	for (i = 0; i < MWIFIEX_TX_DATA_PORT; i++) {
		port = &card->port[i];
		for (j = 0; j < MWIFIEX_TX_DATA_URB; j++) {
			if (port->tx_data_list[j].urb)
				usb_kill_urb(port->tx_data_list[j].urb);
		}
	}

	if (card->tx_cmd.urb)
		usb_kill_urb(card->tx_cmd.urb);

	return 0;
}
コード例 #10
0
ファイル: sta_event.c プロジェクト: AlexShiLucky/linux
static void
mwifiex_fw_dump_info_event(struct mwifiex_private *priv,
			   struct sk_buff *event_skb)
{
	struct mwifiex_adapter *adapter = priv->adapter;
	struct mwifiex_fw_dump_header *fw_dump_hdr =
				(void *)adapter->event_body;

	if (adapter->iface_type != MWIFIEX_USB) {
		mwifiex_dbg(adapter, MSG,
			    "event is not on usb interface, ignore it\n");
		return;
	}

	if (!adapter->devdump_data) {
		/* When receive the first event, allocate device dump
		 * buffer, dump driver info.
		 */
		adapter->devdump_data = vzalloc(MWIFIEX_FW_DUMP_SIZE);
		if (!adapter->devdump_data) {
			mwifiex_dbg(adapter, ERROR,
				    "vzalloc devdump data failure!\n");
			return;
		}

		mwifiex_drv_info_dump(adapter);

		/* If no proceeded event arrive in 10s, upload device
		 * dump data, this will be useful if the end of
		 * transmission event get lost, in this cornel case,
		 * user would still get partial of the dump.
		 */
		mod_timer(&adapter->devdump_timer,
			  jiffies + msecs_to_jiffies(MWIFIEX_TIMER_10S));
	}

	/* Overflow check */
	if (adapter->devdump_len + event_skb->len >= MWIFIEX_FW_DUMP_SIZE)
		goto upload_dump;

	memmove(adapter->devdump_data + adapter->devdump_len,
		adapter->event_skb->data, event_skb->len);
	adapter->devdump_len += event_skb->len;

	if (le16_to_cpu(fw_dump_hdr->type == FW_DUMP_INFO_ENDED)) {
		mwifiex_dbg(adapter, MSG,
			    "receive end of transmission flag event!\n");
		goto upload_dump;
	}
	return;

upload_dump:
	del_timer_sync(&adapter->devdump_timer);
	mwifiex_upload_device_dump(adapter);
}
コード例 #11
0
ファイル: sta_cmdresp.c プロジェクト: mkrufky/linux
/*
 * This function handles the command response error case.
 *
 * For scan response error, the function cancels all the pending
 * scan commands and generates an event to inform the applications
 * of the scan completion.
 *
 * For Power Save command failure, we do not retry enter PS
 * command in case of Ad-hoc mode.
 *
 * For all other response errors, the current command buffer is freed
 * and returned to the free command queue.
 */
static void
mwifiex_process_cmdresp_error(struct mwifiex_private *priv,
			      struct host_cmd_ds_command *resp)
{
	struct mwifiex_adapter *adapter = priv->adapter;
	struct host_cmd_ds_802_11_ps_mode_enh *pm;
	unsigned long flags;

	mwifiex_dbg(adapter, ERROR,
		    "CMD_RESP: cmd %#x error, result=%#x\n",
		    resp->command, resp->result);

	if (adapter->curr_cmd->wait_q_enabled)
		adapter->cmd_wait_q.status = -1;

	switch (le16_to_cpu(resp->command)) {
	case HostCmd_CMD_802_11_PS_MODE_ENH:
		pm = &resp->params.psmode_enh;
		mwifiex_dbg(adapter, ERROR,
			    "PS_MODE_ENH cmd failed: result=0x%x action=0x%X\n",
			    resp->result, le16_to_cpu(pm->action));
		/* We do not re-try enter-ps command in ad-hoc mode. */
		if (le16_to_cpu(pm->action) == EN_AUTO_PS &&
		    (le16_to_cpu(pm->params.ps_bitmap) & BITMAP_STA_PS) &&
		    priv->bss_mode == NL80211_IFTYPE_ADHOC)
			adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM;

		break;
	case HostCmd_CMD_802_11_SCAN:
	case HostCmd_CMD_802_11_SCAN_EXT:
		mwifiex_cancel_pending_scan_cmd(adapter);

		spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
		adapter->scan_processing = false;
		spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
		break;

	case HostCmd_CMD_MAC_CONTROL:
		break;

	case HostCmd_CMD_SDIO_SP_RX_AGGR_CFG:
		mwifiex_dbg(adapter, MSG,
			    "SDIO RX single-port aggregation Not support\n");
		break;

	default:
		break;
	}
	/* Handling errors here */
	mwifiex_recycle_cmd_node(adapter, adapter->curr_cmd);

	spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
	adapter->curr_cmd = NULL;
	spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
}
コード例 #12
0
ファイル: sta_ioctl.c プロジェクト: 513855417/linux
static int mwifiex_process_country_ie(struct mwifiex_private *priv,
				      struct cfg80211_bss *bss)
{
	const u8 *country_ie;
	u8 country_ie_len;
	struct mwifiex_802_11d_domain_reg *domain_info =
					&priv->adapter->domain_reg;

	rcu_read_lock();
	country_ie = ieee80211_bss_get_ie(bss, WLAN_EID_COUNTRY);
	if (!country_ie) {
		rcu_read_unlock();
		return 0;
	}

	country_ie_len = country_ie[1];
	if (country_ie_len < IEEE80211_COUNTRY_IE_MIN_LEN) {
		rcu_read_unlock();
		return 0;
	}

	if (!strncmp(priv->adapter->country_code, &country_ie[2], 2)) {
		rcu_read_unlock();
		mwifiex_dbg(priv->adapter, INFO,
			    "11D: skip setting domain info in FW\n");
		return 0;
	}
	memcpy(priv->adapter->country_code, &country_ie[2], 2);

	domain_info->country_code[0] = country_ie[2];
	domain_info->country_code[1] = country_ie[3];
	domain_info->country_code[2] = ' ';

	country_ie_len -= IEEE80211_COUNTRY_STRING_LEN;

	domain_info->no_of_triplet =
		country_ie_len / sizeof(struct ieee80211_country_ie_triplet);

	memcpy((u8 *)domain_info->triplet,
	       &country_ie[2] + IEEE80211_COUNTRY_STRING_LEN, country_ie_len);

	rcu_read_unlock();

	if (mwifiex_send_cmd(priv, HostCmd_CMD_802_11D_DOMAIN_INFO,
			     HostCmd_ACT_GEN_SET, 0, NULL, false)) {
		mwifiex_dbg(priv->adapter, ERROR,
			    "11D: setting domain info in FW fail\n");
		return -1;
	}

	mwifiex_dnld_txpwr_table(priv);

	return 0;
}
コード例 #13
0
ファイル: init.c プロジェクト: 513855417/linux
/*
 * This function downloads the firmware to the card.
 *
 * The actual download is preceded by two sanity checks -
 *      - Check if firmware is already running
 *      - Check if the interface is the winner to download the firmware
 *
 * ...and followed by another -
 *      - Check if the firmware is downloaded successfully
 *
 * After download is successfully completed, the host interrupts are enabled.
 */
int mwifiex_dnld_fw(struct mwifiex_adapter *adapter,
		    struct mwifiex_fw_image *pmfw)
{
	int ret;
	u32 poll_num = 1;

	if (adapter->if_ops.check_fw_status) {
		/* check if firmware is already running */
		ret = adapter->if_ops.check_fw_status(adapter, poll_num);
		if (!ret) {
			mwifiex_dbg(adapter, MSG,
				    "WLAN FW already running! Skip FW dnld\n");
			return 0;
		}
	}

	/* check if we are the winner for downloading FW */
	if (adapter->if_ops.check_winner_status) {
		adapter->winner = 0;
		ret = adapter->if_ops.check_winner_status(adapter);

		poll_num = MAX_FIRMWARE_POLL_TRIES;
		if (ret) {
			mwifiex_dbg(adapter, MSG,
				    "WLAN read winner status failed!\n");
			return ret;
		}

		if (!adapter->winner) {
			mwifiex_dbg(adapter, MSG,
				    "WLAN is not the winner! Skip FW dnld\n");
			goto poll_fw;
		}
	}

	if (pmfw) {
		/* Download firmware with helper */
		ret = adapter->if_ops.prog_fw(adapter, pmfw);
		if (ret) {
			mwifiex_dbg(adapter, ERROR,
				    "prog_fw failed ret=%#x\n", ret);
			return ret;
		}
	}

poll_fw:
	/* Check if the firmware is downloaded successfully or not */
	ret = adapter->if_ops.check_fw_status(adapter, poll_num);
	if (ret)
		mwifiex_dbg(adapter, ERROR,
			    "FW failed to be active in time\n");

	return ret;
}
コード例 #14
0
ファイル: 11h.c プロジェクト: AlexShiLucky/linux
/* This function is to abort ongoing CAC upon stopping AP operations
 * or during unload.
 */
void mwifiex_abort_cac(struct mwifiex_private *priv)
{
	if (priv->wdev.cac_started) {
		if (mwifiex_stop_radar_detection(priv, &priv->dfs_chandef))
			mwifiex_dbg(priv->adapter, ERROR,
				    "failed to stop CAC in FW\n");
		mwifiex_dbg(priv->adapter, MSG,
			    "Aborting delayed work for CAC.\n");
		cancel_delayed_work_sync(&priv->dfs_cac_work);
		cfg80211_cac_event(priv->netdev, &priv->dfs_chandef,
				   NL80211_RADAR_CAC_ABORTED, GFP_KERNEL);
	}
}
コード例 #15
0
ファイル: sta_cmdresp.c プロジェクト: mkrufky/linux
/*
 * This function handles the command response of set/get Tx power
 * configurations.
 *
 * Handling includes changing the header fields into CPU format
 * 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)
{
	struct mwifiex_adapter *adapter = priv->adapter;
	struct host_cmd_ds_txpwr_cfg *txp_cfg = &resp->params.txp_cfg;
	struct mwifiex_types_power_group *pg_tlv_hdr;
	struct mwifiex_power_group *pg;
	u16 action = le16_to_cpu(txp_cfg->action);
	u16 tlv_buf_left;

	pg_tlv_hdr = (struct mwifiex_types_power_group *)
		((u8 *)txp_cfg +
		 sizeof(struct host_cmd_ds_txpwr_cfg));

	pg = (struct mwifiex_power_group *)
		((u8 *)pg_tlv_hdr +
		 sizeof(struct mwifiex_types_power_group));

	tlv_buf_left = le16_to_cpu(resp->size) - S_DS_GEN - sizeof(*txp_cfg);
	if (tlv_buf_left <
			le16_to_cpu(pg_tlv_hdr->length) + sizeof(*pg_tlv_hdr))
		return 0;

	switch (action) {
	case HostCmd_ACT_GEN_GET:
		if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING)
			mwifiex_get_power_level(priv, pg_tlv_hdr);

		priv->tx_power_level = (u16) pg->power_min;
		break;

	case HostCmd_ACT_GEN_SET:
		if (!le32_to_cpu(txp_cfg->mode))
			break;

		if (pg->power_max == pg->power_min)
			priv->tx_power_level = (u16) pg->power_min;
		break;
	default:
		mwifiex_dbg(adapter, ERROR,
			    "CMD_RESP: unknown cmd action %d\n",
			    action);
		return 0;
	}
	mwifiex_dbg(adapter, INFO,
		    "info: Current TxPower Level = %d, Max Power=%d, Min Power=%d\n",
		    priv->tx_power_level, priv->max_tx_power_level,
		    priv->min_tx_power_level);

	return 0;
}
コード例 #16
0
ファイル: sta_cmdresp.c プロジェクト: mkrufky/linux
static int mwifiex_ret_tdls_oper(struct mwifiex_private *priv,
				 struct host_cmd_ds_command *resp)
{
	struct host_cmd_ds_tdls_oper *cmd_tdls_oper = &resp->params.tdls_oper;
	u16 reason = le16_to_cpu(cmd_tdls_oper->reason);
	u16 action = le16_to_cpu(cmd_tdls_oper->tdls_action);
	struct mwifiex_sta_node *node =
			   mwifiex_get_sta_entry(priv, cmd_tdls_oper->peer_mac);

	switch (action) {
	case ACT_TDLS_DELETE:
		if (reason) {
			if (!node || reason == TDLS_ERR_LINK_NONEXISTENT)
				mwifiex_dbg(priv->adapter, MSG,
					    "TDLS link delete for %pM failed: reason %d\n",
					    cmd_tdls_oper->peer_mac, reason);
			else
				mwifiex_dbg(priv->adapter, ERROR,
					    "TDLS link delete for %pM failed: reason %d\n",
					    cmd_tdls_oper->peer_mac, reason);
		} else {
			mwifiex_dbg(priv->adapter, MSG,
				    "TDLS link delete for %pM successful\n",
				    cmd_tdls_oper->peer_mac);
		}
		break;
	case ACT_TDLS_CREATE:
		if (reason) {
			mwifiex_dbg(priv->adapter, ERROR,
				    "TDLS link creation for %pM failed: reason %d",
				    cmd_tdls_oper->peer_mac, reason);
			if (node && reason != TDLS_ERR_LINK_EXISTS)
				node->tdls_status = TDLS_SETUP_FAILURE;
		} else {
			mwifiex_dbg(priv->adapter, MSG,
				    "TDLS link creation for %pM successful",
				    cmd_tdls_oper->peer_mac);
		}
		break;
	case ACT_TDLS_CONFIG:
		if (reason) {
			mwifiex_dbg(priv->adapter, ERROR,
				    "TDLS link config for %pM failed, reason %d\n",
				    cmd_tdls_oper->peer_mac, reason);
			if (node)
				node->tdls_status = TDLS_SETUP_FAILURE;
		} else {
			mwifiex_dbg(priv->adapter, MSG,
				    "TDLS link config for %pM successful\n",
				    cmd_tdls_oper->peer_mac);
		}
		break;
	default:
		mwifiex_dbg(priv->adapter, ERROR,
			    "Unknown TDLS command action response %d", action);
		return -1;
	}

	return 0;
}
コード例 #17
0
ファイル: sta_cmdresp.c プロジェクト: mkrufky/linux
/*
 * This function handles the command response of set/get v2 key material.
 *
 * Handling includes updating the driver parameters to reflect the
 * changes.
 */
static int mwifiex_ret_802_11_key_material_v2(struct mwifiex_private *priv,
					      struct host_cmd_ds_command *resp)
{
	struct host_cmd_ds_802_11_key_material_v2 *key_v2;
	__le16 len;

	key_v2 = &resp->params.key_material_v2;
	if (le16_to_cpu(key_v2->action) == HostCmd_ACT_GEN_SET) {
		if ((le16_to_cpu(key_v2->key_param_set.key_info) & KEY_MCAST)) {
			mwifiex_dbg(priv->adapter, INFO, "info: key: GTK is set\n");
			priv->wpa_is_gtk_set = true;
			priv->scan_block = false;
			priv->port_open = true;
		}
	}

	if (key_v2->key_param_set.key_type != KEY_TYPE_ID_AES)
		return 0;

	memset(priv->aes_key_v2.key_param_set.key_params.aes.key, 0,
	       WLAN_KEY_LEN_CCMP);
	priv->aes_key_v2.key_param_set.key_params.aes.key_len =
				key_v2->key_param_set.key_params.aes.key_len;
	len = priv->aes_key_v2.key_param_set.key_params.aes.key_len;
	memcpy(priv->aes_key_v2.key_param_set.key_params.aes.key,
	       key_v2->key_param_set.key_params.aes.key, le16_to_cpu(len));

	return 0;
}
コード例 #18
0
ファイル: usb.c プロジェクト: ReneNyffenegger/linux
static void mwifiex_usb_disconnect(struct usb_interface *intf)
{
	struct usb_card_rec *card = usb_get_intfdata(intf);
	struct mwifiex_adapter *adapter;

	wait_for_completion(&card->fw_done);

	adapter = card->adapter;
	if (!adapter || !adapter->priv_num)
		return;

	if (card->udev->state != USB_STATE_NOTATTACHED && !adapter->mfg_mode) {
		mwifiex_deauthenticate_all(adapter);

		mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter,
							  MWIFIEX_BSS_ROLE_ANY),
					 MWIFIEX_FUNC_SHUTDOWN);
	}

	mwifiex_usb_free(card);

	mwifiex_dbg(adapter, FATAL,
		    "%s: removing card\n", __func__);
	mwifiex_remove_card(adapter);

	usb_put_dev(interface_to_usbdev(intf));
}
コード例 #19
0
ファイル: sta_event.c プロジェクト: AlexShiLucky/linux
static void mwifiex_process_uap_tx_pause(struct mwifiex_private *priv,
					 struct mwifiex_ie_types_header *tlv)
{
	struct mwifiex_tx_pause_tlv *tp;
	struct mwifiex_sta_node *sta_ptr;
	unsigned long flags;

	tp = (void *)tlv;
	mwifiex_dbg(priv->adapter, EVENT,
		    "uap tx_pause: %pM pause=%d, pkts=%d\n",
		    tp->peermac, tp->tx_pause,
		    tp->pkt_cnt);

	if (ether_addr_equal(tp->peermac, priv->netdev->dev_addr)) {
		if (tp->tx_pause)
			priv->port_open = false;
		else
			priv->port_open = true;
	} else if (is_multicast_ether_addr(tp->peermac)) {
		mwifiex_update_ralist_tx_pause(priv, tp->peermac, tp->tx_pause);
	} else {
		spin_lock_irqsave(&priv->sta_list_spinlock, flags);
		sta_ptr = mwifiex_get_sta_entry(priv, tp->peermac);
		if (sta_ptr && sta_ptr->tx_pause != tp->tx_pause) {
			sta_ptr->tx_pause = tp->tx_pause;
			mwifiex_update_ralist_tx_pause(priv, tp->peermac,
						       tp->tx_pause);
		}
		spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
	}
}
コード例 #20
0
ファイル: sta_ioctl.c プロジェクト: 513855417/linux
int
mwifiex_remain_on_chan_cfg(struct mwifiex_private *priv, u16 action,
			   struct ieee80211_channel *chan,
			   unsigned int duration)
{
	struct host_cmd_ds_remain_on_chan roc_cfg;
	u8 sc;

	memset(&roc_cfg, 0, sizeof(roc_cfg));
	roc_cfg.action = cpu_to_le16(action);
	if (action == HostCmd_ACT_GEN_SET) {
		roc_cfg.band_cfg = chan->band;
		sc = mwifiex_chan_type_to_sec_chan_offset(NL80211_CHAN_NO_HT);
		roc_cfg.band_cfg |= (sc << 2);

		roc_cfg.channel =
			ieee80211_frequency_to_channel(chan->center_freq);
		roc_cfg.duration = cpu_to_le32(duration);
	}
	if (mwifiex_send_cmd(priv, HostCmd_CMD_REMAIN_ON_CHAN,
			     action, 0, &roc_cfg, true)) {
		mwifiex_dbg(priv->adapter, ERROR,
			    "failed to remain on channel\n");
		return -1;
	}

	return roc_cfg.status;
}
コード例 #21
0
ファイル: debugfs.c プロジェクト: DenisLug/mptcp
/* Proc hscfg file write handler
 * This function can be used to configure the host sleep parameters.
 */
static ssize_t
mwifiex_hscfg_write(struct file *file, const char __user *ubuf,
		    size_t count, loff_t *ppos)
{
	struct mwifiex_private *priv = (void *)file->private_data;
	unsigned long addr = get_zeroed_page(GFP_KERNEL);
	char *buf = (char *)addr;
	size_t buf_size = min_t(size_t, count, PAGE_SIZE - 1);
	int ret, arg_num;
	struct mwifiex_ds_hs_cfg hscfg;
	int conditions = HS_CFG_COND_DEF;
	u32 gpio = HS_CFG_GPIO_DEF, gap = HS_CFG_GAP_DEF;

	if (!buf)
		return -ENOMEM;

	if (copy_from_user(buf, ubuf, buf_size)) {
		ret = -EFAULT;
		goto done;
	}

	arg_num = sscanf(buf, "%d %x %x", &conditions, &gpio, &gap);

	memset(&hscfg, 0, sizeof(struct mwifiex_ds_hs_cfg));

	if (arg_num > 3) {
		mwifiex_dbg(priv->adapter, ERROR,
			    "Too many arguments\n");
		ret = -EINVAL;
		goto done;
	}

	if (arg_num >= 1 && arg_num < 3)
		mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_GET,
				      MWIFIEX_SYNC_CMD, &hscfg);

	if (arg_num) {
		if (conditions == HS_CFG_CANCEL) {
			mwifiex_cancel_hs(priv, MWIFIEX_ASYNC_CMD);
			ret = count;
			goto done;
		}
		hscfg.conditions = conditions;
	}
	if (arg_num >= 2)
		hscfg.gpio = gpio;
	if (arg_num == 3)
		hscfg.gap = gap;

	hscfg.is_invoke_hostcmd = false;
	mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_SET,
			      MWIFIEX_SYNC_CMD, &hscfg);

	mwifiex_enable_hs(priv->adapter);
	priv->adapter->hs_enabling = false;
	ret = count;
done:
	free_page(addr);
	return ret;
}
コード例 #22
0
/*
 * Add buffer into wmm tx queue and queue work to transmit it.
 */
int mwifiex_queue_tx_pkt(struct mwifiex_private *priv, struct sk_buff *skb)
{
	struct netdev_queue *txq;
	int index = mwifiex_1d_to_wmm_queue[skb->priority];

	if (atomic_inc_return(&priv->wmm_tx_pending[index]) >= MAX_TX_PENDING) {
		txq = netdev_get_tx_queue(priv->netdev, index);
		if (!netif_tx_queue_stopped(txq)) {
			netif_tx_stop_queue(txq);
			mwifiex_dbg(priv->adapter, DATA,
				    "stop queue: %d\n", index);
		}
	}

	if (mwifiex_bypass_tx_queue(priv, skb)) {
		atomic_inc(&priv->adapter->tx_pending);
		atomic_inc(&priv->adapter->bypass_tx_pending);
		mwifiex_wmm_add_buf_bypass_txqueue(priv, skb);
	 } else {
		atomic_inc(&priv->adapter->tx_pending);
		mwifiex_wmm_add_buf_txqueue(priv, skb);
	 }

	mwifiex_queue_main_work(priv->adapter);

	return 0;
}
コード例 #23
0
ファイル: uap_cmd.c プロジェクト: DenisLug/mptcp
/* This function prepares the AP specific commands before sending them
 * to the firmware.
 * This is a generic function which calls specific command preparation
 * routines based upon the command number.
 */
int mwifiex_uap_prepare_cmd(struct mwifiex_private *priv, u16 cmd_no,
			    u16 cmd_action, u32 type,
			    void *data_buf, void *cmd_buf)
{
	struct host_cmd_ds_command *cmd = cmd_buf;

	switch (cmd_no) {
	case HostCmd_CMD_UAP_SYS_CONFIG:
		if (mwifiex_cmd_uap_sys_config(cmd, cmd_action, type, data_buf))
			return -1;
		break;
	case HostCmd_CMD_UAP_BSS_START:
	case HostCmd_CMD_UAP_BSS_STOP:
	case HOST_CMD_APCMD_SYS_RESET:
	case HOST_CMD_APCMD_STA_LIST:
		cmd->command = cpu_to_le16(cmd_no);
		cmd->size = cpu_to_le16(S_DS_GEN);
		break;
	case HostCmd_CMD_UAP_STA_DEAUTH:
		if (mwifiex_cmd_uap_sta_deauth(priv, cmd, data_buf))
			return -1;
		break;
	case HostCmd_CMD_CHAN_REPORT_REQUEST:
		if (mwifiex_cmd_issue_chan_report_request(priv, cmd_buf,
							  data_buf))
			return -1;
		break;
	default:
		mwifiex_dbg(priv->adapter, ERROR,
			    "PREP_CMD: unknown cmd %#x\n", cmd_no);
		return -1;
	}

	return 0;
}
コード例 #24
0
ファイル: usb.c プロジェクト: ReneNyffenegger/linux
static int mwifiex_usb_construct_send_urb(struct mwifiex_adapter *adapter,
					  struct usb_tx_data_port *port, u8 ep,
					  struct urb_context *context,
					  struct sk_buff *skb_send)
{
	struct usb_card_rec *card = adapter->card;
	int ret = -EINPROGRESS;
	struct urb *tx_urb;

	context->adapter = adapter;
	context->ep = ep;
	context->skb = skb_send;
	tx_urb = context->urb;

	if (ep == card->tx_cmd_ep &&
	    card->tx_cmd_ep_type == USB_ENDPOINT_XFER_INT)
		usb_fill_int_urb(tx_urb, card->udev,
				 usb_sndintpipe(card->udev, ep), skb_send->data,
				 skb_send->len, mwifiex_usb_tx_complete,
				 (void *)context, card->tx_cmd_interval);
	else
		usb_fill_bulk_urb(tx_urb, card->udev,
				  usb_sndbulkpipe(card->udev, ep),
				  skb_send->data, skb_send->len,
				  mwifiex_usb_tx_complete, (void *)context);

	tx_urb->transfer_flags |= URB_ZERO_PACKET;

	if (ep == card->tx_cmd_ep)
		atomic_inc(&card->tx_cmd_urb_pending);
	else
		atomic_inc(&port->tx_data_urb_pending);

	if (ep != card->tx_cmd_ep &&
	    atomic_read(&port->tx_data_urb_pending) ==
					MWIFIEX_TX_DATA_URB) {
		port->block_status = true;
		adapter->data_sent = mwifiex_usb_data_sent(adapter);
		ret = -ENOSR;
	}

	if (usb_submit_urb(tx_urb, GFP_ATOMIC)) {
		mwifiex_dbg(adapter, ERROR,
			    "%s: usb_submit_urb failed\n", __func__);
		if (ep == card->tx_cmd_ep) {
			atomic_dec(&card->tx_cmd_urb_pending);
		} else {
			atomic_dec(&port->tx_data_urb_pending);
			port->block_status = false;
			adapter->data_sent = false;
			if (port->tx_data_ix)
				port->tx_data_ix--;
			else
				port->tx_data_ix = MWIFIEX_TX_DATA_URB;
		}
		ret = -1;
	}

	return ret;
}
コード例 #25
0
ファイル: 11h.c プロジェクト: AlexShiLucky/linux
/* This function handles channel report event from FW during CAC period.
 * If radar is detected during CAC, driver indicates the same to cfg80211
 * and also cancels ongoing delayed work.
 */
int mwifiex_11h_handle_chanrpt_ready(struct mwifiex_private *priv,
				     struct sk_buff *skb)
{
	struct host_cmd_ds_chan_rpt_event *rpt_event;
	struct mwifiex_ie_types_chan_rpt_data *rpt;
	u8 *evt_buf;
	u16 event_len, tlv_len;

	rpt_event = (void *)(skb->data + sizeof(u32));
	event_len = skb->len - (sizeof(struct host_cmd_ds_chan_rpt_event)+
				sizeof(u32));

	if (le32_to_cpu(rpt_event->result) != HostCmd_RESULT_OK) {
		mwifiex_dbg(priv->adapter, ERROR,
			    "Error in channel report event\n");
		return -1;
	}

	evt_buf = (void *)&rpt_event->tlvbuf;

	while (event_len >= sizeof(struct mwifiex_ie_types_header)) {
		rpt = (void *)&rpt_event->tlvbuf;
		tlv_len = le16_to_cpu(rpt->header.len);

		switch (le16_to_cpu(rpt->header.type)) {
		case TLV_TYPE_CHANRPT_11H_BASIC:
			if (rpt->map.radar) {
				mwifiex_dbg(priv->adapter, MSG,
					    "RADAR Detected on channel %d!\n",
					    priv->dfs_chandef.chan->hw_value);
				cancel_delayed_work_sync(&priv->dfs_cac_work);
				cfg80211_cac_event(priv->netdev,
						   &priv->dfs_chandef,
						   NL80211_RADAR_DETECTED,
						   GFP_KERNEL);
			}
			break;
		default:
			break;
		}

		evt_buf += (tlv_len + sizeof(rpt->header));
		event_len -= (tlv_len + sizeof(rpt->header));
	}

	return 0;
}
コード例 #26
0
ファイル: sta_ioctl.c プロジェクト: 513855417/linux
/*
 * This function prepares the correct firmware command and
 * issues it to set the multicast list.
 *
 * This function can be used to enable promiscuous mode, or enable all
 * multicast packets, or to enable selective multicast.
 */
int mwifiex_request_set_multicast_list(struct mwifiex_private *priv,
				struct mwifiex_multicast_list *mcast_list)
{
	int ret = 0;
	u16 old_pkt_filter;

	old_pkt_filter = priv->curr_pkt_filter;

	if (mcast_list->mode == MWIFIEX_PROMISC_MODE) {
		mwifiex_dbg(priv->adapter, INFO,
			    "info: Enable Promiscuous mode\n");
		priv->curr_pkt_filter |= HostCmd_ACT_MAC_PROMISCUOUS_ENABLE;
		priv->curr_pkt_filter &=
			~HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE;
	} else {
		/* Multicast */
		priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_PROMISCUOUS_ENABLE;
		if (mcast_list->mode == MWIFIEX_ALL_MULTI_MODE) {
			mwifiex_dbg(priv->adapter, INFO,
				    "info: Enabling All Multicast!\n");
			priv->curr_pkt_filter |=
				HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE;
		} else {
			priv->curr_pkt_filter &=
				~HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE;
			mwifiex_dbg(priv->adapter, INFO,
				    "info: Set multicast list=%d\n",
				    mcast_list->num_multicast_addr);
			/* Send multicast addresses to firmware */
			ret = mwifiex_send_cmd(priv,
					       HostCmd_CMD_MAC_MULTICAST_ADR,
					       HostCmd_ACT_GEN_SET, 0,
					       mcast_list, false);
		}
	}
	mwifiex_dbg(priv->adapter, INFO,
		    "info: old_pkt_filter=%#x, curr_pkt_filter=%#x\n",
		    old_pkt_filter, priv->curr_pkt_filter);
	if (old_pkt_filter != priv->curr_pkt_filter) {
		ret = mwifiex_send_cmd(priv, HostCmd_CMD_MAC_CONTROL,
				       HostCmd_ACT_GEN_SET,
				       0, &priv->curr_pkt_filter, false);
	}

	return ret;
}
コード例 #27
0
ファイル: usb.c プロジェクト: ReneNyffenegger/linux
static int mwifiex_usb_submit_rx_urb(struct urb_context *ctx, int size)
{
	struct mwifiex_adapter *adapter = ctx->adapter;
	struct usb_card_rec *card = (struct usb_card_rec *)adapter->card;

	if (card->rx_cmd_ep != ctx->ep) {
		ctx->skb = dev_alloc_skb(size);
		if (!ctx->skb) {
			mwifiex_dbg(adapter, ERROR,
				    "%s: dev_alloc_skb failed\n", __func__);
			return -ENOMEM;
		}
	}

	if (card->rx_cmd_ep == ctx->ep &&
	    card->rx_cmd_ep_type == USB_ENDPOINT_XFER_INT)
		usb_fill_int_urb(ctx->urb, card->udev,
				 usb_rcvintpipe(card->udev, ctx->ep),
				 ctx->skb->data, size, mwifiex_usb_rx_complete,
				 (void *)ctx, card->rx_cmd_interval);
	else
		usb_fill_bulk_urb(ctx->urb, card->udev,
				  usb_rcvbulkpipe(card->udev, ctx->ep),
				  ctx->skb->data, size, mwifiex_usb_rx_complete,
				  (void *)ctx);

	if (card->rx_cmd_ep == ctx->ep)
		atomic_inc(&card->rx_cmd_urb_pending);
	else
		atomic_inc(&card->rx_data_urb_pending);

	if (usb_submit_urb(ctx->urb, GFP_ATOMIC)) {
		mwifiex_dbg(adapter, ERROR, "usb_submit_urb failed\n");
		dev_kfree_skb_any(ctx->skb);
		ctx->skb = NULL;

		if (card->rx_cmd_ep == ctx->ep)
			atomic_dec(&card->rx_cmd_urb_pending);
		else
			atomic_dec(&card->rx_data_urb_pending);

		return -1;
	}

	return 0;
}
コード例 #28
0
ファイル: sta_ioctl.c プロジェクト: 513855417/linux
/*
 * IOCTL request handler to set WPA key.
 *
 * This function prepares the correct firmware command and
 * issues it, after validation checks.
 *
 * Current driver only supports key length of up to 32 bytes.
 *
 * This function can also be used to disable a currently set key.
 */
static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_private *priv,
			      struct mwifiex_ds_encrypt_key *encrypt_key)
{
	int ret;
	u8 remove_key = false;
	struct host_cmd_ds_802_11_key_material *ibss_key;

	/* Current driver only supports key length of up to 32 bytes */
	if (encrypt_key->key_len > WLAN_MAX_KEY_LEN) {
		mwifiex_dbg(priv->adapter, ERROR,
			    "key length too long\n");
		return -1;
	}

	if (priv->bss_mode == NL80211_IFTYPE_ADHOC) {
		/*
		 * IBSS/WPA-None uses only one key (Group) for both receiving
		 * and sending unicast and multicast packets.
		 */
		/* Send the key as PTK to firmware */
		encrypt_key->key_index = MWIFIEX_KEY_INDEX_UNICAST;
		ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL,
				       HostCmd_ACT_GEN_SET,
				       KEY_INFO_ENABLED, encrypt_key, false);
		if (ret)
			return ret;

		ibss_key = &priv->aes_key;
		memset(ibss_key, 0,
		       sizeof(struct host_cmd_ds_802_11_key_material));
		/* Copy the key in the driver */
		memcpy(ibss_key->key_param_set.key, encrypt_key->key_material,
		       encrypt_key->key_len);
		memcpy(&ibss_key->key_param_set.key_len, &encrypt_key->key_len,
		       sizeof(ibss_key->key_param_set.key_len));
		ibss_key->key_param_set.key_type_id
			= cpu_to_le16(KEY_TYPE_ID_TKIP);
		ibss_key->key_param_set.key_info = cpu_to_le16(KEY_ENABLED);

		/* Send the key as GTK to firmware */
		encrypt_key->key_index = ~MWIFIEX_KEY_INDEX_UNICAST;
	}

	if (!encrypt_key->key_index)
		encrypt_key->key_index = MWIFIEX_KEY_INDEX_UNICAST;

	if (remove_key)
		ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL,
				       HostCmd_ACT_GEN_SET,
				       !KEY_INFO_ENABLED, encrypt_key, true);
	else
		ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL,
				       HostCmd_ACT_GEN_SET,
				       KEY_INFO_ENABLED, encrypt_key, true);

	return ret;
}
コード例 #29
0
ファイル: sta_cmdresp.c プロジェクト: mkrufky/linux
/*
 * This function handles the command response of set/get SNMP
 * MIB parameters.
 *
 * Handling includes changing the header fields into CPU format
 * and saving the parameter in driver.
 *
 * The following parameters are supported -
 *      - Fragmentation threshold
 *      - RTS threshold
 *      - Short retry limit
 */
static int mwifiex_ret_802_11_snmp_mib(struct mwifiex_private *priv,
				       struct host_cmd_ds_command *resp,
				       u32 *data_buf)
{
	struct host_cmd_ds_802_11_snmp_mib *smib = &resp->params.smib;
	u16 oid = le16_to_cpu(smib->oid);
	u16 query_type = le16_to_cpu(smib->query_type);
	u32 ul_temp;

	mwifiex_dbg(priv->adapter, INFO,
		    "info: SNMP_RESP: oid value = %#x,\t"
		    "query_type = %#x, buf size = %#x\n",
		    oid, query_type, le16_to_cpu(smib->buf_size));
	if (query_type == HostCmd_ACT_GEN_GET) {
		ul_temp = get_unaligned_le16(smib->value);
		if (data_buf)
			*data_buf = ul_temp;
		switch (oid) {
		case FRAG_THRESH_I:
			mwifiex_dbg(priv->adapter, INFO,
				    "info: SNMP_RESP: FragThsd =%u\n",
				    ul_temp);
			break;
		case RTS_THRESH_I:
			mwifiex_dbg(priv->adapter, INFO,
				    "info: SNMP_RESP: RTSThsd =%u\n",
				    ul_temp);
			break;
		case SHORT_RETRY_LIM_I:
			mwifiex_dbg(priv->adapter, INFO,
				    "info: SNMP_RESP: TxRetryCount=%u\n",
				    ul_temp);
			break;
		case DTIM_PERIOD_I:
			mwifiex_dbg(priv->adapter, INFO,
				    "info: SNMP_RESP: DTIM period=%u\n",
				    ul_temp);
		default:
			break;
		}
	}

	return 0;
}
コード例 #30
0
ファイル: sta_cmdresp.c プロジェクト: mkrufky/linux
/* This function handles the command response of set_cfg_data */
static int mwifiex_ret_cfg_data(struct mwifiex_private *priv,
				struct host_cmd_ds_command *resp)
{
	if (resp->result != HostCmd_RESULT_OK) {
		mwifiex_dbg(priv->adapter, ERROR, "Cal data cmd resp failed\n");
		return -1;
	}

	return 0;
}