📄 ipw2200.c
字号:
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; mutex_lock(&priv->mutex); ipw_led_activity_off(data); mutex_unlock(&priv->mutex);}static 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);}static 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);}static void ipw_led_radio_on(struct ipw_priv *priv){ ipw_led_link_on(priv);}static void ipw_led_radio_off(struct ipw_priv *priv){ ipw_led_activity_off(priv); ipw_led_link_off(priv);}static void ipw_led_link_up(struct ipw_priv *priv){ /* Set the Link Led on for all nic types */ ipw_led_link_on(priv);}static 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);}static void ipw_led_init(struct ipw_priv *priv){ priv->nic_type = priv->eeprom[EEPROM_NIC_TYPE]; /* Set the default PINs for the link and activity leds */ priv->led_activity_on = IPW_ACTIVITY_LED; priv->led_activity_off = ~(IPW_ACTIVITY_LED); priv->led_association_on = IPW_ASSOCIATED_LED; priv->led_association_off = ~(IPW_ASSOCIATED_LED); /* Set the default PINs for the OFDM leds */ priv->led_ofdm_on = IPW_OFDM_LED; priv->led_ofdm_off = ~(IPW_OFDM_LED); switch (priv->nic_type) { case EEPROM_NIC_TYPE_1: /* In this NIC type, the LEDs are reversed.... */ priv->led_activity_on = IPW_ASSOCIATED_LED; priv->led_activity_off = ~(IPW_ASSOCIATED_LED); priv->led_association_on = IPW_ACTIVITY_LED; priv->led_association_off = ~(IPW_ACTIVITY_LED); if (!(priv->config & CFG_NO_LED)) ipw_led_band_on(priv); /* And we don't blink link LEDs for this nic, so * just return here */ return; case EEPROM_NIC_TYPE_3: case EEPROM_NIC_TYPE_2: case EEPROM_NIC_TYPE_4: case EEPROM_NIC_TYPE_0: break; default: IPW_DEBUG_INFO("Unknown NIC type from EEPROM: %d\n", priv->nic_type); priv->nic_type = EEPROM_NIC_TYPE_0; break; } if (!(priv->config & CFG_NO_LED)) { if (priv->status & STATUS_ASSOCIATED) ipw_led_link_on(priv); else ipw_led_link_off(priv); }}static void ipw_led_shutdown(struct ipw_priv *priv){ ipw_led_activity_off(priv); ipw_led_link_off(priv); ipw_led_band_off(priv); cancel_delayed_work(&priv->led_link_on); cancel_delayed_work(&priv->led_link_off); cancel_delayed_work(&priv->led_act_off);}/* * The following adds a new attribute to the sysfs representation * of this device driver (i.e. a new file in /sys/bus/pci/drivers/ipw/) * used for controling the debug level. * * See the level definitions in ipw for details. */static ssize_t show_debug_level(struct device_driver *d, char *buf){ return sprintf(buf, "0x%08X\n", ipw_debug_level);}static ssize_t store_debug_level(struct device_driver *d, const char *buf, size_t count){ char *p = (char *)buf; u32 val; if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') { p++; if (p[0] == 'x' || p[0] == 'X') p++; val = simple_strtoul(p, &p, 16); } else val = simple_strtoul(p, &p, 10); if (p == buf) printk(KERN_INFO DRV_NAME ": %s is not in hex or decimal form.\n", buf); else ipw_debug_level = val; return strnlen(buf, count);}static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO, show_debug_level, store_debug_level);static inline u32 ipw_get_event_log_len(struct ipw_priv *priv){ /* length = 1st dword in log */ return ipw_read_reg32(priv, ipw_read32(priv, IPW_EVENT_LOG));}static void ipw_capture_event_log(struct ipw_priv *priv, u32 log_len, struct ipw_event *log){ u32 base; if (log_len) { base = ipw_read32(priv, IPW_EVENT_LOG); ipw_read_indirect(priv, base + sizeof(base) + sizeof(u32), (u8 *) log, sizeof(*log) * log_len); }}static struct ipw_fw_error *ipw_alloc_error_log(struct ipw_priv *priv){ struct ipw_fw_error *error; u32 log_len = ipw_get_event_log_len(priv); u32 base = ipw_read32(priv, IPW_ERROR_LOG); u32 elem_len = ipw_read_reg32(priv, base); error = kmalloc(sizeof(*error) + sizeof(*error->elem) * elem_len + sizeof(*error->log) * log_len, GFP_ATOMIC); if (!error) { IPW_ERROR("Memory allocation for firmware error log " "failed.\n"); return NULL; } error->jiffies = jiffies; error->status = priv->status; error->config = priv->config; error->elem_len = elem_len; error->log_len = log_len; error->elem = (struct ipw_error_elem *)error->payload; error->log = (struct ipw_event *)(error->elem + elem_len); ipw_capture_event_log(priv, log_len, error->log); if (elem_len) ipw_read_indirect(priv, base + sizeof(base), (u8 *) error->elem, sizeof(*error->elem) * elem_len); return error;}static ssize_t show_event_log(struct device *d,#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12) struct device_attribute *attr,#endif char *buf){ struct ipw_priv *priv = dev_get_drvdata(d); u32 log_len = ipw_get_event_log_len(priv); struct ipw_event log[log_len]; u32 len = 0, i; ipw_capture_event_log(priv, log_len, log); len += snprintf(buf + len, PAGE_SIZE - len, "%08X", log_len); for (i = 0; i < log_len; i++) len += snprintf(buf + len, PAGE_SIZE - len, "\n%08X%08X%08X", log[i].time, log[i].event, log[i].data); len += snprintf(buf + len, PAGE_SIZE - len, "\n"); return len;}static DEVICE_ATTR(event_log, S_IRUGO, show_event_log, NULL);static ssize_t show_error(struct device *d,#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12) struct device_attribute *attr,#endif char *buf){ struct ipw_priv *priv = dev_get_drvdata(d); u32 len = 0, i; if (!priv->error) return 0; len += snprintf(buf + len, PAGE_SIZE - len, "%08lX%08X%08X%08X", priv->error->jiffies, priv->error->status, priv->error->config, priv->error->elem_len); for (i = 0; i < priv->error->elem_len; i++) len += snprintf(buf + len, PAGE_SIZE - len, "\n%08X%08X%08X%08X%08X%08X%08X", priv->error->elem[i].time, priv->error->elem[i].desc, priv->error->elem[i].blink1, priv->error->elem[i].blink2, priv->error->elem[i].link1, priv->error->elem[i].link2, priv->error->elem[i].data); len += snprintf(buf + len, PAGE_SIZE - len, "\n%08X", priv->error->log_len); for (i = 0; i < priv->error->log_len; i++) len += snprintf(buf + len, PAGE_SIZE - len, "\n%08X%08X%08X", priv->error->log[i].time, priv->error->log[i].event, priv->error->log[i].data); len += snprintf(buf + len, PAGE_SIZE - len, "\n"); return len;}static ssize_t clear_error(struct device *d,#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12) struct device_attribute *attr,#endif const char *buf, size_t count){ struct ipw_priv *priv = dev_get_drvdata(d); kfree(priv->error); priv->error = NULL; return count;}static DEVICE_ATTR(error, S_IRUGO | S_IWUSR, show_error, clear_error);static ssize_t show_cmd_log(struct device *d,#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12) struct device_attribute *attr,#endif char *buf){ struct ipw_priv *priv = dev_get_drvdata(d); u32 len = 0, i; if (!priv->cmdlog) return 0; for (i = (priv->cmdlog_pos + 1) % priv->cmdlog_len; (i != priv->cmdlog_pos) && (PAGE_SIZE - len); i = (i + 1) % priv->cmdlog_len) { len += snprintf(buf + len, PAGE_SIZE - len, "\n%08lX%08X%08X%08X\n", priv->cmdlog[i].jiffies, priv->cmdlog[i].retcode, priv->cmdlog[i].cmd.cmd, priv->cmdlog[i].cmd.len); len += snprintk_buf(buf + len, PAGE_SIZE - len, (u8 *) priv->cmdlog[i].cmd.param, priv->cmdlog[i].cmd.len); len += snprintf(buf + len, PAGE_SIZE - len, "\n"); } len += snprintf(buf + len, PAGE_SIZE - len, "\n"); return len;}static DEVICE_ATTR(cmd_log, S_IRUGO, show_cmd_log, NULL);#ifdef CONFIG_IPW2200_PROMISCUOUSstatic void ipw_prom_free(struct ipw_priv *priv);static int ipw_prom_alloc(struct ipw_priv *priv);static ssize_t store_rtap_iface(struct device *d,#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12) struct device_attribute *attr,#endif const char *buf, size_t count){ struct ipw_priv *priv = dev_get_drvdata(d); int rc = 0; if (count < 1) return -EINVAL; switch (buf[0]) { case '0': if (!rtap_iface) return count; if (netif_running(priv->prom_net_dev)) { IPW_WARNING("Interface is up. Cannot unregister.\n"); return count; } ipw_prom_free(priv); rtap_iface = 0; break; case '1': if (rtap_iface) return count; rc = ipw_prom_alloc(priv); if (!rc) rtap_iface = 1; break; default: return -EINVAL; } if (rc) { IPW_ERROR("Failed to register promiscuous network " "device (error %d).\n", rc); } return count;}static ssize_t show_rtap_iface(struct device *d,#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12) struct device_attribute *attr,#endif char *buf){ struct ipw_priv *priv = dev_get_drvdata(d); if (rtap_iface) return sprintf(buf, "%s", priv->prom_net_dev->name); else { buf[0] = '-'; buf[1] = '1'; buf[2] = '\0'; return 3; }}static DEVICE_ATTR(rtap_iface, S_IWUSR | S_IRUSR, show_rtap_iface, store_rtap_iface);static ssize_t store_rtap_filter(struct device *d,#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12) struct device_attribute *attr,#endif const char *buf, size_t count){ struct ipw_priv *priv = dev_get_drvdata(d); if (!priv->prom_priv) { IPW_ERROR("Attempting to set filter without " "rtap_iface enabled.\n"); return -EPERM; } priv->prom_priv->filter = simple_strtol(buf, NULL, 0); IPW_DEBUG_INFO("Setting rtap filter to " BIT_FMT16 "\n", BIT_ARG16(priv->prom_priv->filter)); return count;}static ssize_t show_rtap_filter(struct device *d,#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12) struct device_attribute *attr,#endif char *buf){ struct ipw_priv *priv = dev_get_drvdata(d); return sprintf(buf, "0x%04X", priv->prom_priv ? priv->prom_priv->filter : 0);}static DEVICE_ATTR(rtap_filter, S_IWUSR | S_IRUSR, show_rtap_filter, store_rtap_filter);#endifstatic ssize_t show_scan_age(struct device *d,#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12) struct device_attribute *attr,#endif char *buf){ struct ipw_priv *priv = dev_get_drvdata(d); return sprintf(buf, "%d\n", priv->ieee->scan_age);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -