⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 linux内核源码
💻 C
📖 第 1 页 / 共 5 页
字号:
		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 + -