/* ======================================================================== Routine Description: The entry point for Linux kernel sent packet to our driver. Arguments: sk_buff *skb the pointer refer to a sk_buffer. Return Value: 0 Note: This function is the entry point of Tx Path for Os delivery packet to our driver. You only can put OS-depened & STA/AP common handle procedures in here. ======================================================================== */ int rt28xx_packet_xmit(struct sk_buff *skb) { struct net_device *net_dev = skb->dev; struct rt_rtmp_adapter *pAd = NULL; int status = NETDEV_TX_OK; void *pPacket = (void *)skb; GET_PAD_FROM_NET_DEV(pAd, net_dev); /* RT2870STA does this in RTMPSendPackets() */ { /* Drop send request since we are in monitor mode */ if (MONITOR_ON(pAd)) { RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); goto done; } } /* EapolStart size is 18 */ if (skb->len < 14) { /*printk("bad packet size: %d\n", pkt->len); */ hex_dump("bad packet", skb->data, skb->len); RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); goto done; } RTMP_SET_PACKET_5VT(pPacket, 0); STASendPackets((void *)pAd, (void **)& pPacket, 1); status = NETDEV_TX_OK; done: return status; }
INT rt28xx_ioctl( IN PNET_DEV net_dev, IN OUT struct ifreq *rq, IN INT cmd) { RTMP_ADAPTER *pAd = NULL; INT ret = 0; GET_PAD_FROM_NET_DEV(pAd, net_dev); if (pAd == NULL) { /* if 1st open fail, pAd will be free; So the net_dev->priv will be NULL in 2rd open */ return -ENETDOWN; } #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { ret = rt28xx_sta_ioctl(net_dev, rq, cmd); } #endif // CONFIG_STA_SUPPORT // return ret; }
// This function will be called when query /proc struct iw_statistics *rt28xx_get_wireless_stats( IN struct net_device *net_dev) { PRTMP_ADAPTER pAd = NULL; GET_PAD_FROM_NET_DEV(pAd, net_dev); DBGPRINT(RT_DEBUG_TRACE, ("rt28xx_get_wireless_stats --->\n")); pAd->iw_stats.status = 0; // Status - device dependent for now // link quality pAd->iw_stats.qual.qual = ((pAd->Mlme.ChannelQuality * 12)/10 + 10); if(pAd->iw_stats.qual.qual > 100) pAd->iw_stats.qual.qual = 100; #ifdef CONFIG_STA_SUPPORT if (pAd->OpMode == OPMODE_STA) pAd->iw_stats.qual.level = RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2); #endif // CONFIG_STA_SUPPORT // pAd->iw_stats.qual.noise = pAd->BbpWriteLatch[66]; // noise level (dBm) pAd->iw_stats.qual.noise += 256 - 143; pAd->iw_stats.qual.updated = 1; // Flags to know if updated #ifdef IW_QUAL_DBM pAd->iw_stats.qual.updated |= IW_QUAL_DBM; // Level + Noise are dBm #endif // IW_QUAL_DBM // pAd->iw_stats.discard.nwid = 0; // Rx : Wrong nwid/essid pAd->iw_stats.miss.beacon = 0; // Missed beacons/superframe DBGPRINT(RT_DEBUG_TRACE, ("<--- rt28xx_get_wireless_stats\n")); return &pAd->iw_stats; }
int RtmpOSIRQRelease(IN PNET_DEV pNetDev) { struct net_device *net_dev = pNetDev; PRTMP_ADAPTER pAd = NULL; GET_PAD_FROM_NET_DEV(pAd, net_dev); ASSERT(pAd); #ifdef RTMP_PCI_SUPPORT if (pAd->infType == RTMP_DEV_INF_PCI || pAd->infType == RTMP_DEV_INF_PCIE) { POS_COOKIE pObj = (POS_COOKIE)(pAd->OS_Cookie); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) synchronize_irq(pObj->pci_dev->irq); #endif free_irq(pObj->pci_dev->irq, (net_dev)); RTMP_MSI_DISABLE(pAd); } #endif // RTMP_PCI_SUPPORT // #ifdef RTMP_RBUS_SUPPORT if (pAd->infType == RTMP_DEV_INF_RBUS) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) synchronize_irq(net_dev->irq); #endif free_irq(net_dev->irq, (net_dev)); } #endif // RTMP_RBUS_SUPPORT // return 0; }
/******************************************************************************* Device IRQ related functions. *******************************************************************************/ int RtmpOSIRQRequest(IN PNET_DEV pNetDev) { #if defined(RTMP_PCI_SUPPORT) || defined(RTMP_RBUS_SUPPORT) struct net_device *net_dev = pNetDev; #endif PRTMP_ADAPTER pAd = NULL; int retval = 0; GET_PAD_FROM_NET_DEV(pAd, pNetDev); ASSERT(pAd); #ifdef RTMP_PCI_SUPPORT if (pAd->infType == RTMP_DEV_INF_PCI || pAd->infType == RTMP_DEV_INF_PCIE) { POS_COOKIE _pObj = (POS_COOKIE)(pAd->OS_Cookie); RTMP_MSI_ENABLE(pAd); retval = request_irq(_pObj->pci_dev->irq, rt2860_interrupt, SA_SHIRQ, (net_dev)->name, (net_dev)); if (retval != 0) printk("RT2860: request_irq ERROR(%d)\n", retval); } #endif // RTMP_PCI_SUPPORT // return retval; }
static int rt2860_suspend( struct pci_dev *pci_dev, pm_message_t state) { struct net_device *net_dev = pci_get_drvdata(pci_dev); PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)NULL; INT32 retval = 0; DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_suspend()\n")); if (net_dev == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("net_dev == NULL!\n")); } else { GET_PAD_FROM_NET_DEV(pAd, net_dev); /* we can not use IFF_UP because ra0 down but ra1 up */ /* and 1 suspend/resume function for 1 module, not for each interface */ /* so Linux will call suspend/resume function once */ if (VIRTUAL_IF_NUM(pAd) > 0) { // avoid users do suspend after interface is down // stop interface netif_carrier_off(net_dev); netif_stop_queue(net_dev); // mark device as removed from system and therefore no longer available netif_device_detach(net_dev); // mark halt flag RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF); // take down the device rt28xx_close((PNET_DEV)net_dev); RT_MOD_DEC_USE_COUNT(); } } #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,10) // reference to http://vovo2000.com/type-lab/linux/kernel-api/linux-kernel-api.html // enable device to generate PME# when suspended // pci_choose_state(): Choose the power state of a PCI device to be suspended retval = pci_enable_wake(pci_dev, pci_choose_state(pci_dev, state), 1); // save the PCI configuration space of a device before suspending pci_save_state(pci_dev); // disable PCI device after use pci_disable_device(pci_dev); retval = pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state)); #endif DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_suspend()\n")); return retval; }
/* ======================================================================== Routine Description: Open raxx interface. Arguments: *net_dev the raxx interface pointer Return Value: 0 Open OK otherwise Open Fail Note: 1. if open fail, kernel will not call the close function. 2. Free memory for (1) Mlme Memory Handler: MlmeHalt() (2) TX & RX: RTMPFreeTxRxRingMemory() (3) BA Reordering: ba_reordering_resource_release() ======================================================================== */ int MainVirtualIF_open(IN struct net_device *net_dev) { RTMP_ADAPTER *pAd = NULL; GET_PAD_FROM_NET_DEV(pAd, net_dev); // Sanity check for pAd if (pAd == NULL) return 0; // close ok #ifdef CONFIG_AP_SUPPORT pAd->ApCfg.MBSSID[MAIN_MBSSID].bBcnSntReq = TRUE; #endif // CONFIG_AP_SUPPORT // if (VIRTUAL_IF_UP(pAd) != 0) return -1; // increase MODULE use count RT_MOD_INC_USE_COUNT(); netif_start_queue(net_dev); netif_carrier_on(net_dev); netif_wake_queue(net_dev); return 0; }
/* ======================================================================== Routine Description: Close raxx interface. Arguments: *net_dev the raxx interface pointer Return Value: 0 Open OK otherwise Open Fail Note: 1. if open fail, kernel will not call the close function. 2. Free memory for (1) Mlme Memory Handler: MlmeHalt() (2) TX & RX: RTMPFreeTxRxRingMemory() (3) BA Reordering: ba_reordering_resource_release() ======================================================================== */ int MainVirtualIF_close(IN struct net_device *net_dev) { RTMP_ADAPTER *pAd = NULL; GET_PAD_FROM_NET_DEV(pAd, net_dev); // Sanity check for pAd if (pAd == NULL) return 0; // close ok netif_carrier_off(pAd->net_dev); netif_stop_queue(pAd->net_dev); #ifdef CONFIG_AP_SUPPORT pAd->ApCfg.MBSSID[MAIN_MBSSID].bBcnSntReq = FALSE; IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { // kick out all STAs behind the bss. MbssKickOutStas(pAd, MAIN_MBSSID, REASON_DISASSOC_INACTIVE); } APMakeAllBssBeacon(pAd); APUpdateAllBeaconFrame(pAd); #endif // CONFIG_AP_SUPPORT // VIRTUAL_IF_DOWN(pAd); RT_MOD_DEC_USE_COUNT(); return 0; // close ok }
/* ======================================================================== Routine Description: The entry point for Linux kernel sent packet to our driver. Arguments: sk_buff *skb the pointer refer to a sk_buffer. Return Value: 0 Note: This function is the entry point of Tx Path for Os delivery packet to our driver. You only can put OS-depened & STA/AP common handle procedures in here. ======================================================================== */ int rt28xx_packet_xmit(struct sk_buff *skb) { struct net_device *net_dev = skb->dev; PRTMP_ADAPTER pAd = NULL; int status = 0; PNDIS_PACKET pPacket = (PNDIS_PACKET) skb; GET_PAD_FROM_NET_DEV(pAd, net_dev); /* RT2870STA does this in RTMPSendPackets() */ #ifdef RALINK_ATE if (ATE_ON(pAd)) { RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_RESOURCES); return 0; } #endif // RALINK_ATE // // EapolStart size is 18 if (skb->len < 14) { //printk("bad packet size: %d\n", pkt->len); hex_dump("bad packet", skb->data, skb->len); RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); goto done; } #if !defined(CONFIG_RA_NAT_NONE) // ASUS EXT /* add tx hook point*/ if(ra_sw_nat_hook_tx!= NULL) { unsigned long flags; ra_sw_nat_hook_tx(pPacket); } #endif RTMP_SET_PACKET_5VT(pPacket, 0); // MiniportMMRequest(pAd, pkt->data, pkt->len); #ifdef CONFIG_5VT_ENHANCE if (*(int*)(skb->cb) == BRIDGE_TAG) { RTMP_SET_PACKET_5VT(pPacket, 1); } #endif #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) APSendPackets((NDIS_HANDLE)pAd, (PPNDIS_PACKET) &pPacket, 1); #endif // CONFIG_AP_SUPPORT // status = 0; done: return status; }
static VOID __devexit rt2860_remove_one( IN struct pci_dev *pci_dev) { PNET_DEV net_dev = pci_get_drvdata(pci_dev); RTMP_ADAPTER *pAd = NULL; ULONG csr_addr = net_dev->base_addr; // pAd->CSRBaseAddress; GET_PAD_FROM_NET_DEV(pAd, net_dev); DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_remove_one\n")); if (pAd != NULL) { // Unregister/Free all allocated net_device. RtmpPhyNetDevExit(pAd, net_dev); // Unmap CSR base address iounmap((char *)(csr_addr)); // release memory region release_mem_region(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0)); #ifdef RT_CFG80211_SUPPORT CFG80211_UnRegister(pAd, net_dev); #endif // RT_CFG80211_SUPPORT // #ifdef CREDENTIAL_STORE NdisFreeSpinLock(&pAd->StaCtIf.Lock); #endif /* CREDENTIAL_STORE */ // Free RTMP_ADAPTER related structures. RtmpRaDevCtrlExit(pAd); } else { // Unregister network device RtmpOSNetDevDetach(net_dev); // Unmap CSR base address iounmap((char *)(net_dev->base_addr)); // release memory region release_mem_region(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0)); } // Free the root net_device RtmpOSNetDevFree(net_dev); #ifdef VENDOR_FEATURE4_SUPPORT { extern ULONG OS_NumOfMemAlloc, OS_NumOfMemFree; DBGPRINT(RT_DEBUG_TRACE, ("OS_NumOfMemAlloc = %ld, OS_NumOfMemFree = %ld\n", OS_NumOfMemAlloc, OS_NumOfMemFree)); } #endif // VENDOR_FEATURE4_SUPPORT // }
// This function will be called when query /proc struct iw_statistics *rt28xx_get_wireless_stats( IN struct net_device *net_dev) { PRTMP_ADAPTER pAd = NULL; GET_PAD_FROM_NET_DEV(pAd, net_dev); DBGPRINT(RT_DEBUG_TRACE, ("rt28xx_get_wireless_stats --->\n")); //check if the interface is down if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) return NULL; pAd->iw_stats.status = 0; // Status - device dependent for now // link quality #ifdef CONFIG_STA_SUPPORT if (pAd->OpMode == OPMODE_STA) pAd->iw_stats.qual.qual = ((pAd->Mlme.ChannelQuality * 12)/10 + 10); #endif // CONFIG_STA_SUPPORT // if(pAd->iw_stats.qual.qual > 100) pAd->iw_stats.qual.qual = 100; #ifdef CONFIG_STA_SUPPORT if (pAd->OpMode == OPMODE_STA) { pAd->iw_stats.qual.level = RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.AvgRssi0, pAd->StaCfg.RssiSample.AvgRssi1, pAd->StaCfg.RssiSample.AvgRssi2); } #endif // CONFIG_STA_SUPPORT // #ifdef CONFIG_STA_SUPPORT pAd->iw_stats.qual.noise = RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.AvgRssi0, pAd->StaCfg.RssiSample.AvgRssi1, pAd->StaCfg.RssiSample.AvgRssi2) - RTMPMinSnr(pAd, pAd->StaCfg.RssiSample.AvgSnr0, pAd->StaCfg.RssiSample.AvgSnr1); #endif // CONFIG_STA_SUPPORT // pAd->iw_stats.qual.updated = 1; // Flags to know if updated #ifdef IW_QUAL_DBM pAd->iw_stats.qual.updated |= IW_QUAL_DBM; // Level + Noise are dBm #endif // IW_QUAL_DBM // pAd->iw_stats.discard.nwid = 0; // Rx : Wrong nwid/essid pAd->iw_stats.miss.beacon = 0; // Missed beacons/superframe DBGPRINT(RT_DEBUG_TRACE, ("<--- rt28xx_get_wireless_stats\n")); return &pAd->iw_stats; }
int RtmpOSIRQRelease(IN PNET_DEV pNetDev) { struct net_device *net_dev = pNetDev; PRTMP_ADAPTER pAd = NULL; GET_PAD_FROM_NET_DEV(pAd, net_dev); ASSERT(pAd); return 0; }
/******************************************************************************* Device IRQ related functions. *******************************************************************************/ int RtmpOSIRQRequest(IN PNET_DEV pNetDev) { PRTMP_ADAPTER pAd = NULL; int retval = 0; GET_PAD_FROM_NET_DEV(pAd, pNetDev); ASSERT(pAd); return retval; }
/* ======================================================================== Routine Description: return ethernet statistics counter Arguments: net_dev Pointer to net_device Return Value: net_device_stats* Note: ======================================================================== */ static struct net_device_stats *RT28xx_get_ether_stats( IN struct net_device *net_dev) { RTMP_ADAPTER *pAd = NULL; if (net_dev) GET_PAD_FROM_NET_DEV(pAd, net_dev); if (pAd) { pAd->stats.rx_packets = pAd->WlanCounters.ReceivedFragmentCount.QuadPart; pAd->stats.tx_packets = pAd->WlanCounters.TransmittedFragmentCount.QuadPart; pAd->stats.rx_bytes = pAd->RalinkCounters.ReceivedByteCount; pAd->stats.tx_bytes = pAd->RalinkCounters.TransmittedByteCount; pAd->stats.rx_errors = pAd->Counters8023.RxErrors; pAd->stats.tx_errors = pAd->Counters8023.TxErrors; pAd->stats.rx_dropped = 0; pAd->stats.tx_dropped = 0; pAd->stats.multicast = pAd->WlanCounters.MulticastReceivedFrameCount.QuadPart; // multicast packets received pAd->stats.collisions = pAd->Counters8023.OneCollision + pAd->Counters8023.MoreCollisions; // Collision packets pAd->stats.rx_length_errors = 0; pAd->stats.rx_over_errors = pAd->Counters8023.RxNoBuffer; // receiver ring buff overflow pAd->stats.rx_crc_errors = 0;//pAd->WlanCounters.FCSErrorCount; // recved pkt with crc error pAd->stats.rx_frame_errors = pAd->Counters8023.RcvAlignmentErrors; // recv'd frame alignment error pAd->stats.rx_fifo_errors = pAd->Counters8023.RxNoBuffer; // recv'r fifo overrun pAd->stats.rx_missed_errors = 0; // receiver missed packet // detailed tx_errors pAd->stats.tx_aborted_errors = 0; pAd->stats.tx_carrier_errors = 0; pAd->stats.tx_fifo_errors = 0; pAd->stats.tx_heartbeat_errors = 0; pAd->stats.tx_window_errors = 0; // for cslip etc pAd->stats.rx_compressed = 0; pAd->stats.tx_compressed = 0; return &pAd->stats; } else return NULL; }
static VOID __devexit rt2860_remove_one( IN struct pci_dev *pci_dev) { PNET_DEV net_dev = pci_get_drvdata(pci_dev); RTMP_ADAPTER *pAd = NULL; ULONG csr_addr = net_dev->base_addr; // pAd->CSRBaseAddress; GET_PAD_FROM_NET_DEV(pAd, net_dev); DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_remove_one\n")); if (pAd != NULL) { // Unregister/Free all allocated net_device. RtmpPhyNetDevExit(pAd, net_dev); // Unmap CSR base address iounmap((char *)(csr_addr)); // release memory region release_mem_region(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0)); #ifdef RT_CFG80211_SUPPORT CFG80211_UnRegister(pAd, net_dev); #endif // RT_CFG80211_SUPPORT // // Free RTMP_ADAPTER related structures. RtmpRaDevCtrlExit(pAd); } else { // Unregister network device RtmpOSNetDevDetach(net_dev); // Unmap CSR base address iounmap((char *)(net_dev->base_addr)); // release memory region release_mem_region(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0)); } // Free the root net_device RtmpOSNetDevFree(net_dev); }
static VOID __devexit rt2860_remove_one(struct pci_dev *pci_dev) { PNET_DEV net_dev = pci_get_drvdata(pci_dev); VOID *pAd = NULL; ULONG csr_addr = net_dev->base_addr; GET_PAD_FROM_NET_DEV(pAd, net_dev); DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_remove_one\n")); if (pAd != NULL) { /* Unregister/Free all allocated net_device. */ RtmpPhyNetDevExit(pAd, net_dev); #ifdef RT_CFG80211_SUPPORT RTMP_DRIVER_80211_UNREGISTER(pAd, net_dev); #endif /* RT_CFG80211_SUPPORT */ /* Free RTMP_ADAPTER related structures. */ RtmpRaDevCtrlExit(pAd); /* Unmap CSR base address */ iounmap((char *)(csr_addr)); /* release memory region */ release_mem_region(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0)); } else { /* Unregister network device */ RtmpOSNetDevDetach(net_dev); /* Unmap CSR base address */ iounmap((char *)(net_dev->base_addr)); /* release memory region */ release_mem_region(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0)); } /* Free the root net_device */ RtmpOSNetDevFree(net_dev); wl_proc_exit(); }
/******************************************************************************* Device IRQ related functions. *******************************************************************************/ int RtmpOSIRQRequest(IN PNET_DEV pNetDev) { struct net_device *net_dev = NULL; PRTMP_ADAPTER pAd = NULL; int retval = 0; net_dev = pNetDev; GET_PAD_FROM_NET_DEV(pAd, pNetDev); ASSERT(pAd); return retval; }
/* ======================================================================== Routine Description: Send a packet to WLAN. Arguments: skb_p points to our adapter dev_p which WLAN network interface Return Value: 0: transmit successfully otherwise: transmit fail Note: ======================================================================== */ static int rt28xx_send_packets(IN struct sk_buff *skb_p, IN struct net_device *net_dev) { struct rt_rtmp_adapter *pAd = NULL; GET_PAD_FROM_NET_DEV(pAd, net_dev); if (!(net_dev->flags & IFF_UP)) { RELEASE_NDIS_PACKET(pAd, (void *)skb_p, NDIS_STATUS_FAILURE); return NETDEV_TX_OK; } NdisZeroMemory((u8 *)& skb_p->cb[CB_OFF], 15); RTMP_SET_PACKET_NET_DEVICE_MBSSID(skb_p, MAIN_MBSSID); return rt28xx_packet_xmit(skb_p); }
static VOID DEVEXIT rt_pci_remove(struct pci_dev *pci_dev) { PNET_DEV net_dev = pci_get_drvdata(pci_dev); VOID *pAd = NULL; ULONG csr_addr = net_dev->base_addr; GET_PAD_FROM_NET_DEV(pAd, net_dev); MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("===> %s()\n", __FUNCTION__)); if (pAd != NULL) { /* Unregister/Free all allocated net_device. */ RtmpPhyNetDevExit(pAd, net_dev); #ifdef RT_CFG80211_SUPPORT RTMP_DRIVER_80211_UNREGISTER(pAd, net_dev); #endif /* RT_CFG80211_SUPPORT */ /* Free RTMP_ADAPTER related structures. */ RtmpRaDevCtrlExit(pAd); /* Unmap CSR base address */ iounmap((char *)(csr_addr)); /* release memory region */ release_mem_region(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0)); } else { /* Unregister network device */ RtmpOSNetDevDetach(net_dev); /* Unmap CSR base address */ iounmap((char *)(net_dev->base_addr)); /* release memory region */ release_mem_region(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0)); } /* Free the root net_device */ RtmpOSNetDevFree(net_dev); }
/* ======================================================================== Routine Description: Send a packet to WLAN. Arguments: skb_p points to our adapter dev_p which WLAN network interface Return Value: 0: transmit successfully otherwise: transmit fail Note: ======================================================================== */ static int rt28xx_send_packets( IN struct sk_buff *skb_p, IN struct net_device *net_dev) { RTMP_ADAPTER *pAd = NULL; GET_PAD_FROM_NET_DEV(pAd, net_dev); if (!(net_dev->flags & IFF_UP)) { RELEASE_NDIS_PACKET(pAd, (PNDIS_PACKET)skb_p, NDIS_STATUS_FAILURE); return 0; } NdisZeroMemory((PUCHAR)&skb_p->cb[CB_OFF], 15); RTMP_SET_PACKET_NET_DEVICE_MBSSID(skb_p, MAIN_MBSSID); return rt28xx_packet_xmit(skb_p); }
rt2860_interrupt(int irq, void *dev_instance, struct pt_regs *regs) #endif { struct net_device *net_dev = (struct net_device *) dev_instance; VOID *pAd = NULL; /* INT_SOURCE_CSR_STRUC IntSource; */ /* POS_COOKIE pObj; */ #ifdef MULTI_CORE_SUPPORT unsigned long flags=0; #endif // MULTI_CORE_SUPPORT // GET_PAD_FROM_NET_DEV(pAd, net_dev); RTMPHandleInterrupt(pAd); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) return IRQ_HANDLED; #endif }
/* ======================================================================== Routine Description: Send a packet to WLAN. Arguments: skb_p points to our adapter dev_p which WLAN network interface Return Value: 0: transmit successfully otherwise: transmit fail Note: ======================================================================== */ static int rt28xx_send_packets( IN struct sk_buff *skb_p, IN struct net_device *net_dev) { RTMP_ADAPTER *pAd = NULL; GET_PAD_FROM_NET_DEV(pAd, net_dev); if (!(RTMP_OS_NETDEV_STATE_RUNNING(net_dev))) { RELEASE_NDIS_PACKET(pAd, (PNDIS_PACKET)skb_p, NDIS_STATUS_FAILURE); return 0; } NdisZeroMemory((PUCHAR)&skb_p->cb[CB_OFF], 15); RTMP_SET_PACKET_NET_DEVICE_MBSSID(skb_p, MAIN_MBSSID); MEM_DBG_PKT_ALLOC_INC(pAd); return rt28xx_packet_xmit(skb_p); }
/* ======================================================================== Routine Description: Close raxx interface. Arguments: *net_dev the raxx interface pointer Return Value: 0 Open OK otherwise Open Fail Note: 1. if open fail, kernel will not call the close function. 2. Free memory for (1) Mlme Memory Handler: MlmeHalt() (2) TX & RX: RTMPFreeTxRxRingMemory() (3) BA Reordering: ba_reordering_resource_release() ======================================================================== */ int MainVirtualIF_close(IN struct net_device *net_dev) { RTMP_ADAPTER *pAd = NULL; GET_PAD_FROM_NET_DEV(pAd, net_dev); // Sanity check for pAd if (pAd == NULL) return 0; // close ok netif_carrier_off(pAd->net_dev); netif_stop_queue(pAd->net_dev); VIRTUAL_IF_DOWN(pAd); RT_MOD_DEC_USE_COUNT(); return 0; // close ok }
static void __devexit rt2860_remove_one(IN struct pci_dev *pci_dev) { struct net_device *net_dev = pci_get_drvdata(pci_dev); struct rt_rtmp_adapter *pAd = NULL; unsigned long csr_addr = net_dev->base_addr; /* pAd->CSRBaseAddress; */ GET_PAD_FROM_NET_DEV(pAd, net_dev); DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_remove_one\n")); if (pAd != NULL) { /* Unregister/Free all allocated net_device. */ RtmpPhyNetDevExit(pAd, net_dev); /* Unmap CSR base address */ iounmap((char *)(csr_addr)); /* release memory region */ release_mem_region(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0)); /* Free struct rt_rtmp_adapter related structures. */ RtmpRaDevCtrlExit(pAd); } else { /* Unregister network device */ RtmpOSNetDevDetach(net_dev); /* Unmap CSR base address */ iounmap((char *)(net_dev->base_addr)); /* release memory region */ release_mem_region(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0)); } /* Free the root net_device */ RtmpOSNetDevFree(net_dev); }
/* This function will be called when query /proc */ struct iw_statistics *rt28xx_get_wireless_stats(IN struct net_device *net_dev) { struct rt_rtmp_adapter *pAd = NULL; GET_PAD_FROM_NET_DEV(pAd, net_dev); DBGPRINT(RT_DEBUG_TRACE, ("rt28xx_get_wireless_stats --->\n")); pAd->iw_stats.status = 0; /* Status - device dependent for now */ /* link quality */ if (pAd->OpMode == OPMODE_STA) pAd->iw_stats.qual.qual = ((pAd->Mlme.ChannelQuality * 12) / 10 + 10); if (pAd->iw_stats.qual.qual > 100) pAd->iw_stats.qual.qual = 100; if (pAd->OpMode == OPMODE_STA) { pAd->iw_stats.qual.level = RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2); } pAd->iw_stats.qual.noise = pAd->BbpWriteLatch[66]; /* noise level (dBm) */ pAd->iw_stats.qual.noise += 256 - 143; pAd->iw_stats.qual.updated = 1; /* Flags to know if updated */ #ifdef IW_QUAL_DBM pAd->iw_stats.qual.updated |= IW_QUAL_DBM; /* Level + Noise are dBm */ #endif /* IW_QUAL_DBM // */ pAd->iw_stats.discard.nwid = 0; /* Rx : Wrong nwid/essid */ pAd->iw_stats.miss.beacon = 0; /* Missed beacons/superframe */ DBGPRINT(RT_DEBUG_TRACE, ("<--- rt28xx_get_wireless_stats\n")); return &pAd->iw_stats; }
/* ======================================================================== Routine Description: Open raxx interface. Arguments: *net_dev the raxx interface pointer Return Value: 0 Open OK otherwise Open Fail Note: 1. if open fail, kernel will not call the close function. 2. Free memory for (1) Mlme Memory Handler: MlmeHalt() (2) TX & RX: RTMPFreeTxRxRingMemory() (3) BA Reordering: ba_reordering_resource_release() ======================================================================== */ int MainVirtualIF_open(IN struct net_device *net_dev) { struct rt_rtmp_adapter *pAd = NULL; GET_PAD_FROM_NET_DEV(pAd, net_dev); /* Sanity check for pAd */ if (pAd == NULL) return 0; /* close ok */ if (VIRTUAL_IF_UP(pAd) != 0) return -1; /* increase MODULE use count */ RT_MOD_INC_USE_COUNT(); netif_start_queue(net_dev); netif_carrier_on(net_dev); netif_wake_queue(net_dev); return 0; }
/* ======================================================================== Routine Description: Open raxx interface. Arguments: *net_dev the raxx interface pointer Return Value: 0 Open OK otherwise Open Fail Note: 1. if open fail, kernel will not call the close function. 2. Free memory for (1) Mlme Memory Handler: MlmeHalt() (2) TX & RX: RTMPFreeTxRxRingMemory() (3) BA Reordering: ba_reordering_resource_release() ======================================================================== */ int MainVirtualIF_open(IN struct net_device *net_dev) { RTMP_ADAPTER *pAd = NULL; GET_PAD_FROM_NET_DEV(pAd, net_dev); // Sanity check for pAd if (pAd == NULL) return 0; // close ok if (VIRTUAL_IF_UP(pAd) != 0) return -1; // increase MODULE use count RT_MOD_INC_USE_COUNT(); netif_start_queue(net_dev); netif_carrier_on(net_dev); netif_wake_queue(net_dev); return 0; }
// This function will be called when query /proc struct iw_statistics *rt28xx_get_wireless_stats( IN struct net_device *net_dev) { PRTMP_ADAPTER pAd = NULL; #ifdef CONFIG_AP_SUPPORT PMAC_TABLE_ENTRY pMacEntry = NULL; #endif // CONFIG_AP_SUPPORT // GET_PAD_FROM_NET_DEV(pAd, net_dev); #ifdef CONFIG_AP_SUPPORT if (pAd->OpMode == OPMODE_AP) { #ifdef APCLI_SUPPORT if (RT_DEV_PRIV_FLAGS_GET(net_dev) == INT_APCLI) { INT ApCliIdx = ApCliIfLookUp(pAd, (PUCHAR)net_dev->dev_addr); if ((ApCliIdx >= 0) && VALID_WCID(pAd->ApCfg.ApCliTab[ApCliIdx].MacTabWCID)) pMacEntry = &pAd->MacTab.Content[pAd->ApCfg.ApCliTab[ApCliIdx].MacTabWCID]; } else #endif // APCLI_SUPPORT // { /* only AP client support wireless stats function. return NULL pointer for all other cases. */ pMacEntry = &pAd->MacTab.Content[0]; } } #endif // CONFIG_AP_SUPPORT // DBGPRINT(RT_DEBUG_TRACE, ("rt28xx_get_wireless_stats --->\n")); //check if the interface is down if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) return NULL; pAd->iw_stats.status = 0; // Status - device dependent for now // link quality #ifdef CONFIG_AP_SUPPORT if (pAd->OpMode == OPMODE_AP) { if (pMacEntry != NULL) pAd->iw_stats.qual.qual = ((pMacEntry->ChannelQuality * 12)/10 + 10); } #endif // CONFIG_AP_SUPPORT // if(pAd->iw_stats.qual.qual > 100) pAd->iw_stats.qual.qual = 100; #ifdef CONFIG_AP_SUPPORT if (pAd->OpMode == OPMODE_AP) { if (pMacEntry != NULL) pAd->iw_stats.qual.level = RTMPMaxRssi(pAd, pMacEntry->RssiSample.AvgRssi0, pMacEntry->RssiSample.AvgRssi1, pMacEntry->RssiSample.AvgRssi2); } #endif // CONFIG_AP_SUPPORT // #ifdef CONFIG_AP_SUPPORT pAd->iw_stats.qual.noise = RTMPMaxRssi(pAd, pAd->ApCfg.RssiSample.AvgRssi0, pAd->ApCfg.RssiSample.AvgRssi1, pAd->ApCfg.RssiSample.AvgRssi2) - RTMPMinSnr(pAd, pAd->ApCfg.RssiSample.AvgSnr0, pAd->ApCfg.RssiSample.AvgSnr1); #endif // CONFIG_AP_SUPPORT // pAd->iw_stats.qual.updated = 1; // Flags to know if updated #ifdef IW_QUAL_DBM pAd->iw_stats.qual.updated |= IW_QUAL_DBM; // Level + Noise are dBm #endif // IW_QUAL_DBM // pAd->iw_stats.discard.nwid = 0; // Rx : Wrong nwid/essid pAd->iw_stats.miss.beacon = 0; // Missed beacons/superframe DBGPRINT(RT_DEBUG_TRACE, ("<--- rt28xx_get_wireless_stats\n")); return &pAd->iw_stats; }
/* ======================================================================== Routine Description: Open raxx interface. Arguments: *net_dev the raxx interface pointer Return Value: 0 Open OK otherwise Open Fail Note: ======================================================================== */ int rt28xx_open(IN PNET_DEV dev) { struct net_device * net_dev = (struct net_device *)dev; PRTMP_ADAPTER pAd = NULL; int retval = 0; //POS_COOKIE pObj; GET_PAD_FROM_NET_DEV(pAd, net_dev); // Sanity check for pAd if (pAd == NULL) { /* if 1st open fail, pAd will be free; So the net_dev->priv will be NULL in 2rd open */ return -1; } #ifdef CONFIG_APSTA_MIXED_SUPPORT if (pAd->OpMode == OPMODE_AP) { CW_MAX_IN_BITS = 6; } else if (pAd->OpMode == OPMODE_STA) { CW_MAX_IN_BITS = 10; } #endif // CONFIG_APSTA_MIXED_SUPPORT // #if WIRELESS_EXT >= 12 if (RT_DEV_PRIV_FLAGS_GET(net_dev) == INT_MAIN) { #ifdef CONFIG_APSTA_MIXED_SUPPORT if (pAd->OpMode == OPMODE_AP) net_dev->wireless_handlers = (struct iw_handler_def *) &rt28xx_ap_iw_handler_def; #endif // CONFIG_APSTA_MIXED_SUPPORT // } #endif // WIRELESS_EXT >= 12 // // Request interrupt service routine for PCI device // register the interrupt routine with the os /* AP Channel auto-selection will be run in rt28xx_init(), so we must reqister IRQ hander here. */ RtmpOSIRQRequest(net_dev); // Init IRQ parameters stored in pAd RTMP_IRQ_INIT(pAd); // Chip & other init if (rt28xx_init(pAd, mac, hostname) == FALSE) goto err; #ifdef LINUX #ifdef RT_CFG80211_SUPPORT RT_CFG80211_REINIT(pAd); RT_CFG80211_CRDA_REG_RULE_APPLY(pAd); #endif // RT_CFG80211_SUPPORT // #endif // LINUX // // Enable Interrupt RTMP_IRQ_ENABLE(pAd); // Now Enable RxTx RTMPEnableRxTx(pAd); RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP); { UINT32 reg = 0; RTMP_IO_READ32(pAd, 0x1300, ®); // clear garbage interrupts if (reg); DBGPRINT(RT_DEBUG_TRACE, ("0x1300 = %08x\n", reg)); } { // u32 reg; // UINT8 byte; // u16 tmp; // RTMP_IO_READ32(pAd, XIFS_TIME_CFG, ®); // tmp = 0x0805; // reg = (reg & 0xffff0000) | tmp; // RTMP_IO_WRITE32(pAd, XIFS_TIME_CFG, reg); } #ifdef CONFIG_AP_SUPPORT #ifdef BG_FT_SUPPORT BG_FTPH_Init(); #endif // BG_FT_SUPPORT // #endif // CONFIG_AP_SUPPORT // #ifdef VENDOR_FEATURE2_SUPPORT printk("Number of Packet Allocated in open = %d\n", pAd->NumOfPktAlloc); printk("Number of Packet Freed in open = %d\n", pAd->NumOfPktFree); #endif // VENDOR_FEATURE2_SUPPORT // return (retval); err: //+++Add by shiang, move from rt28xx_init() to here. RtmpOSIRQRelease(net_dev); //---Add by shiang, move from rt28xx_init() to here. return (-1); } /* End of rt28xx_open */
/* ======================================================================== Routine Description: Close raxx interface. Arguments: *net_dev the raxx interface pointer Return Value: 0 Open OK otherwise Open Fail Note: 1. if open fail, kernel will not call the close function. 2. Free memory for (1) Mlme Memory Handler: MlmeHalt() (2) TX & RX: RTMPFreeTxRxRingMemory() (3) BA Reordering: ba_reordering_resource_release() ======================================================================== */ int rt28xx_close(IN PNET_DEV dev) { struct net_device * net_dev = (struct net_device *)dev; RTMP_ADAPTER *pAd = NULL; BOOLEAN Cancelled; UINT32 i = 0; GET_PAD_FROM_NET_DEV(pAd, net_dev); DBGPRINT(RT_DEBUG_TRACE, ("===> rt28xx_close\n")); #ifdef CONFIG_AP_SUPPORT #ifdef BG_FT_SUPPORT BG_FTPH_Remove(); #endif // BG_FT_SUPPORT // #endif // CONFIG_AP_SUPPORT // Cancelled = FALSE; // Sanity check for pAd if (pAd == NULL) return 0; // close ok RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); #ifdef WMM_ACM_SUPPORT /* must call first */ ACMP_Release(pAd); #endif // WMM_ACM_SUPPORT // #ifdef WDS_SUPPORT WdsDown(pAd); #endif // WDS_SUPPORT // mdelay(20); /* wait for disconnect requests transmitted */ for (i = 0 ; i < NUM_OF_TX_RING; i++) { while (pAd->DeQueueRunning[i] == TRUE) { DBGPRINT(RT_DEBUG_TRACE, ("Waiting for TxQueue[%d] done..........\n", i)); RTMPusecDelay(1000); } } #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { #ifdef DOT11N_DRAFT3 if (pAd->CommonCfg.Bss2040CoexistFlag & BSS_2040_COEXIST_TIMER_FIRED) { RTMPCancelTimer(&pAd->CommonCfg.Bss2040CoexistTimer, &Cancelled); pAd->CommonCfg.Bss2040CoexistFlag = 0; } #endif // DOT11N_DRAFT3 // // PeriodicTimer already been canceled by MlmeHalt() API. //RTMPCancelTimer(&pAd->PeriodicTimer, &Cancelled); } #endif // CONFIG_AP_SUPPORT // // Stop Mlme state machine MlmeHalt(pAd); // Close net tasklets RtmpNetTaskExit(pAd); #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { #ifdef MAT_SUPPORT MATEngineExit(pAd); #endif // MAT_SUPPORT // #ifdef CLIENT_WDS CliWds_ProxyTabDestory(pAd); #endif // CLIENT_WDS // // Shutdown Access Point function, release all related resources APShutdown(pAd); #ifdef AUTO_CH_SELECT_ENHANCE // Free BssTab & ChannelInfo tabbles. AutoChBssTableDestroy(pAd); ChannelInfoDestroy(pAd); #endif // AUTO_CH_SELECT_ENHANCE // } #endif // CONFIG_AP_SUPPORT // MeasureReqTabExit(pAd); TpcReqTabExit(pAd); #ifdef WSC_INCLUDED #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { INT ap_idx; for (ap_idx = 0; ap_idx < pAd->ApCfg.BssidNum; ap_idx++) { PWSC_CTRL pWpsCtrl = &pAd->ApCfg.MBSSID[ap_idx].WscControl; WscStop(pAd, FALSE, pWpsCtrl); } #ifdef APCLI_SUPPORT WscStop(pAd, TRUE, &pAd->ApCfg.ApCliTab[BSS0].WscControl); #endif // APCLI_SUPPORT // } #endif // CONFIG_AP_SUPPORT // #ifdef OLD_DH_KEY #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) WSC_VFREE_KEY_MEM(pAd->ApCfg.MBSSID[0].WscControl.pPubKeyMem, pAd->ApCfg.MBSSID[0].WscControl.pSecKeyMem); #endif // CONFIG_AP_SUPPORT // #endif // OLD_DH_KEY // /* WSC hardware push button function 0811 */ WSC_HDR_BTN_Stop(pAd); #endif // WSC_INCLUDED // // Close kernel threads RtmpMgmtTaskExit(pAd); #ifdef RTMP_MAC_PCI { BOOLEAN brc; // ULONG Value; if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE)) { RTMP_ASIC_INTERRUPT_DISABLE(pAd); } // Receive packets to clear DMA index after disable interrupt. //RTMPHandleRxDoneInterrupt(pAd); // put to radio off to save power when driver unload. After radiooff, can't write /read register. So need to finish all // register access before Radio off. brc=RT28xxPciAsicRadioOff(pAd, RTMP_HALT, 0); //In solution 3 of 3090F, the bPCIclkOff will be set to TRUE after calling RT28xxPciAsicRadioOff #ifdef PCIE_PS_SUPPORT pAd->bPCIclkOff = FALSE; #endif // PCIE_PS_SUPPORT // if (brc==FALSE) { DBGPRINT(RT_DEBUG_ERROR,("%s call RT28xxPciAsicRadioOff fail !!\n", __FUNCTION__)); } } /* if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE)) { RTMP_ASIC_INTERRUPT_DISABLE(pAd); } // Disable Rx, register value supposed will remain after reset NICIssueReset(pAd); */ #endif // RTMP_MAC_PCI // // Free IRQ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) { #ifdef RTMP_MAC_PCI // Deregister interrupt function RtmpOSIRQRelease(net_dev); #endif // RTMP_MAC_PCI // RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE); } #ifdef RESOURCE_PRE_ALLOC RTMPResetTxRxRingMemory(pAd); #else // Free Ring or USB buffers RTMPFreeTxRxRingMemory(pAd); #endif // RESOURCE_PRE_ALLOC // RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); #ifdef DOT11_N_SUPPORT // Free BA reorder resource ba_reordering_resource_release(pAd); #endif // DOT11_N_SUPPORT // RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_START_UP); /*+++Modify by woody to solve the bulk fail+++*/ #ifdef VENDOR_FEATURE2_SUPPORT printk("Number of Packet Allocated = %d\n", pAd->NumOfPktAlloc); printk("Number of Packet Freed = %d\n", pAd->NumOfPktFree); #endif // VENDOR_FEATURE2_SUPPORT // /* clear MAC table */ /* TODO: do not clear spin lock, such as fLastChangeAccordingMfbLock */ NdisZeroMemory(&pAd->MacTab, sizeof(MAC_TABLE)); /* release all timers */ RTMPusecDelay(2000); RTMP_TimerListRelease(pAd); DBGPRINT(RT_DEBUG_TRACE, ("<=== rt28xx_close\n")); return 0; // close ok } /* End of rt28xx_close */