Exemple #1
0
static int wlan_cmd_802_11_data_rate(wlan_private * priv,
				     struct cmd_ds_command *cmd,
				     u16 cmd_action)
{
	struct cmd_ds_802_11_data_rate *pdatarate = &cmd->params.drate;
	wlan_adapter *adapter = priv->adapter;

	lbs_deb_enter(LBS_DEB_CMD);

	cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_data_rate) +
			     S_DS_GEN);
	cmd->command = cpu_to_le16(CMD_802_11_DATA_RATE);
	memset(pdatarate, 0, sizeof(struct cmd_ds_802_11_data_rate));
	pdatarate->action = cpu_to_le16(cmd_action);

	if (cmd_action == CMD_ACT_SET_TX_FIX_RATE) {
		pdatarate->rates[0] = libertas_data_rate_to_fw_index(adapter->cur_rate);
		lbs_deb_cmd("DATA_RATE: set fixed 0x%02X\n",
		       adapter->cur_rate);
	} else if (cmd_action == CMD_ACT_SET_TX_AUTO) {
		lbs_deb_cmd("DATA_RATE: setting auto\n");
	}

	lbs_deb_leave(LBS_DEB_CMD);
	return 0;
}
Exemple #2
0
/**
 *  @brief This function handles disconnect event. it
 *  reports disconnect to upper layer, clean tx/rx packets,
 *  reset link state etc.
 *
 *  @param priv    A pointer to wlan_private structure
 *  @return 	   n/a
 */
void libertas_mac_event_disconnected(wlan_private * priv)
{
	wlan_adapter *adapter = priv->adapter;
	union iwreq_data wrqu;

	if (adapter->connect_status != LIBERTAS_CONNECTED)
		return;

	lbs_deb_enter(LBS_DEB_CMD);

	memset(wrqu.ap_addr.sa_data, 0x00, ETH_ALEN);
	wrqu.ap_addr.sa_family = ARPHRD_ETHER;

	/*
	 * Cisco AP sends EAP failure and de-auth in less than 0.5 ms.
	 * It causes problem in the Supplicant
	 */

	msleep_interruptible(1000);
	wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);

	/* Free Tx and Rx packets */
	kfree_skb(priv->adapter->currenttxskb);
	priv->adapter->currenttxskb = NULL;

	/* report disconnect to upper layer */
	netif_stop_queue(priv->dev);
	netif_carrier_off(priv->dev);

	/* reset SNR/NF/RSSI values */
	memset(adapter->SNR, 0x00, sizeof(adapter->SNR));
	memset(adapter->NF, 0x00, sizeof(adapter->NF));
	memset(adapter->RSSI, 0x00, sizeof(adapter->RSSI));
	memset(adapter->rawSNR, 0x00, sizeof(adapter->rawSNR));
	memset(adapter->rawNF, 0x00, sizeof(adapter->rawNF));
	adapter->nextSNRNF = 0;
	adapter->numSNRNF = 0;
	lbs_deb_cmd("current SSID '%s', length %u\n",
	            escape_essid(adapter->curbssparams.ssid,
	                         adapter->curbssparams.ssid_len),
	            adapter->curbssparams.ssid_len);

	adapter->connect_status = LIBERTAS_DISCONNECTED;

	/* Clear out associated SSID and BSSID since connection is
	 * no longer valid.
	 */
	memset(&adapter->curbssparams.bssid, 0, ETH_ALEN);
	memset(&adapter->curbssparams.ssid, 0, IW_ESSID_MAX_SIZE);
	adapter->curbssparams.ssid_len = 0;

	if (adapter->psstate != PS_STATE_FULL_POWER) {
		/* make firmware to exit PS mode */
		lbs_deb_cmd("disconnected, so exit PS mode\n");
		libertas_ps_wakeup(priv, 0);
	}
	lbs_deb_leave(LBS_DEB_CMD);
}
Exemple #3
0
/**
 *  @brief This function handles disconnect event. it
 *  reports disconnect to upper layer, clean tx/rx packets,
 *  reset link state etc.
 *
 *  @param priv    A pointer to struct lbs_private structure
 *  @return 	   n/a
 */
void lbs_mac_event_disconnected(struct lbs_private *priv)
{
	if (priv->connect_status != LBS_CONNECTED)
		return;

	lbs_deb_enter(LBS_DEB_ASSOC);

	/*
	 * Cisco AP sends EAP failure and de-auth in less than 0.5 ms.
	 * It causes problem in the Supplicant
	 */
	msleep_interruptible(1000);

	if (priv->wdev->iftype == NL80211_IFTYPE_STATION)
		lbs_send_disconnect_notification(priv);

	/* report disconnect to upper layer */
	netif_stop_queue(priv->dev);
	netif_carrier_off(priv->dev);

	/* Free Tx and Rx packets */
	kfree_skb(priv->currenttxskb);
	priv->currenttxskb = NULL;
	priv->tx_pending_len = 0;

	priv->connect_status = LBS_DISCONNECTED;

	if (priv->psstate != PS_STATE_FULL_POWER) {
		/* make firmware to exit PS mode */
		lbs_deb_cmd("disconnected, so exit PS mode\n");
		lbs_set_ps_mode(priv, PS_MODE_ACTION_EXIT_PS, false);
	}
	lbs_deb_leave(LBS_DEB_ASSOC);
}
Exemple #4
0
static int wlan_cmd_802_11_enable_rsn(wlan_private * priv,
				      struct cmd_ds_command *cmd,
				      u16 cmd_action,
				      void * pdata_buf)
{
	struct cmd_ds_802_11_enable_rsn *penableRSN = &cmd->params.enbrsn;
	u32 * enable = pdata_buf;

	lbs_deb_enter(LBS_DEB_CMD);

	cmd->command = cpu_to_le16(CMD_802_11_ENABLE_RSN);
	cmd->size = cpu_to_le16(sizeof(*penableRSN) + S_DS_GEN);
	penableRSN->action = cpu_to_le16(cmd_action);

	if (cmd_action == CMD_ACT_SET) {
		if (*enable)
			penableRSN->enable = cpu_to_le16(CMD_ENABLE_RSN);
		else
			penableRSN->enable = cpu_to_le16(CMD_DISABLE_RSN);
		lbs_deb_cmd("ENABLE_RSN: %d\n", *enable);
	}

	lbs_deb_leave(LBS_DEB_CMD);
	return 0;
}
void lbs_mac_event_disconnected(struct lbs_private *priv)
{
	if (priv->connect_status != LBS_CONNECTED)
		return;

	lbs_deb_enter(LBS_DEB_ASSOC);

	/*
                                                               
                                       
  */
	msleep_interruptible(1000);

	if (priv->wdev->iftype == NL80211_IFTYPE_STATION)
		lbs_send_disconnect_notification(priv);

	/*                                  */
	netif_stop_queue(priv->dev);
	netif_carrier_off(priv->dev);

	/*                        */
	kfree_skb(priv->currenttxskb);
	priv->currenttxskb = NULL;
	priv->tx_pending_len = 0;

	priv->connect_status = LBS_DISCONNECTED;

	if (priv->psstate != PS_STATE_FULL_POWER) {
		/*                               */
		lbs_deb_cmd("disconnected, so exit PS mode\n");
		lbs_set_ps_mode(priv, PS_MODE_ACTION_EXIT_PS, false);
	}
	lbs_deb_leave(LBS_DEB_ASSOC);
}
static int lbs_ret_802_11_rssi(struct lbs_private *priv,
				struct cmd_ds_command *resp)
{
	struct cmd_ds_802_11_rssi_rsp *rssirsp = &resp->params.rssirsp;

	lbs_deb_enter(LBS_DEB_CMD);

	/* store the non average value */
	priv->SNR[TYPE_BEACON][TYPE_NOAVG] = le16_to_cpu(rssirsp->SNR);
	priv->NF[TYPE_BEACON][TYPE_NOAVG] = le16_to_cpu(rssirsp->noisefloor);

	priv->SNR[TYPE_BEACON][TYPE_AVG] = le16_to_cpu(rssirsp->avgSNR);
	priv->NF[TYPE_BEACON][TYPE_AVG] = le16_to_cpu(rssirsp->avgnoisefloor);

	priv->RSSI[TYPE_BEACON][TYPE_NOAVG] =
	    CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_NOAVG],
		     priv->NF[TYPE_BEACON][TYPE_NOAVG]);

	priv->RSSI[TYPE_BEACON][TYPE_AVG] =
	    CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_AVG] / AVG_SCALE,
		     priv->NF[TYPE_BEACON][TYPE_AVG] / AVG_SCALE);

	lbs_deb_cmd("RSSI: beacon %d, avg %d\n",
	       priv->RSSI[TYPE_BEACON][TYPE_NOAVG],
	       priv->RSSI[TYPE_BEACON][TYPE_AVG]);

	lbs_deb_leave(LBS_DEB_CMD);
	return 0;
}
Exemple #7
0
static int wlan_ret_802_11_eeprom_access(wlan_private * priv,
				  struct cmd_ds_command *resp)
{
	wlan_adapter *adapter = priv->adapter;
	struct wlan_ioctl_regrdwr *pbuf;
	pbuf = (struct wlan_ioctl_regrdwr *) adapter->prdeeprom;

	lbs_deb_enter_args(LBS_DEB_CMD, "len %d",
	       le16_to_cpu(resp->params.rdeeprom.bytecount));
	if (pbuf->NOB < le16_to_cpu(resp->params.rdeeprom.bytecount)) {
		pbuf->NOB = 0;
		lbs_deb_cmd("EEPROM read length too big\n");
		return -1;
	}
	pbuf->NOB = le16_to_cpu(resp->params.rdeeprom.bytecount);
	if (pbuf->NOB > 0) {

		memcpy(&pbuf->value, (u8 *) & resp->params.rdeeprom.value,
		       le16_to_cpu(resp->params.rdeeprom.bytecount));
		lbs_deb_hex(LBS_DEB_CMD, "EEPROM", (char *)&pbuf->value,
			le16_to_cpu(resp->params.rdeeprom.bytecount));
	}
	lbs_deb_leave(LBS_DEB_CMD);
	return 0;
}
static int lbs_ret_802_11_snmp_mib(struct lbs_private *priv,
				    struct cmd_ds_command *resp)
{
	struct cmd_ds_802_11_snmp_mib *smib = &resp->params.smib;
	u16 oid = le16_to_cpu(smib->oid);
	u16 querytype = le16_to_cpu(smib->querytype);

	lbs_deb_enter(LBS_DEB_CMD);

	lbs_deb_cmd("SNMP_RESP: oid 0x%x, querytype 0x%x\n", oid,
	       querytype);
	lbs_deb_cmd("SNMP_RESP: Buf size %d\n", le16_to_cpu(smib->bufsize));

	if (querytype == CMD_ACT_GET) {
		switch (oid) {
		case FRAGTHRESH_I:
			priv->fragthsd =
				le16_to_cpu(*((__le16 *)(smib->value)));
			lbs_deb_cmd("SNMP_RESP: frag threshold %u\n",
				    priv->fragthsd);
			break;
		case RTSTHRESH_I:
			priv->rtsthsd =
				le16_to_cpu(*((__le16 *)(smib->value)));
			lbs_deb_cmd("SNMP_RESP: rts threshold %u\n",
				    priv->rtsthsd);
			break;
		case SHORT_RETRYLIM_I:
			priv->txretrycount =
				le16_to_cpu(*((__le16 *)(smib->value)));
			lbs_deb_cmd("SNMP_RESP: tx retry count %u\n",
				    priv->rtsthsd);
			break;
		default:
			break;
		}
	}

	lbs_deb_enter(LBS_DEB_CMD);
	return 0;
}
Exemple #9
0
static int wlan_cmd_802_11_ps_mode(wlan_private * priv,
				   struct cmd_ds_command *cmd,
				   u16 cmd_action)
{
	struct cmd_ds_802_11_ps_mode *psm = &cmd->params.psmode;

	lbs_deb_enter(LBS_DEB_CMD);

	cmd->command = cpu_to_le16(CMD_802_11_PS_MODE);
	cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_ps_mode) +
				S_DS_GEN);
	psm->action = cpu_to_le16(cmd_action);
	psm->multipledtim = 0;
	switch (cmd_action) {
	case CMD_SUBCMD_ENTER_PS:
		lbs_deb_cmd("PS command:" "SubCode- Enter PS\n");

		psm->locallisteninterval = 0;
		psm->nullpktinterval = 0;
		psm->multipledtim =
		    cpu_to_le16(MRVDRV_DEFAULT_MULTIPLE_DTIM);
		break;

	case CMD_SUBCMD_EXIT_PS:
		lbs_deb_cmd("PS command:" "SubCode- Exit PS\n");
		break;

	case CMD_SUBCMD_SLEEP_CONFIRMED:
		lbs_deb_cmd("PS command: SubCode- sleep confirm\n");
		break;

	default:
		break;
	}

	lbs_deb_leave(LBS_DEB_CMD);
	return 0;
}
static int lbs_ret_802_11_rf_tx_power(struct lbs_private *priv,
				       struct cmd_ds_command *resp)
{
	struct cmd_ds_802_11_rf_tx_power *rtp = &resp->params.txp;

	lbs_deb_enter(LBS_DEB_CMD);

	priv->txpowerlevel = le16_to_cpu(rtp->currentlevel);

	lbs_deb_cmd("TX power currently %d\n", priv->txpowerlevel);

	lbs_deb_leave(LBS_DEB_CMD);
	return 0;
}
/**
 *  @brief This function handles disconnect event. it
 *  reports disconnect to upper layer, clean tx/rx packets,
 *  reset link state etc.
 *
 *  @param priv    A pointer to struct lbs_private structure
 *  @return 	   n/a
 */
void lbs_mac_event_disconnected(struct lbs_private *priv)
{
	if (priv->connect_status != LBS_CONNECTED)
		return;

	lbs_deb_enter(LBS_DEB_ASSOC);

	/*
	 * Cisco AP sends EAP failure and de-auth in less than 0.5 ms.
	 * It causes problem in the Supplicant
	 */
	msleep_interruptible(1000);
	lbs_send_disconnect_notification(priv);

	/* report disconnect to upper layer */
	netif_stop_queue(priv->dev);
	netif_carrier_off(priv->dev);

	/* Free Tx and Rx packets */
	kfree_skb(priv->currenttxskb);
	priv->currenttxskb = NULL;
	priv->tx_pending_len = 0;

	/* reset SNR/NF/RSSI values */
	memset(priv->SNR, 0x00, sizeof(priv->SNR));
	memset(priv->NF, 0x00, sizeof(priv->NF));
	memset(priv->RSSI, 0x00, sizeof(priv->RSSI));
	memset(priv->rawSNR, 0x00, sizeof(priv->rawSNR));
	memset(priv->rawNF, 0x00, sizeof(priv->rawNF));
	priv->nextSNRNF = 0;
	priv->numSNRNF = 0;
	priv->connect_status = LBS_DISCONNECTED;

	/* Clear out associated SSID and BSSID since connection is
	 * no longer valid.
	 */
	memset(&priv->curbssparams.bssid, 0, ETH_ALEN);
	memset(&priv->curbssparams.ssid, 0, IEEE80211_MAX_SSID_LEN);
	priv->curbssparams.ssid_len = 0;

	if (priv->psstate != PS_STATE_FULL_POWER) {
		/* make firmware to exit PS mode */
		lbs_deb_cmd("disconnected, so exit PS mode\n");
		lbs_ps_wakeup(priv, 0);
	}
	lbs_deb_leave(LBS_DEB_ASSOC);
}
Exemple #12
0
int libertas_set_radio_control(wlan_private * priv)
{
	int ret = 0;

	lbs_deb_enter(LBS_DEB_CMD);

	ret = libertas_prepare_and_send_command(priv,
				    CMD_802_11_RADIO_CONTROL,
				    CMD_ACT_SET,
				    CMD_OPTION_WAITFORRSP, 0, NULL);

	lbs_deb_cmd("RADIO_SET: radio %d, preamble %d\n",
	       priv->adapter->radioon, priv->adapter->preamble);

	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
	return ret;
}
Exemple #13
0
static int wlan_cmd_mac_control(wlan_private * priv,
				struct cmd_ds_command *cmd)
{
	struct cmd_ds_mac_control *mac = &cmd->params.macctrl;

	lbs_deb_enter(LBS_DEB_CMD);

	cmd->command = cpu_to_le16(CMD_MAC_CONTROL);
	cmd->size = cpu_to_le16(sizeof(struct cmd_ds_mac_control) + S_DS_GEN);
	mac->action = cpu_to_le16(priv->adapter->currentpacketfilter);

	lbs_deb_cmd("MAC_CONTROL: action 0x%x, size %d\n",
		    le16_to_cpu(mac->action), le16_to_cpu(cmd->size));

	lbs_deb_leave(LBS_DEB_CMD);
	return 0;
}
Exemple #14
0
static int wlan_cmd_802_11_rf_tx_power(wlan_private * priv,
				       struct cmd_ds_command *cmd,
				       u16 cmd_action, void *pdata_buf)
{

	struct cmd_ds_802_11_rf_tx_power *prtp = &cmd->params.txp;

	lbs_deb_enter(LBS_DEB_CMD);

	cmd->size =
	    cpu_to_le16((sizeof(struct cmd_ds_802_11_rf_tx_power)) + S_DS_GEN);
	cmd->command = cpu_to_le16(CMD_802_11_RF_TX_POWER);
	prtp->action = cpu_to_le16(cmd_action);

	lbs_deb_cmd("RF_TX_POWER_CMD: size:%d cmd:0x%x Act:%d\n",
		    le16_to_cpu(cmd->size), le16_to_cpu(cmd->command),
		    le16_to_cpu(prtp->action));

	switch (cmd_action) {
	case CMD_ACT_TX_POWER_OPT_GET:
		prtp->action = cpu_to_le16(CMD_ACT_GET);
		prtp->currentlevel = 0;
		break;

	case CMD_ACT_TX_POWER_OPT_SET_HIGH:
		prtp->action = cpu_to_le16(CMD_ACT_SET);
		prtp->currentlevel = cpu_to_le16(CMD_ACT_TX_POWER_INDEX_HIGH);
		break;

	case CMD_ACT_TX_POWER_OPT_SET_MID:
		prtp->action = cpu_to_le16(CMD_ACT_SET);
		prtp->currentlevel = cpu_to_le16(CMD_ACT_TX_POWER_INDEX_MID);
		break;

	case CMD_ACT_TX_POWER_OPT_SET_LOW:
		prtp->action = cpu_to_le16(CMD_ACT_SET);
		prtp->currentlevel = cpu_to_le16(*((u16 *) pdata_buf));
		break;
	}

	lbs_deb_leave(LBS_DEB_CMD);
	return 0;
}
Exemple #15
0
static int wlan_ret_802_11_data_rate(wlan_private * priv,
				     struct cmd_ds_command *resp)
{
	struct cmd_ds_802_11_data_rate *pdatarate = &resp->params.drate;
	wlan_adapter *adapter = priv->adapter;

	lbs_deb_enter(LBS_DEB_CMD);

	lbs_deb_hex(LBS_DEB_CMD, "DATA_RATE_RESP", (u8 *) pdatarate,
		sizeof(struct cmd_ds_802_11_data_rate));

	/* FIXME: get actual rates FW can do if this command actually returns
	 * all data rates supported.
	 */
	adapter->cur_rate = libertas_fw_index_to_data_rate(pdatarate->rates[0]);
	lbs_deb_cmd("DATA_RATE: current rate 0x%02x\n", adapter->cur_rate);

	lbs_deb_leave(LBS_DEB_CMD);
	return 0;
}
Exemple #16
0
/* This function is the CMD_MESH_CONFIG legacy function.  It only handles the
 * START and STOP actions.  The extended actions supported by CMD_MESH_CONFIG
 * are all handled by preparing a struct cmd_ds_mesh_config and passing it to
 * lbs_mesh_config_send.
 */
static int lbs_mesh_config(struct lbs_private *priv, uint16_t action,
		uint16_t chan)
{
	struct cmd_ds_mesh_config cmd;
	struct mrvl_meshie *ie;
	DECLARE_SSID_BUF(ssid);

	memset(&cmd, 0, sizeof(cmd));
	cmd.channel = cpu_to_le16(chan);
	ie = (struct mrvl_meshie *)cmd.data;

	switch (action) {
	case CMD_ACT_MESH_CONFIG_START:
		ie->id = WLAN_EID_GENERIC;
		ie->val.oui[0] = 0x00;
		ie->val.oui[1] = 0x50;
		ie->val.oui[2] = 0x43;
		ie->val.type = MARVELL_MESH_IE_TYPE;
		ie->val.subtype = MARVELL_MESH_IE_SUBTYPE;
		ie->val.version = MARVELL_MESH_IE_VERSION;
		ie->val.active_protocol_id = MARVELL_MESH_PROTO_ID_HWMP;
		ie->val.active_metric_id = MARVELL_MESH_METRIC_ID;
		ie->val.mesh_capability = MARVELL_MESH_CAPABILITY;
		ie->val.mesh_id_len = priv->mesh_ssid_len;
		memcpy(ie->val.mesh_id, priv->mesh_ssid, priv->mesh_ssid_len);
		ie->len = sizeof(struct mrvl_meshie_val) -
			IEEE80211_MAX_SSID_LEN + priv->mesh_ssid_len;
		cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie_val));
		break;
	case CMD_ACT_MESH_CONFIG_STOP:
		break;
	default:
		return -1;
	}
	lbs_deb_cmd("mesh config action %d type %x channel %d SSID %s\n",
		    action, priv->mesh_tlv, chan,
		    print_ssid(ssid, priv->mesh_ssid, priv->mesh_ssid_len));

	return __lbs_mesh_config_send(priv, &cmd, action, priv->mesh_tlv);
}
Exemple #17
0
static int wlan_cmd_mac_multicast_adr(wlan_private * priv,
				      struct cmd_ds_command *cmd,
				      u16 cmd_action)
{
	struct cmd_ds_mac_multicast_adr *pMCastAdr = &cmd->params.madr;
	wlan_adapter *adapter = priv->adapter;

	lbs_deb_enter(LBS_DEB_CMD);
	cmd->size = cpu_to_le16(sizeof(struct cmd_ds_mac_multicast_adr) +
			     S_DS_GEN);
	cmd->command = cpu_to_le16(CMD_MAC_MULTICAST_ADR);

	lbs_deb_cmd("MULTICAST_ADR: setting %d addresses\n", pMCastAdr->nr_of_adrs);
	pMCastAdr->action = cpu_to_le16(cmd_action);
	pMCastAdr->nr_of_adrs =
	    cpu_to_le16((u16) adapter->nr_of_multicastmacaddr);
	memcpy(pMCastAdr->maclist, adapter->multicastlist,
	       adapter->nr_of_multicastmacaddr * ETH_ALEN);

	lbs_deb_leave(LBS_DEB_CMD);
	return 0;
}
Exemple #18
0
static int wlan_ret_802_11_rf_channel(wlan_private * priv,
				      struct cmd_ds_command *resp)
{
	struct cmd_ds_802_11_rf_channel *rfchannel = &resp->params.rfchannel;
	wlan_adapter *adapter = priv->adapter;
	u16 action = le16_to_cpu(rfchannel->action);
	u16 newchannel = le16_to_cpu(rfchannel->currentchannel);

	lbs_deb_enter(LBS_DEB_CMD);

	if (action == CMD_OPT_802_11_RF_CHANNEL_GET
	    && adapter->curbssparams.channel != newchannel) {
		lbs_deb_cmd("channel switch from %d to %d\n",
		       adapter->curbssparams.channel, newchannel);

		/* Update the channel again */
		adapter->curbssparams.channel = newchannel;
	}

	lbs_deb_enter(LBS_DEB_CMD);
	return 0;
}
Exemple #19
0
static int wlan_ret_802_11_sleep_params(wlan_private * priv,
					struct cmd_ds_command *resp)
{
	struct cmd_ds_802_11_sleep_params *sp = &resp->params.sleep_params;
	wlan_adapter *adapter = priv->adapter;

	lbs_deb_enter(LBS_DEB_CMD);

	lbs_deb_cmd("error 0x%x, offset 0x%x, stabletime 0x%x, calcontrol 0x%x "
		    "extsleepclk 0x%x\n", le16_to_cpu(sp->error),
		    le16_to_cpu(sp->offset), le16_to_cpu(sp->stabletime),
		    sp->calcontrol, sp->externalsleepclk);

	adapter->sp.sp_error = le16_to_cpu(sp->error);
	adapter->sp.sp_offset = le16_to_cpu(sp->offset);
	adapter->sp.sp_stabletime = le16_to_cpu(sp->stabletime);
	adapter->sp.sp_calcontrol = sp->calcontrol;
	adapter->sp.sp_extsleepclk = sp->externalsleepclk;
	adapter->sp.sp_reserved = le16_to_cpu(sp->reserved);

	lbs_deb_enter(LBS_DEB_CMD);
	return 0;
}
Exemple #20
0
int lbs_process_event(struct lbs_private *priv, u32 event)
{
	int ret = 0;
	struct cmd_header cmd;

	lbs_deb_enter(LBS_DEB_CMD);

	switch (event) {
	case MACREG_INT_CODE_LINK_SENSED:
		lbs_deb_cmd("EVENT: link sensed\n");
		break;

	case MACREG_INT_CODE_DEAUTHENTICATED:
		lbs_deb_cmd("EVENT: deauthenticated\n");
		lbs_mac_event_disconnected(priv);
		break;

	case MACREG_INT_CODE_DISASSOCIATED:
		lbs_deb_cmd("EVENT: disassociated\n");
		lbs_mac_event_disconnected(priv);
		break;

	case MACREG_INT_CODE_LINK_LOST_NO_SCAN:
		lbs_deb_cmd("EVENT: link lost\n");
		lbs_mac_event_disconnected(priv);
		break;

	case MACREG_INT_CODE_PS_SLEEP:
		lbs_deb_cmd("EVENT: ps sleep\n");

		/* handle unexpected PS SLEEP event */
		if (priv->psstate == PS_STATE_FULL_POWER) {
			lbs_deb_cmd(
			       "EVENT: in FULL POWER mode, ignoreing PS_SLEEP\n");
			break;
		}
		priv->psstate = PS_STATE_PRE_SLEEP;

		lbs_ps_confirm_sleep(priv);

		break;

	case MACREG_INT_CODE_HOST_AWAKE:
		lbs_deb_cmd("EVENT: host awake\n");
		if (priv->reset_deep_sleep_wakeup)
			priv->reset_deep_sleep_wakeup(priv);
		priv->is_deep_sleep = 0;
		lbs_cmd_async(priv, CMD_802_11_WAKEUP_CONFIRM, &cmd,
				sizeof(cmd));
		priv->is_host_sleep_activated = 0;
		wake_up_interruptible(&priv->host_sleep_q);
		break;

	case MACREG_INT_CODE_DEEP_SLEEP_AWAKE:
		if (priv->reset_deep_sleep_wakeup)
			priv->reset_deep_sleep_wakeup(priv);
		lbs_deb_cmd("EVENT: ds awake\n");
		priv->is_deep_sleep = 0;
		priv->wakeup_dev_required = 0;
		wake_up_interruptible(&priv->ds_awake_q);
		break;

	case MACREG_INT_CODE_PS_AWAKE:
		lbs_deb_cmd("EVENT: ps awake\n");
		/* handle unexpected PS AWAKE event */
		if (priv->psstate == PS_STATE_FULL_POWER) {
			lbs_deb_cmd(
			       "EVENT: In FULL POWER mode - ignore PS AWAKE\n");
			break;
		}

		priv->psstate = PS_STATE_AWAKE;

		if (priv->needtowakeup) {
			/*
			 * wait for the command processing to finish
			 * before resuming sending
			 * priv->needtowakeup will be set to FALSE
			 * in lbs_ps_wakeup()
			 */
			lbs_deb_cmd("waking up ...\n");
			lbs_set_ps_mode(priv, PS_MODE_ACTION_EXIT_PS, false);
		}
		break;

	case MACREG_INT_CODE_MIC_ERR_UNICAST:
		lbs_deb_cmd("EVENT: UNICAST MIC ERROR\n");
		lbs_send_mic_failureevent(priv, event);
		break;

	case MACREG_INT_CODE_MIC_ERR_MULTICAST:
		lbs_deb_cmd("EVENT: MULTICAST MIC ERROR\n");
		lbs_send_mic_failureevent(priv, event);
		break;

	case MACREG_INT_CODE_MIB_CHANGED:
		lbs_deb_cmd("EVENT: MIB CHANGED\n");
		break;
	case MACREG_INT_CODE_INIT_DONE:
		lbs_deb_cmd("EVENT: INIT DONE\n");
		break;
	case MACREG_INT_CODE_ADHOC_BCN_LOST:
		lbs_deb_cmd("EVENT: ADHOC beacon lost\n");
		break;
	case MACREG_INT_CODE_RSSI_LOW:
		netdev_alert(priv->dev, "EVENT: rssi low\n");
		break;
	case MACREG_INT_CODE_SNR_LOW:
		netdev_alert(priv->dev, "EVENT: snr low\n");
		break;
	case MACREG_INT_CODE_MAX_FAIL:
		netdev_alert(priv->dev, "EVENT: max fail\n");
		break;
	case MACREG_INT_CODE_RSSI_HIGH:
		netdev_alert(priv->dev, "EVENT: rssi high\n");
		break;
	case MACREG_INT_CODE_SNR_HIGH:
		netdev_alert(priv->dev, "EVENT: snr high\n");
		break;

	case MACREG_INT_CODE_MESH_AUTO_STARTED:
		/* Ignore spurious autostart events */
		netdev_info(priv->dev, "EVENT: MESH_AUTO_STARTED (ignoring)\n");
		break;

	default:
		netdev_alert(priv->dev, "EVENT: unknown event id %d\n", event);
		break;
	}

	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
	return ret;
}
int lbs_process_event(struct lbs_private *priv, u32 event)
{
	int ret = 0;

	lbs_deb_enter(LBS_DEB_CMD);

	switch (event) {
	case MACREG_INT_CODE_LINK_SENSED:
		lbs_deb_cmd("EVENT: link sensed\n");
		break;

	case MACREG_INT_CODE_DEAUTHENTICATED:
		lbs_deb_cmd("EVENT: deauthenticated\n");
		lbs_mac_event_disconnected(priv);
		break;

	case MACREG_INT_CODE_DISASSOCIATED:
		lbs_deb_cmd("EVENT: disassociated\n");
		lbs_mac_event_disconnected(priv);
		break;

	case MACREG_INT_CODE_LINK_LOST_NO_SCAN:
		lbs_deb_cmd("EVENT: link lost\n");
		lbs_mac_event_disconnected(priv);
		break;

	case MACREG_INT_CODE_PS_SLEEP:
		lbs_deb_cmd("EVENT: ps sleep\n");

		/* handle unexpected PS SLEEP event */
		if (priv->psstate == PS_STATE_FULL_POWER) {
			lbs_deb_cmd(
			       "EVENT: in FULL POWER mode, ignoreing PS_SLEEP\n");
			break;
		}
		priv->psstate = PS_STATE_PRE_SLEEP;

		lbs_ps_confirm_sleep(priv);

		break;

	case MACREG_INT_CODE_HOST_AWAKE:
		lbs_deb_cmd("EVENT: host awake\n");
		lbs_send_confirmwake(priv);
		break;

	case MACREG_INT_CODE_PS_AWAKE:
		lbs_deb_cmd("EVENT: ps awake\n");
		/* handle unexpected PS AWAKE event */
		if (priv->psstate == PS_STATE_FULL_POWER) {
			lbs_deb_cmd(
			       "EVENT: In FULL POWER mode - ignore PS AWAKE\n");
			break;
		}

		priv->psstate = PS_STATE_AWAKE;

		if (priv->needtowakeup) {
			/*
			 * wait for the command processing to finish
			 * before resuming sending
			 * priv->needtowakeup will be set to FALSE
			 * in lbs_ps_wakeup()
			 */
			lbs_deb_cmd("waking up ...\n");
			lbs_ps_wakeup(priv, 0);
		}
		break;

	case MACREG_INT_CODE_MIC_ERR_UNICAST:
		lbs_deb_cmd("EVENT: UNICAST MIC ERROR\n");
		handle_mic_failureevent(priv, MACREG_INT_CODE_MIC_ERR_UNICAST);
		break;

	case MACREG_INT_CODE_MIC_ERR_MULTICAST:
		lbs_deb_cmd("EVENT: MULTICAST MIC ERROR\n");
		handle_mic_failureevent(priv, MACREG_INT_CODE_MIC_ERR_MULTICAST);
		break;

	case MACREG_INT_CODE_MIB_CHANGED:
		lbs_deb_cmd("EVENT: MIB CHANGED\n");
		break;
	case MACREG_INT_CODE_INIT_DONE:
		lbs_deb_cmd("EVENT: INIT DONE\n");
		break;
	case MACREG_INT_CODE_ADHOC_BCN_LOST:
		lbs_deb_cmd("EVENT: ADHOC beacon lost\n");
		break;
	case MACREG_INT_CODE_RSSI_LOW:
		lbs_pr_alert("EVENT: rssi low\n");
		break;
	case MACREG_INT_CODE_SNR_LOW:
		lbs_pr_alert("EVENT: snr low\n");
		break;
	case MACREG_INT_CODE_MAX_FAIL:
		lbs_pr_alert("EVENT: max fail\n");
		break;
	case MACREG_INT_CODE_RSSI_HIGH:
		lbs_pr_alert("EVENT: rssi high\n");
		break;
	case MACREG_INT_CODE_SNR_HIGH:
		lbs_pr_alert("EVENT: snr high\n");
		break;

	case MACREG_INT_CODE_MESH_AUTO_STARTED:
		/* Ignore spurious autostart events if autostart is disabled */
		if (!priv->mesh_autostart_enabled) {
			lbs_pr_info("EVENT: MESH_AUTO_STARTED (ignoring)\n");
			break;
		}
		lbs_pr_info("EVENT: MESH_AUTO_STARTED\n");
		priv->mesh_connect_status = LBS_CONNECTED;
		if (priv->mesh_open) {
			netif_carrier_on(priv->mesh_dev);
			if (!priv->tx_pending_len)
				netif_wake_queue(priv->mesh_dev);
		}
		priv->mode = IW_MODE_ADHOC;
		schedule_work(&priv->sync_channel);
		break;

	default:
		lbs_pr_alert("EVENT: unknown event id %d\n", event);
		break;
	}

	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
	return ret;
}
Exemple #22
0
int libertas_process_event(wlan_private * priv)
{
	int ret = 0;
	wlan_adapter *adapter = priv->adapter;
	u32 eventcause;

	lbs_deb_enter(LBS_DEB_CMD);

	spin_lock_irq(&adapter->driver_lock);
	eventcause = adapter->eventcause;
	spin_unlock_irq(&adapter->driver_lock);

	lbs_deb_cmd("event cause 0x%x\n", eventcause);

	switch (eventcause >> SBI_EVENT_CAUSE_SHIFT) {
	case MACREG_INT_CODE_LINK_SENSED:
		lbs_deb_cmd("EVENT: MACREG_INT_CODE_LINK_SENSED\n");
		break;

	case MACREG_INT_CODE_DEAUTHENTICATED:
		lbs_deb_cmd("EVENT: deauthenticated\n");
		libertas_mac_event_disconnected(priv);
		break;

	case MACREG_INT_CODE_DISASSOCIATED:
		lbs_deb_cmd("EVENT: disassociated\n");
		libertas_mac_event_disconnected(priv);
		break;

	case MACREG_INT_CODE_LINK_LOSE_NO_SCAN:
		lbs_deb_cmd("EVENT: link lost\n");
		libertas_mac_event_disconnected(priv);
		break;

	case MACREG_INT_CODE_PS_SLEEP:
		lbs_deb_cmd("EVENT: sleep\n");

		/* handle unexpected PS SLEEP event */
		if (adapter->psstate == PS_STATE_FULL_POWER) {
			lbs_deb_cmd(
			       "EVENT: in FULL POWER mode, ignoreing PS_SLEEP\n");
			break;
		}
		adapter->psstate = PS_STATE_PRE_SLEEP;

		libertas_ps_confirm_sleep(priv, (u16) adapter->psmode);

		break;

	case MACREG_INT_CODE_PS_AWAKE:
		lbs_deb_cmd("EVENT: awake\n");

		/* handle unexpected PS AWAKE event */
		if (adapter->psstate == PS_STATE_FULL_POWER) {
			lbs_deb_cmd(
			       "EVENT: In FULL POWER mode - ignore PS AWAKE\n");
			break;
		}

		adapter->psstate = PS_STATE_AWAKE;

		if (adapter->needtowakeup) {
			/*
			 * wait for the command processing to finish
			 * before resuming sending
			 * adapter->needtowakeup will be set to FALSE
			 * in libertas_ps_wakeup()
			 */
			lbs_deb_cmd("waking up ...\n");
			libertas_ps_wakeup(priv, 0);
		}
		break;

	case MACREG_INT_CODE_MIC_ERR_UNICAST:
		lbs_deb_cmd("EVENT: UNICAST MIC ERROR\n");
		handle_mic_failureevent(priv, MACREG_INT_CODE_MIC_ERR_UNICAST);
		break;

	case MACREG_INT_CODE_MIC_ERR_MULTICAST:
		lbs_deb_cmd("EVENT: MULTICAST MIC ERROR\n");
		handle_mic_failureevent(priv, MACREG_INT_CODE_MIC_ERR_MULTICAST);
		break;
	case MACREG_INT_CODE_MIB_CHANGED:
	case MACREG_INT_CODE_INIT_DONE:
		break;

	case MACREG_INT_CODE_ADHOC_BCN_LOST:
		lbs_deb_cmd("EVENT: ADHOC beacon lost\n");
		break;

	case MACREG_INT_CODE_RSSI_LOW:
		lbs_pr_alert("EVENT: rssi low\n");
		break;
	case MACREG_INT_CODE_SNR_LOW:
		lbs_pr_alert("EVENT: snr low\n");
		break;
	case MACREG_INT_CODE_MAX_FAIL:
		lbs_pr_alert("EVENT: max fail\n");
		break;
	case MACREG_INT_CODE_RSSI_HIGH:
		lbs_pr_alert("EVENT: rssi high\n");
		break;
	case MACREG_INT_CODE_SNR_HIGH:
		lbs_pr_alert("EVENT: snr high\n");
		break;

	case MACREG_INT_CODE_MESH_AUTO_STARTED:
		/* Ignore spurious autostart events if autostart is disabled */
		if (!priv->mesh_autostart_enabled) {
			lbs_pr_info("EVENT: MESH_AUTO_STARTED (ignoring)\n");
			break;
		}
		lbs_pr_info("EVENT: MESH_AUTO_STARTED\n");
		adapter->connect_status = LIBERTAS_CONNECTED;
		if (priv->mesh_open == 1) {
			netif_wake_queue(priv->mesh_dev);
			netif_carrier_on(priv->mesh_dev);
		}
		adapter->mode = IW_MODE_ADHOC;
		schedule_work(&priv->sync_channel);
		break;

	default:
		lbs_pr_alert("EVENT: unknown event id 0x%04x\n",
		       eventcause >> SBI_EVENT_CAUSE_SHIFT);
		break;
	}

	spin_lock_irq(&adapter->driver_lock);
	adapter->eventcause = 0;
	spin_unlock_irq(&adapter->driver_lock);

	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
	return ret;
}
Exemple #23
0
static int wlan_cmd_802_11_set_wep(wlan_private * priv,
                                   struct cmd_ds_command *cmd,
                                   u32 cmd_act,
                                   void * pdata_buf)
{
	struct cmd_ds_802_11_set_wep *wep = &cmd->params.wep;
	wlan_adapter *adapter = priv->adapter;
	int ret = 0;
	struct assoc_request * assoc_req = pdata_buf;

	lbs_deb_enter(LBS_DEB_CMD);

	cmd->command = cpu_to_le16(CMD_802_11_SET_WEP);
	cmd->size = cpu_to_le16(sizeof(*wep) + S_DS_GEN);

	if (cmd_act == CMD_ACT_ADD) {
		int i;

		if (!assoc_req) {
			lbs_deb_cmd("Invalid association request!");
			ret = -1;
			goto done;
		}

		wep->action = cpu_to_le16(CMD_ACT_ADD);

		/* default tx key index */
		wep->keyindex = cpu_to_le16((u16)(assoc_req->wep_tx_keyidx &
						  (u32)CMD_WEP_KEY_INDEX_MASK));

		/* Copy key types and material to host command structure */
		for (i = 0; i < 4; i++) {
			struct enc_key * pkey = &assoc_req->wep_keys[i];

			switch (pkey->len) {
			case KEY_LEN_WEP_40:
				wep->keytype[i] = CMD_TYPE_WEP_40_BIT;
				memmove(&wep->keymaterial[i], pkey->key,
				        pkey->len);
				lbs_deb_cmd("SET_WEP: add key %d (40 bit)\n", i);
				break;
			case KEY_LEN_WEP_104:
				wep->keytype[i] = CMD_TYPE_WEP_104_BIT;
				memmove(&wep->keymaterial[i], pkey->key,
				        pkey->len);
				lbs_deb_cmd("SET_WEP: add key %d (104 bit)\n", i);
				break;
			case 0:
				break;
			default:
				lbs_deb_cmd("SET_WEP: invalid key %d, length %d\n",
				       i, pkey->len);
				ret = -1;
				goto done;
				break;
			}
		}
	} else if (cmd_act == CMD_ACT_REMOVE) {
		/* ACT_REMOVE clears _all_ WEP keys */
		wep->action = cpu_to_le16(CMD_ACT_REMOVE);

		/* default tx key index */
		wep->keyindex = cpu_to_le16((u16)(adapter->wep_tx_keyidx &
						  (u32)CMD_WEP_KEY_INDEX_MASK));
		lbs_deb_cmd("SET_WEP: remove key %d\n", adapter->wep_tx_keyidx);
	}

	ret = 0;

done:
	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
	return ret;
}
int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len)
{
	uint16_t respcmd, curcmd;
	struct cmd_header *resp;
	int ret = 0;
	unsigned long flags;
	uint16_t result;

	lbs_deb_enter(LBS_DEB_HOST);

	mutex_lock(&priv->lock);
	spin_lock_irqsave(&priv->driver_lock, flags);

	if (!priv->cur_cmd) {
		lbs_deb_host("CMD_RESP: cur_cmd is NULL\n");
		ret = -1;
		spin_unlock_irqrestore(&priv->driver_lock, flags);
		goto done;
	}

	resp = (void *)data;
	curcmd = le16_to_cpu(priv->cur_cmd->cmdbuf->command);
	respcmd = le16_to_cpu(resp->command);
	result = le16_to_cpu(resp->result);

	lbs_deb_cmd("CMD_RESP: response 0x%04x, seq %d, size %d\n",
		     respcmd, le16_to_cpu(resp->seqnum), len);
	lbs_deb_hex(LBS_DEB_CMD, "CMD_RESP", (void *) resp, len);

	if (resp->seqnum != priv->cur_cmd->cmdbuf->seqnum) {
		netdev_info(priv->dev,
			    "Received CMD_RESP with invalid sequence %d (expected %d)\n",
			    le16_to_cpu(resp->seqnum),
			    le16_to_cpu(priv->cur_cmd->cmdbuf->seqnum));
		spin_unlock_irqrestore(&priv->driver_lock, flags);
		ret = -1;
		goto done;
	}
	if (respcmd != CMD_RET(curcmd) &&
	    respcmd != CMD_RET_802_11_ASSOCIATE && curcmd != CMD_802_11_ASSOCIATE) {
		netdev_info(priv->dev, "Invalid CMD_RESP %x to command %x!\n",
			    respcmd, curcmd);
		spin_unlock_irqrestore(&priv->driver_lock, flags);
		ret = -1;
		goto done;
	}

	if (resp->result == cpu_to_le16(0x0004)) {
		/*                                                         
                        */
		netdev_info(priv->dev,
			    "Firmware returns DEFER to command %x. Will let it time out...\n",
			    le16_to_cpu(resp->command));
		spin_unlock_irqrestore(&priv->driver_lock, flags);
		ret = -1;
		goto done;
	}

	/*                                                       */
	del_timer(&priv->command_timer);
	priv->cmd_timed_out = 0;

	if (respcmd == CMD_RET(CMD_802_11_PS_MODE)) {
		struct cmd_ds_802_11_ps_mode *psmode = (void *) &resp[1];
		u16 action = le16_to_cpu(psmode->action);

		lbs_deb_host(
		       "CMD_RESP: PS_MODE cmd reply result 0x%x, action 0x%x\n",
		       result, action);

		if (result) {
			lbs_deb_host("CMD_RESP: PS command failed with 0x%x\n",
				    result);
			/*
                                              
                                    
                                 
    */
			if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR &&
			    action == PS_MODE_ACTION_ENTER_PS)
				priv->psmode = LBS802_11POWERMODECAM;
		} else if (action == PS_MODE_ACTION_ENTER_PS) {
			priv->needtowakeup = 0;
			priv->psstate = PS_STATE_AWAKE;

			lbs_deb_host("CMD_RESP: ENTER_PS command response\n");
			if (priv->connect_status != LBS_CONNECTED) {
				/*
                                                         
                                                 
     */
				lbs_deb_host(
				       "disconnected, invoking lbs_ps_wakeup\n");

				spin_unlock_irqrestore(&priv->driver_lock, flags);
				mutex_unlock(&priv->lock);
				lbs_set_ps_mode(priv, PS_MODE_ACTION_EXIT_PS,
						false);
				mutex_lock(&priv->lock);
				spin_lock_irqsave(&priv->driver_lock, flags);
			}
		} else if (action == PS_MODE_ACTION_EXIT_PS) {
			priv->needtowakeup = 0;
			priv->psstate = PS_STATE_FULL_POWER;
			lbs_deb_host("CMD_RESP: EXIT_PS command response\n");
		} else {
			lbs_deb_host("CMD_RESP: PS action 0x%X\n", action);
		}

		__lbs_complete_command(priv, priv->cur_cmd, result);
		spin_unlock_irqrestore(&priv->driver_lock, flags);

		ret = 0;
		goto done;
	}

	/*                                                              */
	if ((result != 0 || !(respcmd & 0x8000))) {
		lbs_deb_host("CMD_RESP: error 0x%04x in command reply 0x%04x\n",
		       result, respcmd);
		/*
                         
   */
		switch (respcmd) {
		case CMD_RET(CMD_GET_HW_SPEC):
		case CMD_RET(CMD_802_11_RESET):
			lbs_deb_host("CMD_RESP: reset failed\n");
			break;

		}
		__lbs_complete_command(priv, priv->cur_cmd, result);
		spin_unlock_irqrestore(&priv->driver_lock, flags);

		ret = -1;
		goto done;
	}

	spin_unlock_irqrestore(&priv->driver_lock, flags);

	if (priv->cur_cmd && priv->cur_cmd->callback) {
		ret = priv->cur_cmd->callback(priv, priv->cur_cmd->callback_arg,
				resp);
	}

	spin_lock_irqsave(&priv->driver_lock, flags);

	if (priv->cur_cmd) {
		/*                                                   */
		__lbs_complete_command(priv, priv->cur_cmd, result);
	}
	spin_unlock_irqrestore(&priv->driver_lock, flags);

done:
	mutex_unlock(&priv->lock);
	lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret);
	return ret;
}
Exemple #25
0
static int wlan_cmd_802_11_snmp_mib(wlan_private * priv,
				    struct cmd_ds_command *cmd,
				    int cmd_action,
				    int cmd_oid, void *pdata_buf)
{
	struct cmd_ds_802_11_snmp_mib *pSNMPMIB = &cmd->params.smib;
	wlan_adapter *adapter = priv->adapter;
	u8 ucTemp;

	lbs_deb_enter(LBS_DEB_CMD);

	lbs_deb_cmd("SNMP_CMD: cmd_oid = 0x%x\n", cmd_oid);

	cmd->command = cpu_to_le16(CMD_802_11_SNMP_MIB);
	cmd->size = cpu_to_le16(sizeof(*pSNMPMIB) + S_DS_GEN);

	switch (cmd_oid) {
	case OID_802_11_INFRASTRUCTURE_MODE:
	{
		u8 mode = (u8) (size_t) pdata_buf;
		pSNMPMIB->querytype = cpu_to_le16(CMD_ACT_SET);
		pSNMPMIB->oid = cpu_to_le16((u16) DESIRED_BSSTYPE_I);
		pSNMPMIB->bufsize = sizeof(u8);
		if (mode == IW_MODE_ADHOC) {
			ucTemp = SNMP_MIB_VALUE_ADHOC;
		} else {
			/* Infra and Auto modes */
			ucTemp = SNMP_MIB_VALUE_INFRA;
		}

		memmove(pSNMPMIB->value, &ucTemp, sizeof(u8));

		break;
	}

	case OID_802_11D_ENABLE:
		{
			u32 ulTemp;

			pSNMPMIB->oid = cpu_to_le16((u16) DOT11D_I);

			if (cmd_action == CMD_ACT_SET) {
				pSNMPMIB->querytype = CMD_ACT_SET;
				pSNMPMIB->bufsize = sizeof(u16);
				ulTemp = *(u32 *)pdata_buf;
				*((__le16 *)(pSNMPMIB->value)) =
				    cpu_to_le16((u16) ulTemp);
			}
			break;
		}

	case OID_802_11_FRAGMENTATION_THRESHOLD:
		{
			u32 ulTemp;

			pSNMPMIB->oid = cpu_to_le16((u16) FRAGTHRESH_I);

			if (cmd_action == CMD_ACT_GET) {
				pSNMPMIB->querytype = cpu_to_le16(CMD_ACT_GET);
			} else if (cmd_action == CMD_ACT_SET) {
				pSNMPMIB->querytype = cpu_to_le16(CMD_ACT_SET);
				pSNMPMIB->bufsize = cpu_to_le16(sizeof(u16));
				ulTemp = *((u32 *) pdata_buf);
				*((__le16 *)(pSNMPMIB->value)) =
				    cpu_to_le16((u16) ulTemp);

			}

			break;
		}

	case OID_802_11_RTS_THRESHOLD:
		{

			u32 ulTemp;
			pSNMPMIB->oid = le16_to_cpu((u16) RTSTHRESH_I);

			if (cmd_action == CMD_ACT_GET) {
				pSNMPMIB->querytype = cpu_to_le16(CMD_ACT_GET);
			} else if (cmd_action == CMD_ACT_SET) {
				pSNMPMIB->querytype = cpu_to_le16(CMD_ACT_SET);
				pSNMPMIB->bufsize = cpu_to_le16(sizeof(u16));
				ulTemp = *((u32 *)pdata_buf);
				*(__le16 *)(pSNMPMIB->value) =
				    cpu_to_le16((u16) ulTemp);

			}
			break;
		}
	case OID_802_11_TX_RETRYCOUNT:
		pSNMPMIB->oid = cpu_to_le16((u16) SHORT_RETRYLIM_I);

		if (cmd_action == CMD_ACT_GET) {
			pSNMPMIB->querytype = cpu_to_le16(CMD_ACT_GET);
		} else if (cmd_action == CMD_ACT_SET) {
			pSNMPMIB->querytype = cpu_to_le16(CMD_ACT_SET);
			pSNMPMIB->bufsize = cpu_to_le16(sizeof(u16));
			*((__le16 *)(pSNMPMIB->value)) =
			    cpu_to_le16((u16) adapter->txretrycount);
		}

		break;
	default:
		break;
	}

	lbs_deb_cmd(
	       "SNMP_CMD: command=0x%x, size=0x%x, seqnum=0x%x, result=0x%x\n",
	       le16_to_cpu(cmd->command), le16_to_cpu(cmd->size),
	       le16_to_cpu(cmd->seqnum), le16_to_cpu(cmd->result));

	lbs_deb_cmd(
	       "SNMP_CMD: action 0x%x, oid 0x%x, oidsize 0x%x, value 0x%x\n",
	       le16_to_cpu(pSNMPMIB->querytype), le16_to_cpu(pSNMPMIB->oid),
	       le16_to_cpu(pSNMPMIB->bufsize),
	       le16_to_cpu(*(__le16 *) pSNMPMIB->value));

	lbs_deb_leave(LBS_DEB_CMD);
	return 0;
}
Exemple #26
0
int lbs_process_event(struct lbs_private *priv, u32 event)
{
	int ret = 0;
	struct cmd_header cmd;

	lbs_deb_enter(LBS_DEB_CMD);

	switch (event) {
	case MACREG_INT_CODE_LINK_SENSED:
		lbs_deb_cmd("EVENT: link sensed\n");
		break;

	case MACREG_INT_CODE_DEAUTHENTICATED:
		lbs_deb_cmd("EVENT: deauthenticated\n");
		lbs_mac_event_disconnected(priv);
		break;

	case MACREG_INT_CODE_DISASSOCIATED:
		lbs_deb_cmd("EVENT: disassociated\n");
		lbs_mac_event_disconnected(priv);
		break;

	case MACREG_INT_CODE_LINK_LOST_NO_SCAN:
		lbs_deb_cmd("EVENT: link lost\n");
		lbs_mac_event_disconnected(priv);
		break;

	case MACREG_INT_CODE_PS_SLEEP:
		lbs_deb_cmd("EVENT: ps sleep\n");

		/* handle unexpected PS SLEEP event */
		if (priv->psstate == PS_STATE_FULL_POWER) {
			lbs_deb_cmd(
			       "EVENT: in FULL POWER mode, ignoreing PS_SLEEP\n");
			break;
		}
		priv->psstate = PS_STATE_PRE_SLEEP;

		lbs_ps_confirm_sleep(priv);

		break;

	case MACREG_INT_CODE_HOST_AWAKE:
		lbs_deb_cmd("EVENT: host awake\n");
		if (priv->reset_deep_sleep_wakeup)
			priv->reset_deep_sleep_wakeup(priv);
		priv->is_deep_sleep = 0;
		lbs_cmd_async(priv, CMD_802_11_WAKEUP_CONFIRM, &cmd,
				sizeof(cmd));
		priv->is_host_sleep_activated = 0;
		wake_up_interruptible(&priv->host_sleep_q);
		break;

	case MACREG_INT_CODE_DEEP_SLEEP_AWAKE:
		if (priv->reset_deep_sleep_wakeup)
			priv->reset_deep_sleep_wakeup(priv);
		lbs_deb_cmd("EVENT: ds awake\n");
		priv->is_deep_sleep = 0;
		priv->wakeup_dev_required = 0;
		wake_up_interruptible(&priv->ds_awake_q);
		break;

	case MACREG_INT_CODE_PS_AWAKE:
		lbs_deb_cmd("EVENT: ps awake\n");
		/* handle unexpected PS AWAKE event */
		if (priv->psstate == PS_STATE_FULL_POWER) {
			lbs_deb_cmd(
			       "EVENT: In FULL POWER mode - ignore PS AWAKE\n");
			break;
		}

		priv->psstate = PS_STATE_AWAKE;

		if (priv->needtowakeup) {
			/*
			 * wait for the command processing to finish
			 * before resuming sending
			 * priv->needtowakeup will be set to FALSE
			 * in lbs_ps_wakeup()
			 */
			lbs_deb_cmd("waking up ...\n");
			lbs_set_ps_mode(priv, PS_MODE_ACTION_EXIT_PS, false);
		}
		break;

	case MACREG_INT_CODE_MIC_ERR_UNICAST:
		lbs_deb_cmd("EVENT: UNICAST MIC ERROR\n");
		lbs_send_mic_failureevent(priv, event);
		break;

	case MACREG_INT_CODE_MIC_ERR_MULTICAST:
		lbs_deb_cmd("EVENT: MULTICAST M
Exemple #27
0
/*
 * TODO: Fix the issue when DownloadcommandToStation is being called the
 * second time when the command times out. All the cmdptr->xxx are in little
 * endian and therefore all the comparissions will fail.
 * For now - we are not performing the endian conversion the second time - but
 * for PS and DEEP_SLEEP we need to worry
 */
static int DownloadcommandToStation(wlan_private * priv,
				    struct cmd_ctrl_node *cmdnode)
{
	unsigned long flags;
	struct cmd_ds_command *cmdptr;
	wlan_adapter *adapter = priv->adapter;
	int ret = -1;
	u16 cmdsize;
	u16 command;

	lbs_deb_enter(LBS_DEB_HOST);

	if (!adapter || !cmdnode) {
		lbs_deb_host("DNLD_CMD: adapter or cmdmode is NULL\n");
		goto done;
	}

	cmdptr = (struct cmd_ds_command *)cmdnode->bufvirtualaddr;

	spin_lock_irqsave(&adapter->driver_lock, flags);
	if (!cmdptr || !cmdptr->size) {
		lbs_deb_host("DNLD_CMD: cmdptr is NULL or zero\n");
		__libertas_cleanup_and_insert_cmd(priv, cmdnode);
		spin_unlock_irqrestore(&adapter->driver_lock, flags);
		goto done;
	}

	adapter->cur_cmd = cmdnode;
	adapter->cur_cmd_retcode = 0;
	spin_unlock_irqrestore(&adapter->driver_lock, flags);

	cmdsize = cmdptr->size;
	command = cpu_to_le16(cmdptr->command);

	lbs_deb_host("DNLD_CMD: command 0x%04x, size %d, jiffies %lu\n",
		    command, le16_to_cpu(cmdptr->size), jiffies);
	lbs_deb_hex(LBS_DEB_HOST, "DNLD_CMD", cmdnode->bufvirtualaddr, cmdsize);

	cmdnode->cmdwaitqwoken = 0;
	cmdsize = cpu_to_le16(cmdsize);

	ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) cmdptr, cmdsize);

	if (ret != 0) {
		lbs_deb_host("DNLD_CMD: hw_host_to_card failed\n");
		spin_lock_irqsave(&adapter->driver_lock, flags);
		adapter->cur_cmd_retcode = ret;
		__libertas_cleanup_and_insert_cmd(priv, adapter->cur_cmd);
		adapter->nr_cmd_pending--;
		adapter->cur_cmd = NULL;
		spin_unlock_irqrestore(&adapter->driver_lock, flags);
		goto done;
	}

	lbs_deb_cmd("DNLD_CMD: sent command 0x%04x, jiffies %lu\n", command, jiffies);

	/* Setup the timer after transmit command */
	if (command == CMD_802_11_SCAN || command == CMD_802_11_AUTHENTICATE
	    || command == CMD_802_11_ASSOCIATE)
		mod_timer(&adapter->command_timer, jiffies + (10*HZ));
	else
		mod_timer(&adapter->command_timer, jiffies + (5*HZ));

	ret = 0;

done:
	lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret);
	return ret;
}
Exemple #28
0
int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len)
{
	uint16_t respcmd, curcmd;
	struct cmd_header *resp;
	int ret = 0;
	unsigned long flags;
	uint16_t result;

	lbs_deb_enter(LBS_DEB_HOST);

	mutex_lock(&priv->lock);
	spin_lock_irqsave(&priv->driver_lock, flags);

	if (!priv->cur_cmd) {
		lbs_deb_host("CMD_RESP: cur_cmd is NULL\n");
		ret = -1;
		spin_unlock_irqrestore(&priv->driver_lock, flags);
		goto done;
	}

	resp = (void *)data;
	curcmd = le16_to_cpu(priv->cur_cmd->cmdbuf->command);
	respcmd = le16_to_cpu(resp->command);
	result = le16_to_cpu(resp->result);

	lbs_deb_cmd("CMD_RESP: response 0x%04x, seq %d, size %d\n",
		     respcmd, le16_to_cpu(resp->seqnum), len);
	lbs_deb_hex(LBS_DEB_CMD, "CMD_RESP", (void *) resp, len);

	if (resp->seqnum != priv->cur_cmd->cmdbuf->seqnum) {
		lbs_pr_info("Received CMD_RESP with invalid sequence %d (expected %d)\n",
			    le16_to_cpu(resp->seqnum), le16_to_cpu(priv->cur_cmd->cmdbuf->seqnum));
		spin_unlock_irqrestore(&priv->driver_lock, flags);
		ret = -1;
		goto done;
	}
	if (respcmd != CMD_RET(curcmd) &&
	    respcmd != CMD_RET_802_11_ASSOCIATE && curcmd != CMD_802_11_ASSOCIATE) {
		lbs_pr_info("Invalid CMD_RESP %x to command %x!\n", respcmd, curcmd);
		spin_unlock_irqrestore(&priv->driver_lock, flags);
		ret = -1;
		goto done;
	}

	if (resp->result == cpu_to_le16(0x0004)) {
		/* 0x0004 means -EAGAIN. Drop the response, let it time out
		   and be resubmitted */
		lbs_pr_info("Firmware returns DEFER to command %x. Will let it time out...\n",
			    le16_to_cpu(resp->command));
		spin_unlock_irqrestore(&priv->driver_lock, flags);
		ret = -1;
		goto done;
	}

	/* Now we got response from FW, cancel the command timer */
	del_timer(&priv->command_timer);
	priv->cmd_timed_out = 0;

	if (respcmd == CMD_RET(CMD_802_11_PS_MODE)) {
		struct cmd_ds_802_11_ps_mode *psmode = (void *) &resp[1];
		u16 action = le16_to_cpu(psmode->action);

		lbs_deb_host(
		       "CMD_RESP: PS_MODE cmd reply result 0x%x, action 0x%x\n",
		       result, action);

		if (result) {
			lbs_deb_host("CMD_RESP: PS command failed with 0x%x\n",
				    result);
			/*
			 * We should not re-try enter-ps command in
			 * ad-hoc mode. It takes place in
			 * lbs_execute_next_command().
			 */
			if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR &&
			    action == PS_MODE_ACTION_ENTER_PS)
				priv->psmode = LBS802_11POWERMODECAM;
		} else if (action == PS_MODE_ACTION_ENTER_PS) {
			priv->needtowakeup = 0;
			priv->psstate = PS_STATE_AWAKE;

			lbs_deb_host("CMD_RESP: ENTER_PS command response\n");
			if (priv->connect_status != LBS_CONNECTED) {
				/*
				 * When Deauth Event received before Enter_PS command
				 * response, We need to wake up the firmware.
				 */
				lbs_deb_host(
				       "disconnected, invoking lbs_ps_wakeup\n");

				spin_unlock_irqrestore(&priv->driver_lock, flags);
				mutex_unlock(&priv->lock);
				lbs_set_ps_mode(priv, PS_MODE_ACTION_EXIT_PS,
						false);
				mutex_lock(&priv->lock);
				spin_lock_irqsave(&priv->driver_lock, flags);
			}
		} else if (action == PS_MODE_ACTION_EXIT_PS) {
			priv->needtowakeup = 0;
			priv->psstate = PS_STATE_FULL_POWER;
			lbs_deb_host("CMD_RESP: EXIT_PS command response\n");
		} else {
			lbs_deb_host("CMD_RESP: PS action 0x%X\n", action);
		}

		lbs_complete_command(priv, priv->cur_cmd, result);
		spin_unlock_irqrestore(&priv->driver_lock, flags);

		ret = 0;
		goto done;
	}

	/* If the command is not successful, cleanup and return failure */
	if ((result != 0 || !(respcmd & 0x8000))) {
		lbs_deb_host("CMD_RESP: error 0x%04x in command reply 0x%04x\n",
		       result, respcmd);
		/*
		 * Handling errors here
		 */
		switch (respcmd) {
		case CMD_RET(CMD_GET_HW_SPEC):
		case CMD_RET(CMD_802_11_RESET):
			lbs_deb_host("CMD_RESP: reset failed\n");
			break;

		}
		lbs_complete_command(priv, priv->cur_cmd, result);
		spin_unlock_irqrestore(&priv->driver_lock, flags);

		ret = -1;
		goto done;
	}

	spin_unlock_irqrestore(&priv->driver_lock, flags);

	if (priv->cur_cmd && priv->cur_cmd->callback) {
		ret = priv->cur_cmd->callback(priv, priv->cur_cmd->callback_arg,
				resp);
	}

	spin_lock_irqsave(&priv->driver_lock, flags);

	if (priv->cur_cmd) {
		/* Clean up and Put current command back to cmdfreeq */
		lbs_complete_command(priv, priv->cur_cmd, result);
	}
	spin_unlock_irqrestore(&priv->driver_lock, flags);

done:
	mutex_unlock(&priv->lock);
	lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret);
	return ret;
}
Exemple #29
0
static int wlan_ret_get_hw_spec(wlan_private * priv,
				struct cmd_ds_command *resp)
{
	u32 i;
	struct cmd_ds_get_hw_spec *hwspec = &resp->params.hwspec;
	wlan_adapter *adapter = priv->adapter;
	int ret = 0;
	DECLARE_MAC_BUF(mac);

	lbs_deb_enter(LBS_DEB_CMD);

	adapter->fwcapinfo = le32_to_cpu(hwspec->fwcapinfo);

	memcpy(adapter->fwreleasenumber, hwspec->fwreleasenumber, 4);

	lbs_deb_cmd("GET_HW_SPEC: firmware release %u.%u.%up%u\n",
		    adapter->fwreleasenumber[2], adapter->fwreleasenumber[1],
		    adapter->fwreleasenumber[0], adapter->fwreleasenumber[3]);
	lbs_deb_cmd("GET_HW_SPEC: MAC addr %s\n",
		    print_mac(mac, hwspec->permanentaddr));
	lbs_deb_cmd("GET_HW_SPEC: hardware interface 0x%x, hardware spec 0x%04x\n",
	       hwspec->hwifversion, hwspec->version);

	/* Clamp region code to 8-bit since FW spec indicates that it should
	 * only ever be 8-bit, even though the field size is 16-bit.  Some firmware
	 * returns non-zero high 8 bits here.
	 */
	adapter->regioncode = le16_to_cpu(hwspec->regioncode) & 0xFF;

	for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) {
		/* use the region code to search for the index */
		if (adapter->regioncode == libertas_region_code_to_index[i]) {
			break;
		}
	}

	/* if it's unidentified region code, use the default (USA) */
	if (i >= MRVDRV_MAX_REGION_CODE) {
		adapter->regioncode = 0x10;
		lbs_pr_info("unidentified region code; using the default (USA)\n");
	}

	if (adapter->current_addr[0] == 0xff)
		memmove(adapter->current_addr, hwspec->permanentaddr, ETH_ALEN);

	memcpy(priv->dev->dev_addr, adapter->current_addr, ETH_ALEN);
	if (priv->mesh_dev)
		memcpy(priv->mesh_dev->dev_addr, adapter->current_addr, ETH_ALEN);

	if (libertas_set_regiontable(priv, adapter->regioncode, 0)) {
		ret = -1;
		goto done;
	}

	if (libertas_set_universaltable(priv, 0)) {
		ret = -1;
		goto done;
	}

done:
	lbs_deb_enter_args(LBS_DEB_CMD, "ret %d", ret);
	return ret;
}