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

📄 main.c

📁 linux内核源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	ctl |= B43legacy_MACCTL_INFRA;	if (b43legacy_is_mode(wl, IEEE80211_IF_TYPE_AP))		ctl |= B43legacy_MACCTL_AP;	else if (b43legacy_is_mode(wl, IEEE80211_IF_TYPE_IBSS))		ctl &= ~B43legacy_MACCTL_INFRA;	if (wl->filter_flags & FIF_CONTROL)		ctl |= B43legacy_MACCTL_KEEP_CTL;	if (wl->filter_flags & FIF_FCSFAIL)		ctl |= B43legacy_MACCTL_KEEP_BAD;	if (wl->filter_flags & FIF_PLCPFAIL)		ctl |= B43legacy_MACCTL_KEEP_BADPLCP;	if (wl->filter_flags & FIF_PROMISC_IN_BSS)		ctl |= B43legacy_MACCTL_PROMISC;	if (wl->filter_flags & FIF_BCN_PRBRESP_PROMISC)		ctl |= B43legacy_MACCTL_BEACPROMISC;	/* Workaround: On old hardware the HW-MAC-address-filter	 * doesn't work properly, so always run promisc in filter	 * it in software. */	if (dev->dev->id.revision <= 4)		ctl |= B43legacy_MACCTL_PROMISC;	b43legacy_write32(dev, B43legacy_MMIO_MACCTL, ctl);	cfp_pretbtt = 2;	if ((ctl & B43legacy_MACCTL_INFRA) &&	    !(ctl & B43legacy_MACCTL_AP)) {		if (dev->dev->bus->chip_id == 0x4306 &&		    dev->dev->bus->chip_rev == 3)			cfp_pretbtt = 100;		else			cfp_pretbtt = 50;	}	b43legacy_write16(dev, 0x612, cfp_pretbtt);}static void b43legacy_rate_memory_write(struct b43legacy_wldev *dev,					u16 rate,					int is_ofdm){	u16 offset;	if (is_ofdm) {		offset = 0x480;		offset += (b43legacy_plcp_get_ratecode_ofdm(rate) & 0x000F) * 2;	} else {		offset = 0x4C0;		offset += (b43legacy_plcp_get_ratecode_cck(rate) & 0x000F) * 2;	}	b43legacy_shm_write16(dev, B43legacy_SHM_SHARED, offset + 0x20,			      b43legacy_shm_read16(dev,			      B43legacy_SHM_SHARED, offset));}static void b43legacy_rate_memory_init(struct b43legacy_wldev *dev){	switch (dev->phy.type) {	case B43legacy_PHYTYPE_G:		b43legacy_rate_memory_write(dev, B43legacy_OFDM_RATE_6MB, 1);		b43legacy_rate_memory_write(dev, B43legacy_OFDM_RATE_12MB, 1);		b43legacy_rate_memory_write(dev, B43legacy_OFDM_RATE_18MB, 1);		b43legacy_rate_memory_write(dev, B43legacy_OFDM_RATE_24MB, 1);		b43legacy_rate_memory_write(dev, B43legacy_OFDM_RATE_36MB, 1);		b43legacy_rate_memory_write(dev, B43legacy_OFDM_RATE_48MB, 1);		b43legacy_rate_memory_write(dev, B43legacy_OFDM_RATE_54MB, 1);		/* fallthrough */	case B43legacy_PHYTYPE_B:		b43legacy_rate_memory_write(dev, B43legacy_CCK_RATE_1MB, 0);		b43legacy_rate_memory_write(dev, B43legacy_CCK_RATE_2MB, 0);		b43legacy_rate_memory_write(dev, B43legacy_CCK_RATE_5MB, 0);		b43legacy_rate_memory_write(dev, B43legacy_CCK_RATE_11MB, 0);		break;	default:		B43legacy_BUG_ON(1);	}}/* Set the TX-Antenna for management frames sent by firmware. */static void b43legacy_mgmtframe_txantenna(struct b43legacy_wldev *dev,					  int antenna){	u16 ant = 0;	u16 tmp;	switch (antenna) {	case B43legacy_ANTENNA0:		ant |= B43legacy_TX4_PHY_ANT0;		break;	case B43legacy_ANTENNA1:		ant |= B43legacy_TX4_PHY_ANT1;		break;	case B43legacy_ANTENNA_AUTO:		ant |= B43legacy_TX4_PHY_ANTLAST;		break;	default:		B43legacy_BUG_ON(1);	}	/* FIXME We also need to set the other flags of the PHY control	 * field somewhere. */	/* For Beacons */	tmp = b43legacy_shm_read16(dev, B43legacy_SHM_SHARED,				   B43legacy_SHM_SH_BEACPHYCTL);	tmp = (tmp & ~B43legacy_TX4_PHY_ANT) | ant;	b43legacy_shm_write16(dev, B43legacy_SHM_SHARED,			      B43legacy_SHM_SH_BEACPHYCTL, tmp);	/* For ACK/CTS */	tmp = b43legacy_shm_read16(dev, B43legacy_SHM_SHARED,				   B43legacy_SHM_SH_ACKCTSPHYCTL);	tmp = (tmp & ~B43legacy_TX4_PHY_ANT) | ant;	b43legacy_shm_write16(dev, B43legacy_SHM_SHARED,			      B43legacy_SHM_SH_ACKCTSPHYCTL, tmp);	/* For Probe Resposes */	tmp = b43legacy_shm_read16(dev, B43legacy_SHM_SHARED,				   B43legacy_SHM_SH_PRPHYCTL);	tmp = (tmp & ~B43legacy_TX4_PHY_ANT) | ant;	b43legacy_shm_write16(dev, B43legacy_SHM_SHARED,			      B43legacy_SHM_SH_PRPHYCTL, tmp);}/* Returns TRUE, if the radio is enabled in hardware. */static bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev){	if (dev->phy.rev >= 3) {		if (!(b43legacy_read32(dev, B43legacy_MMIO_RADIO_HWENABLED_HI)		      & B43legacy_MMIO_RADIO_HWENABLED_HI_MASK))			return 1;	} else {		if (b43legacy_read16(dev, B43legacy_MMIO_RADIO_HWENABLED_LO)		    & B43legacy_MMIO_RADIO_HWENABLED_LO_MASK)			return 1;	}	return 0;}/* This is the opposite of b43legacy_chip_init() */static void b43legacy_chip_exit(struct b43legacy_wldev *dev){	b43legacy_radio_turn_off(dev);	if (!modparam_noleds)		b43legacy_leds_exit(dev);	b43legacy_gpio_cleanup(dev);	/* firmware is released later */}/* Initialize the chip * http://bcm-specs.sipsolutions.net/ChipInit */static int b43legacy_chip_init(struct b43legacy_wldev *dev){	struct b43legacy_phy *phy = &dev->phy;	int err;	int tmp;	u32 value32;	u16 value16;	b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD,			  B43legacy_SBF_CORE_READY			  | B43legacy_SBF_400);	err = b43legacy_request_firmware(dev);	if (err)		goto out;	err = b43legacy_upload_microcode(dev);	if (err)		goto out; /* firmware is released later */	err = b43legacy_gpio_init(dev);	if (err)		goto out; /* firmware is released later */	err = b43legacy_upload_initvals(dev);	if (err)		goto err_gpio_cleanup;	b43legacy_radio_turn_on(dev);	b43legacy_write16(dev, 0x03E6, 0x0000);	err = b43legacy_phy_init(dev);	if (err)		goto err_radio_off;	/* Select initial Interference Mitigation. */	tmp = phy->interfmode;	phy->interfmode = B43legacy_INTERFMODE_NONE;	b43legacy_radio_set_interference_mitigation(dev, tmp);	b43legacy_phy_set_antenna_diversity(dev);	b43legacy_mgmtframe_txantenna(dev, B43legacy_ANTENNA_DEFAULT);	if (phy->type == B43legacy_PHYTYPE_B) {		value16 = b43legacy_read16(dev, 0x005E);		value16 |= 0x0004;		b43legacy_write16(dev, 0x005E, value16);	}	b43legacy_write32(dev, 0x0100, 0x01000000);	if (dev->dev->id.revision < 5)		b43legacy_write32(dev, 0x010C, 0x01000000);	value32 = b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD);	value32 &= ~B43legacy_SBF_MODE_NOTADHOC;	b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, value32);	value32 = b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD);	value32 |= B43legacy_SBF_MODE_NOTADHOC;	b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, value32);	if (b43legacy_using_pio(dev)) {		b43legacy_write32(dev, 0x0210, 0x00000100);		b43legacy_write32(dev, 0x0230, 0x00000100);		b43legacy_write32(dev, 0x0250, 0x00000100);		b43legacy_write32(dev, 0x0270, 0x00000100);		b43legacy_shm_write16(dev, B43legacy_SHM_SHARED, 0x0034,				      0x0000);	}	/* Probe Response Timeout value */	/* FIXME: Default to 0, has to be set by ioctl probably... :-/ */	b43legacy_shm_write16(dev, B43legacy_SHM_SHARED, 0x0074, 0x0000);	/* Initially set the wireless operation mode. */	b43legacy_adjust_opmode(dev);	if (dev->dev->id.revision < 3) {		b43legacy_write16(dev, 0x060E, 0x0000);		b43legacy_write16(dev, 0x0610, 0x8000);		b43legacy_write16(dev, 0x0604, 0x0000);		b43legacy_write16(dev, 0x0606, 0x0200);	} else {		b43legacy_write32(dev, 0x0188, 0x80000000);		b43legacy_write32(dev, 0x018C, 0x02000000);	}	b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_REASON, 0x00004000);	b43legacy_write32(dev, B43legacy_MMIO_DMA0_IRQ_MASK, 0x0001DC00);	b43legacy_write32(dev, B43legacy_MMIO_DMA1_IRQ_MASK, 0x0000DC00);	b43legacy_write32(dev, B43legacy_MMIO_DMA2_IRQ_MASK, 0x0000DC00);	b43legacy_write32(dev, B43legacy_MMIO_DMA3_IRQ_MASK, 0x0001DC00);	b43legacy_write32(dev, B43legacy_MMIO_DMA4_IRQ_MASK, 0x0000DC00);	b43legacy_write32(dev, B43legacy_MMIO_DMA5_IRQ_MASK, 0x0000DC00);	value32 = ssb_read32(dev->dev, SSB_TMSLOW);	value32 |= 0x00100000;	ssb_write32(dev->dev, SSB_TMSLOW, value32);	b43legacy_write16(dev, B43legacy_MMIO_POWERUP_DELAY,			  dev->dev->bus->chipco.fast_pwrup_delay);	B43legacy_WARN_ON(err != 0);	b43legacydbg(dev->wl, "Chip initialized\n");out:	return err;err_radio_off:	b43legacy_radio_turn_off(dev);err_gpio_cleanup:	b43legacy_gpio_cleanup(dev);	goto out;}static void b43legacy_periodic_every120sec(struct b43legacy_wldev *dev){	struct b43legacy_phy *phy = &dev->phy;	if (phy->type != B43legacy_PHYTYPE_G || phy->rev < 2)		return;	b43legacy_mac_suspend(dev);	b43legacy_phy_lo_g_measure(dev);	b43legacy_mac_enable(dev);}static void b43legacy_periodic_every60sec(struct b43legacy_wldev *dev){	b43legacy_phy_lo_mark_all_unused(dev);	if (dev->dev->bus->sprom.r1.boardflags_lo & B43legacy_BFL_RSSI) {		b43legacy_mac_suspend(dev);		b43legacy_calc_nrssi_slope(dev);		b43legacy_mac_enable(dev);	}}static void b43legacy_periodic_every30sec(struct b43legacy_wldev *dev){	/* Update device statistics. */	b43legacy_calculate_link_quality(dev);}static void b43legacy_periodic_every15sec(struct b43legacy_wldev *dev){	b43legacy_phy_xmitpower(dev); /* FIXME: unless scanning? */}static void b43legacy_periodic_every1sec(struct b43legacy_wldev *dev){	bool radio_hw_enable;	/* check if radio hardware enabled status changed */	radio_hw_enable = b43legacy_is_hw_radio_enabled(dev);	if (unlikely(dev->radio_hw_enable != radio_hw_enable)) {		dev->radio_hw_enable = radio_hw_enable;		b43legacyinfo(dev->wl, "Radio hardware status changed to %s\n",		       (radio_hw_enable) ? "enabled" : "disabled");		b43legacy_leds_update(dev, 0);	}}static void do_periodic_work(struct b43legacy_wldev *dev){	unsigned int state;	state = dev->periodic_state;	if (state % 120 == 0)		b43legacy_periodic_every120sec(dev);	if (state % 60 == 0)		b43legacy_periodic_every60sec(dev);	if (state % 30 == 0)		b43legacy_periodic_every30sec(dev);	if (state % 15 == 0)		b43legacy_periodic_every15sec(dev);	b43legacy_periodic_every1sec(dev);}/* Estimate a "Badness" value based on the periodic work * state-machine state. "Badness" is worse (bigger), if the * periodic work will take longer. */static int estimate_periodic_work_badness(unsigned int state){	int badness = 0;	if (state % 120 == 0) /* every 120 sec */		badness += 10;	if (state % 60 == 0) /* every 60 sec */		badness += 5;	if (state % 30 == 0) /* every 30 sec */		badness += 1;	if (state % 15 == 0) /* every 15 sec */		badness += 1;#define BADNESS_LIMIT	4	return badness;}static void b43legacy_periodic_work_handler(struct work_struct *work){	struct b43legacy_wldev *dev =			     container_of(work, struct b43legacy_wldev,			     periodic_work.work);	unsigned long flags;	unsigned long delay;	u32 savedirqs = 0;	int badness;	mutex_lock(&dev->wl->mutex);	if (unlikely(b43legacy_status(dev) != B43legacy_STAT_STARTED))		goto out;	if (b43legacy_debug(dev, B43legacy_DBG_PWORK_STOP))		goto out_requeue;	badness = estimate_periodic_work_badness(dev->periodic_state);	if (badness > BADNESS_LIMIT) {		spin_lock_irqsave(&dev->wl->irq_lock, flags);		/* Suspend TX as we don't want to transmit packets while		 * we recalibrate the hardware. */		b43legacy_tx_suspend(dev);		savedirqs = b43legacy_interrupt_disable(dev,							  B43legacy_IRQ_ALL);		/* Periodic work will take a long time, so we want it to		 * be preemtible and release the spinlock. */		spin_unlock_irqrestore(&dev->wl->irq_lock, flags);		b43legacy_synchronize_irq(dev);		do_periodic_work(dev);		spin_lock_irqsave(&dev->wl->irq_lock, flags);		b43legacy_interrupt_enable(dev, savedirqs);		b43legacy_tx_resume(dev);		mmiowb();		spin_unlock_irqrestore(&dev->wl->irq_lock, flags);	} else {		/* Take the global driver lock. This will lock any operation. */		spin_lock_irqsave(&dev->wl->irq_lock, flags);		do_periodic_work(dev);		mmiowb();		spin_unlock_irqrestore(&dev->wl->irq_lock, flags);	}	dev->periodic_state++;out_requeue:	if (b43legacy_debug(dev, B43legacy_DBG_PWORK_FAST))		delay = msecs_to_jiffies(50);	else		delay = round_jiffies_relative(HZ);	queue_delayed_work(dev->wl->hw->workqueue,			   &dev->periodic_work, delay);out:	mutex_unlock(&dev->wl->mutex);}static void b43legacy_periodic_tasks_setup(struct b43legacy_wldev *dev){	struct delayed_work *work = &dev->periodic_work;	dev->periodic_state = 0;	INIT_DELAYED_WORK(work, b43legacy_periodic_work_handler);	queue_delayed_work(dev->wl->hw->workqueue, work, 0);}/* Validate access to the chip (SHM) */static int b43legacy_validate_chipaccess(struct b43legacy_wldev *dev){	u32 value;	u32 shm_backup;	shm_backup = b43legacy_shm_read32(dev, B43legacy_SHM_SHARED, 0);	b43legacy_shm_write32(dev, B43legacy_SHM_SHARED, 0, 0xAA5555AA);	if (b43legacy_shm_read32(dev, B43legacy_SHM_SHARED, 0) !=				 0xAA5555AA)		goto error;	b43legacy_shm_write32(dev, B43legacy_SHM_SHARED, 0, 0x55AAAA55);	if (b43legacy_shm_read32(dev, B43legacy_SHM_SHARED, 0) !=				 0x55AAAA55)		goto error;	b43legacy_shm_write32(dev, B43legacy_SHM_SHARED, 0, shm_backup);	value = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);	if ((value | B43legacy_MACCTL_GMODE) !=	    (B43legacy_MACCTL_GMODE | B43legacy_MACCTL_IHR_ENABLED))		goto error;	value = b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_REASON);	if (value)		goto error;	return 0;error:	b43legacyerr(dev->wl, "Failed to validate the chipaccess\n");	return -ENODEV;}static void b43legacy_security_init(struct b43legacy_wldev *dev){	dev->max_nr_keys = (dev->dev->id.revision >= 5) ? 58 : 20;	B43legacy_WARN_ON(dev->max_nr_keys > ARRAY_SIZE(dev->key));	dev->ktp = b43legacy_shm_read16(dev, B43legacy_SHM_SHARED,					0x0056);	/* KTP is a word address, but we address SHM bytewise.	 * So multiply by two.	 */	dev->ktp *= 2;	if (dev->dev->id.revision >= 5)		/* Number of RCMTA address slots */		b43legacy_write16(dev, B43legacy_MMIO_RCMTA_COUNT,				  dev->max_nr_keys - 8);}static int b43legacy_rng_read(struct hwrng *rng, u32 *data){	struct b43legacy_wl *wl = (struct b43legacy_wl *)rng->priv;	unsigned long flags;	/* Don't take wl->mutex here, as it could deadlock with	 * hwrng internal lock

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -