📄 atmel.c
字号:
0x00,0x40,0x2d,0xe9,0x00,0x20,0xa0,0xe3,0x02,0x3c,0xa0,0xe3,0x00,0x10,0xa0,0xe3, 0x28,0x00,0x9f,0xe5,0x37,0x00,0x00,0xeb,0x00,0x40,0xbd,0xe8,0x1e,0xff,0x2f,0xe1, 0x00,0x40,0x2d,0xe9,0x12,0x2e,0xa0,0xe3,0x06,0x30,0xa0,0xe3,0x00,0x10,0xa0,0xe3, 0x02,0x04,0xa0,0xe3,0x2f,0x00,0x00,0xeb,0x00,0x40,0xbd,0xe8,0x1e,0xff,0x2f,0xe1, 0x00,0x02,0x00,0x02,0x80,0x01,0x90,0xe0,0x01,0x00,0x00,0x0a,0x01,0x00,0x50,0xe2, 0xfc,0xff,0xff,0xea,0x1e,0xff,0x2f,0xe1,0x80,0x10,0xa0,0xe3,0xf3,0x06,0xa0,0xe3, 0x00,0x10,0x80,0xe5,0x00,0x10,0xa0,0xe3,0x00,0x10,0x80,0xe5,0x01,0x10,0xa0,0xe3, 0x04,0x10,0x80,0xe5,0x00,0x10,0x80,0xe5,0x0e,0x34,0xa0,0xe3,0x1c,0x10,0x93,0xe5, 0x02,0x1a,0x81,0xe3,0x1c,0x10,0x83,0xe5,0x58,0x11,0x9f,0xe5,0x30,0x10,0x80,0xe5, 0x54,0x11,0x9f,0xe5,0x34,0x10,0x80,0xe5,0x38,0x10,0x80,0xe5,0x3c,0x10,0x80,0xe5, 0x10,0x10,0x90,0xe5,0x08,0x00,0x90,0xe5,0x1e,0xff,0x2f,0xe1,0xf3,0x16,0xa0,0xe3, 0x08,0x00,0x91,0xe5,0x05,0x00,0xa0,0xe3,0x0c,0x00,0x81,0xe5,0x10,0x00,0x91,0xe5, 0x02,0x00,0x10,0xe3,0xfc,0xff,0xff,0x0a,0xff,0x00,0xa0,0xe3,0x0c,0x00,0x81,0xe5, 0x10,0x00,0x91,0xe5,0x02,0x00,0x10,0xe3,0xfc,0xff,0xff,0x0a,0x08,0x00,0x91,0xe5, 0x10,0x00,0x91,0xe5,0x01,0x00,0x10,0xe3,0xfc,0xff,0xff,0x0a,0x08,0x00,0x91,0xe5, 0xff,0x00,0x00,0xe2,0x1e,0xff,0x2f,0xe1,0x30,0x40,0x2d,0xe9,0x00,0x50,0xa0,0xe1, 0x03,0x40,0xa0,0xe1,0xa2,0x02,0xa0,0xe1,0x08,0x00,0x00,0xe2,0x03,0x00,0x80,0xe2, 0xd8,0x10,0x9f,0xe5,0x00,0x00,0xc1,0xe5,0x01,0x20,0xc1,0xe5,0xe2,0xff,0xff,0xeb, 0x01,0x00,0x10,0xe3,0xfc,0xff,0xff,0x1a,0x14,0x00,0xa0,0xe3,0xc4,0xff,0xff,0xeb, 0x04,0x20,0xa0,0xe1,0x05,0x10,0xa0,0xe1,0x02,0x00,0xa0,0xe3,0x01,0x00,0x00,0xeb, 0x30,0x40,0xbd,0xe8,0x1e,0xff,0x2f,0xe1,0x70,0x40,0x2d,0xe9,0xf3,0x46,0xa0,0xe3, 0x00,0x30,0xa0,0xe3,0x00,0x00,0x50,0xe3,0x08,0x00,0x00,0x9a,0x8c,0x50,0x9f,0xe5, 0x03,0x60,0xd5,0xe7,0x0c,0x60,0x84,0xe5,0x10,0x60,0x94,0xe5,0x02,0x00,0x16,0xe3, 0xfc,0xff,0xff,0x0a,0x01,0x30,0x83,0xe2,0x00,0x00,0x53,0xe1,0xf7,0xff,0xff,0x3a, 0xff,0x30,0xa0,0xe3,0x0c,0x30,0x84,0xe5,0x08,0x00,0x94,0xe5,0x10,0x00,0x94,0xe5, 0x01,0x00,0x10,0xe3,0xfc,0xff,0xff,0x0a,0x08,0x00,0x94,0xe5,0x00,0x00,0xa0,0xe3, 0x00,0x00,0x52,0xe3,0x0b,0x00,0x00,0x9a,0x10,0x50,0x94,0xe5,0x02,0x00,0x15,0xe3, 0xfc,0xff,0xff,0x0a,0x0c,0x30,0x84,0xe5,0x10,0x50,0x94,0xe5,0x01,0x00,0x15,0xe3, 0xfc,0xff,0xff,0x0a,0x08,0x50,0x94,0xe5,0x01,0x50,0xc1,0xe4,0x01,0x00,0x80,0xe2, 0x02,0x00,0x50,0xe1,0xf3,0xff,0xff,0x3a,0xc8,0x00,0xa0,0xe3,0x98,0xff,0xff,0xeb, 0x70,0x40,0xbd,0xe8,0x1e,0xff,0x2f,0xe1,0x01,0x0c,0x00,0x02,0x01,0x02,0x00,0x02, 0x00,0x01,0x00,0x02};struct atmel_private { void *card; /* Bus dependent stucture varies for PCcard */ int (*present_callback)(void *); /* And callback which uses it */ char firmware_id[32]; char firmware_template[32]; unsigned char *firmware; int firmware_length; struct timer_list management_timer; struct net_device *dev; struct device *sys_dev; struct iw_statistics wstats; struct net_device_stats stats; // device stats spinlock_t irqlock, timerlock; // spinlocks enum { BUS_TYPE_PCCARD, BUS_TYPE_PCI } bus_type; enum { CARD_TYPE_PARALLEL_FLASH, CARD_TYPE_SPI_FLASH, CARD_TYPE_EEPROM } card_type; int do_rx_crc; /* If we need to CRC incoming packets */ int probe_crc; /* set if we don't yet know */ int crc_ok_cnt, crc_ko_cnt; /* counters for probing */ u16 rx_desc_head; u16 tx_desc_free, tx_desc_head, tx_desc_tail, tx_desc_previous; u16 tx_free_mem, tx_buff_head, tx_buff_tail; u16 frag_seq, frag_len, frag_no; u8 frag_source[6]; u8 wep_is_on, default_key, exclude_unencrypted, encryption_level; u8 group_cipher_suite, pairwise_cipher_suite; u8 wep_keys[MAX_ENCRYPTION_KEYS][MAX_ENCRYPTION_KEY_SIZE]; int wep_key_len[MAX_ENCRYPTION_KEYS]; int use_wpa, radio_on_broken; /* firmware dependent stuff. */ u16 host_info_base; struct host_info_struct { /* NB this is matched to the hardware, don't change. */ u8 volatile int_status; u8 volatile int_mask; u8 volatile lockout_host; u8 volatile lockout_mac; u16 tx_buff_pos; u16 tx_buff_size; u16 tx_desc_pos; u16 tx_desc_count; u16 rx_buff_pos; u16 rx_buff_size; u16 rx_desc_pos; u16 rx_desc_count; u16 build_version; u16 command_pos; u16 major_version; u16 minor_version; u16 func_ctrl; u16 mac_status; u16 generic_IRQ_type; u8 reserved[2]; } host_info; enum { STATION_STATE_SCANNING, STATION_STATE_JOINNING, STATION_STATE_AUTHENTICATING, STATION_STATE_ASSOCIATING, STATION_STATE_READY, STATION_STATE_REASSOCIATING, STATION_STATE_DOWN, STATION_STATE_MGMT_ERROR } station_state; int operating_mode, power_mode; time_t last_qual; int beacons_this_sec; int channel; int reg_domain, config_reg_domain; int tx_rate; int auto_tx_rate; int rts_threshold; int frag_threshold; int long_retry, short_retry; int preamble; int default_beacon_period, beacon_period, listen_interval; int CurrentAuthentTransactionSeqNum, ExpectedAuthentTransactionSeqNum; int AuthenticationRequestRetryCnt, AssociationRequestRetryCnt, ReAssociationRequestRetryCnt; enum { SITE_SURVEY_IDLE, SITE_SURVEY_IN_PROGRESS, SITE_SURVEY_COMPLETED } site_survey_state; time_t last_survey; int station_was_associated, station_is_associated; int fast_scan; struct bss_info { int channel; int SSIDsize; int RSSI; int UsingWEP; int preamble; int beacon_period; int BSStype; u8 BSSID[6]; u8 SSID[MAX_SSID_LENGTH]; } BSSinfo[MAX_BSS_ENTRIES]; int BSS_list_entries, current_BSS; int connect_to_any_BSS; int SSID_size, new_SSID_size; u8 CurrentBSSID[6], BSSID[6]; u8 SSID[MAX_SSID_LENGTH], new_SSID[MAX_SSID_LENGTH]; u64 last_beacon_timestamp; u8 rx_buf[MAX_WIRELESS_BODY]; };static u8 atmel_basic_rates[4] = {0x82,0x84,0x0b,0x16};static const struct { int reg_domain; int min, max; char *name; } channel_table[] = { { REG_DOMAIN_FCC, 1, 11, "USA" }, { REG_DOMAIN_DOC, 1, 11, "Canada" }, { REG_DOMAIN_ETSI, 1, 13, "Europe" }, { REG_DOMAIN_SPAIN, 10, 11, "Spain" }, { REG_DOMAIN_FRANCE, 10, 13, "France" }, { REG_DOMAIN_MKK, 14, 14, "MKK" }, { REG_DOMAIN_MKK1, 1, 14, "MKK1" }, { REG_DOMAIN_ISRAEL, 3, 9, "Israel"} };static void build_wpa_mib(struct atmel_private *priv);static int atmel_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);static void atmel_copy_to_card(struct net_device *dev, u16 dest, unsigned char *src, u16 len);static void atmel_copy_to_host(struct net_device *dev, unsigned char *dest, u16 src, u16 len);static void atmel_set_gcr(struct net_device *dev, u16 mask);static void atmel_clear_gcr(struct net_device *dev, u16 mask);static int atmel_lock_mac(struct atmel_private *priv);static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data);static void atmel_command_irq(struct atmel_private *priv);static int atmel_validate_channel(struct atmel_private *priv, int channel);static void atmel_management_frame(struct atmel_private *priv, struct ieee802_11_hdr *header, u16 frame_len, u8 rssi);static void atmel_management_timer(u_long a);static void atmel_send_command(struct atmel_private *priv, int command, void *cmd, int cmd_size);static int atmel_send_command_wait(struct atmel_private *priv, int command, void *cmd, int cmd_size);static void atmel_transmit_management_frame(struct atmel_private *priv, struct ieee802_11_hdr *header, u8 *body, int body_len);static u8 atmel_get_mib8(struct atmel_private *priv, u8 type, u8 index);static void atmel_set_mib8(struct atmel_private *priv, u8 type, u8 index, u8 data);static void atmel_set_mib16(struct atmel_private *priv, u8 type, u8 index, u16 data);static void atmel_set_mib(struct atmel_private *priv, u8 type, u8 index, u8 *data, int data_len);static void atmel_get_mib(struct atmel_private *priv, u8 type, u8 index, u8 *data, int data_len);static void atmel_scan(struct atmel_private *priv, int specific_ssid);static void atmel_join_bss(struct atmel_private *priv, int bss_index);static void atmel_smooth_qual(struct atmel_private *priv);static void atmel_writeAR(struct net_device *dev, u16 data);static int probe_atmel_card(struct net_device *dev);static int reset_atmel_card(struct net_device *dev );static void atmel_enter_state(struct atmel_private *priv, int new_state);int atmel_open (struct net_device *dev);static inline u16 atmel_hi(struct atmel_private *priv, u16 offset){ return priv->host_info_base + offset;}static inline u16 atmel_co(struct atmel_private *priv, u16 offset){ return priv->host_info.command_pos + offset;}static inline u16 atmel_rx(struct atmel_private *priv, u16 offset, u16 desc){ return priv->host_info.rx_desc_pos + (sizeof(struct rx_desc) * desc) + offset;}static inline u16 atmel_tx(struct atmel_private *priv, u16 offset, u16 desc){ return priv->host_info.tx_desc_pos + (sizeof(struct tx_desc) * desc) + offset;}static inline u8 atmel_read8(struct net_device *dev, u16 offset){ return inb(dev->base_addr + offset);}static inline void atmel_write8(struct net_device *dev, u16 offset, u8 data){ outb(data, dev->base_addr + offset);}static inline u16 atmel_read16(struct net_device *dev, u16 offset){ return inw(dev->base_addr + offset);}static inline void atmel_write16(struct net_device *dev, u16 offset, u16 data){ outw(data, dev->base_addr + offset);}static inline u8 atmel_rmem8(struct atmel_private *priv, u16 pos){ atmel_writeAR(priv->dev, pos); return atmel_read8(priv->dev, DR);}static inline void atmel_wmem8(struct atmel_private *priv, u16 pos, u16 data){ atmel_writeAR(priv->dev, pos); atmel_write8(priv->dev, DR, data);}static inline u16 atmel_rmem16(struct atmel_private *priv, u16 pos){ atmel_writeAR(priv->dev, pos); return atmel_read16(priv->dev, DR);}static inline void atmel_wmem16(struct atmel_private *priv, u16 pos, u16 data){ atmel_writeAR(priv->dev, pos); atmel_write16(priv->dev, DR, data);}static const struct iw_handler_def atmel_handler_def;static void tx_done_irq(struct atmel_private *priv){ int i; for (i = 0; atmel_rmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, priv->tx_desc_head)) == TX_DONE && i < priv->host_info.tx_desc_count; i++) { u8 status = atmel_rmem8(priv, atmel_tx(priv, TX_DESC_STATUS_OFFSET, priv->tx_desc_head)); u16 msdu_size = atmel_rmem16(priv, atmel_tx(priv, TX_DESC_SIZE_OFFSET, priv->tx_desc_head)); u8 type = atmel_rmem8(priv, atmel_tx(priv, TX_DESC_PACKET_TYPE_OFFSET, priv->tx_desc_head)); atmel_wmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, priv->tx_desc_head), 0); priv->tx_free_mem += msdu_size; priv->tx_desc_free++; if (priv->tx_buff_head + msdu_size > (priv->host_info.tx_buff_pos + priv->host_info.tx_buff_size)) priv->tx_buff_head = 0; else priv->tx_buff_head += msdu_size; if (priv->tx_desc_head < (priv->host_info.tx_desc_count - 1)) priv->tx_desc_head++ ; else priv->tx_desc_head = 0; if (type == TX_PACKET_TYPE_DATA) { if (status == TX_STATUS_SUCCESS) priv->stats.tx_packets++; else priv->stats.tx_errors++; netif_wake_queue(priv->dev); } }}static u16 find_tx_buff(struct atmel_private *priv, u16 len){ u16 bottom_free = priv->host_info.tx_buff_size - priv->tx_buff_tail; if (priv->tx_desc_free == 3 || priv->tx_free_mem < len) return 0; if (bottom_free >= len) return priv->host_info.tx_buff_pos + priv->tx_buff_tail; if (priv->tx_free_mem - bottom_free >= len) { priv->tx_buff_tail = 0; return priv->host_info.tx_buff_pos; } return 0;}static void tx_update_descriptor(struct atmel_private *priv, int is_bcast, u16 len, u16 buff, u8 type){ atmel_wmem16(priv, atmel_tx(priv, TX_DESC_POS_OFFSET, priv->tx_desc_tail), buff); atmel_wmem16(priv, atmel_tx(priv, TX_DESC_SIZE_OFFSET, priv->tx_desc_tail), len); if (!priv->use_wpa) atmel_wmem16(priv, atmel_tx(priv, TX_DESC_HOST_LENGTH_OFFSET, priv->tx_desc_tail), len); atmel_wmem8(priv, atmel_tx(priv, TX_DESC_PACKET_TYPE_OFFSET, priv->tx_desc_tail), type); atmel_wmem8(priv, atmel_tx(priv, TX_DESC_RATE_OFFSET, priv->tx_desc_tail), priv->tx_rate); atmel_wmem8(priv, atmel_tx(priv, TX_DESC_RETRY_OFFSET, priv->tx_desc_tail), 0); if (priv->use_wpa) { int cipher_type, cipher_length; if (is_bcast) { cipher_type = priv->group_cipher_suite; if (cipher_type == CIPHER_SUITE_WEP_64 || cipher_type == CIPHER_SUITE_WEP_128 ) cipher_length = 8; else if (cipher_type == CIPHER_SUITE_TKIP) cipher_length = 12; else if (priv->pairwise_cipher_suite == CIPHER_SUITE_WEP_64 || priv->pairwise_cipher_suite == CIPHER_SUITE_WEP_128) { cipher_type = priv->pairwise_cipher_suite; cipher_length = 8; } else { cipher_type = CIPHER_SUITE_NONE; cipher_length = 0; } } else { cipher_type = priv->pairwise_cipher_suite; if (cipher_type == CIPHER_SUITE_WEP_64 || cipher_type == CIPHER_SUITE_WEP_128 ) cipher_length = 8; else if (cipher_type == CIPHER_SUITE_TKIP) cipher_length = 12; else if (priv->group_cipher_suite == CIPHER_SUITE_WEP_64 || priv->group_cipher_suite == CIPHER_SUITE_WEP_128) { cipher_type = priv->group_cipher_suite; cipher_length = 8; } else { cipher_type = CIPHER_SUITE_NONE; cipher_length = 0; } } atmel_wmem8(priv, atmel_tx(priv, TX_DESC_CIPHER_TYPE_OFFSET, priv->tx_desc_tail), cipher_type); atmel_wmem8(priv, atmel_tx(priv, TX_DESC_CIPHER_LENGTH_OFFSET, priv->tx_desc_tail), cipher_length); } atmel_wmem32(priv, atmel_tx(priv, TX_DESC_NEXT_OFFSET, priv->tx_desc_tail), 0x80000000L); atmel_wmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, priv->tx_desc_tail), TX_FIRM_OWN); if (priv->tx_desc_previous != priv->tx_desc_tail) atmel_wmem32(priv, atmel_tx(priv, TX_DESC_NEXT_OFFSET, priv->tx_desc_previous), 0); priv->tx_desc_previous = priv->tx_desc_tail; if (priv->tx_desc_tail < (priv->host_info.tx_desc_count -1 )) priv->tx_desc_tail++; else priv->tx_desc_tail = 0; priv->tx_desc_free--; priv->tx_free_mem -= len;}static int start_tx (struct sk_buff *skb, struct net_device *dev){ struct atmel_private *priv = netdev_priv(dev); struct ieee802_11_hdr header; unsigned long flags; u16 buff, frame_ctl, len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN; u8 SNAP_RFC1024[6] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00}; if (priv->card && priv->present_callback && !(*priv->present_callback)(priv->card)) { priv->stats.tx_errors++; dev_kfree_skb(skb); return 0; } if (priv->station_state != STATION_STATE_READY) { priv->stats.tx_errors++; dev_kfree_skb(skb); return 0; } /* first ensure the timer func cannot run */ spin_lock_bh(&priv->timerlock); /* then stop the hardware ISR */ spin_lock_irqsave(&priv->irqlock, flags); /* nb doing the above in the opposite order will deadlock */ /* The Wireless Header is 30 bytes. In the Ethernet packet we "cut" the 12 first bytes (containing DA/SA) and put them in the appropriate fields of the Wireless Header. Thus the packet length is then the initial + 18 (+30-12) */ if (!(buff = find_tx_buff(priv, len + 18))) { priv->stats.tx_dropped++; spin_unlock_irqrestore(&priv->irqlock, flags); spin_unlock_bh(&priv->timerlock); netif_stop_queue(dev);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -