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

📄 ipw2200.c

📁 和我之前上载的intel 802.11协议源码是配套的
💻 C
📖 第 1 页 / 共 5 页
字号:
}static DEVICE_ATTR(net_stats, S_IWUSR | S_IRUGO,		   show_net_stats, store_net_stats);static void notify_wx_assoc_event(struct ipw_priv *priv){	union iwreq_data wrqu;	wrqu.ap_addr.sa_family = ARPHRD_ETHER;	if (priv->status & STATUS_ASSOCIATED)		memcpy(wrqu.ap_addr.sa_data, priv->bssid, ETH_ALEN);	else		memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);	wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL);}static void ipw_irq_tasklet(struct ipw_priv *priv){	u32 inta, inta_mask, handled = 0;	unsigned long flags;	int rc = 0;	spin_lock_irqsave(&priv->irq_lock, flags);	inta = ipw_read32(priv, IPW_INTA_RW);	inta_mask = ipw_read32(priv, IPW_INTA_MASK_R);	inta &= (IPW_INTA_MASK_ALL & inta_mask);	/* Add any cached INTA values that need to be handled */	inta |= priv->isr_inta;	spin_unlock_irqrestore(&priv->irq_lock, flags);	spin_lock_irqsave(&priv->lock, flags);	/* handle all the justifications for the interrupt */	if (inta & IPW_INTA_BIT_RX_TRANSFER) {		ipw_rx(priv);		handled |= IPW_INTA_BIT_RX_TRANSFER;	}	if (inta & IPW_INTA_BIT_TX_CMD_QUEUE) {		IPW_DEBUG_HC("Command completed.\n");		rc = ipw_queue_tx_reclaim(priv, &priv->txq_cmd, -1);		priv->status &= ~STATUS_HCMD_ACTIVE;		wake_up_interruptible(&priv->wait_command_queue);		handled |= IPW_INTA_BIT_TX_CMD_QUEUE;	}	if (inta & IPW_INTA_BIT_TX_QUEUE_1) {		IPW_DEBUG_TX("TX_QUEUE_1\n");		rc = ipw_queue_tx_reclaim(priv, &priv->txq[0], 0);		handled |= IPW_INTA_BIT_TX_QUEUE_1;	}	if (inta & IPW_INTA_BIT_TX_QUEUE_2) {		IPW_DEBUG_TX("TX_QUEUE_2\n");		rc = ipw_queue_tx_reclaim(priv, &priv->txq[1], 1);		handled |= IPW_INTA_BIT_TX_QUEUE_2;	}	if (inta & IPW_INTA_BIT_TX_QUEUE_3) {		IPW_DEBUG_TX("TX_QUEUE_3\n");		rc = ipw_queue_tx_reclaim(priv, &priv->txq[2], 2);		handled |= IPW_INTA_BIT_TX_QUEUE_3;	}	if (inta & IPW_INTA_BIT_TX_QUEUE_4) {		IPW_DEBUG_TX("TX_QUEUE_4\n");		rc = ipw_queue_tx_reclaim(priv, &priv->txq[3], 3);		handled |= IPW_INTA_BIT_TX_QUEUE_4;	}	if (inta & IPW_INTA_BIT_STATUS_CHANGE) {		IPW_WARNING("STATUS_CHANGE\n");		handled |= IPW_INTA_BIT_STATUS_CHANGE;	}	if (inta & IPW_INTA_BIT_BEACON_PERIOD_EXPIRED) {		IPW_WARNING("TX_PERIOD_EXPIRED\n");		handled |= IPW_INTA_BIT_BEACON_PERIOD_EXPIRED;	}	if (inta & IPW_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE) {		IPW_WARNING("HOST_CMD_DONE\n");		handled |= IPW_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE;	}	if (inta & IPW_INTA_BIT_FW_INITIALIZATION_DONE) {		IPW_WARNING("FW_INITIALIZATION_DONE\n");		handled |= IPW_INTA_BIT_FW_INITIALIZATION_DONE;	}	if (inta & IPW_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE) {		IPW_WARNING("PHY_OFF_DONE\n");		handled |= IPW_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE;	}	if (inta & IPW_INTA_BIT_RF_KILL_DONE) {		IPW_DEBUG_RF_KILL("RF_KILL_DONE\n");		priv->status |= STATUS_RF_KILL_HW;		wake_up_interruptible(&priv->wait_command_queue);		priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING);		cancel_delayed_work(&priv->request_scan);		schedule_work(&priv->link_down);		queue_delayed_work(priv->workqueue, &priv->rf_kill, 2 * HZ);		handled |= IPW_INTA_BIT_RF_KILL_DONE;	}	if (inta & IPW_INTA_BIT_FATAL_ERROR) {		IPW_WARNING("Firmware error detected.  Restarting.\n");		if (priv->error) {			IPW_DEBUG_FW("Sysfs 'error' log already exists.\n");			if (ipw_debug_level & IPW_DL_FW_ERRORS) {				struct ipw_fw_error *error =				    ipw_alloc_error_log(priv);				ipw_dump_error_log(priv, error);				kfree(error);			}		} else {			priv->error = ipw_alloc_error_log(priv);			if (priv->error)				IPW_DEBUG_FW("Sysfs 'error' log captured.\n");			else				IPW_DEBUG_FW("Error allocating sysfs 'error' "					     "log.\n");			if (ipw_debug_level & IPW_DL_FW_ERRORS)				ipw_dump_error_log(priv, priv->error);		}		/* XXX: If hardware encryption is for WPA/WPA2,		 * we have to notify the supplicant. */		if (priv->ieee->sec.encrypt) {			priv->status &= ~STATUS_ASSOCIATED;			notify_wx_assoc_event(priv);		}		/* Keep the restart process from trying to send host		 * commands by clearing the INIT status bit */		priv->status &= ~STATUS_INIT;		/* Cancel currently queued command. */		priv->status &= ~STATUS_HCMD_ACTIVE;		wake_up_interruptible(&priv->wait_command_queue);		queue_work(priv->workqueue, &priv->adapter_restart);		handled |= IPW_INTA_BIT_FATAL_ERROR;	}	if (inta & IPW_INTA_BIT_PARITY_ERROR) {		IPW_ERROR("Parity error\n");		handled |= IPW_INTA_BIT_PARITY_ERROR;	}	if (handled != inta) {		IPW_ERROR("Unhandled INTA bits 0x%08x\n", inta & ~handled);	}	spin_unlock_irqrestore(&priv->lock, flags);	/* enable all interrupts */	ipw_enable_interrupts(priv);}#define IPW_CMD(x) case IPW_CMD_ ## x : return #xstatic char *get_cmd_string(u8 cmd){	switch (cmd) {		IPW_CMD(HOST_COMPLETE);		IPW_CMD(POWER_DOWN);		IPW_CMD(SYSTEM_CONFIG);		IPW_CMD(MULTICAST_ADDRESS);		IPW_CMD(SSID);		IPW_CMD(ADAPTER_ADDRESS);		IPW_CMD(PORT_TYPE);		IPW_CMD(RTS_THRESHOLD);		IPW_CMD(FRAG_THRESHOLD);		IPW_CMD(POWER_MODE);		IPW_CMD(WEP_KEY);		IPW_CMD(TGI_TX_KEY);		IPW_CMD(SCAN_REQUEST);		IPW_CMD(SCAN_REQUEST_EXT);		IPW_CMD(ASSOCIATE);		IPW_CMD(SUPPORTED_RATES);		IPW_CMD(SCAN_ABORT);		IPW_CMD(TX_FLUSH);		IPW_CMD(QOS_PARAMETERS);		IPW_CMD(DINO_CONFIG);		IPW_CMD(RSN_CAPABILITIES);		IPW_CMD(RX_KEY);		IPW_CMD(CARD_DISABLE);		IPW_CMD(SEED_NUMBER);		IPW_CMD(TX_POWER);		IPW_CMD(COUNTRY_INFO);		IPW_CMD(AIRONET_INFO);		IPW_CMD(AP_TX_POWER);		IPW_CMD(CCKM_INFO);		IPW_CMD(CCX_VER_INFO);		IPW_CMD(SET_CALIBRATION);		IPW_CMD(SENSITIVITY_CALIB);		IPW_CMD(RETRY_LIMIT);		IPW_CMD(IPW_PRE_POWER_DOWN);		IPW_CMD(VAP_BEACON_TEMPLATE);		IPW_CMD(VAP_DTIM_PERIOD);		IPW_CMD(EXT_SUPPORTED_RATES);		IPW_CMD(VAP_LOCAL_TX_PWR_CONSTRAINT);		IPW_CMD(VAP_QUIET_INTERVALS);		IPW_CMD(VAP_CHANNEL_SWITCH);		IPW_CMD(VAP_MANDATORY_CHANNELS);		IPW_CMD(VAP_CELL_PWR_LIMIT);		IPW_CMD(VAP_CF_PARAM_SET);		IPW_CMD(VAP_SET_BEACONING_STATE);		IPW_CMD(MEASUREMENT);		IPW_CMD(POWER_CAPABILITY);		IPW_CMD(SUPPORTED_CHANNELS);		IPW_CMD(TPC_REPORT);		IPW_CMD(WME_INFO);		IPW_CMD(PRODUCTION_COMMAND);	default:		return "UNKNOWN";	}}#define HOST_COMPLETE_TIMEOUT HZstatic int __ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd){	int rc = 0;	unsigned long flags;	spin_lock_irqsave(&priv->lock, flags);	if (priv->status & STATUS_HCMD_ACTIVE) {		IPW_ERROR("Failed to send %s: Already sending a command.\n",			  get_cmd_string(cmd->cmd));		spin_unlock_irqrestore(&priv->lock, flags);		return -EAGAIN;	}	priv->status |= STATUS_HCMD_ACTIVE;	if (priv->cmdlog) {		priv->cmdlog[priv->cmdlog_pos].jiffies = jiffies;		priv->cmdlog[priv->cmdlog_pos].cmd.cmd = cmd->cmd;		priv->cmdlog[priv->cmdlog_pos].cmd.len = cmd->len;		memcpy(priv->cmdlog[priv->cmdlog_pos].cmd.param, cmd->param,		       cmd->len);		priv->cmdlog[priv->cmdlog_pos].retcode = -1;	}	IPW_DEBUG_HC("%s command (#%d) %d bytes: 0x%08X\n",		     get_cmd_string(cmd->cmd), cmd->cmd, cmd->len,		     priv->status);#ifndef DEBUG_CMD_WEP_KEY	if (cmd->cmd == IPW_CMD_WEP_KEY)		IPW_DEBUG_HC("WEP_KEY command masked out for secure.\n");	else#endif		printk_buf(IPW_DL_HOST_COMMAND, (u8 *) cmd->param, cmd->len);	rc = ipw_queue_tx_hcmd(priv, cmd->cmd, cmd->param, cmd->len, 0);	if (rc) {		priv->status &= ~STATUS_HCMD_ACTIVE;		IPW_ERROR("Failed to send %s: Reason %d\n",			  get_cmd_string(cmd->cmd), rc);		spin_unlock_irqrestore(&priv->lock, flags);		goto exit;	}	spin_unlock_irqrestore(&priv->lock, flags);	rc = wait_event_interruptible_timeout(priv->wait_command_queue,					      !(priv->						status & STATUS_HCMD_ACTIVE),					      HOST_COMPLETE_TIMEOUT);	if (rc == 0) {		spin_lock_irqsave(&priv->lock, flags);		if (priv->status & STATUS_HCMD_ACTIVE) {			IPW_ERROR("Failed to send %s: Command timed out.\n",				  get_cmd_string(cmd->cmd));			priv->status &= ~STATUS_HCMD_ACTIVE;			spin_unlock_irqrestore(&priv->lock, flags);			rc = -EIO;			goto exit;		}		spin_unlock_irqrestore(&priv->lock, flags);	} else		rc = 0;	if (priv->status & STATUS_RF_KILL_HW) {		IPW_ERROR("Failed to send %s: Aborted due to RF kill switch.\n",			  get_cmd_string(cmd->cmd));		rc = -EIO;		goto exit;	}      exit:	if (priv->cmdlog) {		priv->cmdlog[priv->cmdlog_pos++].retcode = rc;		priv->cmdlog_pos %= priv->cmdlog_len;	}	return rc;}static int ipw_send_cmd_simple(struct ipw_priv *priv, u8 command){	struct host_cmd cmd = {		.cmd = command,	};	return __ipw_send_cmd(priv, &cmd);}static int ipw_send_cmd_pdu(struct ipw_priv *priv, u8 command, u8 len,			    void *data){	struct host_cmd cmd = {		.cmd = command,		.len = len,		.param = data,	};	return __ipw_send_cmd(priv, &cmd);}static int ipw_send_host_complete(struct ipw_priv *priv){	if (!priv) {		IPW_ERROR("Invalid args\n");		return -1;	}	return ipw_send_cmd_simple(priv, IPW_CMD_HOST_COMPLETE);}static int ipw_send_system_config(struct ipw_priv *priv){	return ipw_send_cmd_pdu(priv, IPW_CMD_SYSTEM_CONFIG,				sizeof(priv->sys_config), &priv->sys_config);}static int ipw_send_ssid(struct ipw_priv *priv, u8 * ssid, int len){	if (!priv || !ssid) {		IPW_ERROR("Invalid args\n");		return -1;	}	return ipw_send_cmd_pdu(priv, IPW_CMD_SSID, min(len, IW_ESSID_MAX_SIZE),				ssid);}static int ipw_send_adapter_address(struct ipw_priv *priv, u8 * mac){	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));	return ipw_send_cmd_pdu(priv, IPW_CMD_ADAPTER_ADDRESS, ETH_ALEN, mac);}/* * 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;	mutex_lock(&priv->mutex);	ipw_adapter_restart(data);	mutex_unlock(&priv->mutex);}#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 after (%dms).\n",			       jiffies_to_msecs(IPW_SCAN_CHECK_WATCHDOG));		queue_work(priv->workqueue, &priv->adapter_restart);	}}static void ipw_bg_scan_check(void *data){	struct ipw_priv *priv = data;	mutex_lock(&priv->mutex);	ipw_scan_check(data);	mutex_unlock(&priv->mutex);}static int ipw_send_scan_request_ext(struct ipw_priv *priv,				     struct ipw_scan_request_ext *request){	return ipw_send_cmd_pdu(priv, IPW_CMD_SCAN_REQUEST_EXT,				sizeof(*request), request);}static int ipw_send_scan_abort(struct ipw_priv *priv){	if (!priv) {		IPW_ERROR("Invalid args\n");		return -1;	}	return ipw_send_cmd_simple(priv, IPW_CMD_SCAN_ABORT);}static int ipw_set_sensitivity(struct ipw_priv *priv, u16 sens){	struct ipw_sensitivity_calib calib = {		.beacon_rssi_raw = cpu_to_le16(sens),	};	return ipw_send_cmd_pdu(priv, IPW_CMD_SENSITIVITY_CALIB, sizeof(calib),				&calib);}static int ipw_send_associate(struct ipw_priv *priv,			      struct ipw_associate *associate){	struct ipw_associate tmp_associate;	if (!priv || !associate) {		IPW_ERROR("Invalid args\n");		return -1;	}	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);	return ipw_send_cmd_pdu(priv, IPW_CMD_ASSOCIATE, sizeof(tmp_associate),				&tmp_associate);}static int ipw_send_supported_rates(struct ipw_priv *priv,				    struct ipw_supported_rates *rates){	if (!priv || !rates) {		IPW_ERROR("Invalid args\n");		return -1;	}	return ipw_send_cmd_pdu(priv, IPW_CMD_SUPPORTED_RATES, sizeof(*rates),				rates);}static int ipw_set_r

⌨️ 快捷键说明

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