📄 wlan_main.c
字号:
#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 + -