📄 atmel.c
字号:
priv->station_is_associated = 0; atmel_scan(priv, 1); } break; case ISR_RxFRAMELOST: priv->wstats.discard.misc++; /* fall through */ case ISR_RxCOMPLETE: rx_done_irq(priv); break; case ISR_TxCOMPLETE: tx_done_irq(priv); break; case ISR_FATAL_ERROR: printk(KERN_ALERT "%s: *** FATAL error interrupt ***\n", dev->name); atmel_enter_state(priv, STATION_STATE_MGMT_ERROR); break; case ISR_COMMAND_COMPLETE: atmel_command_irq(priv); break; case ISR_IBSS_MERGE: atmel_get_mib(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_BSSID_POS, priv->CurrentBSSID, 6); /* The WPA stuff cares about the current AP address */ if (priv->use_wpa) build_wpa_mib(priv); break; case ISR_GENERIC_IRQ: printk(KERN_INFO "%s: Generic_irq received.\n", dev->name); break; } } }static struct net_device_stats *atmel_get_stats (struct net_device *dev){ struct atmel_private *priv = netdev_priv(dev); return &priv->stats;}static struct iw_statistics *atmel_get_wireless_stats (struct net_device *dev){ struct atmel_private *priv = netdev_priv(dev); /* update the link quality here in case we are seeing no beacons at all to drive the process */ atmel_smooth_qual(priv); priv->wstats.status = priv->station_state; if (priv->operating_mode == IW_MODE_INFRA) { if (priv->station_state != STATION_STATE_READY) { priv->wstats.qual.qual = 0; priv->wstats.qual.level = 0; priv->wstats.qual.updated = (IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_INVALID); } priv->wstats.qual.noise = 0; priv->wstats.qual.updated |= IW_QUAL_NOISE_INVALID; } else { /* Quality levels cannot be determined in ad-hoc mode, because we can 'hear' more that one remote station. */ priv->wstats.qual.qual = 0; priv->wstats.qual.level = 0; priv->wstats.qual.noise = 0; priv->wstats.qual.updated = IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_INVALID | IW_QUAL_NOISE_INVALID; priv->wstats.miss.beacon = 0; } return (&priv->wstats);}static int atmel_change_mtu(struct net_device *dev, int new_mtu){ if ((new_mtu < 68) || (new_mtu > 2312)) return -EINVAL; dev->mtu = new_mtu; return 0;}static int atmel_set_mac_address(struct net_device *dev, void *p){ struct sockaddr *addr = p; memcpy (dev->dev_addr, addr->sa_data, dev->addr_len); return atmel_open(dev);}EXPORT_SYMBOL(atmel_open);int atmel_open (struct net_device *dev){ struct atmel_private *priv = netdev_priv(dev); int i, channel; /* any scheduled timer is no longer needed and might screw things up.. */ del_timer_sync(&priv->management_timer); /* Interrupts will not touch the card once in this state... */ priv->station_state = STATION_STATE_DOWN; if (priv->new_SSID_size) { memcpy(priv->SSID, priv->new_SSID, priv->new_SSID_size); priv->SSID_size = priv->new_SSID_size; priv->new_SSID_size = 0; } priv->BSS_list_entries = 0; priv->AuthenticationRequestRetryCnt = 0; priv->AssociationRequestRetryCnt = 0; priv->ReAssociationRequestRetryCnt = 0; priv->CurrentAuthentTransactionSeqNum = 0x0001; priv->ExpectedAuthentTransactionSeqNum = 0x0002; priv->site_survey_state = SITE_SURVEY_IDLE; priv->station_is_associated = 0; if (!reset_atmel_card(dev)) return -EAGAIN; if (priv->config_reg_domain) { priv->reg_domain = priv->config_reg_domain; atmel_set_mib8(priv, Phy_Mib_Type, PHY_MIB_REG_DOMAIN_POS, priv->reg_domain); } else { priv->reg_domain = atmel_get_mib8(priv, Phy_Mib_Type, PHY_MIB_REG_DOMAIN_POS); for (i = 0; i < sizeof(channel_table)/sizeof(channel_table[0]); i++) if (priv->reg_domain == channel_table[i].reg_domain) break; if (i == sizeof(channel_table)/sizeof(channel_table[0])) { priv->reg_domain = REG_DOMAIN_MKK1; printk(KERN_ALERT "%s: failed to get regulatory domain: assuming MKK1.\n", dev->name); } } if ((channel = atmel_validate_channel(priv, priv->channel))) priv->channel = channel; /* this moves station_state on.... */ atmel_scan(priv, 1); atmel_set_gcr(priv->dev, GCR_ENINT); /* enable interrupts */ return 0;}static int atmel_close (struct net_device *dev){ struct atmel_private *priv = netdev_priv(dev); atmel_enter_state(priv, STATION_STATE_DOWN); if (priv->bus_type == BUS_TYPE_PCCARD) atmel_write16(dev, GCR, 0x0060); atmel_write16(dev, GCR, 0x0040); return 0;}static int atmel_validate_channel(struct atmel_private *priv, int channel){ /* check that channel is OK, if so return zero, else return suitable default channel */ int i; for (i = 0; i < sizeof(channel_table)/sizeof(channel_table[0]); i++) if (priv->reg_domain == channel_table[i].reg_domain) { if (channel >= channel_table[i].min && channel <= channel_table[i].max) return 0; else return channel_table[i].min; } return 0;}static int atmel_proc_output (char *buf, struct atmel_private *priv){ int i; char *p = buf; char *s, *r, *c; p += sprintf(p, "Driver version:\t\t%d.%d\n", DRIVER_MAJOR, DRIVER_MINOR); if (priv->station_state != STATION_STATE_DOWN) { p += sprintf(p, "Firmware version:\t%d.%d build %d\nFirmware location:\t", priv->host_info.major_version, priv->host_info.minor_version, priv->host_info.build_version); if (priv->card_type != CARD_TYPE_EEPROM) p += sprintf(p, "on card\n"); else if (priv->firmware) p += sprintf(p, "%s loaded by host\n", priv->firmware_id); else p += sprintf(p, "%s loaded by hotplug\n", priv->firmware_id); switch(priv->card_type) { case CARD_TYPE_PARALLEL_FLASH: c = "Parallel flash"; break; case CARD_TYPE_SPI_FLASH: c = "SPI flash\n"; break; case CARD_TYPE_EEPROM: c = "EEPROM"; break; default: c = "<unknown>"; } r = "<unknown>"; for (i = 0; i < sizeof(channel_table)/sizeof(channel_table[0]); i++) if (priv->reg_domain == channel_table[i].reg_domain) r = channel_table[i].name; p += sprintf(p, "MAC memory type:\t%s\n", c); p += sprintf(p, "Regulatory domain:\t%s\n", r); p += sprintf(p, "Host CRC checking:\t%s\n", priv->do_rx_crc ? "On" : "Off"); p += sprintf(p, "WPA-capable firmware:\t%s\n", priv->use_wpa ? "Yes" : "No"); } switch(priv->station_state) { case STATION_STATE_SCANNING: s = "Scanning"; break; case STATION_STATE_JOINNING: s = "Joining"; break; case STATION_STATE_AUTHENTICATING: s = "Authenticating"; break; case STATION_STATE_ASSOCIATING: s = "Associating"; break; case STATION_STATE_READY: s = "Ready"; break; case STATION_STATE_REASSOCIATING: s = "Reassociating"; break; case STATION_STATE_MGMT_ERROR: s = "Management error"; break; case STATION_STATE_DOWN: s = "Down"; break; default: s = "<unknown>"; } p += sprintf(p, "Current state:\t\t%s\n", s); return p - buf;}static int atmel_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data){ struct atmel_private *priv = data; int len = atmel_proc_output (page, priv); if (len <= off+count) *eof = 1; *start = page + off; len -= off; if (len>count) len = count; if (len<0) len = 0; return len;}struct net_device *init_atmel_card( unsigned short irq, unsigned long port, const AtmelFWType fw_type, struct device *sys_dev, int (*card_present)(void *), void *card){ struct net_device *dev; struct atmel_private *priv; int rc; /* Create the network device object. */ dev = alloc_etherdev(sizeof(*priv)); if (!dev) { printk(KERN_ERR "atmel: Couldn't alloc_etherdev\n"); return NULL; } if (dev_alloc_name(dev, dev->name) < 0) { printk(KERN_ERR "atmel: Couldn't get name!\n"); goto err_out_free; } priv = netdev_priv(dev); priv->dev = dev; priv->sys_dev = sys_dev; priv->present_callback = card_present; priv->card = card; priv->firmware = NULL; priv->firmware_id[0] = '\0'; priv->firmware_type = fw_type; if (firmware) /* module parameter */ strcpy(priv->firmware_id, firmware); priv->bus_type = card_present ? BUS_TYPE_PCCARD : BUS_TYPE_PCI; priv->station_state = STATION_STATE_DOWN; priv->do_rx_crc = 0; /* For PCMCIA cards, some chips need CRC, some don't so we have to probe. */ if (priv->bus_type == BUS_TYPE_PCCARD) { priv->probe_crc = 1; priv->crc_ok_cnt = priv->crc_ko_cnt = 0; } else priv->probe_crc = 0; memset(&priv->stats, 0, sizeof(priv->stats)); memset(&priv->wstats, 0, sizeof(priv->wstats)); priv->last_qual = jiffies; priv->last_beacon_timestamp = 0; memset(priv->frag_source, 0xff, sizeof(priv->frag_source)); memset(priv->BSSID, 0, 6); priv->CurrentBSSID[0] = 0xFF; /* Initialize to something invalid.... */ priv->station_was_associated = 0; priv->last_survey = jiffies; priv->preamble = LONG_PREAMBLE; priv->operating_mode = IW_MODE_INFRA; priv->connect_to_any_BSS = 0; priv->config_reg_domain = 0; priv->reg_domain = 0; priv->tx_rate = 3; priv->auto_tx_rate = 1; priv->channel = 4; priv->power_mode = 0; priv->SSID[0] = '\0'; priv->SSID_size = 0; priv->new_SSID_size = 0; priv->frag_threshold = 2346; priv->rts_threshold = 2347; priv->short_retry = 7; priv->long_retry = 4; priv->wep_is_on = 0; priv->default_key = 0; priv->encryption_level = 0; priv->exclude_unencrypted = 0; priv->group_cipher_suite = priv->pairwise_cipher_suite = CIPHER_SUITE_NONE; priv->use_wpa = 0; memset(priv->wep_keys, 0, sizeof(priv->wep_keys)); memset(priv->wep_key_len, 0, sizeof(priv->wep_key_len)); priv->default_beacon_period = priv->beacon_period = 100; priv->listen_interval = 1; init_timer(&priv->management_timer); spin_lock_init(&priv->irqlock); spin_lock_init(&priv->timerlock); priv->management_timer.function = atmel_management_timer; priv->management_timer.data = (unsigned long) dev; dev->open = atmel_open; dev->stop = atmel_close; dev->change_mtu = atmel_change_mtu; dev->set_mac_address = atmel_set_mac_address; dev->hard_start_xmit = start_tx; dev->get_stats = atmel_get_stats; dev->wireless_handlers = (struct iw_handler_def *)&atmel_handler_def; dev->do_ioctl = atmel_ioctl; dev->irq = irq; dev->base_addr = port; SET_NETDEV_DEV(dev, sys_dev); if ((rc = request_irq(dev->irq, service_interrupt, SA_SHIRQ, dev->name, dev))) { printk(KERN_ERR "%s: register interrupt %d failed, rc %d\n", dev->name, irq, rc ); goto err_out_free; } if (!request_region(dev->base_addr, 32, priv->bus_type == BUS_TYPE_PCCARD ? "atmel_cs" : "atmel_pci")) { goto err_out_irq; } if (register_netdev(dev)) goto err_out_res; if (!probe_atmel_card(dev)){ unregister_netdev(dev); goto err_out_res; } netif_carrier_off(dev); create_proc_read_entry ("driver/atmel", 0, NULL, atmel_read_proc, priv); printk(KERN_INFO "%s: Atmel at76c50x. Version %d.%d. MAC %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", dev->name, DRIVER_MAJOR, DRIVER_MINOR, dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5] ); SET_MODULE_OWNER(dev); return dev; err_out_res: release_region( dev->base_addr, 32); err_out_irq: free_irq(dev->irq, dev); err_out_free: free_netdev(dev); return NULL;}EXPORT_SYMBOL(init_atmel_card);void stop_atmel_card(struct net_device *dev){ struct atmel_private *priv = netdev_priv(dev); /* put a brick on it... */ if (priv->bus_type == BUS_TYPE_PCCARD) atmel_write16(dev, GCR, 0x0060); atmel_write16(dev, GCR, 0x0040); del_timer_sync(&priv->management_timer); unregister_netdev(dev); remove_proc_entry("driver/atmel", NULL); free_irq(dev->irq, dev); kfree(priv->firmware); release_region(dev->base_addr, 32); free_netdev(dev);}EXPORT_SYMBOL(stop_atmel_card);static int atmel_set_essid(struct net_device *dev, struct iw_request_info *info, struct iw_point *dwrq, char *extra){ struct atmel_private *priv = netdev_priv(dev); /* Check if we asked for `any' */ if(dwrq->flags == 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -