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

📄 ipw2200.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
	case IPW_FW_ERROR_DMA_STATUS:		return "DMA_STATUS";	case IPW_FW_ERROR_DINO_ERROR:		return "DINO_ERROR";	case IPW_FW_ERROR_EEPROM_ERROR:		return "EEPROM_ERROR";	case IPW_FW_ERROR_SYSASSERT:		return "SYSASSERT";	case IPW_FW_ERROR_FATAL_ERROR:		return "FATAL_ERROR";	default:		return "UNKNOWN_ERROR";	}}static void ipw_dump_error_log(struct ipw_priv *priv,			       struct ipw_fw_error *error){	u32 i;	if (!error) {		IPW_ERROR("Error allocating and capturing error log.  "			  "Nothing to dump.\n");		return;	}	IPW_ERROR("Start IPW Error Log Dump:\n");	IPW_ERROR("Status: 0x%08X, Config: %08X\n",		  error->status, error->config);	for (i = 0; i < error->elem_len; i++)		IPW_ERROR("%s %i 0x%08x  0x%08x  0x%08x  0x%08x  0x%08x\n",			  ipw_error_desc(error->elem[i].desc),			  error->elem[i].time,			  error->elem[i].blink1,			  error->elem[i].blink2,			  error->elem[i].link1,			  error->elem[i].link2, error->elem[i].data);	for (i = 0; i < error->log_len; i++)		IPW_ERROR("%i\t0x%08x\t%i\n",			  error->log[i].time,			  error->log[i].data, error->log[i].event);}#endifstatic inline int ipw_is_init(struct ipw_priv *priv){	return (priv->status & STATUS_INIT) ? 1 : 0;}static int ipw_get_ordinal(struct ipw_priv *priv, u32 ord, void *val, u32 * len){	u32 addr, field_info, field_len, field_count, total_len;	IPW_DEBUG_ORD("ordinal = %i\n", ord);	if (!priv || !val || !len) {		IPW_DEBUG_ORD("Invalid argument\n");		return -EINVAL;	}	/* verify device ordinal tables have been initialized */	if (!priv->table0_addr || !priv->table1_addr || !priv->table2_addr) {		IPW_DEBUG_ORD("Access ordinals before initialization\n");		return -EINVAL;	}	switch (IPW_ORD_TABLE_ID_MASK & ord) {	case IPW_ORD_TABLE_0_MASK:		/*		 * TABLE 0: Direct access to a table of 32 bit values		 *		 * This is a very simple table with the data directly		 * read from the table		 */		/* remove the table id from the ordinal */		ord &= IPW_ORD_TABLE_VALUE_MASK;		/* boundary check */		if (ord > priv->table0_len) {			IPW_DEBUG_ORD("ordinal value (%i) longer then "				      "max (%i)\n", ord, priv->table0_len);			return -EINVAL;		}		/* verify we have enough room to store the value */		if (*len < sizeof(u32)) {			IPW_DEBUG_ORD("ordinal buffer length too small, "				      "need %zd\n", sizeof(u32));			return -EINVAL;		}		IPW_DEBUG_ORD("Reading TABLE0[%i] from offset 0x%08x\n",			      ord, priv->table0_addr + (ord << 2));		*len = sizeof(u32);		ord <<= 2;		*((u32 *) val) = ipw_read32(priv, priv->table0_addr + ord);		break;	case IPW_ORD_TABLE_1_MASK:		/*		 * TABLE 1: Indirect access to a table of 32 bit values		 *		 * This is a fairly large table of u32 values each		 * representing starting addr for the data (which is		 * also a u32)		 */		/* remove the table id from the ordinal */		ord &= IPW_ORD_TABLE_VALUE_MASK;		/* boundary check */		if (ord > priv->table1_len) {			IPW_DEBUG_ORD("ordinal value too long\n");			return -EINVAL;		}		/* verify we have enough room to store the value */		if (*len < sizeof(u32)) {			IPW_DEBUG_ORD("ordinal buffer length too small, "				      "need %zd\n", sizeof(u32));			return -EINVAL;		}		*((u32 *) val) =		    ipw_read_reg32(priv, (priv->table1_addr + (ord << 2)));		*len = sizeof(u32);		break;	case IPW_ORD_TABLE_2_MASK:		/*		 * TABLE 2: Indirect access to a table of variable sized values		 *		 * This table consist of six values, each containing		 *     - dword containing the starting offset of the data		 *     - dword containing the lengh in the first 16bits		 *       and the count in the second 16bits		 */		/* remove the table id from the ordinal */		ord &= IPW_ORD_TABLE_VALUE_MASK;		/* boundary check */		if (ord > priv->table2_len) {			IPW_DEBUG_ORD("ordinal value too long\n");			return -EINVAL;		}		/* get the address of statistic */		addr = ipw_read_reg32(priv, priv->table2_addr + (ord << 3));		/* get the second DW of statistics ;		 * two 16-bit words - first is length, second is count */		field_info =		    ipw_read_reg32(priv,				   priv->table2_addr + (ord << 3) +				   sizeof(u32));		/* get each entry length */		field_len = *((u16 *) & field_info);		/* get number of entries */		field_count = *(((u16 *) & field_info) + 1);		/* abort if not enought memory */		total_len = field_len * field_count;		if (total_len > *len) {			*len = total_len;			return -EINVAL;		}		*len = total_len;		if (!total_len)			return 0;		IPW_DEBUG_ORD("addr = 0x%08x, total_len = %i, "			      "field_info = 0x%08x\n",			      addr, total_len, field_info);		ipw_read_indirect(priv, addr, val, total_len);		break;	default:		IPW_DEBUG_ORD("Invalid ordinal!\n");		return -EINVAL;	}	return 0;}static void ipw_init_ordinals(struct ipw_priv *priv){	priv->table0_addr = IPW_ORDINALS_TABLE_LOWER;	priv->table0_len = ipw_read32(priv, priv->table0_addr);	IPW_DEBUG_ORD("table 0 offset at 0x%08x, len = %i\n",		      priv->table0_addr, priv->table0_len);	priv->table1_addr = ipw_read32(priv, IPW_ORDINALS_TABLE_1);	priv->table1_len = ipw_read_reg32(priv, priv->table1_addr);	IPW_DEBUG_ORD("table 1 offset at 0x%08x, len = %i\n",		      priv->table1_addr, priv->table1_len);	priv->table2_addr = ipw_read32(priv, IPW_ORDINALS_TABLE_2);	priv->table2_len = ipw_read_reg32(priv, priv->table2_addr);	priv->table2_len &= 0x0000ffff;	/* use first two bytes */	IPW_DEBUG_ORD("table 2 offset at 0x%08x, len = %i\n",		      priv->table2_addr, priv->table2_len);}u32 ipw_register_toggle(u32 reg){	reg &= ~IPW_START_STANDBY;	if (reg & IPW_GATE_ODMA)		reg &= ~IPW_GATE_ODMA;	if (reg & IPW_GATE_IDMA)		reg &= ~IPW_GATE_IDMA;	if (reg & IPW_GATE_ADMA)		reg &= ~IPW_GATE_ADMA;	return reg;}/* * LED behavior: * - On radio ON, turn on any LEDs that require to be on during start * - On initialization, start unassociated blink * - On association, disable unassociated blink * - On disassociation, start unassociated blink * - On radio OFF, turn off any LEDs started during radio on * */#define LD_TIME_LINK_ON 300#define LD_TIME_LINK_OFF 2700#define LD_TIME_ACT_ON 250void ipw_led_link_on(struct ipw_priv *priv){	unsigned long flags;	u32 led;	/* If configured to not use LEDs, or nic_type is 1,	 * then we don't toggle a LINK led */	if (priv->config & CFG_NO_LED || priv->nic_type == EEPROM_NIC_TYPE_1)		return;	spin_lock_irqsave(&priv->lock, flags);	if (!(priv->status & STATUS_RF_KILL_MASK) &&	    !(priv->status & STATUS_LED_LINK_ON)) {		IPW_DEBUG_LED("Link LED On\n");		led = ipw_read_reg32(priv, IPW_EVENT_REG);		led |= priv->led_association_on;		led = ipw_register_toggle(led);		IPW_DEBUG_LED("Reg: 0x%08X\n", led);		ipw_write_reg32(priv, IPW_EVENT_REG, led);		priv->status |= STATUS_LED_LINK_ON;		/* If we aren't associated, schedule turning the LED off */		if (!(priv->status & STATUS_ASSOCIATED))			queue_delayed_work(priv->workqueue,					   &priv->led_link_off,					   LD_TIME_LINK_ON);	}	spin_unlock_irqrestore(&priv->lock, flags);}static void ipw_bg_led_link_on(void *data){	struct ipw_priv *priv = data;	down(&priv->sem);	ipw_led_link_on(data);	up(&priv->sem);}void ipw_led_link_off(struct ipw_priv *priv){	unsigned long flags;	u32 led;	/* If configured not to use LEDs, or nic type is 1,	 * then we don't goggle the LINK led. */	if (priv->config & CFG_NO_LED || priv->nic_type == EEPROM_NIC_TYPE_1)		return;	spin_lock_irqsave(&priv->lock, flags);	if (priv->status & STATUS_LED_LINK_ON) {		led = ipw_read_reg32(priv, IPW_EVENT_REG);		led &= priv->led_association_off;		led = ipw_register_toggle(led);		IPW_DEBUG_LED("Reg: 0x%08X\n", led);		ipw_write_reg32(priv, IPW_EVENT_REG, led);		IPW_DEBUG_LED("Link LED Off\n");		priv->status &= ~STATUS_LED_LINK_ON;		/* If we aren't associated and the radio is on, schedule		 * turning the LED on (blink while unassociated) */		if (!(priv->status & STATUS_RF_KILL_MASK) &&		    !(priv->status & STATUS_ASSOCIATED))			queue_delayed_work(priv->workqueue, &priv->led_link_on,					   LD_TIME_LINK_OFF);	}	spin_unlock_irqrestore(&priv->lock, flags);}static void ipw_bg_led_link_off(void *data){	struct ipw_priv *priv = data;	down(&priv->sem);	ipw_led_link_off(data);	up(&priv->sem);}static inline void __ipw_led_activity_on(struct ipw_priv *priv){	u32 led;	if (priv->config & CFG_NO_LED)		return;	if (priv->status & STATUS_RF_KILL_MASK)		return;	if (!(priv->status & STATUS_LED_ACT_ON)) {		led = ipw_read_reg32(priv, IPW_EVENT_REG);		led |= priv->led_activity_on;		led = ipw_register_toggle(led);		IPW_DEBUG_LED("Reg: 0x%08X\n", led);		ipw_write_reg32(priv, IPW_EVENT_REG, led);		IPW_DEBUG_LED("Activity LED On\n");		priv->status |= STATUS_LED_ACT_ON;		cancel_delayed_work(&priv->led_act_off);		queue_delayed_work(priv->workqueue, &priv->led_act_off,				   LD_TIME_ACT_ON);	} else {		/* Reschedule LED off for full time period */		cancel_delayed_work(&priv->led_act_off);		queue_delayed_work(priv->workqueue, &priv->led_act_off,				   LD_TIME_ACT_ON);	}}void ipw_led_activity_on(struct ipw_priv *priv){	unsigned long flags;	spin_lock_irqsave(&priv->lock, flags);	__ipw_led_activity_on(priv);	spin_unlock_irqrestore(&priv->lock, flags);}void ipw_led_activity_off(struct ipw_priv *priv){	unsigned long flags;	u32 led;	if (priv->config & CFG_NO_LED)		return;	spin_lock_irqsave(&priv->lock, flags);	if (priv->status & STATUS_LED_ACT_ON) {		led = ipw_read_reg32(priv, IPW_EVENT_REG);		led &= priv->led_activity_off;		led = ipw_register_toggle(led);		IPW_DEBUG_LED("Reg: 0x%08X\n", led);		ipw_write_reg32(priv, IPW_EVENT_REG, led);		IPW_DEBUG_LED("Activity LED Off\n");		priv->status &= ~STATUS_LED_ACT_ON;	}	spin_unlock_irqrestore(&priv->lock, flags);}static void ipw_bg_led_activity_off(void *data){	struct ipw_priv *priv = data;	down(&priv->sem);	ipw_led_activity_off(data);	up(&priv->sem);}void ipw_led_band_on(struct ipw_priv *priv){	unsigned long flags;	u32 led;	/* Only nic type 1 supports mode LEDs */	if (priv->config & CFG_NO_LED ||	    priv->nic_type != EEPROM_NIC_TYPE_1 || !priv->assoc_network)		return;	spin_lock_irqsave(&priv->lock, flags);	led = ipw_read_reg32(priv, IPW_EVENT_REG);	if (priv->assoc_network->mode == IEEE_A) {		led |= priv->led_ofdm_on;		led &= priv->led_association_off;		IPW_DEBUG_LED("Mode LED On: 802.11a\n");	} else if (priv->assoc_network->mode == IEEE_G) {		led |= priv->led_ofdm_on;		led |= priv->led_association_on;		IPW_DEBUG_LED("Mode LED On: 802.11g\n");	} else {		led &= priv->led_ofdm_off;		led |= priv->led_association_on;		IPW_DEBUG_LED("Mode LED On: 802.11b\n");	}	led = ipw_register_toggle(led);	IPW_DEBUG_LED("Reg: 0x%08X\n", led);	ipw_write_reg32(priv, IPW_EVENT_REG, led);	spin_unlock_irqrestore(&priv->lock, flags);}void ipw_led_band_off(struct ipw_priv *priv){	unsigned long flags;	u32 led;	/* Only nic type 1 supports mode LEDs */	if (priv->config & CFG_NO_LED || priv->nic_type != EEPROM_NIC_TYPE_1)		return;	spin_lock_irqsave(&priv->lock, flags);	led = ipw_read_reg32(priv, IPW_EVENT_REG);	led &= priv->led_ofdm_off;	led &= priv->led_association_off;	led = ipw_register_toggle(led);	IPW_DEBUG_LED("Reg: 0x%08X\n", led);	ipw_write_reg32(priv, IPW_EVENT_REG, led);	spin_unlock_irqrestore(&priv->lock, flags);}void ipw_led_radio_on(struct ipw_priv *priv){	ipw_led_link_on(priv);}void ipw_led_radio_off(struct ipw_priv *priv){	ipw_led_activity_off(priv);	ipw_led_link_off(priv);}void ipw_led_link_up(struct ipw_priv *priv){	/* Set the Link Led on for all nic types */	ipw_led_link_on(priv);}void ipw_led_link_down(struct ipw_priv *priv){	ipw_led_activity_off(priv);	ipw_led_link_off(priv);	if (priv->status & STATUS_RF_KILL_MASK)		ipw_led_radio_off(priv);}

⌨️ 快捷键说明

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