📄 main.c
字号:
b43_write16(dev, B43_MMIO_TSF_0, v0); }}void b43_tsf_write(struct b43_wldev *dev, u64 tsf){ b43_time_lock(dev); b43_tsf_write_locked(dev, tsf); b43_time_unlock(dev);}staticvoid b43_macfilter_set(struct b43_wldev *dev, u16 offset, const u8 * mac){ static const u8 zero_addr[ETH_ALEN] = { 0 }; u16 data; if (!mac) mac = zero_addr; offset |= 0x0020; b43_write16(dev, B43_MMIO_MACFILTER_CONTROL, offset); data = mac[0]; data |= mac[1] << 8; b43_write16(dev, B43_MMIO_MACFILTER_DATA, data); data = mac[2]; data |= mac[3] << 8; b43_write16(dev, B43_MMIO_MACFILTER_DATA, data); data = mac[4]; data |= mac[5] << 8; b43_write16(dev, B43_MMIO_MACFILTER_DATA, data);}static void b43_write_mac_bssid_templates(struct b43_wldev *dev){ const u8 *mac; const u8 *bssid; u8 mac_bssid[ETH_ALEN * 2]; int i; u32 tmp; bssid = dev->wl->bssid; mac = dev->wl->mac_addr; b43_macfilter_set(dev, B43_MACFILTER_BSSID, bssid); memcpy(mac_bssid, mac, ETH_ALEN); memcpy(mac_bssid + ETH_ALEN, bssid, ETH_ALEN); /* Write our MAC address and BSSID to template ram */ for (i = 0; i < ARRAY_SIZE(mac_bssid); i += sizeof(u32)) { tmp = (u32) (mac_bssid[i + 0]); tmp |= (u32) (mac_bssid[i + 1]) << 8; tmp |= (u32) (mac_bssid[i + 2]) << 16; tmp |= (u32) (mac_bssid[i + 3]) << 24; b43_ram_write(dev, 0x20 + i, tmp); }}static void b43_upload_card_macaddress(struct b43_wldev *dev){ b43_write_mac_bssid_templates(dev); b43_macfilter_set(dev, B43_MACFILTER_SELF, dev->wl->mac_addr);}static void b43_set_slot_time(struct b43_wldev *dev, u16 slot_time){ /* slot_time is in usec. */ if (dev->phy.type != B43_PHYTYPE_G) return; b43_write16(dev, 0x684, 510 + slot_time); b43_shm_write16(dev, B43_SHM_SHARED, 0x0010, slot_time);}static void b43_short_slot_timing_enable(struct b43_wldev *dev){ b43_set_slot_time(dev, 9); dev->short_slot = 1;}static void b43_short_slot_timing_disable(struct b43_wldev *dev){ b43_set_slot_time(dev, 20); dev->short_slot = 0;}/* Enable a Generic IRQ. "mask" is the mask of which IRQs to enable. * Returns the _previously_ enabled IRQ mask. */static inline u32 b43_interrupt_enable(struct b43_wldev *dev, u32 mask){ u32 old_mask; old_mask = b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, old_mask | mask); return old_mask;}/* Disable a Generic IRQ. "mask" is the mask of which IRQs to disable. * Returns the _previously_ enabled IRQ mask. */static inline u32 b43_interrupt_disable(struct b43_wldev *dev, u32 mask){ u32 old_mask; old_mask = b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, old_mask & ~mask); return old_mask;}/* Synchronize IRQ top- and bottom-half. * IRQs must be masked before calling this. * This must not be called with the irq_lock held. */static void b43_synchronize_irq(struct b43_wldev *dev){ synchronize_irq(dev->dev->irq); tasklet_kill(&dev->isr_tasklet);}/* DummyTransmission function, as documented on * http://bcm-specs.sipsolutions.net/DummyTransmission */void b43_dummy_transmission(struct b43_wldev *dev){ struct b43_phy *phy = &dev->phy; unsigned int i, max_loop; u16 value; u32 buffer[5] = { 0x00000000, 0x00D40000, 0x00000000, 0x01000000, 0x00000000, }; switch (phy->type) { case B43_PHYTYPE_A: max_loop = 0x1E; buffer[0] = 0x000201CC; break; case B43_PHYTYPE_B: case B43_PHYTYPE_G: max_loop = 0xFA; buffer[0] = 0x000B846E; break; default: B43_WARN_ON(1); return; } for (i = 0; i < 5; i++) b43_ram_write(dev, i * 4, buffer[i]); /* Commit writes */ b43_read32(dev, B43_MMIO_MACCTL); b43_write16(dev, 0x0568, 0x0000); b43_write16(dev, 0x07C0, 0x0000); value = ((phy->type == B43_PHYTYPE_A) ? 1 : 0); b43_write16(dev, 0x050C, value); b43_write16(dev, 0x0508, 0x0000); b43_write16(dev, 0x050A, 0x0000); b43_write16(dev, 0x054C, 0x0000); b43_write16(dev, 0x056A, 0x0014); b43_write16(dev, 0x0568, 0x0826); b43_write16(dev, 0x0500, 0x0000); b43_write16(dev, 0x0502, 0x0030); if (phy->radio_ver == 0x2050 && phy->radio_rev <= 0x5) b43_radio_write16(dev, 0x0051, 0x0017); for (i = 0x00; i < max_loop; i++) { value = b43_read16(dev, 0x050E); if (value & 0x0080) break; udelay(10); } for (i = 0x00; i < 0x0A; i++) { value = b43_read16(dev, 0x050E); if (value & 0x0400) break; udelay(10); } for (i = 0x00; i < 0x0A; i++) { value = b43_read16(dev, 0x0690); if (!(value & 0x0100)) break; udelay(10); } if (phy->radio_ver == 0x2050 && phy->radio_rev <= 0x5) b43_radio_write16(dev, 0x0051, 0x0037);}static void key_write(struct b43_wldev *dev, u8 index, u8 algorithm, const u8 * key){ unsigned int i; u32 offset; u16 value; u16 kidx; /* Key index/algo block */ kidx = b43_kidx_to_fw(dev, index); value = ((kidx << 4) | algorithm); b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_KEYIDXBLOCK + (kidx * 2), value); /* Write the key to the Key Table Pointer offset */ offset = dev->ktp + (index * B43_SEC_KEYSIZE); for (i = 0; i < B43_SEC_KEYSIZE; i += 2) { value = key[i]; value |= (u16) (key[i + 1]) << 8; b43_shm_write16(dev, B43_SHM_SHARED, offset + i, value); }}static void keymac_write(struct b43_wldev *dev, u8 index, const u8 * addr){ u32 addrtmp[2] = { 0, 0, }; u8 per_sta_keys_start = 8; if (b43_new_kidx_api(dev)) per_sta_keys_start = 4; B43_WARN_ON(index < per_sta_keys_start); /* We have two default TX keys and possibly two default RX keys. * Physical mac 0 is mapped to physical key 4 or 8, depending * on the firmware version. * So we must adjust the index here. */ index -= per_sta_keys_start; if (addr) { addrtmp[0] = addr[0]; addrtmp[0] |= ((u32) (addr[1]) << 8); addrtmp[0] |= ((u32) (addr[2]) << 16); addrtmp[0] |= ((u32) (addr[3]) << 24); addrtmp[1] = addr[4]; addrtmp[1] |= ((u32) (addr[5]) << 8); } if (dev->dev->id.revision >= 5) { /* Receive match transmitter address mechanism */ b43_shm_write32(dev, B43_SHM_RCMTA, (index * 2) + 0, addrtmp[0]); b43_shm_write16(dev, B43_SHM_RCMTA, (index * 2) + 1, addrtmp[1]); } else { /* RXE (Receive Engine) and * PSM (Programmable State Machine) mechanism */ if (index < 8) { /* TODO write to RCM 16, 19, 22 and 25 */ } else { b43_shm_write32(dev, B43_SHM_SHARED, B43_SHM_SH_PSM + (index * 6) + 0, addrtmp[0]); b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_PSM + (index * 6) + 4, addrtmp[1]); } }}static void do_key_write(struct b43_wldev *dev, u8 index, u8 algorithm, const u8 * key, size_t key_len, const u8 * mac_addr){ u8 buf[B43_SEC_KEYSIZE] = { 0, }; u8 per_sta_keys_start = 8; if (b43_new_kidx_api(dev)) per_sta_keys_start = 4; B43_WARN_ON(index >= dev->max_nr_keys); B43_WARN_ON(key_len > B43_SEC_KEYSIZE); if (index >= per_sta_keys_start) keymac_write(dev, index, NULL); /* First zero out mac. */ if (key) memcpy(buf, key, key_len); key_write(dev, index, algorithm, buf); if (index >= per_sta_keys_start) keymac_write(dev, index, mac_addr); dev->key[index].algorithm = algorithm;}static int b43_key_write(struct b43_wldev *dev, int index, u8 algorithm, const u8 * key, size_t key_len, const u8 * mac_addr, struct ieee80211_key_conf *keyconf){ int i; int sta_keys_start; if (key_len > B43_SEC_KEYSIZE) return -EINVAL; for (i = 0; i < dev->max_nr_keys; i++) { /* Check that we don't already have this key. */ B43_WARN_ON(dev->key[i].keyconf == keyconf); } if (index < 0) { /* Either pairwise key or address is 00:00:00:00:00:00 * for transmit-only keys. Search the index. */ if (b43_new_kidx_api(dev)) sta_keys_start = 4; else sta_keys_start = 8; for (i = sta_keys_start; i < dev->max_nr_keys; i++) { if (!dev->key[i].keyconf) { /* found empty */ index = i; break; } } if (index < 0) { b43err(dev->wl, "Out of hardware key memory\n"); return -ENOSPC; } } else B43_WARN_ON(index > 3); do_key_write(dev, index, algorithm, key, key_len, mac_addr); if ((index <= 3) && !b43_new_kidx_api(dev)) { /* Default RX key */ B43_WARN_ON(mac_addr); do_key_write(dev, index + 4, algorithm, key, key_len, NULL); } keyconf->hw_key_idx = index; dev->key[index].keyconf = keyconf; return 0;}static int b43_key_clear(struct b43_wldev *dev, int index){ if (B43_WARN_ON((index < 0) || (index >= dev->max_nr_keys))) return -EINVAL; do_key_write(dev, index, B43_SEC_ALGO_NONE, NULL, B43_SEC_KEYSIZE, NULL); if ((index <= 3) && !b43_new_kidx_api(dev)) { do_key_write(dev, index + 4, B43_SEC_ALGO_NONE, NULL, B43_SEC_KEYSIZE, NULL); } dev->key[index].keyconf = NULL; return 0;}static void b43_clear_keys(struct b43_wldev *dev){ int i; for (i = 0; i < dev->max_nr_keys; i++) b43_key_clear(dev, i);}void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags){ u32 macctl; u16 ucstat; bool hwps; bool awake; int i; B43_WARN_ON((ps_flags & B43_PS_ENABLED) && (ps_flags & B43_PS_DISABLED)); B43_WARN_ON((ps_flags & B43_PS_AWAKE) && (ps_flags & B43_PS_ASLEEP)); if (ps_flags & B43_PS_ENABLED) { hwps = 1; } else if (ps_flags & B43_PS_DISABLED) { hwps = 0; } else { //TODO: If powersave is not off and FIXME is not set and we are not in adhoc // and thus is not an AP and we are associated, set bit 25 } if (ps_flags & B43_PS_AWAKE) { awake = 1; } else if (ps_flags & B43_PS_ASLEEP) { awake = 0; } else { //TODO: If the device is awake or this is an AP, or we are scanning, or FIXME, // or we are associated, or FIXME, or the latest PS-Poll packet sent was // successful, set bit26 }/* FIXME: For now we force awake-on and hwps-off */ hwps = 0; awake = 1; macctl = b43_read32(dev, B43_MMIO_MACCTL); if (hwps) macctl |= B43_MACCTL_HWPS; else macctl &= ~B43_MACCTL_HWPS; if (awake) macctl |= B43_MACCTL_AWAKE; else macctl &= ~B43_MACCTL_AWAKE; b43_write32(dev, B43_MMIO_MACCTL, macctl); /* Commit write */ b43_read32(dev, B43_MMIO_MACCTL); if (awake && dev->dev->id.revision >= 5) { /* Wait for the microcode to wake up. */ for (i = 0; i < 100; i++) { ucstat = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_UCODESTAT); if (ucstat != B43_SHM_SH_UCODESTAT_SLEEP) break; udelay(10); } }}/* Turn the Analog ON/OFF */static void b43_switch_analog(struct b43_wldev *dev, int on){ b43_write16(dev, B43_MMIO_PHY0, on ? 0 : 0xF4);}void b43_wireless_core_reset(struct b43_wldev *dev, u32 flags){ u32 tmslow; u32 macctl; flags |= B43_TMSLOW_PHYCLKEN; flags |= B43_TMSLOW_PHYRESET; ssb_device_enable(dev->dev, flags); msleep(2); /* Wait for the PLL to turn on. */ /* Now take the PHY out of Reset again */ tmslow = ssb_read32(dev->dev, SSB_TMSLOW); tmslow |= SSB_TMSLOW_FGC; tmslow &= ~B43_TMSLOW_PHYRESET; ssb_write32(dev->dev, SSB_TMSLOW, tmslow); ssb_read32(dev->dev, SSB_TMSLOW); /* flush */ msleep(1); tmslow &= ~SSB_TMSLOW_FGC; ssb_write32(dev->dev, SSB_TMSLOW, tmslow); ssb_read32(dev->dev, SSB_TMSLOW); /* flush */ msleep(1); /* Turn Analog ON */ b43_switch_analog(dev, 1); macctl = b43_read32(dev, B43_MMIO_MACCTL); macctl &= ~B43_MACCTL_GMODE; if (flags & B43_TMSLOW_GMODE) macctl |= B43_MACCTL_GMODE; macctl |= B43_MACCTL_IHR_ENABLED; b43_write32(dev, B43_MMIO_MACCTL, macctl);}static void handle_irq_transmit_status(struct b43_wldev *dev){ u32 v0, v1; u16 tmp; struct b43_txstatus stat; while (1) { v0 = b43_read32(dev, B43_MMIO_XMITSTAT_0); if (!(v0 & 0x00000001)) break; v1 = b43_read32(dev, B43_MMIO_XMITSTAT_1); stat.cookie = (v0 >> 16); stat.seq = (v1 & 0x0000FFFF); stat.phy_stat = ((v1 & 0x00FF0000) >> 16); tmp = (v0 & 0x0000FFFF); stat.frame_count = ((tmp & 0xF000) >> 12); stat.rts_count = ((tmp & 0x0F00) >> 8); stat.supp_reason = ((tmp & 0x001C) >> 2); stat.pm_indicated = !!(tmp & 0x0080); stat.intermediate = !!(tmp & 0x0040); stat.for_ampdu = !!(tmp & 0x0020); stat.acked = !!(tmp & 0x0002); b43_handle_txstatus(dev, &stat); }}static void drain_txstatus_queue(struct b43_wldev *dev){ u32 dummy;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -