📄 ipw2200.c
字号:
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); }}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){ 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 void ipw_free_error_log(struct ipw_fw_error *error){ if (error) kfree(error);}static ssize_t show_event_log(struct device *d, struct device_attribute *attr, 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, struct device_attribute *attr, 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, struct device_attribute *attr, const char *buf, size_t count){ struct ipw_priv *priv = dev_get_drvdata(d); if (priv->error) { ipw_free_error_log(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, struct device_attribute *attr, 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);static ssize_t show_scan_age(struct device *d, struct device_attribute *attr, char *buf){ struct ipw_priv *priv = dev_get_drvdata(d); return sprintf(buf, "%d\n", priv->ieee->scan_age);}static ssize_t store_scan_age(struct device *d, struct device_attribute *attr, const char *buf, size_t count){ struct ipw_priv *priv = dev_get_drvdata(d);#ifdef CONFIG_IPW_DEBUG struct net_device *dev = priv->net_dev;#endif char buffer[] = "00000000"; unsigned long len = (sizeof(buffer) - 1) > count ? count : sizeof(buffer) - 1; unsigned long val; char *p = buffer; IPW_DEBUG_INFO("enter\n"); strncpy(buffer, buf, len); buffer[len] = 0; 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 == buffer) { IPW_DEBUG_INFO("%s: user supplied invalid value.\n", dev->name); } else { priv->ieee->scan_age = val; IPW_DEBUG_INFO("set scan_age = %u\n", priv->ieee->scan_age); } IPW_DEBUG_INFO("exit\n"); return len;}static DEVICE_ATTR(scan_age, S_IWUSR | S_IRUGO, show_scan_age, store_scan_age);static ssize_t show_led(struct device *d, struct device_attribute *attr, char *buf){ struct ipw_priv *priv = dev_get_drvdata(d); return sprintf(buf, "%d\n", (priv->config & CFG_NO_LED) ? 0 : 1);}static ssize_t store_led(struct device *d, struct device_attribute *attr, const char *buf, size_t count){ struct ipw_priv *priv = dev_get_drvdata(d); IPW_DEBUG_INFO("enter\n"); if (count == 0) return 0; if (*buf == 0) { IPW_DEBUG_LED("Disabling LED control.\n"); priv->config |= CFG_NO_LED; ipw_led_shutdown(priv); } else { IPW_DEBUG_LED("Enabling LED control.\n"); priv->config &= ~CFG_NO_LED; ipw_led_init(priv); } IPW_DEBUG_INFO("exit\n"); return count;}static DEVICE_ATTR(led, S_IWUSR | S_IRUGO, show_led, store_led);static ssize_t show_status(struct device *d, struct device_attribute *attr, char *buf){ struct ipw_priv *p = d->driver_data; return sprintf(buf, "0x%08x\n", (int)p->status);}static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);static ssize_t show_cfg(struct device *d, struct device_attribute *attr, char *buf){ struct ipw_priv *p = d->driver_data; return sprintf(buf, "0x%08x\n", (int)p->config);}static DEVICE_ATTR(cfg, S_IRUGO, show_cfg, NULL);static ssize_t show_nic_type(struct device *d, struct device_attribute *attr, char *buf){ struct ipw_priv *priv = d->driver_data; return sprintf(buf, "TYPE: %d\n", priv->nic_type);}static DEVICE_ATTR(nic_type, S_IRUGO, show_nic_type, NULL);static ssize_t show_ucode_version(struct device *d, struct device_attribute *attr, char *buf){ u32 len = sizeof(u32), tmp = 0; struct ipw_priv *p = d->driver_data; if (ipw_get_ordinal(p, IPW_ORD_STAT_UCODE_VERSION, &tmp, &len)) return 0; return sprintf(buf, "0x%08x\n", tmp);}static DEVICE_ATTR(ucode_version, S_IWUSR | S_IRUGO, show_ucode_version, NULL);static ssize_t show_rtc(struct device *d, struct device_attribute *attr, char *buf){ u32 len = sizeof(u32), tmp = 0; struct ipw_priv *p = d->driver_data; if (ipw_get_ordinal(p, IPW_ORD_STAT_RTC, &tmp, &len)) return 0; return sprintf(buf, "0x%08x\n", tmp);}static DEVICE_ATTR(rtc, S_IWUSR | S_IRUGO, show_rtc, NULL);/* * Add a device attribute to view/control the delay between eeprom * operations. */static ssize_t show_eeprom_delay(struct device *d, struct device_attribute *attr, char *buf){ int n = ((struct ipw_priv *)d->driver_data)->eeprom_delay; return sprintf(buf, "%i\n", n);}static ssize_t store_eeprom_delay(struct device *d, struct device_attribute *attr, const char *buf, size_t count){ struct ipw_priv *p = d->driver_data; sscanf(buf, "%i", &p->eeprom_delay); return strnlen(buf, count);}static DEVICE_ATTR(eeprom_delay, S_IWUSR | S_IRUGO, show_eeprom_delay, store_eeprom_delay);static ssize_t show_command_event_reg(struct device *d, struct device_attribute *attr, char *buf){ u32 reg = 0; struct ipw_priv *p = d->driver_data; reg = ipw_read_reg32(p, IPW_INTERNAL_CMD_EVENT); return sprintf(buf, "0x%08x\n", reg);}static ssize_t store_command_event_reg(struct device *d, struct device_attribute *attr, const char *buf, size_t count){ u32 reg; struct ipw_priv *p = d->driver_data; sscanf(buf, "%x", ®); ipw_write_reg32(p, IPW_INTERNAL_CMD_EVENT, reg); return strnlen(buf, count);}static DEVICE_ATTR(command_event_reg, S_IWUSR | S_IRUGO, show_command_event_reg, store_command_event_reg);static ssize_t show_mem_gpio_reg(struct device *d, struct device_attribute *attr, char *buf){ u32 reg = 0; struct ipw_priv *p = d->driver_data; reg = ipw_read_reg32(p, 0x301100); return sprintf(buf, "0x%08x\n", reg);}static ssize_t store_mem_gpio_reg(struct device *d, struct device_attribute *attr, const char *buf, size_t count){ u32 reg; struct ipw_priv *p = d->driver_data; sscanf(buf, "%x", ®); ipw_write_reg32(p, 0x301100, reg); return strnlen(buf, count);}static DEVICE_ATTR(mem_gpio_reg, S_IWUSR | S_IRUGO, show_mem_gpio_reg, store_mem_gpio_reg);static ssize_t show_indirect_dword(struct device *d, struct device_attribute *attr, char *buf){ u32 reg = 0; struct ipw_priv *priv = d->driver_data; if (priv->status & STATUS_INDIRECT_DWORD) reg = ipw_read_reg32(priv, priv->indirect_dword); else reg = 0; return sprintf(buf, "0x%08x\n", reg);}static ssize_t store_indirect_dword(struct device *d, struct device_attribute *attr, const char *buf, size_t count){ struct ipw_priv *priv = d->driver_data; sscanf(buf, "%x", &priv->indirect_dword); priv->status |= STATUS_INDIRECT_DWORD; return strnlen(buf, count);}static DEVICE_ATTR(indirect_dword, S_IWUSR | S_IRUGO, show_indirect_dword, store_indirect_dword);static ssize_t show_indirect_byte(struct device *d, struct device_attribute *attr, char *buf){ u8 reg = 0; struct ipw_priv *priv = d->driver_data; if (priv->status & STATUS_INDIRECT_BYTE) reg = ipw_read_reg8(priv, priv->indirect_byte);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -