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

📄 ipw2200.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
		IPW_ERROR("Invalid args\n");		return -1;	}	return ipw_send_cmd(priv, &cmd);}static int ipw_send_system_config(struct ipw_priv *priv,				  struct ipw_sys_config *config){	struct host_cmd cmd = {		.cmd = IPW_CMD_SYSTEM_CONFIG,		.len = sizeof(*config)	};	if (!priv || !config) {		IPW_ERROR("Invalid args\n");		return -1;	}	memcpy(cmd.param, config, sizeof(*config));	return ipw_send_cmd(priv, &cmd);}static int ipw_send_ssid(struct ipw_priv *priv, u8 * ssid, int len){	struct host_cmd cmd = {		.cmd = IPW_CMD_SSID,		.len = min(len, IW_ESSID_MAX_SIZE)	};	if (!priv || !ssid) {		IPW_ERROR("Invalid args\n");		return -1;	}	memcpy(cmd.param, ssid, cmd.len);	return ipw_send_cmd(priv, &cmd);}static int ipw_send_adapter_address(struct ipw_priv *priv, u8 * mac){	struct host_cmd cmd = {		.cmd = IPW_CMD_ADAPTER_ADDRESS,		.len = ETH_ALEN	};	if (!priv || !mac) {		IPW_ERROR("Invalid args\n");		return -1;	}	IPW_DEBUG_INFO("%s: Setting MAC to " MAC_FMT "\n",		       priv->net_dev->name, MAC_ARG(mac));	memcpy(cmd.param, mac, ETH_ALEN);	return ipw_send_cmd(priv, &cmd);}/* * NOTE: This must be executed from our workqueue as it results in udelay * being called which may corrupt the keyboard if executed on default * workqueue */static void ipw_adapter_restart(void *adapter){	struct ipw_priv *priv = adapter;	if (priv->status & STATUS_RF_KILL_MASK)		return;	ipw_down(priv);	if (priv->assoc_network &&	    (priv->assoc_network->capability & WLAN_CAPABILITY_IBSS))		ipw_remove_current_network(priv);	if (ipw_up(priv)) {		IPW_ERROR("Failed to up device\n");		return;	}}static void ipw_bg_adapter_restart(void *data){	struct ipw_priv *priv = data;	down(&priv->sem);	ipw_adapter_restart(data);	up(&priv->sem);}#define IPW_SCAN_CHECK_WATCHDOG (5 * HZ)static void ipw_scan_check(void *data){	struct ipw_priv *priv = data;	if (priv->status & (STATUS_SCANNING | STATUS_SCAN_ABORTING)) {		IPW_DEBUG_SCAN("Scan completion watchdog resetting "			       "adapter (%dms).\n",			       IPW_SCAN_CHECK_WATCHDOG / 100);		queue_work(priv->workqueue, &priv->adapter_restart);	}}static void ipw_bg_scan_check(void *data){	struct ipw_priv *priv = data;	down(&priv->sem);	ipw_scan_check(data);	up(&priv->sem);}static int ipw_send_scan_request_ext(struct ipw_priv *priv,				     struct ipw_scan_request_ext *request){	struct host_cmd cmd = {		.cmd = IPW_CMD_SCAN_REQUEST_EXT,		.len = sizeof(*request)	};	memcpy(cmd.param, request, sizeof(*request));	return ipw_send_cmd(priv, &cmd);}static int ipw_send_scan_abort(struct ipw_priv *priv){	struct host_cmd cmd = {		.cmd = IPW_CMD_SCAN_ABORT,		.len = 0	};	if (!priv) {		IPW_ERROR("Invalid args\n");		return -1;	}	return ipw_send_cmd(priv, &cmd);}static int ipw_set_sensitivity(struct ipw_priv *priv, u16 sens){	struct host_cmd cmd = {		.cmd = IPW_CMD_SENSITIVITY_CALIB,		.len = sizeof(struct ipw_sensitivity_calib)	};	struct ipw_sensitivity_calib *calib = (struct ipw_sensitivity_calib *)	    &cmd.param;	calib->beacon_rssi_raw = sens;	return ipw_send_cmd(priv, &cmd);}static int ipw_send_associate(struct ipw_priv *priv,			      struct ipw_associate *associate){	struct host_cmd cmd = {		.cmd = IPW_CMD_ASSOCIATE,		.len = sizeof(*associate)	};	struct ipw_associate tmp_associate;	memcpy(&tmp_associate, associate, sizeof(*associate));	tmp_associate.policy_support =	    cpu_to_le16(tmp_associate.policy_support);	tmp_associate.assoc_tsf_msw = cpu_to_le32(tmp_associate.assoc_tsf_msw);	tmp_associate.assoc_tsf_lsw = cpu_to_le32(tmp_associate.assoc_tsf_lsw);	tmp_associate.capability = cpu_to_le16(tmp_associate.capability);	tmp_associate.listen_interval =	    cpu_to_le16(tmp_associate.listen_interval);	tmp_associate.beacon_interval =	    cpu_to_le16(tmp_associate.beacon_interval);	tmp_associate.atim_window = cpu_to_le16(tmp_associate.atim_window);	if (!priv || !associate) {		IPW_ERROR("Invalid args\n");		return -1;	}	memcpy(cmd.param, &tmp_associate, sizeof(*associate));	return ipw_send_cmd(priv, &cmd);}static int ipw_send_supported_rates(struct ipw_priv *priv,				    struct ipw_supported_rates *rates){	struct host_cmd cmd = {		.cmd = IPW_CMD_SUPPORTED_RATES,		.len = sizeof(*rates)	};	if (!priv || !rates) {		IPW_ERROR("Invalid args\n");		return -1;	}	memcpy(cmd.param, rates, sizeof(*rates));	return ipw_send_cmd(priv, &cmd);}static int ipw_set_random_seed(struct ipw_priv *priv){	struct host_cmd cmd = {		.cmd = IPW_CMD_SEED_NUMBER,		.len = sizeof(u32)	};	if (!priv) {		IPW_ERROR("Invalid args\n");		return -1;	}	get_random_bytes(&cmd.param, sizeof(u32));	return ipw_send_cmd(priv, &cmd);}static int ipw_send_card_disable(struct ipw_priv *priv, u32 phy_off){	struct host_cmd cmd = {		.cmd = IPW_CMD_CARD_DISABLE,		.len = sizeof(u32)	};	if (!priv) {		IPW_ERROR("Invalid args\n");		return -1;	}	*((u32 *) & cmd.param) = phy_off;	return ipw_send_cmd(priv, &cmd);}static int ipw_send_tx_power(struct ipw_priv *priv, struct ipw_tx_power *power){	struct host_cmd cmd = {		.cmd = IPW_CMD_TX_POWER,		.len = sizeof(*power)	};	if (!priv || !power) {		IPW_ERROR("Invalid args\n");		return -1;	}	memcpy(cmd.param, power, sizeof(*power));	return ipw_send_cmd(priv, &cmd);}static int ipw_set_tx_power(struct ipw_priv *priv){	const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee);	struct ipw_tx_power tx_power;	s8 max_power;	int i;	memset(&tx_power, 0, sizeof(tx_power));	/* configure device for 'G' band */	tx_power.ieee_mode = IPW_G_MODE;	tx_power.num_channels = geo->bg_channels;	for (i = 0; i < geo->bg_channels; i++) {		max_power = geo->bg[i].max_power;		tx_power.channels_tx_power[i].channel_number =		    geo->bg[i].channel;		tx_power.channels_tx_power[i].tx_power = max_power ?		    min(max_power, priv->tx_power) : priv->tx_power;	}	if (ipw_send_tx_power(priv, &tx_power))		return -EIO;	/* configure device to also handle 'B' band */	tx_power.ieee_mode = IPW_B_MODE;	if (ipw_send_tx_power(priv, &tx_power))		return -EIO;	/* configure device to also handle 'A' band */	if (priv->ieee->abg_true) {		tx_power.ieee_mode = IPW_A_MODE;		tx_power.num_channels = geo->a_channels;		for (i = 0; i < tx_power.num_channels; i++) {			max_power = geo->a[i].max_power;			tx_power.channels_tx_power[i].channel_number =			    geo->a[i].channel;			tx_power.channels_tx_power[i].tx_power = max_power ?			    min(max_power, priv->tx_power) : priv->tx_power;		}		if (ipw_send_tx_power(priv, &tx_power))			return -EIO;	}	return 0;}static int ipw_send_rts_threshold(struct ipw_priv *priv, u16 rts){	struct ipw_rts_threshold rts_threshold = {		.rts_threshold = rts,	};	struct host_cmd cmd = {		.cmd = IPW_CMD_RTS_THRESHOLD,		.len = sizeof(rts_threshold)	};	if (!priv) {		IPW_ERROR("Invalid args\n");		return -1;	}	memcpy(cmd.param, &rts_threshold, sizeof(rts_threshold));	return ipw_send_cmd(priv, &cmd);}static int ipw_send_frag_threshold(struct ipw_priv *priv, u16 frag){	struct ipw_frag_threshold frag_threshold = {		.frag_threshold = frag,	};	struct host_cmd cmd = {		.cmd = IPW_CMD_FRAG_THRESHOLD,		.len = sizeof(frag_threshold)	};	if (!priv) {		IPW_ERROR("Invalid args\n");		return -1;	}	memcpy(cmd.param, &frag_threshold, sizeof(frag_threshold));	return ipw_send_cmd(priv, &cmd);}static int ipw_send_power_mode(struct ipw_priv *priv, u32 mode){	struct host_cmd cmd = {		.cmd = IPW_CMD_POWER_MODE,		.len = sizeof(u32)	};	u32 *param = (u32 *) (&cmd.param);	if (!priv) {		IPW_ERROR("Invalid args\n");		return -1;	}	/* If on battery, set to 3, if AC set to CAM, else user	 * level */	switch (mode) {	case IPW_POWER_BATTERY:		*param = IPW_POWER_INDEX_3;		break;	case IPW_POWER_AC:		*param = IPW_POWER_MODE_CAM;		break;	default:		*param = mode;		break;	}	return ipw_send_cmd(priv, &cmd);}static int ipw_send_retry_limit(struct ipw_priv *priv, u8 slimit, u8 llimit){	struct ipw_retry_limit retry_limit = {		.short_retry_limit = slimit,		.long_retry_limit = llimit	};	struct host_cmd cmd = {		.cmd = IPW_CMD_RETRY_LIMIT,		.len = sizeof(retry_limit)	};	if (!priv) {		IPW_ERROR("Invalid args\n");		return -1;	}	memcpy(cmd.param, &retry_limit, sizeof(retry_limit));	return ipw_send_cmd(priv, &cmd);}/* * The IPW device contains a Microwire compatible EEPROM that stores * various data like the MAC address.  Usually the firmware has exclusive * access to the eeprom, but during device initialization (before the * device driver has sent the HostComplete command to the firmware) the * device driver has read access to the EEPROM by way of indirect addressing * through a couple of memory mapped registers. * * The following is a simplified implementation for pulling data out of the * the eeprom, along with some helper functions to find information in * the per device private data's copy of the eeprom. * * NOTE: To better understand how these functions work (i.e what is a chip *       select and why do have to keep driving the eeprom clock?), read *       just about any data sheet for a Microwire compatible EEPROM. *//* write a 32 bit value into the indirect accessor register */static inline void eeprom_write_reg(struct ipw_priv *p, u32 data){	ipw_write_reg32(p, FW_MEM_REG_EEPROM_ACCESS, data);	/* the eeprom requires some time to complete the operation */	udelay(p->eeprom_delay);	return;}/* perform a chip select operation */static inline void eeprom_cs(struct ipw_priv *priv){	eeprom_write_reg(priv, 0);	eeprom_write_reg(priv, EEPROM_BIT_CS);	eeprom_write_reg(priv, EEPROM_BIT_CS | EEPROM_BIT_SK);	eeprom_write_reg(priv, EEPROM_BIT_CS);}/* perform a chip select operation */static inline void eeprom_disable_cs(struct ipw_priv *priv){	eeprom_write_reg(priv, EEPROM_BIT_CS);	eeprom_write_reg(priv, 0);	eeprom_write_reg(priv, EEPROM_BIT_SK);}/* push a single bit down to the eeprom */static inline void eeprom_write_bit(struct ipw_priv *p, u8 bit){	int d = (bit ? EEPROM_BIT_DI : 0);	eeprom_write_reg(p, EEPROM_BIT_CS | d);	eeprom_write_reg(p, EEPROM_BIT_CS | d | EEPROM_BIT_SK);}/* push an opcode followed by an address down to the eeprom */static void eeprom_op(struct ipw_priv *priv, u8 op, u8 addr){	int i;	eeprom_cs(priv);	eeprom_write_bit(priv, 1);	eeprom_write_bit(priv, op & 2);	eeprom_write_bit(priv, op & 1);	for (i = 7; i >= 0; i--) {		eeprom_write_bit(priv, addr & (1 << i));	}}/* pull 16 bits off the eeprom, one bit at a time */static u16 eeprom_read_u16(struct ipw_priv *priv, u8 addr){	int i;	u16 r = 0;	/* Send READ Opcode */	eeprom_op(priv, EEPROM_CMD_READ, addr);	/* Send dummy bit */	eeprom_write_reg(priv, EEPROM_BIT_CS);	/* Read the byte off the eeprom one bit at a time */	for (i = 0; i < 16; i++) {		u32 data = 0;		eeprom_write_reg(priv, EEPROM_BIT_CS | EEPROM_BIT_SK);		eeprom_write_reg(priv, EEPROM_BIT_CS);		data = ipw_read_reg32(priv, FW_MEM_REG_EEPROM_ACCESS);		r = (r << 1) | ((data & EEPROM_BIT_DO) ? 1 : 0);	}	/* Send another dummy bit */	eeprom_write_reg(priv, 0);	eeprom_disable_cs(priv);	return r;}/* helper function for pulling the mac address out of the private *//* data's copy of the eeprom data                                 */static void eeprom_parse_mac(struct ipw_priv *priv, u8 * mac){	memcpy(mac, &priv->eeprom[EEPROM_MAC_ADDRESS], 6);}/* * Either the device driver (i.e. the host) or the firmware can * load eeprom data into the designated region in SRAM.  If neither * happens then the FW will shutdown with a fatal error. * * In order to signal the FW to load the EEPROM, the EEPROM_L

⌨️ 快捷键说明

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