📄 at76c503.c
字号:
int set_rts(struct at76c503 *dev, u16 size){ int ret = 0; struct set_mib_buffer mib_buf; memset(&mib_buf, 0, sizeof(struct set_mib_buffer)); mib_buf.type = MIB_MAC; mib_buf.size = 2; mib_buf.index = RTS_OFFSET; *(u16*)mib_buf.data = cpu_to_le16(size); ret = set_mib(dev, &mib_buf); if(ret < 0){ err("%s: set_mib (rts) failed: %d", dev->netdev->name, ret); } return ret;}staticint set_autorate_fallback(struct at76c503 *dev, int onoff){ int ret = 0; struct set_mib_buffer mib_buf; memset(&mib_buf, 0, sizeof(struct set_mib_buffer)); mib_buf.type = MIB_LOCAL; mib_buf.size = 1; mib_buf.index = TX_AUTORATE_FALLBACK_OFFSET; mib_buf.data[0] = onoff; ret = set_mib(dev, &mib_buf); if(ret < 0){ err("%s: set_mib (autorate fallback) failed: %d", dev->netdev->name, ret); } return ret;}static int set_mac_address(struct at76c503 *dev, void *addr){ struct set_mib_buffer mib_buf; int ret = 0; memset(&mib_buf, 0, sizeof(struct set_mib_buffer)); mib_buf.type = MIB_MAC_ADD; mib_buf.size = ETH_ALEN; mib_buf.index = offsetof(struct mib_mac_addr, mac_addr); memcpy(mib_buf.data, addr, ETH_ALEN); ret = set_mib(dev, &mib_buf); if(ret < 0){ err("%s: set_mib (MAC_ADDR, mac_addr) failed: %d", dev->netdev->name, ret); } return ret;}#if 0/* implemented to get promisc. mode working, but does not help. May still be useful for multicast eventually. */static int set_group_address(struct at76c503 *dev, u8 *addr, int n){ struct set_mib_buffer mib_buf; int ret = 0; memset(&mib_buf, 0, sizeof(struct set_mib_buffer)); mib_buf.type = MIB_MAC_ADD; mib_buf.size = ETH_ALEN; mib_buf.index = offsetof(struct mib_mac_addr, group_addr) + n*ETH_ALEN; memcpy(mib_buf.data, addr, ETH_ALEN); ret = set_mib(dev, &mib_buf); if(ret < 0){ err("%s: set_mib (MIB_MAC_ADD, group_addr) failed: %d", dev->netdev->name, ret); }#if 1 /* I do not know anything about the group_addr_status field... (oku)*/ memset(&mib_buf, 0, sizeof(struct set_mib_buffer)); mib_buf.type = MIB_MAC_ADD; mib_buf.size = 1; mib_buf.index = offsetof(struct mib_mac_addr, group_addr_status) + n; mib_buf.data[0] = 1; ret = set_mib(dev, &mib_buf); if(ret < 0){ err("%s: set_mib (MIB_MAC_ADD, group_addr_status) failed: %d", dev->netdev->name, ret); }#endif return ret;}#endifstaticint set_promisc(struct at76c503 *dev, int onoff){ int ret = 0; struct set_mib_buffer mib_buf; memset(&mib_buf, 0, sizeof(struct set_mib_buffer)); mib_buf.type = MIB_LOCAL; mib_buf.size = 1; mib_buf.index = offsetof(struct mib_local, promiscuous_mode); mib_buf.data[0] = onoff ? 1 : 0; ret = set_mib(dev, &mib_buf); if(ret < 0){ err("%s: set_mib (promiscous_mode) failed: %d", dev->netdev->name, ret); } return ret;}static int dump_mib_mac_addr(struct at76c503 *dev) __attribute__ ((unused));static int dump_mib_mac_addr(struct at76c503 *dev){ int ret = 0; struct mib_mac_addr *mac_addr = kmalloc(sizeof(struct mib_mac_addr), GFP_KERNEL); char abuf[2*(4*ETH_ALEN)+1] __attribute__ ((unused)); if(!mac_addr){ ret = -ENOMEM; goto exit; } ret = get_mib(dev->udev, MIB_MAC_ADD, (u8*)mac_addr, sizeof(struct mib_mac_addr)); if(ret < 0){ err("%s: get_mib (MAC_ADDR) failed: %d", dev->netdev->name, ret); goto err; } dbg_uc("%s: MIB MAC_ADDR: mac_addr %s group_addr %s status %d %d %d %d", dev->netdev->name, mac2str(mac_addr->mac_addr), hex2str(abuf, (u8 *)mac_addr->group_addr, (sizeof(abuf)-1)/2,'\0'), mac_addr->group_addr_status[0], mac_addr->group_addr_status[1], mac_addr->group_addr_status[2], mac_addr->group_addr_status[3]); err: kfree(mac_addr); exit: return ret;}static int dump_mib_mac_wep(struct at76c503 *dev) __attribute__ ((unused));static int dump_mib_mac_wep(struct at76c503 *dev){ int ret = 0; struct mib_mac_wep *mac_wep = kmalloc(sizeof(struct mib_mac_wep), GFP_KERNEL); char kbuf[2*WEP_KEY_SIZE+1] __attribute__ ((unused)); if(!mac_wep){ ret = -ENOMEM; goto exit; } ret = get_mib(dev->udev, MIB_MAC_WEP, (u8*)mac_wep, sizeof(struct mib_mac_wep)); if(ret < 0){ err("%s: get_mib (MAC_WEP) failed: %d", dev->netdev->name, ret); goto err; } dbg_uc("%s: MIB MAC_WEP: priv_invoked %u def_key_id %u key_len %u " "excl_unencr %u wep_icv_err %u wep_excluded %u encr_level %u key %d: %s", dev->netdev->name, mac_wep->privacy_invoked, mac_wep->wep_default_key_id, mac_wep->wep_key_mapping_len, mac_wep->exclude_unencrypted,le32_to_cpu( mac_wep->wep_icv_error_count), le32_to_cpu(mac_wep->wep_excluded_count), mac_wep->encryption_level, mac_wep->wep_default_key_id, mac_wep->wep_default_key_id < 4 ? hex2str(kbuf, mac_wep->wep_default_keyvalue[mac_wep->wep_default_key_id], mac_wep->encryption_level == 2 ? 13 : 5, '\0') : "<invalid key id>"); err: kfree(mac_wep); exit: return ret;}static int dump_mib_mac_mgmt(struct at76c503 *dev) __attribute__ ((unused));static int dump_mib_mac_mgmt(struct at76c503 *dev){ int ret = 0; struct mib_mac_mgmt *mac_mgmt = kmalloc(sizeof(struct mib_mac_mgmt), GFP_KERNEL); if(!mac_mgmt){ ret = -ENOMEM; goto exit; } ret = get_mib(dev->udev, MIB_MAC_MGMT, (u8*)mac_mgmt, sizeof(struct mib_mac_mgmt)); if(ret < 0){ err("%s: get_mib failed: %d", dev->netdev->name, ret); goto err; } dbg_uc("%s: MIB MAC_MGMT: station_id x%x pm_mode %d\n", dev->netdev->name, le16_to_cpu(mac_mgmt->station_id), mac_mgmt->power_mgmt_mode); err: kfree(mac_mgmt); exit: return ret;}static int dump_mib_mac(struct at76c503 *dev) __attribute__ ((unused));static int dump_mib_mac(struct at76c503 *dev){ int ret = 0; struct mib_mac *mac = kmalloc(sizeof(struct mib_mac), GFP_KERNEL); if(!mac){ ret = -ENOMEM; goto exit; } ret = get_mib(dev->udev, MIB_MAC, (u8*)mac, sizeof(struct mib_mac)); if(ret < 0){ err("%s: get_mib failed: %d", dev->netdev->name, ret); goto err; } dbg_uc("%s: MIB MAC: listen_int %d", dev->netdev->name, le16_to_cpu(mac->listen_interval)); err: kfree(mac); exit: return ret;}staticint get_current_bssid(struct at76c503 *dev){ int ret = 0; struct mib_mac_mgmt *mac_mgmt = kmalloc(sizeof(struct mib_mac_mgmt), GFP_KERNEL); if(!mac_mgmt){ ret = -ENOMEM; goto exit; } ret = get_mib(dev->udev, MIB_MAC_MGMT, (u8*)mac_mgmt, sizeof(struct mib_mac_mgmt)); if(ret < 0){ err("%s: get_mib failed: %d", dev->netdev->name, ret); goto err; } memcpy(dev->bssid, mac_mgmt->current_bssid, ETH_ALEN); info("using BSSID %s", mac2str(dev->bssid)); err: kfree(mac_mgmt); exit: return ret;}staticint get_current_channel(struct at76c503 *dev){ int ret = 0; struct mib_phy *phy = kmalloc(sizeof(struct mib_phy), GFP_KERNEL); if(!phy){ ret = -ENOMEM; goto exit; } ret = get_mib(dev->udev, MIB_PHY, (u8*)phy, sizeof(struct mib_phy)); if(ret < 0){ err("%s: get_mib(MIB_PHY) failed: %d", dev->netdev->name, ret); goto err; } dev->channel = phy->channel_id; err: kfree(phy); exit: return ret;}staticint start_scan(struct at76c503 *dev, int use_essid){ struct at76c503_start_scan scan; memset(&scan, 0, sizeof(struct at76c503_start_scan)); memset(scan.bssid, 0xff, ETH_ALEN); if (use_essid) { memcpy(scan.essid, dev->essid, IW_ESSID_MAX_SIZE); scan.essid_size = dev->essid_size; } else scan.essid_size = 0; scan.probe_delay = cpu_to_le16(10000); //jal: why should we start at a certain channel? we do scan the whole range //allowed by reg domain. scan.channel = dev->channel; /* atmelwlandriver differs between scan type 0 and 1 (active/passive) For ad-hoc mode, it uses type 0 only.*/ scan.scan_type = dev->scan_mode; scan.min_channel_time = cpu_to_le16(dev->scan_min_time); scan.max_channel_time = cpu_to_le16(dev->scan_max_time); /* other values are set to 0 for type 0 */ return set_card_command(dev->udev, CMD_SCAN, (unsigned char*)&scan, sizeof(scan));}staticint start_ibss(struct at76c503 *dev){ struct at76c503_start_bss bss; memset(&bss, 0, sizeof(struct at76c503_start_bss)); memset(bss.bssid, 0xff, ETH_ALEN); memcpy(bss.essid, dev->essid, IW_ESSID_MAX_SIZE); bss.essid_size = dev->essid_size; bss.bss_type = ADHOC_MODE; bss.channel = dev->channel; return set_card_command(dev->udev, CMD_START_IBSS, (unsigned char*)&bss, sizeof(struct at76c503_start_bss));}/* idx points into dev->bss */staticint join_bss(struct at76c503 *dev, struct bss_info *ptr){ struct at76c503_join join; assert(ptr != NULL); memset(&join, 0, sizeof(struct at76c503_join)); memcpy(join.bssid, ptr->bssid, ETH_ALEN); memcpy(join.essid, ptr->ssid, ptr->ssid_len); join.essid_size = ptr->ssid_len; join.bss_type = (dev->iw_mode == IW_MODE_ADHOC ? 1 : 2); join.channel = ptr->channel; join.timeout = cpu_to_le16(2000); dbg(DBG_PROGRESS, "%s join addr %s ssid %s type %d ch %d timeout %d", dev->netdev->name, mac2str(join.bssid), join.essid, join.bss_type, join.channel, le16_to_cpu(join.timeout)); return set_card_command(dev->udev, CMD_JOIN, (unsigned char*)&join, sizeof(struct at76c503_join));} /* join_bss *//* the restart timer timed out */void restart_timeout(unsigned long par){ struct at76c503 *dev = (struct at76c503 *)par; defer_kevent(dev, KEVENT_RESTART);}/* we got to check the bss_list for old entries */void bss_list_timeout(unsigned long par){ struct at76c503 *dev = (struct at76c503 *)par; unsigned long flags; struct list_head *lptr, *nptr; struct bss_info *ptr; spin_lock_irqsave(&dev->bss_list_spinlock, flags); list_for_each_safe(lptr, nptr, &dev->bss_list) { ptr = list_entry(lptr, struct bss_info, list); if (ptr != dev->curr_bss && ptr != dev->new_bss && time_after(jiffies, ptr->last_rx+BSS_LIST_TIMEOUT)) { dbg(DBG_BSS_TABLE_RM, "%s: bss_list: removing old BSS %s ch %d", dev->netdev->name, mac2str(ptr->bssid), ptr->channel); list_del(&ptr->list); kfree(ptr); } } spin_unlock_irqrestore(&dev->bss_list_spinlock, flags); /* restart the timer */ mod_timer(&dev->bss_list_timer, jiffies+BSS_LIST_TIMEOUT); }/* we got a timeout for a infrastructure mgmt packet */void mgmt_timeout(unsigned long par){ struct at76c503 *dev = (struct at76c503 *)par; defer_kevent(dev, KEVENT_MGMT_TIMEOUT);}/* the deferred procedure called from kevent() */void handle_mgmt_timeout(struct at76c503 *dev){ if (dev->istate != SCANNING) /* this is normal behaviour in state SCANNING ... */ dbg(DBG_PROGRESS, "%s: timeout, state %d", dev->netdev->name, dev->istate); switch(dev->istate) { case SCANNING: /* we use the mgmt_timer to delay the next scan for some time */ defer_kevent(dev, KEVENT_SCAN); break; case JOINING: assert(0); break; case CONNECTED: /* we haven't received the beacon of this BSS for BEACON_TIMEOUT seconds */ info("%s: lost beacon bssid %s", dev->netdev->name, mac2str(dev->curr_bss->bssid)); /* jal: starting mgmt_timer in adhoc mode is questionable, but I'll leave it here to track down another lockup problem */ if (dev->iw_mode != IW_MODE_ADHOC) { netif_carrier_off(dev->netdev); netif_stop_queue(dev->netdev); NEW_STATE(dev,SCANNING); defer_kevent(dev,KEVENT_SCAN); } break; case AUTHENTICATING: if (dev->retries-- >= 0) { auth_req(dev, dev->curr_bss, 1, NULL); mod_timer(&dev->mgmt_timer, jiffies+HZ); } else { /* try to get next matching BSS */ NEW_STATE(dev,JOINING); defer_kevent(dev,KEVENT_JOIN); } break; case ASSOCIATING: if (dev->retries-- >= 0) { assoc_req(dev,dev->curr_bss); mod_timer(&dev->mgmt_timer, jiffies+HZ); } else { /* jal: TODO: we may be authenticated to several BSS and may try to associate to the next of them here in the future ... */ /* try to get next matching BSS */ NEW_STATE(dev,JOINING); defer_kevent(dev,KEVENT_JOIN); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -