📄 wlan_main.c
字号:
*/
static int wlan_open(struct net_device *dev)
{
wlan_private *priv = (wlan_private *) dev->priv;
wlan_adapter *adapter = priv->adapter;
ENTER();
memcpy(dev->dev_addr, adapter->PermanentAddr, ETH_ALEN);
MOD_INC_USE_COUNT;
priv->open = TRUE;
netif_start_queue(dev); // To be compatible with ifconfig up/down
LEAVE();
return 0;
}
/*
* Network stop function
*/
static int wlan_stop(struct net_device *dev)
{
wlan_private *priv = dev->priv;
ENTER();
/* Flush all the packets upto the OS before stopping */
wlan_send_rxskbQ(priv);
netif_stop_queue(dev);
MOD_DEC_USE_COUNT;
priv->open = FALSE;
LEAVE();
return 0;
}
/*
* To push the packets on to the net work
*/
int wlan_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
int ret;
wlan_private *priv = dev->priv;
wlan_adapter *adapter = priv->adapter;
#ifdef OMAP1510_TIMER_DEBUG
int i;
#endif /* OMAP1510_TIMER_DEBUG */
ENTER();
if (adapter->SurpriseRemoved) {
PRINTK1("Card Removed!!\n");
ret = 1;
goto done;
}
if (!skb) {
PRINTK1("No SKB Available\n");
ret = 1;
goto done;
}
if (priv->open != TRUE) {
PRINTK1("priv->open is set to false!!\n");
ret = 1;
goto done;
}
if (netif_queue_stopped(dev)) {
PRINTK1("called when queue stopped.\n");
ret = 1;
goto done;
}
if (adapter->MediaConnectStatus != WlanMediaStateConnected) {
ret = 1;
goto done;
}
#ifdef PS_REQUIRED
if ((adapter->PSState == PS_STATE_SLEEP
#ifdef HOST_WAKEUP
&& (!adapter->bHostWakeupDevRequired)
#endif
)
#ifdef PS_PRESLEEP
|| (adapter->PSState == PS_STATE_PRE_SLEEP)
#endif
) {
PRINTK1("_xmit() in PS state: %d\n", adapter->PSState);
ret = 1;
goto done;
}
#endif
#ifdef DEEP_SLEEP
if (adapter->IsDeepSleep == TRUE) {
ret = 1;
goto done;
}
#endif // DEEP_SLEEP
#ifdef TXRX_DEBUG
tx_n++;
if(tx_n>=16) tx_n=0;
tt[0][tx_n] = get_utimeofday();
#endif
#ifdef OMAP1510_TIMER_DEBUG
for(i=0; i<10; ++i)
tm_ind[i] = 0;
outl(0x22, OMAP1510_TIMER1_BASE);
outl(0xFFFFFFFF, OMAP1510_TIMER1_BASE + 0x04);
outl(0x23, OMAP1510_TIMER1_BASE);
times[0][(tm_ind[0])++] = inw(0xFFFEC500 + 0x08);
#endif /* OMAP1510_TIMER_DEBUG */
if (wlan_tx_packet(priv, skb)) {
/* Transmit failed */
ret = 1;
goto done;
} else {
/* Transmit succeeded */
#ifdef WMM
if (!adapter->wmm.enabled) {
#endif /* WMM */
UpdateTransStart(dev);
netif_stop_queue(dev);
#ifdef WMM
}
#endif
}
ret = 0;
done:
LEAVE();
return ret;
}
#ifdef linux
/*
* Time out watch dog , which wakes up on a time out!
*/
void wlan_tx_timeout(struct net_device *dev)
{
wlan_private *priv = (wlan_private *) dev->priv;
#ifdef TXRX_DEBUG
int i,j;
int trd_n_save = 0;
#endif
ENTER1();
#ifdef TXRX_DEBUG
trd_n_save = trd_n;
trd_n = -1;
trd_p = -1;
wake_up_interruptible(&priv->MainThread.waitQ);
PRINTK("tx_n=%d\n",tx_n);
for(i=0;i<16;i++) {
PRINTK("i=%02d: ",i);
for(j=0;j<1;j++)
PRINTK("tt%d=%ld.%03ld.%03ld ", j, tt[j][i]/1000000,
(tt[j][i]%1000000)/1000,tt[j][i]%1000);
for(j=1;j<7;j++) {
long tt1 = tt[j][i] - tt[j-1][i];
if(tt1<0) tt1=0;
PRINTK("tt%d=%ld.%ld.%03ld ", j, tt1/1000000,
(tt1%1000000)/1000,tt1%1000);
}
PRINTK("\n");
}
PRINTK("trd_n=%d\n",trd_n_save);
for(i=0;i<TRD_N;i++) {
PRINTK("i=%02d: ",i);
PRINTK("%ld.%03ld.%03ld ", trd[i].time/1000000,
(trd[i].time%1000000)/1000,trd[i].time%1000);
PRINTK("loc=%02X intc=%d txskb=%d "
"dnld=%02X ireg=%02X cs=%02X\n",
trd[i].loc, trd[i].intc, trd[i].txskb,
trd[i].dnld,trd[i].ireg,trd[i].cs);
if (i == trd_n_save) PRINTK("\n");
}
#endif
priv->wlan_dev.dnld_sent = DNLD_RES_RECEIVED;
dev->trans_start = jiffies;
if (priv->adapter->CurrentTxSkb) {
wake_up_interruptible(&priv->MainThread.waitQ);
} else {
if (netif_queue_stopped(dev))
netif_wake_queue(dev);
}
LEAVE1();
}
#endif // linux
/*
* Network statistics!!
*/
static struct net_device_stats *wlan_get_stats(struct net_device *dev)
{
wlan_private *priv = (wlan_private *) dev->priv;
return &priv->stats;
}
/* set the MAC address through ifconfig */
int wlan_set_mac_address(struct net_device *dev, void *addr)
{
int ret = 0;
wlan_private *priv = (wlan_private *) dev->priv;
wlan_adapter *Adapter = priv->adapter;
struct sockaddr *pHwAddr = (struct sockaddr *)addr;
ENTER();
memset(Adapter->CurrentAddr, 0, MRVDRV_ETH_ADDR_LEN);
/* dev->dev_addr is 8 bytes */
HEXDUMP("dev->dev_addr:", dev->dev_addr, ETH_ALEN);
HEXDUMP("addr:", pHwAddr->sa_data, ETH_ALEN);
memcpy(Adapter->CurrentAddr, pHwAddr->sa_data, ETH_ALEN);
ret = PrepareAndSendCommand(priv, HostCmd_CMD_802_11_MAC_ADDRESS,
HostCmd_ACT_SET,
HostCmd_OPTION_USE_INT | HostCmd_OPTION_WAITFORRSP,
0, HostCmd_PENDING_ON_NONE, NULL);
if (ret) {
LEAVE();
return ret;
}
/* This is not necessary for production code */
PRINTK1("Get MAC Address\n");
ret = PrepareAndSendCommand(priv, HostCmd_CMD_802_11_MAC_ADDRESS,
HostCmd_ACT_GET,
HostCmd_OPTION_USE_INT | HostCmd_OPTION_WAITFORRSP,
0, HostCmd_PENDING_ON_NONE, NULL);
if (ret) {
LEAVE();
return ret;
}
HEXDUMP("Adapter->MacAddr:", Adapter->CurrentAddr, ETH_ALEN);
memcpy(dev->dev_addr, Adapter->CurrentAddr, ETH_ALEN);
LEAVE();
return ret;
}
int wlan_get_mac_address(struct net_device *dev, unsigned char *Addr)
{
wlan_private *priv = (wlan_private *) dev->priv;
wlan_adapter *Adapter = priv->adapter;
ENTER();
memcpy(Addr, Adapter->CurrentAddr, ETH_ALEN);
LEAVE();
return 0;
}
int SendSetMulticast(wlan_private * priv, void *p)
{
int ret = 0;
ret = PrepareAndSendCommand(priv, HostCmd_CMD_MAC_MULTICAST_ADR,
HostCmd_ACT_GEN_SET,
HostCmd_OPTION_USE_INT,
0, HostCmd_PENDING_ON_GET_OID, NULL);
return ret;
}
void wlan_set_multicast_list(struct net_device *dev)
{
wlan_private *priv = dev->priv;
wlan_adapter *Adapter = priv->adapter;
int OldPacketFilter;
ENTER();
OldPacketFilter = Adapter->CurrentPacketFilter;
if (dev->flags & IFF_PROMISC) {
PRINTK1("Enable Promiscuous mode\n");
Adapter->CurrentPacketFilter |=
HostCmd_ACT_MAC_PROMISCUOUS_ENABLE;
Adapter->CurrentPacketFilter &=
~(HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE |
HostCmd_ACT_MAC_MULTICAST_ENABLE);
} else {
/* Multicast */
Adapter->CurrentPacketFilter &=
~HostCmd_ACT_MAC_PROMISCUOUS_ENABLE;
if (dev->flags & IFF_ALLMULTI || dev->mc_count >
MRVDRV_MAX_MULTICAST_LIST_SIZE) {
PRINTK1("Enabling All Multicast!\n");
Adapter->CurrentPacketFilter |=
HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE;
Adapter->CurrentPacketFilter &=
~HostCmd_ACT_MAC_MULTICAST_ENABLE;
} else {
Adapter->CurrentPacketFilter &=
~HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE;
if (!dev->mc_count) {
PRINTK1("No multicast addresses - "
"disabling multicast!\n");
Adapter->CurrentPacketFilter &=
~HostCmd_ACT_MAC_MULTICAST_ENABLE;
} else {
#ifdef DEBUG_LEVEL1
int i;
#endif
Adapter->CurrentPacketFilter |=
HostCmd_ACT_MAC_MULTICAST_ENABLE;
Adapter->NumOfMulticastMACAddr =
CopyMulticastAddrs(Adapter, dev);
#ifdef DEBUG_LEVEL1
PRINTK1("Multicast addresses: %d\n",
dev->mc_count);
for (i = 0; i < dev->mc_count; i++) {
PRINTK1("Multicast address %d:"
"%x %x %x %x %x %x\n", i,
Adapter->MulticastList[i][0],
Adapter->MulticastList[i][1],
Adapter->MulticastList[i][2],
Adapter->MulticastList[i][3],
Adapter->MulticastList[i][4],
Adapter->MulticastList[i][5]);
}
#endif
SendSetMulticast(priv, NULL);
}
}
}
if (Adapter->CurrentPacketFilter != OldPacketFilter) {
SetMacPacketFilter(priv);
}
LEAVE();
}
#ifdef REASSOCIATION
int wlan_reassociation_thread(void *data)
{
wlan_thread *thread = data;
wlan_private *priv = thread->priv;
wlan_adapter *Adapter = priv->adapter;
wait_queue_t wait;
int i;
OS_INTERRUPT_SAVE_AREA;
ENTER();
wlan_activate_thread(thread);
init_waitqueue_entry(&wait, current);
for (;;) {
/*
* go to sleep slowly to take care of races
*/
add_wait_queue(&thread->waitQ, &wait);
OS_SET_THREAD_STATE(TASK_INTERRUPTIBLE);
TX_DISABLE; /* required for threadx */
if (!Adapter->EventCounter) {
schedule();
TX_DISABLE; /* required for threadx */
}
OS_SET_THREAD_STATE(TASK_RUNNING);
remove_wait_queue(&thread->waitQ, &wait);
Adapter->EventCounter = 0;
if (thread->state == WLAN_THREAD_STOPPED)
break;
#ifdef PS_REQUIRED
#ifdef BULVERDE_SDIO
if ((Adapter->PSState == PS_STATE_SLEEP)
#ifdef PS_PRESLEEP
|| (Adapter->PSState == PS_STATE_PRE_SLEEP)
#endif
) {
continue;
}
#endif
#endif
PRINTK1("Re-association Thread running...\n");
PRINTK1("Performing Active Scan @ %lu\n", os_time_get());
SendSpecificScan(priv, &Adapter->PreviousSSID);
PRINTK1("#### PERIODIC TIMER ON, Previous SSID = %s"
" #####\n", Adapter->PreviousSSID.Ssid);
PRINTK1("Required ESSID :%s\n", Adapter->PreviousSSID.Ssid);
PRINTK1("No of BSSID: %d\n", Adapter->ulNumOfBSSIDs);
PRINTK1("InfrastructureMode: 0x%x\n",
Adapter->InfrastructureMode);
PRINTK1("MediaConnectStatus: 0x%x\n",
Adapter->MediaConnectStatus);
if (Adapter->MediaConnectStatus == WlanMediaStateDisconnected) {
u8 *pReqBSSID = NULL;
/*
* Comparing our PreviousSSID
* and finding a match SSID from list
*/
PRINTK1("Adapter->ulNumOfBSSIDs= %d\n",
Adapter->ulNumOfBSSIDs);
if (Adapter->RequestViaBSSID)
pReqBSSID = Adapter->RequestedBSSID;
i = FindSSIDInList(Adapter, &Adapter->PreviousSSID,
pReqBSSID, Adapter->InfrastructureMode);
if (i >= 0) {
if (Adapter->InfrastructureMode ==
Wlan802_11Infrastructure) {
// send an association command
PRINTK1("MISC - Do recover association,"
"previous SSID = %s\n",
Adapter->PreviousSSID.Ssid);
wlan_associate(priv,
&Adapter->PreviousSSID);
#ifdef PS_REQUIRED
if (Adapter->PSState !=
PS_STATE_FULL_POWER)
PSWakeup(priv, 0);
#endif
} else if (Adapter->InfrastructureMode ==
Wlan802_11IBSS) {
PRINTK1("MISC - Do a recover join"
" command \n");
PrepareAndSendCommand(priv,
HostCmd_CMD_802_11_AD_HOC_JOIN,
0, HostCmd_OPTION_USE_INT
| HostCmd_OPTION_WAITFORRSP,
0, HostCmd_PENDING_ON_CMD,
&Adapter->PreviousSSID);
}
} else {
/* No handling for infrastructure mode */
if (Adapter->InfrastructureMode ==
Wlan802_11IBSS) {
PrepareAndSendCommand(priv,
HostCmd_CMD_802_11_AD_HOC_START,
0, HostCmd_OPTION_USE_INT
| HostCmd_OPTION_WAITFORRSP,
0, HostCmd_PENDING_ON_CMD,
&Adapter->PreviousSSID);
}
}
}
if (Adapter->MediaConnectStatus == WlanMediaStateDisconnected) {
PRINTK1("Restarting Re-association Timer @ %lu\n",
os_time_get());
Adapter->TimerIsSet = TRUE;
ModTimer(&Adapter->MrvDrvTimer, MRVDRV_TIMER_10S);
}
}
wlan_deactivate_thread(thread);
LEAVE();
return 0;
}
#endif /* REASSOCIATION */
struct sk_buff* wlan_pop_rx_skb(struct sk_buff *RxSkbQ)
{
struct sk_buff* skb_data = NULL;
if(!list_empty((struct list_head *) RxSkbQ)) {
skb_data = RxSkbQ->next;
list_del((struct list_head *) RxSkbQ->next);
}
return skb_data;
}
int wlan_service_main_thread(void *data)
{
wlan_thread *thread = data;
wlan_private *priv = thread->priv;
wlan_adapter *Adapter = priv->adapter;
wait_queue_t wait;
u8 ireg = 0;
OS_INTERRUPT_SAVE_AREA; /* Required for ThreadX */
ENTER();
wlan_activate_thread(thread);
init_waitqueue_entry(&wait, current);
for (;;) {
/* Go to sleep slowly to take care of races */
TXRX_DEBUG_GET_ALL(0x10, 0xff, 0xff);
PRINTK1("Interrupt thread 111: IntCounter=%d "
"CurrentTxSkb=%p dnld_sent=%d\n", Adapter->IntCounter,
Adapter->CurrentTxSkb, priv->wlan_dev.dnld_sent);
add_wait_queue(&thread->waitQ, &wait);
OS_SET_THREAD_STATE(TASK_INTERRUPTIBLE);
TXRX_DEBUG_GET_ALL(0x11, 0xff, 0xff);
TX_DISABLE; /* required for threadx */
if (
#ifdef PS_REQUIRED
(Adapter->PSState == PS_STATE_SLEEP
#ifdef HOST_WAKEUP
&& !Adapter->bHostWakeupDevRequired
#endif /* HOST_WAKEUP */
) ||
#endif /* PS_REQUIRED */
(
!Adapter->IntCounter
#ifdef WMM
&& (priv->wlan_dev.dnld_sent || !Adapter->wmm.enabled ||
wmm_lists_empty(priv))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -