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

📄 main.c

📁 linux内核源码
💻 C
📖 第 1 页 / 共 5 页
字号:
		    (ssb_read32(gpiodev, B43_GPIO_CONTROL)		     & mask) | set);	return 0;}/* Turn off all GPIO stuff. Call this on module unload, for example. */static void b43_gpio_cleanup(struct b43_wldev *dev){	struct ssb_bus *bus = dev->dev->bus;	struct ssb_device *gpiodev, *pcidev = NULL;#ifdef CONFIG_SSB_DRIVER_PCICORE	pcidev = bus->pcicore.dev;#endif	gpiodev = bus->chipco.dev ? : pcidev;	if (!gpiodev)		return;	ssb_write32(gpiodev, B43_GPIO_CONTROL, 0);}/* http://bcm-specs.sipsolutions.net/EnableMac */void b43_mac_enable(struct b43_wldev *dev){	dev->mac_suspended--;	B43_WARN_ON(dev->mac_suspended < 0);	B43_WARN_ON(irqs_disabled());	if (dev->mac_suspended == 0) {		b43_write32(dev, B43_MMIO_MACCTL,			    b43_read32(dev, B43_MMIO_MACCTL)			    | B43_MACCTL_ENABLED);		b43_write32(dev, B43_MMIO_GEN_IRQ_REASON,			    B43_IRQ_MAC_SUSPENDED);		/* Commit writes */		b43_read32(dev, B43_MMIO_MACCTL);		b43_read32(dev, B43_MMIO_GEN_IRQ_REASON);		b43_power_saving_ctl_bits(dev, 0);		/* Re-enable IRQs. */		spin_lock_irq(&dev->wl->irq_lock);		b43_interrupt_enable(dev, dev->irq_savedstate);		spin_unlock_irq(&dev->wl->irq_lock);	}}/* http://bcm-specs.sipsolutions.net/SuspendMAC */void b43_mac_suspend(struct b43_wldev *dev){	int i;	u32 tmp;	might_sleep();	B43_WARN_ON(irqs_disabled());	B43_WARN_ON(dev->mac_suspended < 0);	if (dev->mac_suspended == 0) {		/* Mask IRQs before suspending MAC. Otherwise		 * the MAC stays busy and won't suspend. */		spin_lock_irq(&dev->wl->irq_lock);		tmp = b43_interrupt_disable(dev, B43_IRQ_ALL);		spin_unlock_irq(&dev->wl->irq_lock);		b43_synchronize_irq(dev);		dev->irq_savedstate = tmp;		b43_power_saving_ctl_bits(dev, B43_PS_AWAKE);		b43_write32(dev, B43_MMIO_MACCTL,			    b43_read32(dev, B43_MMIO_MACCTL)			    & ~B43_MACCTL_ENABLED);		/* force pci to flush the write */		b43_read32(dev, B43_MMIO_MACCTL);		for (i = 40; i; i--) {			tmp = b43_read32(dev, B43_MMIO_GEN_IRQ_REASON);			if (tmp & B43_IRQ_MAC_SUSPENDED)				goto out;			msleep(1);		}		b43err(dev->wl, "MAC suspend failed\n");	}out:	dev->mac_suspended++;}static void b43_adjust_opmode(struct b43_wldev *dev){	struct b43_wl *wl = dev->wl;	u32 ctl;	u16 cfp_pretbtt;	ctl = b43_read32(dev, B43_MMIO_MACCTL);	/* Reset status to STA infrastructure mode. */	ctl &= ~B43_MACCTL_AP;	ctl &= ~B43_MACCTL_KEEP_CTL;	ctl &= ~B43_MACCTL_KEEP_BADPLCP;	ctl &= ~B43_MACCTL_KEEP_BAD;	ctl &= ~B43_MACCTL_PROMISC;	ctl &= ~B43_MACCTL_BEACPROMISC;	ctl |= B43_MACCTL_INFRA;	if (b43_is_mode(wl, IEEE80211_IF_TYPE_AP))		ctl |= B43_MACCTL_AP;	else if (b43_is_mode(wl, IEEE80211_IF_TYPE_IBSS))		ctl &= ~B43_MACCTL_INFRA;	if (wl->filter_flags & FIF_CONTROL)		ctl |= B43_MACCTL_KEEP_CTL;	if (wl->filter_flags & FIF_FCSFAIL)		ctl |= B43_MACCTL_KEEP_BAD;	if (wl->filter_flags & FIF_PLCPFAIL)		ctl |= B43_MACCTL_KEEP_BADPLCP;	if (wl->filter_flags & FIF_PROMISC_IN_BSS)		ctl |= B43_MACCTL_PROMISC;	if (wl->filter_flags & FIF_BCN_PRBRESP_PROMISC)		ctl |= B43_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 |= B43_MACCTL_PROMISC;	b43_write32(dev, B43_MMIO_MACCTL, ctl);	cfp_pretbtt = 2;	if ((ctl & B43_MACCTL_INFRA) && !(ctl & B43_MACCTL_AP)) {		if (dev->dev->bus->chip_id == 0x4306 &&		    dev->dev->bus->chip_rev == 3)			cfp_pretbtt = 100;		else			cfp_pretbtt = 50;	}	b43_write16(dev, 0x612, cfp_pretbtt);}static void b43_rate_memory_write(struct b43_wldev *dev, u16 rate, int is_ofdm){	u16 offset;	if (is_ofdm) {		offset = 0x480;		offset += (b43_plcp_get_ratecode_ofdm(rate) & 0x000F) * 2;	} else {		offset = 0x4C0;		offset += (b43_plcp_get_ratecode_cck(rate) & 0x000F) * 2;	}	b43_shm_write16(dev, B43_SHM_SHARED, offset + 0x20,			b43_shm_read16(dev, B43_SHM_SHARED, offset));}static void b43_rate_memory_init(struct b43_wldev *dev){	switch (dev->phy.type) {	case B43_PHYTYPE_A:	case B43_PHYTYPE_G:		b43_rate_memory_write(dev, B43_OFDM_RATE_6MB, 1);		b43_rate_memory_write(dev, B43_OFDM_RATE_12MB, 1);		b43_rate_memory_write(dev, B43_OFDM_RATE_18MB, 1);		b43_rate_memory_write(dev, B43_OFDM_RATE_24MB, 1);		b43_rate_memory_write(dev, B43_OFDM_RATE_36MB, 1);		b43_rate_memory_write(dev, B43_OFDM_RATE_48MB, 1);		b43_rate_memory_write(dev, B43_OFDM_RATE_54MB, 1);		if (dev->phy.type == B43_PHYTYPE_A)			break;		/* fallthrough */	case B43_PHYTYPE_B:		b43_rate_memory_write(dev, B43_CCK_RATE_1MB, 0);		b43_rate_memory_write(dev, B43_CCK_RATE_2MB, 0);		b43_rate_memory_write(dev, B43_CCK_RATE_5MB, 0);		b43_rate_memory_write(dev, B43_CCK_RATE_11MB, 0);		break;	default:		B43_WARN_ON(1);	}}/* Set the TX-Antenna for management frames sent by firmware. */static void b43_mgmtframe_txantenna(struct b43_wldev *dev, int antenna){	u16 ant = 0;	u16 tmp;	switch (antenna) {	case B43_ANTENNA0:		ant |= B43_TX4_PHY_ANT0;		break;	case B43_ANTENNA1:		ant |= B43_TX4_PHY_ANT1;		break;	case B43_ANTENNA_AUTO:		ant |= B43_TX4_PHY_ANTLAST;		break;	default:		B43_WARN_ON(1);	}	/* FIXME We also need to set the other flags of the PHY control field somewhere. */	/* For Beacons */	tmp = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_BEACPHYCTL);	tmp = (tmp & ~B43_TX4_PHY_ANT) | ant;	b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_BEACPHYCTL, tmp);	/* For ACK/CTS */	tmp = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_ACKCTSPHYCTL);	tmp = (tmp & ~B43_TX4_PHY_ANT) | ant;	b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_ACKCTSPHYCTL, tmp);	/* For Probe Resposes */	tmp = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_PRPHYCTL);	tmp = (tmp & ~B43_TX4_PHY_ANT) | ant;	b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_PRPHYCTL, tmp);}/* This is the opposite of b43_chip_init() */static void b43_chip_exit(struct b43_wldev *dev){	b43_radio_turn_off(dev, 1);	b43_gpio_cleanup(dev);	/* firmware is released later */}/* Initialize the chip * http://bcm-specs.sipsolutions.net/ChipInit */static int b43_chip_init(struct b43_wldev *dev){	struct b43_phy *phy = &dev->phy;	int err, tmp;	u32 value32;	u16 value16;	b43_write32(dev, B43_MMIO_MACCTL,		    B43_MACCTL_PSM_JMP0 | B43_MACCTL_IHR_ENABLED);	err = b43_request_firmware(dev);	if (err)		goto out;	err = b43_upload_microcode(dev);	if (err)		goto out;	/* firmware is released later */	err = b43_gpio_init(dev);	if (err)		goto out;	/* firmware is released later */	err = b43_upload_initvals(dev);	if (err)		goto err_gpio_clean;	b43_radio_turn_on(dev);	b43_write16(dev, 0x03E6, 0x0000);	err = b43_phy_init(dev);	if (err)		goto err_radio_off;	/* Select initial Interference Mitigation. */	tmp = phy->interfmode;	phy->interfmode = B43_INTERFMODE_NONE;	b43_radio_set_interference_mitigation(dev, tmp);	b43_set_rx_antenna(dev, B43_ANTENNA_DEFAULT);	b43_mgmtframe_txantenna(dev, B43_ANTENNA_DEFAULT);	if (phy->type == B43_PHYTYPE_B) {		value16 = b43_read16(dev, 0x005E);		value16 |= 0x0004;		b43_write16(dev, 0x005E, value16);	}	b43_write32(dev, 0x0100, 0x01000000);	if (dev->dev->id.revision < 5)		b43_write32(dev, 0x010C, 0x01000000);	b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL)		    & ~B43_MACCTL_INFRA);	b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL)		    | B43_MACCTL_INFRA);	if (b43_using_pio(dev)) {		b43_write32(dev, 0x0210, 0x00000100);		b43_write32(dev, 0x0230, 0x00000100);		b43_write32(dev, 0x0250, 0x00000100);		b43_write32(dev, 0x0270, 0x00000100);		b43_shm_write16(dev, B43_SHM_SHARED, 0x0034, 0x0000);	}	/* Probe Response Timeout value */	/* FIXME: Default to 0, has to be set by ioctl probably... :-/ */	b43_shm_write16(dev, B43_SHM_SHARED, 0x0074, 0x0000);	/* Initially set the wireless operation mode. */	b43_adjust_opmode(dev);	if (dev->dev->id.revision < 3) {		b43_write16(dev, 0x060E, 0x0000);		b43_write16(dev, 0x0610, 0x8000);		b43_write16(dev, 0x0604, 0x0000);		b43_write16(dev, 0x0606, 0x0200);	} else {		b43_write32(dev, 0x0188, 0x80000000);		b43_write32(dev, 0x018C, 0x02000000);	}	b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, 0x00004000);	b43_write32(dev, B43_MMIO_DMA0_IRQ_MASK, 0x0001DC00);	b43_write32(dev, B43_MMIO_DMA1_IRQ_MASK, 0x0000DC00);	b43_write32(dev, B43_MMIO_DMA2_IRQ_MASK, 0x0000DC00);	b43_write32(dev, B43_MMIO_DMA3_IRQ_MASK, 0x0001DC00);	b43_write32(dev, B43_MMIO_DMA4_IRQ_MASK, 0x0000DC00);	b43_write32(dev, B43_MMIO_DMA5_IRQ_MASK, 0x0000DC00);	value32 = ssb_read32(dev->dev, SSB_TMSLOW);	value32 |= 0x00100000;	ssb_write32(dev->dev, SSB_TMSLOW, value32);	b43_write16(dev, B43_MMIO_POWERUP_DELAY,		    dev->dev->bus->chipco.fast_pwrup_delay);	err = 0;	b43dbg(dev->wl, "Chip initialized\n");out:	return err;err_radio_off:	b43_radio_turn_off(dev, 1);err_gpio_clean:	b43_gpio_cleanup(dev);	return err;}static void b43_periodic_every120sec(struct b43_wldev *dev){	struct b43_phy *phy = &dev->phy;	if (phy->type != B43_PHYTYPE_G || phy->rev < 2)		return;	b43_mac_suspend(dev);	b43_lo_g_measure(dev);	b43_mac_enable(dev);	if (b43_has_hardware_pctl(phy))		b43_lo_g_ctl_mark_all_unused(dev);}static void b43_periodic_every60sec(struct b43_wldev *dev){	struct b43_phy *phy = &dev->phy;	if (!b43_has_hardware_pctl(phy))		b43_lo_g_ctl_mark_all_unused(dev);	if (dev->dev->bus->sprom.r1.boardflags_lo & B43_BFL_RSSI) {		b43_mac_suspend(dev);		b43_calc_nrssi_slope(dev);		if ((phy->radio_ver == 0x2050) && (phy->radio_rev == 8)) {			u8 old_chan = phy->channel;			/* VCO Calibration */			if (old_chan >= 8)				b43_radio_selectchannel(dev, 1, 0);			else				b43_radio_selectchannel(dev, 13, 0);			b43_radio_selectchannel(dev, old_chan, 0);		}		b43_mac_enable(dev);	}}static void b43_periodic_every30sec(struct b43_wldev *dev){	/* Update device statistics. */	b43_calculate_link_quality(dev);}static void b43_periodic_every15sec(struct b43_wldev *dev){	struct b43_phy *phy = &dev->phy;	if (phy->type == B43_PHYTYPE_G) {		//TODO: update_aci_moving_average		if (phy->aci_enable && phy->aci_wlan_automatic) {			b43_mac_suspend(dev);			if (!phy->aci_enable && 1 /*TODO: not scanning? */ ) {				if (0 /*TODO: bunch of conditions */ ) {					b43_radio_set_interference_mitigation					    (dev, B43_INTERFMODE_MANUALWLAN);				}			} else if (1 /*TODO*/) {				/*				   if ((aci_average > 1000) && !(b43_radio_aci_scan(dev))) {				   b43_radio_set_interference_mitigation(dev,				   B43_INTERFMODE_NONE);				   }				 */			}			b43_mac_enable(dev);		} else if (phy->interfmode == B43_INTERFMODE_NONWLAN &&			   phy->rev == 1) {			//TODO: implement rev1 workaround		}	}	b43_phy_xmitpower(dev);	//FIXME: unless scanning?	//TODO for APHY (temperature?)}static void do_periodic_work(struct b43_wldev *dev){	unsigned int state;	state = dev->periodic_state;	if (state % 8 == 0)		b43_periodic_every120sec(dev);	if (state % 4 == 0)		b43_periodic_every60sec(dev);	if (state % 2 == 0)		b43_periodic_every30sec(dev);	b43_periodic_every15sec(dev);}/* Periodic work locking policy: * 	The whole periodic work handler is protected by * 	wl->mutex. If another lock is needed somewhere in the * 	pwork callchain, it's aquired in-place, where it's needed. */static void b43_periodic_work_handler(struct work_struct *work){	struct b43_wldev *dev = container_of(work, struct b43_wldev,					     periodic_work.work);	struct b43_wl *wl = dev->wl;	unsigned long delay;	mutex_lock(&wl->mutex);	if (unlikely(b43_status(dev) != B43_STAT_STARTED))		goto out;	if (b43_debug(dev, B43_DBG_PWORK_STOP))		goto out_requeue;	do_periodic_work(dev);	dev->periodic_state++;out_requeue:	if (b43_debug(dev, B43_DBG_PWORK_FAST))		delay = msecs_to_jiffies(50);	else		delay = round_jiffies_relative(HZ * 15);	queue_delayed_work(wl->hw->workqueue, &dev->periodic_work, delay);out:	mutex_unlock(&wl->mutex);}static void b43_periodic_tasks_setup(struct b43_wldev *dev){	struct delayed_work *work = &dev->periodic_work;	dev->periodic_state = 0;	INIT_DELAYED_WORK(work, b43_periodic_work_handler);	queue_delayed_work(dev->wl->hw->workqueue, work, 0);}/* Validate access to the chip (SHM) */static int b43_validate_chipaccess(struct b43_wldev *dev){	u32 value;	u32 shm_backup;	shm_backup = b43_shm_read32(dev, B43_SHM_SHARED, 0);	b43_shm_write32(dev, B43_SHM_SHARED, 0, 0xAA5555AA);	if (b43_shm_read32(dev, B43_SHM_SHARED, 0) != 0xAA5555AA)		goto error;	b43_shm_write32(dev, B43_SHM_SHARED, 0, 0x55AAAA55);	if (b43_shm_read32(dev, B43_SHM_SHARED, 0) != 0x55AAAA55)		goto error;	b43_shm_write32(dev, B43_SHM_SHARED, 0, shm_backup);	value = b43_read32(dev, B43_MMIO_MACCTL);	if ((value | B43_MACCTL_GMODE) !=	    (B43_MACCTL_GMODE | B43_MACCTL_IHR_ENABLED))		goto error;	value = b43_read32(dev, B43_MMIO_GEN_IRQ_REASON);	if (value)		goto error;	return 0;      error:	b43err(dev->wl, "Failed to validate the chipaccess\n");	return -ENODEV;}static void b43_security_init(struct b43_wldev *dev){	dev->max_nr_keys = (dev->dev->id.revision >= 5) ? 58 : 20;	B43_WARN_ON(dev->max_nr_keys > ARRAY_SIZE(dev->key));	dev->ktp = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_KTP);	/* KTP is a word address, but we address SHM bytewise.	 * So multiply 

⌨️ 快捷键说明

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