⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cmdresp.c

📁 linux内核源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/**  * This file contains the handling of command  * responses as well as events generated by firmware.  */#include <linux/delay.h>#include <linux/if_arp.h>#include <linux/netdevice.h>#include <net/iw_handler.h>#include "host.h"#include "decl.h"#include "defs.h"#include "dev.h"#include "join.h"#include "wext.h"/** *  @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);}/** *  @brief This function handles MIC failure event. * *  @param priv    A pointer to wlan_private structure *  @para  event   the event id *  @return 	   n/a */static void handle_mic_failureevent(wlan_private * priv, u32 event){	char buf[50];	lbs_deb_enter(LBS_DEB_CMD);	memset(buf, 0, sizeof(buf));	sprintf(buf, "%s", "MLME-MICHAELMICFAILURE.indication ");	if (event == MACREG_INT_CODE_MIC_ERR_UNICAST) {		strcat(buf, "unicast ");	} else {		strcat(buf, "multicast ");	}	libertas_send_iwevcustom_event(priv, buf);	lbs_deb_leave(LBS_DEB_CMD);}static int wlan_ret_reg_access(wlan_private * priv,			       u16 type, struct cmd_ds_command *resp){	int ret = 0;	wlan_adapter *adapter = priv->adapter;	lbs_deb_enter(LBS_DEB_CMD);	switch (type) {	case CMD_RET(CMD_MAC_REG_ACCESS):		{			struct cmd_ds_mac_reg_access *reg = &resp->params.macreg;			adapter->offsetvalue.offset = (u32)le16_to_cpu(reg->offset);			adapter->offsetvalue.value = le32_to_cpu(reg->value);			break;		}	case CMD_RET(CMD_BBP_REG_ACCESS):		{			struct cmd_ds_bbp_reg_access *reg = &resp->params.bbpreg;			adapter->offsetvalue.offset = (u32)le16_to_cpu(reg->offset);			adapter->offsetvalue.value = reg->value;			break;		}	case CMD_RET(CMD_RF_REG_ACCESS):		{			struct cmd_ds_rf_reg_access *reg = &resp->params.rfreg;			adapter->offsetvalue.offset = (u32)le16_to_cpu(reg->offset);			adapter->offsetvalue.value = reg->value;			break;		}	default:		ret = -1;	}	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);	return ret;}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;}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;}static int wlan_ret_802_11_stat(wlan_private * priv,				struct cmd_ds_command *resp){	lbs_deb_enter(LBS_DEB_CMD);/*	currently adapter->wlan802_11Stat is unused	struct cmd_ds_802_11_get_stat *p11Stat = &resp->params.gstat;	wlan_adapter *adapter = priv->adapter;	// TODO Convert it to Big endian befor copy	memcpy(&adapter->wlan802_11Stat,	       p11Stat, sizeof(struct cmd_ds_802_11_get_stat));*/	lbs_deb_leave(LBS_DEB_CMD);	return 0;}static int wlan_ret_802_11_snmp_mib(wlan_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->adapter->fragthsd =				le16_to_cpu(*((__le16 *)(smib->value)));			lbs_deb_cmd("SNMP_RESP: frag threshold %u\n",				    priv->adapter->fragthsd);			break;		case RTSTHRESH_I:			priv->adapter->rtsthsd =				le16_to_cpu(*((__le16 *)(smib->value)));			lbs_deb_cmd("SNMP_RESP: rts threshold %u\n",				    priv->adapter->rtsthsd);			break;		case SHORT_RETRYLIM_I:			priv->adapter->txretrycount =				le16_to_cpu(*((__le16 *)(smib->value)));			lbs_deb_cmd("SNMP_RESP: tx retry count %u\n",				    priv->adapter->rtsthsd);			break;		default:			break;		}	}	lbs_deb_enter(LBS_DEB_CMD);	return 0;}static int wlan_ret_802_11_key_material(wlan_private * priv,					struct cmd_ds_command *resp){	struct cmd_ds_802_11_key_material *pkeymaterial =	    &resp->params.keymaterial;	wlan_adapter *adapter = priv->adapter;	u16 action = le16_to_cpu(pkeymaterial->action);	lbs_deb_enter(LBS_DEB_CMD);	/* Copy the returned key to driver private data */	if (action == CMD_ACT_GET) {		u8 * buf_ptr = (u8 *) &pkeymaterial->keyParamSet;		u8 * resp_end = (u8 *) (resp + le16_to_cpu(resp->size));		while (buf_ptr < resp_end) {			struct MrvlIEtype_keyParamSet * pkeyparamset =			    (struct MrvlIEtype_keyParamSet *) buf_ptr;			struct enc_key * pkey;			u16 param_set_len = le16_to_cpu(pkeyparamset->length);			u16 key_len = le16_to_cpu(pkeyparamset->keylen);			u16 key_flags = le16_to_cpu(pkeyparamset->keyinfo);			u16 key_type = le16_to_cpu(pkeyparamset->keytypeid);			u8 * end;			end = (u8 *) pkeyparamset + sizeof (pkeyparamset->type)			                          + sizeof (pkeyparamset->length)			                          + param_set_len;			/* Make sure we don't access past the end of the IEs */			if (end > resp_end)				break;			if (key_flags & KEY_INFO_WPA_UNICAST)				pkey = &adapter->wpa_unicast_key;			else if (key_flags & KEY_INFO_WPA_MCAST)				pkey = &adapter->wpa_mcast_key;			else				break;			/* Copy returned key into driver */			memset(pkey, 0, sizeof(struct enc_key));			if (key_len > sizeof(pkey->key))				break;			pkey->type = key_type;			pkey->flags = key_flags;			pkey->len = key_len;			memcpy(pkey->key, pkeyparamset->key, pkey->len);			buf_ptr = end + 1;		}	}	lbs_deb_enter(LBS_DEB_CMD);	return 0;}static int wlan_ret_802_11_mac_address(wlan_private * priv,				       struct cmd_ds_command *resp){	struct cmd_ds_802_11_mac_address *macadd = &resp->params.macadd;	wlan_adapter *adapter = priv->adapter;	lbs_deb_enter(LBS_DEB_CMD);	memcpy(adapter->current_addr, macadd->macadd, ETH_ALEN);	lbs_deb_enter(LBS_DEB_CMD);	return 0;}static int wlan_ret_802_11_rf_tx_power(wlan_private * priv,				       struct cmd_ds_command *resp){	struct cmd_ds_802_11_rf_tx_power *rtp = &resp->params.txp;	wlan_adapter *adapter = priv->adapter;	lbs_deb_enter(LBS_DEB_CMD);	adapter->txpowerlevel = le16_to_cpu(rtp->currentlevel);	lbs_deb_cmd("TX power currently %d\n", adapter->txpowerlevel);	lbs_deb_leave(LBS_DEB_CMD);	return 0;}static int wlan_ret_802_11_rate_adapt_rateset(wlan_private * priv,					      struct cmd_ds_command *resp){	struct cmd_ds_802_11_rate_adapt_rateset *rates = &resp->params.rateset;	wlan_adapter *adapter = priv->adapter;	lbs_deb_enter(LBS_DEB_CMD);	if (rates->action == CMD_ACT_GET) {		adapter->enablehwauto = le16_to_cpu(rates->enablehwauto);		adapter->ratebitmap = le16_to_cpu(rates->bitmap);	}	lbs_deb_leave(LBS_DEB_CMD);	return 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;}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;}static int wlan_ret_802_11_rssi(wlan_private * priv,				struct cmd_ds_command *resp){	struct cmd_ds_802_11_rssi_rsp *rssirsp = &resp->params.rssirsp;	wlan_adapter *adapter = priv->adapter;	lbs_deb_enter(LBS_DEB_CMD);	/* store the non average value */	adapter->SNR[TYPE_BEACON][TYPE_NOAVG] = le16_to_cpu(rssirsp->SNR);	adapter->NF[TYPE_BEACON][TYPE_NOAVG] = le16_to_cpu(rssirsp->noisefloor);	adapter->SNR[TYPE_BEACON][TYPE_AVG] = le16_to_cpu(rssirsp->avgSNR);	adapter->NF[TYPE_BEACON][TYPE_AVG] = le16_to_cpu(rssirsp->avgnoisefloor);	adapter->RSSI[TYPE_BEACON][TYPE_NOAVG] =	    CAL_RSSI(adapter->SNR[TYPE_BEACON][TYPE_NOAVG],		     adapter->NF[TYPE_BEACON][TYPE_NOAVG]);	adapter->RSSI[TYPE_BEACON][TYPE_AVG] =	    CAL_RSSI(adapter->SNR[TYPE_BEACON][TYPE_AVG] / AVG_SCALE,		     adapter->NF[TYPE_BEACON][TYPE_AVG] / AVG_SCALE);	lbs_deb_cmd("RSSI: beacon %d, avg %d\n",	       adapter->RSSI[TYPE_BEACON][TYPE_NOAVG],	       adapter->RSSI[TYPE_BEACON][TYPE_AVG]);	lbs_deb_leave(LBS_DEB_CMD);	return 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);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -