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

📄 wlan_main.c

📁 marvell wifi driver GSPI-8385-LINUX-OMAP1510-5.0.10.p0-144-src.rar
💻 C
📖 第 1 页 / 共 3 页
字号:
#endif /* WMM */
			&& (priv->wlan_dev.dnld_sent || !Adapter->CurrentTxSkb)
			&& (priv->wlan_dev.dnld_sent || Adapter->CurCmd ||
				list_empty(&Adapter->CmdPendingQ))
			)
		) {
			PRINTK1("scheduling out... Conn=%d IntC=%d PS_Mode=%d PS_State=%d\n",
				Adapter->MediaConnectStatus, Adapter->IntCounter,
				Adapter->PSMode, Adapter->PSState);			
#ifdef _MAINSTONE
			MST_LEDDAT1 = get_utimeofday();
#endif
			TX_RESTORE;	/* required for threadx */
			schedule();
		} else {
			TX_RESTORE;	/* required for threadx */
		}

		PRINTK1("Interrupt thread 222: IntCounter=%d CurrentTxSkb=%p "
				"dnld_sent=%d\n", Adapter->IntCounter, 
				Adapter->CurrentTxSkb,priv->wlan_dev.dnld_sent);

		TXRX_DEBUG_GET_ALL(0x12, 0xff, 0xff);
		OS_SET_THREAD_STATE(TASK_RUNNING);
		remove_wait_queue(&thread->waitQ, &wait);

		TXRX_DEBUG_GET_ALL(0x13, 0xff, 0xff);
		PRINTK1("Interrupt thread 333: IntCounter=%d CurrentTxSkb=%p "
				"dnld_sent=%d\n", Adapter->IntCounter, 
				Adapter->CurrentTxSkb,priv->wlan_dev.dnld_sent);

		PRINTK1("Main thread wakes up for service!\n");

		if ((thread->state == WLAN_THREAD_STOPPED) || 
					Adapter->SurpriseRemoved)
			break;

		if (Adapter->IntCounter) {
			OS_INT_DISABLE;
			Adapter->IntCounter = 0;
			OS_INT_RESTORE;
			/*
			 * Read the interrupt status register 
			 */
			if (sbi_get_int_status(priv, &ireg)) {
				PRINTK1("ERROR: reading HOST_INT_STATUS_REG\n");
				continue;
			}
			Adapter->HisRegCpy |= ireg;
		}
#ifdef HOST_WAKEUP
#ifdef PS_REQUIRED
		else if (Adapter->PSState == PS_STATE_SLEEP
				&& Adapter->bHostWakeupDevRequired
#ifdef FW_WAKEUP_TIME
				&& (wt_pwrup_sending == 0L)
#endif
		) {
#ifdef DEEP_SLEEP
#ifdef FW_WAKEUP_TIME
			wt_pwrup_sending = get_utimeofday();
#endif
			Adapter->WakeupTries++;
			/* we borrow deep_sleep wakeup code for time being */
			if(sbi_exit_deep_sleep(priv))
				printk("Host Wakeup Dev: wakeup failed\n");
#endif //DEEP_SLEEP
			continue;
		}
#endif //PS_REQUIRED
#endif //HOST_WAKEUP

		PRINTK1("Interrupt thread 444: IntCounter=%d CurrentTxSkb=%p "
				"dnld_sent=%d\n", Adapter->IntCounter, 
				Adapter->CurrentTxSkb,priv->wlan_dev.dnld_sent);
		
		TXRX_DEBUG_GET_ALL(0x14, ireg, 0xff);

		/* Command response? */
		if (Adapter->HisRegCpy & HIS_CmdUpLdRdy) {
			PRINTK1("Cmd response ready! 0x%x\n",ireg);

			OS_INT_DISABLE;
			Adapter->HisRegCpy &= ~HIS_CmdUpLdRdy;
			OS_INT_RESTORE;

			wlan_process_rx_command(priv);
		}

		/* Any received data? */
		if (Adapter->HisRegCpy & HIS_RxUpLdRdy) {
			PRINTK1("Rx Packet ready! 0x%x\n",ireg);
			TXRX_DEBUG_GET_ALL(0x16, ireg, 0xff);
			
			OS_INT_DISABLE;
			Adapter->HisRegCpy &= ~HIS_RxUpLdRdy;
			OS_INT_RESTORE;

#ifndef THROUGHPUT_TEST
			wlan_send_rxskbQ(priv);
#else
			Adapter->NumTransfersRx += 1;
#endif /* THROUGHPUT_TEST */
		}

		/* Any Card Event */
		if (Adapter->HisRegCpy & HIS_CardEvent) {
			PRINTK1("Card Event Activity 0x%x\n",ireg);

			OS_INT_DISABLE;
			Adapter->HisRegCpy &= ~HIS_CardEvent;
			OS_INT_RESTORE;

			if (sbi_read_event_cause(priv)) {
				continue;
			}
			wlan_process_event(priv);
			PRINTK1("Clearing CardEvent INT\n");
		}

#ifdef PS_REQUIRED
#ifdef PS_PRESLEEP
		/* Check if we need to confirm Sleep Request received previously */
		if (Adapter->PSState == PS_STATE_PRE_SLEEP) {
			if (!priv->wlan_dev.dnld_sent && !Adapter->CurCmd) {
                            if(Adapter->MediaConnectStatus == WlanMediaStateConnected) {
				PRINTK1("main_thread PRE_SLEEP: IntCounter=%d CurrentTxSkb=%p "
				"dnld_sent=%d CurCmd=%p, confirm now\n", Adapter->IntCounter, 
				Adapter->CurrentTxSkb,priv->wlan_dev.dnld_sent,Adapter->CurCmd);
				PSConfirmSleep(priv, (u16) Adapter->PSMode);
			    }
			    else {
				/* workaround for firmware sending deauth/linkloss event
					immediately after sleep request, remove this after
					firmware fixes it */
				Adapter->PSState = PS_STATE_AWAKE;
				printk("ignore PS_SleepConfirm in non-connected state\n");
			    }
			}
		}
#endif

		/* The PS state is changed during processing of Sleep Request event */
		if ((priv->adapter->PSState == PS_STATE_SLEEP)
#ifdef PS_PRESLEEP
			|| (priv->adapter->PSState == PS_STATE_PRE_SLEEP)
#endif
		) {
			continue;
		}
#endif

		/* Execute the next command */
		if (!priv->wlan_dev.dnld_sent)
			ExecuteNextCommand(priv);

#ifdef THROUGHPUT_TEST
		if (!priv->wlan_dev.dnld_sent && 
				(Adapter->ThruputTest & 0x01)) {
			sbi_host_to_card(priv, MVMS_DAT, G_buf, 1530);
			Adapter->NumTransfersTx += 1;
		}
#endif /* THROUGHPUT_TEST */
#ifdef WMM
		if (Adapter->wmm.enabled) {
			if (!wmm_lists_empty(priv)) {
#ifdef WMM_UAPSD
			if ((Adapter->PSState == PS_STATE_FULL_POWER) || (Adapter->wmm.no_more_packet == 0))
#endif
				wmm_process_tx(priv);
			}
		} else {
#endif /* WMM */
			if (!priv->wlan_dev.dnld_sent && Adapter->CurrentTxSkb) {
				PRINTK1("Tx Download Ready! 0x%x\n",ireg);
				TXRX_DEBUG_GET_TIME(6);
				wlan_process_tx(priv);
				TXRX_DEBUG_GET_ALL(0x15, ireg, 0xff);
			}
#ifdef WMM
		}
#endif

		if (Adapter->HisRegCpy & HIS_CmdDnLdRdy) {
			PRINTK1("Command Download Ready 0x%x\n",ireg);
		}

		TXRX_DEBUG_GET_ALL(0x17, ireg, 0xff);
		TXRX_DEBUG_GET_ALL(0x18, ireg, 0xff);
	}

	wlan_deactivate_thread(thread);

	LEAVE();
	return 0;
}

/*
 * This is the entry point to the card , *1.Probe for the card *2.Get the 
 * priv strucutre allocated *3.Get the adapter structure initialized
 * 4.Initialize the Device 
 */
static wlan_private *wlan_add_card(void *card)
{
	struct net_device *dev = NULL;
	/*
	 * being used uninitialized 
	 */
	wlan_private   *priv = NULL;

	ENTER();

	if (sbi_probe_card(card) < 0) {
		/*
		 * No device found Return ---exit the module 
		 */
		return NULL;
	}

	/*
	 * Allocate an Ethernet device and register it 
	 */
	if (!(dev = init_etherdev(dev, sizeof(wlan_private)))) {
		PRINTK(KERN_ERR "%s: %s", driver_name, errNoEtherDev);
		return NULL;
	}

	priv = dev->priv;
	
	if (!(priv->adapter = kmalloc(sizeof(wlan_adapter), GFP_KERNEL))) {
		PRINTK(KERN_ERR "%s: Adapter %s", driver_name, errAllocation);
		goto err_freeadapter;
	}

	memset(priv->adapter, 0, sizeof(wlan_adapter));

	priv->wlan_dev.netdev = dev;
	priv->wlan_dev.card = card;
	wlanpriv = priv;

	SET_MODULE_OWNER(dev);

	/*
	 * Setup the OS Interface to our functions 
	 */
	dev->open = wlan_open;
	dev->hard_start_xmit = wlan_hard_start_xmit;
	dev->stop = wlan_stop;
	dev->do_ioctl = wlan_do_ioctl;
	dev->set_mac_address = wlan_set_mac_address;

#ifdef linux 

#define	WLAN_WATCHDOG_TIMEOUT	(HZ*2)

	dev->tx_timeout = wlan_tx_timeout;
	dev->get_stats = wlan_get_stats;
	dev->watchdog_timeo = WLAN_WATCHDOG_TIMEOUT;

#ifdef	WIRELESS_EXT
	dev->get_wireless_stats = wlan_get_wireless_stats;
	dev->wireless_handlers = (struct iw_handler_def *) &wlan_handler_def;
#endif
#endif  /* linux */	

	dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
	dev->set_multicast_list = wlan_set_multicast_list;

#ifdef MANF_CMD_SUPPORT
	/* Required for the mfg command */
	init_waitqueue_head(&priv->adapter->mfg_cmd_q);
#endif
    
	init_waitqueue_head(&priv->adapter->scan_q);
	init_waitqueue_head(&priv->adapter->ds_awake_q);

#ifdef CONFIG_PM
  	if(!(wlan_pm_dev = pm_register(PM_UNKNOWN_DEV, 0, wlan_pm_callback)))
		printk("Failed to register PM callback\n");
#endif

 	INIT_LIST_HEAD(&priv->adapter->CmdFreeQ);
        INIT_LIST_HEAD(&priv->adapter->CmdPendingQ);

	PRINTK("Starting kthread...\n");
	priv->MainThread.priv = priv;
	wlan_create_thread(wlan_service_main_thread, &priv->MainThread,
							"wlan_main_service");

	ConfigureThreadPriority();

#ifdef REASSOCIATION
	priv->ReassocThread.priv = priv;
	wlan_create_thread(wlan_reassociation_thread, &priv->ReassocThread,
						"wlan_reassoc_service");
#endif /* REASSOCIATION */

	/*
	 * Register the device. Fillup the private data structure with
	 * relevant information from the card and request for the required
	 * IRQ. 
	 */

	if (sbi_register_dev(priv) < 0) {
		PRINTK1(KERN_ERR "Failed to register wlan device!\n");
		goto err_unregisternet;
	}

#ifdef linux
	printk(KERN_INFO "%s: Marvell Wlan 802.11 Adapter "
			"revision 0x%02X at IRQ %i\n", dev->name,
			priv->adapter->chip_rev, dev->irq);

	wlan_proc_entry(priv, dev);
#ifdef PROC_DEBUG
	wlan_debug_entry(priv, dev);
#endif
#endif

	/* Get the CIS Table */
	sbi_get_cis_info(priv);
	
	if (wlan_init_fw(priv)) {
		PRINTK1("Firmware Init Failed\n");
		goto err_unregisterdev;
	}

	LEAVE();
	return priv;

err_unregisterdev:
	sbi_unregister_dev(priv);
err_unregisternet:
err_freeadapter:
	unregister_netdev(dev);
	/* Stop the thread servicing the interrupts */
	wake_up_interruptible(&priv->MainThread.waitQ);
	wlan_terminate_thread(&priv->MainThread);

#ifdef REASSOCIATION
	wake_up_interruptible(&priv->ReassocThread.waitQ);
	wlan_terminate_thread(&priv->ReassocThread);
#endif /* REASSOCIATION */

	kfree(priv->adapter);
	wlanpriv = NULL;

	LEAVE();
	return NULL;
}

/*
 * Remove the card , *Uninitialize all the stuff we allocated above 
 */
static int wlan_remove_card(void *card)
{
	wlan_private		*priv = wlanpriv;
	wlan_adapter		*Adapter = priv->adapter;
	struct net_device	*dev;
#ifdef WPA
	union	iwreq_data	wrqu;
#endif

#ifdef DEEP_SLEEP
#ifdef BULVERDE_SDIO
	int			ret;
#endif /* BULVERDE_SDIO */
#endif

	ENTER();

	dev = priv->wlan_dev.netdev;

	wake_up_interruptible(&Adapter->scan_q);
	wake_up_interruptible(&Adapter->ds_awake_q);

	if (Adapter->CurCmd) {
		PRINTK1("Wake up current command\n");
		wake_up_interruptible(&Adapter->CurCmd->cmdwait_q);
	}

	Adapter->CurCmd = NULL;
	
#ifdef DEEP_SLEEP
#ifdef BULVERDE_SDIO
	if (ps_sleep_confirmed){
		ps_sleep_confirmed = 0;
		ret = sbi_exit_deep_sleep(priv);
#ifdef PS_REQUIRED
		if (!ret) {
			Adapter->PSState = PS_STATE_FULL_POWER;
			netif_carrier_on(priv->wlan_dev.netdev);
		}
		else
			PRINTK("Deep Sleep Exit failed\n");
#endif
	}
#endif /* BULVERDE_SDIO */
#endif /* DEEP SLEEP */
	
#ifdef PS_REQUIRED
	if (Adapter->PSMode == Wlan802_11PowerModeMAX_PSP) {
		Adapter->PSMode = Wlan802_11PowerModeCAM;
		PSWakeup(priv, HostCmd_OPTION_WAITFORRSP);
	}
#endif

#ifdef WPA
	memset(wrqu.ap_addr.sa_data, 0xaa, ETH_ALEN);
	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
#ifdef linux
	wireless_send_event(priv->wlan_dev.netdev, SIOCGIWAP, &wrqu, NULL);
#endif
#endif

	/* Disable interrupts on the card as we cannot handle them after RESET */
	sbi_disable_host_int(priv, HIM_DISABLE);

	PrepareAndSendCommand(priv, HostCmd_CMD_802_11_RESET,
			HostCmd_ACT_HALT, HostCmd_OPTION_USE_INT,
			0, HostCmd_PENDING_ON_NONE, NULL);

	os_sched_timeout(200);

#ifdef CONFIG_PM
        pm_unregister(wlan_pm_dev);
#endif
	
	netif_carrier_off(dev);
	/* Flush all the packets upto the OS before stopping */
	wlan_send_rxskbQ(priv);
	/* Stop the thread servicing the interrupts */

	wake_up_interruptible(&priv->MainThread.waitQ);
	wlan_terminate_thread(&priv->MainThread);

#ifdef REASSOCIATION
	wake_up_interruptible(&priv->ReassocThread.waitQ);
	wlan_terminate_thread(&priv->ReassocThread);
#endif /* REASSOCIATION */

	Adapter->SurpriseRemoved = TRUE;

#ifdef linux
#ifdef PROC_DEBUG
  wlan_debug_remove(priv);
#endif
	wlan_proc_remove("wlan");
#endif
	
	PRINTK1("Netif Stop Queue\n");

	PRINTK1("unregester dev\n");
    	sbi_unregister_dev(priv);

	PRINTK1("Free Adapter\n");
    	wlan_free_adapter(priv);
    
	netif_stop_queue(dev);

	priv->wlan_dev.netdev = NULL;
	wlanpriv = NULL;

	/* Last reference is our one */
	PRINTK1("refcnt = %d\n", atomic_read(&dev->refcnt));
	
	os_schedule(10);
	
	PRINTK1("netdevice unregister\n");
	
	PRINTK1("netdev_finish_unregister: %s%s.\n", dev->name,
	       (dev->features & NETIF_F_DYNALLOC)?"":", old style");
	unregister_netdev(dev);

	PRINTK1("Unregister finish\n");

	LEAVE();
	return 0;
}

void wlan_interrupt(struct net_device *dev)
{
	wlan_private   *priv = dev->priv;

	ENTER1();

	PRINTK1("wlan_interrupt: IntCounter=%d\n",priv->adapter->IntCounter);
	priv->adapter->IntCounter++;

#ifdef HOST_WAKEUP
	priv->adapter->WakeupTries = 0;
#endif

#ifdef PS_REQUIRED
	if(priv->adapter->PSState == PS_STATE_SLEEP) {
#ifdef BULVERDE_SDIO
		ps_sleep_confirmed = 0;
#endif
		priv->adapter->PSState = PS_STATE_AWAKE;
	}
#endif

#ifdef DEEP_SLEEP
	if (priv->adapter->IsDeepSleep == TRUE) {
		priv->adapter->IsDeepSleep = FALSE;
		printk("Interrupt received in DEEP SLEEP mode!\n");
		if (netif_queue_stopped(priv->wlan_dev.netdev))
			netif_wake_queue(priv->wlan_dev.netdev);
	}
#endif /* DEEP_SLEEP */

	wake_up_interruptible(&priv->MainThread.waitQ);

	LEAVE1();
}

int wlan_init_module(void)
{
	int            *wlan_ret;
	int             ret;

	ENTER();

	wlan_ret = sbi_register(wlan_add_card, wlan_remove_card, NULL);

	if (wlan_ret == NULL) {
		PRINTK(KERN_NOTICE "Unable to register serial WLAN driver!\n");
		ret = -ENXIO;
		goto done;
	}

	ret = 0;

done:
	LEAVE();
	return ret;
}

void wlan_cleanup_module(void)
{
	ENTER();

	sbi_unregister();

	LEAVE();
}


module_init(wlan_init_module);
module_exit(wlan_cleanup_module);

MODULE_DESCRIPTION("Marvell WLAN SB83XX Driver");
MODULE_AUTHOR("Marvell Semiconductor Inc");

⌨️ 快捷键说明

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