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

📄 ipw2200.c

📁 和我之前上载的intel 802.11协议源码是配套的
💻 C
📖 第 1 页 / 共 5 页
字号:
	u32 dif_len = addr - aligned_addr;	u32 i;	IPW_DEBUG_IO("addr = %i, buf = %p, num = %i\n", addr, buf, num);	if (num <= 0) {		return;	}	/* Write the first dword (or portion) byte by byte */	if (unlikely(dif_len)) {		_ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);		/* Start writing at aligned_addr + dif_len */		for (i = dif_len; ((i < 4) && (num > 0)); i++, num--, buf++)			_ipw_write8(priv, IPW_INDIRECT_DATA + i, *buf);		aligned_addr += 4;	}	/* Write all of the middle dwords as dwords, with auto-increment */	_ipw_write32(priv, IPW_AUTOINC_ADDR, aligned_addr);	for (; num >= 4; buf += 4, aligned_addr += 4, num -= 4)		_ipw_write32(priv, IPW_AUTOINC_DATA, *(u32 *) buf);	/* Write the last dword (or portion) byte by byte */	if (unlikely(num)) {		_ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);		for (i = 0; num > 0; i++, num--, buf++)			_ipw_write8(priv, IPW_INDIRECT_DATA + i, *buf);	}}/* General purpose, no alignment requirement, iterative (multi-byte) write, *//*    for 1st 4K of SRAM/regs space */static void ipw_write_direct(struct ipw_priv *priv, u32 addr, void *buf,			     int num){	memcpy_toio((priv->hw_base + addr), buf, num);}/* Set bit(s) in low 4K of SRAM/regs */static inline void ipw_set_bit(struct ipw_priv *priv, u32 reg, u32 mask){	ipw_write32(priv, reg, ipw_read32(priv, reg) | mask);}/* Clear bit(s) in low 4K of SRAM/regs */static inline void ipw_clear_bit(struct ipw_priv *priv, u32 reg, u32 mask){	ipw_write32(priv, reg, ipw_read32(priv, reg) & ~mask);}static inline void __ipw_enable_interrupts(struct ipw_priv *priv){	if (priv->status & STATUS_INT_ENABLED)		return;	priv->status |= STATUS_INT_ENABLED;	ipw_write32(priv, IPW_INTA_MASK_R, IPW_INTA_MASK_ALL);}static inline void __ipw_disable_interrupts(struct ipw_priv *priv){	if (!(priv->status & STATUS_INT_ENABLED))		return;	priv->status &= ~STATUS_INT_ENABLED;	ipw_write32(priv, IPW_INTA_MASK_R, ~IPW_INTA_MASK_ALL);}static inline void ipw_enable_interrupts(struct ipw_priv *priv){	unsigned long flags;	spin_lock_irqsave(&priv->irq_lock, flags);	__ipw_enable_interrupts(priv);	spin_unlock_irqrestore(&priv->irq_lock, flags);}static inline void ipw_disable_interrupts(struct ipw_priv *priv){	unsigned long flags;	spin_lock_irqsave(&priv->irq_lock, flags);	__ipw_disable_interrupts(priv);	spin_unlock_irqrestore(&priv->irq_lock, flags);}static char *ipw_error_desc(u32 val){	switch (val) {	case IPW_FW_ERROR_OK:		return "ERROR_OK";	case IPW_FW_ERROR_FAIL:		return "ERROR_FAIL";	case IPW_FW_ERROR_MEMORY_UNDERFLOW:		return "MEMORY_UNDERFLOW";	case IPW_FW_ERROR_MEMORY_OVERFLOW:		return "MEMORY_OVERFLOW";	case IPW_FW_ERROR_BAD_PARAM:		return "BAD_PARAM";	case IPW_FW_ERROR_BAD_CHECKSUM:		return "BAD_CHECKSUM";	case IPW_FW_ERROR_NMI_INTERRUPT:		return "NMI_INTERRUPT";	case IPW_FW_ERROR_BAD_DATABASE:		return "BAD_DATABASE";	case IPW_FW_ERROR_ALLOC_FAIL:		return "ALLOC_FAIL";	case IPW_FW_ERROR_DMA_UNDERRUN:		return "DMA_UNDERRUN";	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);}static inline int ipw_is_init(struct ipw_priv *priv){	return (priv->status & STATUS_INIT) ? 1 : 0;}#include "compat.c"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);}static 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 msecs_to_jiffies(300)#define LD_TIME_LINK_OFF msecs_to_jiffies(2700)#define LD_TIME_ACT_ON msecs_to_jiffies(250)static void 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;	mutex_lock(&priv->mutex);	ipw_led_link_on(data);	mutex_unlock(&priv->mutex);}static 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;	mutex_lock(&priv->mutex);	ipw_led_link_off(data);	mutex_unlock(&priv->mutex);}static 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);	}}#if 0void 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);}#endif				/*  0  */static void ipw_led_activity_off(struct ipw_priv *priv){	unsigned long flags;	u32 led;

⌨️ 快捷键说明

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