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

📄 oid_mgt.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (islpci_get_state(priv) >= PRV_STATE_READY) {		ret = islpci_mgt_transaction(priv->ndev, PIMFOR_OP_SET, oid,					     _data, dlen, &response);		if (!ret) {			response_op = response->header->operation;			islpci_mgt_release(response);		}		if (ret || response_op == PIMFOR_OP_ERROR)			ret = -EIO;	} else if (!cache)		ret = -EIO;	if (cache) {		if (!ret && data)			memcpy(cache, _data, dlen);		up_write(&priv->mib_sem);	}	/* re-set given data to what it was */	if (data)		mgt_le_to_cpu(isl_oid[n].flags & OID_FLAG_TYPE, data);	return ret;}/* None of these are cached */intmgt_set_varlen(islpci_private *priv, enum oid_num_t n, void *data, int extra_len){	int ret = 0;	struct islpci_mgmtframe *response;	int response_op = PIMFOR_OP_ERROR;	int dlen;	u32 oid;	BUG_ON(OID_NUM_LAST <= n);	dlen = isl_oid[n].size;	oid = isl_oid[n].oid;	mgt_cpu_to_le(isl_oid[n].flags & OID_FLAG_TYPE, data);	if (islpci_get_state(priv) >= PRV_STATE_READY) {		ret = islpci_mgt_transaction(priv->ndev, PIMFOR_OP_SET, oid,					     data, dlen + extra_len, &response);		if (!ret) {			response_op = response->header->operation;			islpci_mgt_release(response);		}		if (ret || response_op == PIMFOR_OP_ERROR)			ret = -EIO;	} else 		ret = -EIO;	/* re-set given data to what it was */	if (data)		mgt_le_to_cpu(isl_oid[n].flags & OID_FLAG_TYPE, data);	return ret;}intmgt_get_request(islpci_private *priv, enum oid_num_t n, int extra, void *data,		union oid_res_t *res){	int ret = -EIO;	int reslen = 0;	struct islpci_mgmtframe *response = NULL;	int dlen;	void *cache, *_res = NULL;	u32 oid;	BUG_ON(OID_NUM_LAST <= n);	BUG_ON(extra > isl_oid[n].range);	res->ptr = NULL;	if (!priv->mib)		/* memory has been freed */		return -1;	dlen = isl_oid[n].size;	cache = priv->mib[n];	cache += cache ? extra * dlen : 0;	oid = isl_oid[n].oid + extra;	reslen = dlen;	if (cache)		down_read(&priv->mib_sem);	if (islpci_get_state(priv) >= PRV_STATE_READY) {		ret = islpci_mgt_transaction(priv->ndev, PIMFOR_OP_GET,					     oid, data, dlen, &response);		if (ret || !response ||		    response->header->operation == PIMFOR_OP_ERROR) {			if (response)				islpci_mgt_release(response);			ret = -EIO;		}		if (!ret) {			_res = response->data;			reslen = response->header->length;		}	} else if (cache) {		_res = cache;		ret = 0;	}	if ((isl_oid[n].flags & OID_FLAG_TYPE) == OID_TYPE_U32)		res->u = ret ? 0 : le32_to_cpu(*(u32 *) _res);	else {		res->ptr = kmalloc(reslen, GFP_KERNEL);		BUG_ON(res->ptr == NULL);		if (ret)			memset(res->ptr, 0, reslen);		else {			memcpy(res->ptr, _res, reslen);			mgt_le_to_cpu(isl_oid[n].flags & OID_FLAG_TYPE,				      res->ptr);		}	}	if (cache)		up_read(&priv->mib_sem);	if (response && !ret)		islpci_mgt_release(response);	if (reslen > isl_oid[n].size)		printk(KERN_DEBUG		       "mgt_get_request(0x%x): received data length was bigger "		       "than expected (%d > %d). Memory is probably corrupted...",		       oid, reslen, isl_oid[n].size);	return ret;}/* lock outside */intmgt_commit_list(islpci_private *priv, enum oid_num_t *l, int n){	int i, ret = 0;	struct islpci_mgmtframe *response;	for (i = 0; i < n; i++) {		struct oid_t *t = &(isl_oid[l[i]]);		void *data = priv->mib[l[i]];		int j = 0;		u32 oid = t->oid;		BUG_ON(data == NULL);		while (j <= t->range) {			int r = islpci_mgt_transaction(priv->ndev, PIMFOR_OP_SET,						      oid, data, t->size,						      &response);			if (response) {				r |= (response->header->operation == PIMFOR_OP_ERROR);				islpci_mgt_release(response);			}			if (r)				printk(KERN_ERR "%s: mgt_commit_list: failure. "					"oid=%08x err=%d\n",					priv->ndev->name, oid, r);			ret |= r;			j++;			oid++;			data += t->size;		}	}	return ret;}/* Lock outside */voidmgt_set(islpci_private *priv, enum oid_num_t n, void *data){	BUG_ON(OID_NUM_LAST <= n);	BUG_ON(priv->mib[n] == NULL);	memcpy(priv->mib[n], data, isl_oid[n].size);	mgt_cpu_to_le(isl_oid[n].flags & OID_FLAG_TYPE, priv->mib[n]);}voidmgt_get(islpci_private *priv, enum oid_num_t n, void *res){	BUG_ON(OID_NUM_LAST <= n);	BUG_ON(priv->mib[n] == NULL);	BUG_ON(res == NULL);	memcpy(res, priv->mib[n], isl_oid[n].size);	mgt_le_to_cpu(isl_oid[n].flags & OID_FLAG_TYPE, res);}/* Commits the cache. Lock outside. */static enum oid_num_t commit_part1[] = {	OID_INL_CONFIG,	OID_INL_MODE,	DOT11_OID_BSSTYPE,	DOT11_OID_CHANNEL,	DOT11_OID_MLMEAUTOLEVEL};static enum oid_num_t commit_part2[] = {	DOT11_OID_SSID,	DOT11_OID_PSMBUFFER,	DOT11_OID_AUTHENABLE,	DOT11_OID_PRIVACYINVOKED,	DOT11_OID_EXUNENCRYPTED,	DOT11_OID_DEFKEYX,	/* MULTIPLE */	DOT11_OID_DEFKEYID,	DOT11_OID_DOT1XENABLE,	OID_INL_DOT11D_CONFORMANCE,	/* Do not initialize this - fw < 1.0.4.3 rejects it	OID_INL_OUTPUTPOWER,	*/};/* update the MAC addr. */static intmgt_update_addr(islpci_private *priv){	struct islpci_mgmtframe *res;	int ret;	ret = islpci_mgt_transaction(priv->ndev, PIMFOR_OP_GET,				     isl_oid[GEN_OID_MACADDRESS].oid, NULL,				     isl_oid[GEN_OID_MACADDRESS].size, &res);	if ((ret == 0) && res && (res->header->operation != PIMFOR_OP_ERROR))		memcpy(priv->ndev->dev_addr, res->data, 6);	else		ret = -EIO;	if (res)		islpci_mgt_release(res);	if (ret)		printk(KERN_ERR "%s: mgt_update_addr: failure\n", priv->ndev->name);	return ret;}#define VEC_SIZE(a) (sizeof(a)/sizeof(a[0]))intmgt_commit(islpci_private *priv){	int rvalue;	u32 u;	if (islpci_get_state(priv) < PRV_STATE_INIT)		return 0;	rvalue = mgt_commit_list(priv, commit_part1, VEC_SIZE(commit_part1));	if (priv->iw_mode != IW_MODE_MONITOR)		rvalue |= mgt_commit_list(priv, commit_part2, VEC_SIZE(commit_part2));	u = OID_INL_MODE;	rvalue |= mgt_commit_list(priv, &u, 1);	rvalue |= mgt_update_addr(priv);	if (rvalue) {		/* some request have failed. The device might be in an		   incoherent state. We should reset it ! */		printk(KERN_DEBUG "%s: mgt_commit: failure\n", priv->ndev->name);	}	return rvalue;}/* The following OIDs need to be "unlatched": * * MEDIUMLIMIT,BEACONPERIOD,DTIMPERIOD,ATIMWINDOW,LISTENINTERVAL * FREQUENCY,EXTENDEDRATES. * * The way to do this is to set ESSID. Note though that they may get  * unlatch before though by setting another OID. */#if 0voidmgt_unlatch_all(islpci_private *priv){	u32 u;	int rvalue = 0;	if (islpci_get_state(priv) < PRV_STATE_INIT)		return;	u = DOT11_OID_SSID;	rvalue = mgt_commit_list(priv, &u, 1);	/* Necessary if in MANUAL RUN mode? */#if 0	u = OID_INL_MODE;	rvalue |= mgt_commit_list(priv, &u, 1);	u = DOT11_OID_MLMEAUTOLEVEL;	rvalue |= mgt_commit_list(priv, &u, 1);	u = OID_INL_MODE;	rvalue |= mgt_commit_list(priv, &u, 1);#endif	if (rvalue)		printk(KERN_DEBUG "%s: Unlatching OIDs failed\n", priv->ndev->name);}#endif/* This will tell you if you are allowed to answer a mlme(ex) request .*/intmgt_mlme_answer(islpci_private *priv){	u32 mlmeautolevel;	/* Acquire a read lock because if we are in a mode change, it's	 * possible to answer true, while the card is leaving master to managed	 * mode. Answering to a mlme in this situation could hang the card.	 */	down_read(&priv->mib_sem);	mlmeautolevel =	    le32_to_cpu(*(u32 *) priv->mib[DOT11_OID_MLMEAUTOLEVEL]);	up_read(&priv->mib_sem);	return ((priv->iw_mode == IW_MODE_MASTER) &&		(mlmeautolevel >= DOT11_MLME_INTERMEDIATE));}enum oid_num_tmgt_oidtonum(u32 oid){	int i;	for (i = 0; i < OID_NUM_LAST; i++)		if (isl_oid[i].oid == oid)			return i;	printk(KERN_DEBUG "looking for an unknown oid 0x%x", oid);	return OID_NUM_LAST;}intmgt_response_to_str(enum oid_num_t n, union oid_res_t *r, char *str){	switch (isl_oid[n].flags & OID_FLAG_TYPE) {	case OID_TYPE_U32:		return snprintf(str, PRIV_STR_SIZE, "%u\n", r->u);		break;	case OID_TYPE_BUFFER:{			struct obj_buffer *buff = r->ptr;			return snprintf(str, PRIV_STR_SIZE,					"size=%u\naddr=0x%X\n", buff->size,					buff->addr);		}		break;	case OID_TYPE_BSS:{			struct obj_bss *bss = r->ptr;			return snprintf(str, PRIV_STR_SIZE,					"age=%u\nchannel=%u\n"					"capinfo=0x%X\nrates=0x%X\n"					"basic_rates=0x%X\n", bss->age,					bss->channel, bss->capinfo,					bss->rates, bss->basic_rates);		}		break;	case OID_TYPE_BSSLIST:{			struct obj_bsslist *list = r->ptr;			int i, k;			k = snprintf(str, PRIV_STR_SIZE, "nr=%u\n", list->nr);			for (i = 0; i < list->nr; i++)				k += snprintf(str + k, PRIV_STR_SIZE - k,					      "bss[%u] : \nage=%u\nchannel=%u\n"					      "capinfo=0x%X\nrates=0x%X\n"					      "basic_rates=0x%X\n",					      i, list->bsslist[i].age,					      list->bsslist[i].channel,					      list->bsslist[i].capinfo,					      list->bsslist[i].rates,					      list->bsslist[i].basic_rates);			return k;		}		break;	case OID_TYPE_FREQUENCIES:{			struct obj_frequencies *freq = r->ptr;			int i, t;			printk("nr : %u\n", freq->nr);			t = snprintf(str, PRIV_STR_SIZE, "nr=%u\n", freq->nr);			for (i = 0; i < freq->nr; i++)				t += snprintf(str + t, PRIV_STR_SIZE - t,					      "mhz[%u]=%u\n", i, freq->mhz[i]);			return t;		}		break;	case OID_TYPE_MLME:{			struct obj_mlme *mlme = r->ptr;			return snprintf(str, PRIV_STR_SIZE,					"id=0x%X\nstate=0x%X\ncode=0x%X\n",					mlme->id, mlme->state, mlme->code);		}		break;	case OID_TYPE_MLMEEX:{			struct obj_mlmeex *mlme = r->ptr;			return snprintf(str, PRIV_STR_SIZE,					"id=0x%X\nstate=0x%X\n"					"code=0x%X\nsize=0x%X\n", mlme->id,					mlme->state, mlme->code, mlme->size);		}		break;	case OID_TYPE_ATTACH:{			struct obj_attachment *attach = r->ptr;			return snprintf(str, PRIV_STR_SIZE,					"id=%d\nsize=%d\n",					attach->id,					attach->size);		}		break;	case OID_TYPE_SSID:{			struct obj_ssid *ssid = r->ptr;			return snprintf(str, PRIV_STR_SIZE,					"length=%u\noctets=%.*s\n",					ssid->length, ssid->length,					ssid->octets);		}		break;	case OID_TYPE_KEY:{			struct obj_key *key = r->ptr;			int t, i;			t = snprintf(str, PRIV_STR_SIZE,				     "type=0x%X\nlength=0x%X\nkey=0x",				     key->type, key->length);			for (i = 0; i < key->length; i++)				t += snprintf(str + t, PRIV_STR_SIZE - t,					      "%02X:", key->key[i]);			t += snprintf(str + t, PRIV_STR_SIZE - t, "\n");			return t;		}		break;	case OID_TYPE_RAW:	case OID_TYPE_ADDR:{			unsigned char *buff = r->ptr;			int t, i;			t = snprintf(str, PRIV_STR_SIZE, "hex data=");			for (i = 0; i < isl_oid[n].size; i++)				t += snprintf(str + t, PRIV_STR_SIZE - t,					      "%02X:", buff[i]);			t += snprintf(str + t, PRIV_STR_SIZE - t, "\n");			return t;		}		break;	default:		BUG();	}	return 0;}

⌨️ 快捷键说明

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