rt_main_dev.c
来自「Linux下的RT系列无线网卡驱动,可以直接在x86平台上编译」· C语言 代码 · 共 1,657 行 · 第 1/4 页
C
1,657 行
MlmeHalt(pAd);#ifdef CONFIG_STA_SUPPORT STAMacTableReset(pAd);#endif // CONFIG_STA_SUPPORT // netif_stop_queue(net_dev); netif_carrier_off(net_dev); if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE)) { NICDisableInterrupt(pAd); } // Disable Rx, register value supposed will remain after reset NICIssueReset(pAd); // Free IRQ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) { // Deregister interrupt function#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) synchronize_irq(net_dev->irq);#endif free_irq(net_dev->irq, net_dev); RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE); } // Free Ring buffers RTMPFreeDMAMemory(pAd); // Free ba reorder resource ba_reordering_resource_release(pAd); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) module_put(THIS_MODULE);#else MOD_DEC_USE_COUNT;#endif return 0;}#if LINUX_VERSION_CODE <= 0x20402 // Red Hat 7.1static struct net_device *alloc_netdev(int sizeof_priv, const char *mask, void (*setup)(struct net_device *)){ struct net_device *dev; INT alloc_size; /* ensure 32-byte alignment of the private area */ alloc_size = sizeof (*dev) + sizeof_priv + 31; dev = (struct net_device *) kmalloc (alloc_size, GFP_KERNEL); if (dev == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("alloc_netdev: Unable to allocate device memory.\n")); return NULL; } memset(dev, 0, alloc_size); if (sizeof_priv) dev->priv = (void *) (((long)(dev + 1) + 31) & ~31); setup(dev); strcpy(dev->name,mask); return dev;}#endifvoid CfgInitHook(PRTMP_ADAPTER pAd){ pAd->bBroadComHT = TRUE;}static int rt2860_init(IN struct net_device *net_dev){ PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)net_dev->priv; UINT index; UCHAR TmpPhy;// ULONG Value=0; NDIS_STATUS Status; WPDMA_GLO_CFG_STRUC GloCfg; init_thread_task(pAd); NICInitTxRxRingAndBacklogQueue(pAd); /* Allocate BA Reordering memory */ ba_reordering_resource_init(pAd, MAX_REORDERING_MPDU_NUM); // // Make sure MAC gets ready. // index = 0; do { RTMP_IO_READ32(pAd, MAC_CSR0, &pAd->MACVersion); if ((pAd->MACVersion != 0x00) && (pAd->MACVersion != 0xFFFFFFFF)) break; RTMPusecDelay(10); } while (index++ < 100); DBGPRINT(RT_DEBUG_TRACE, ("MAC_CSR0 [ Ver:Rev=0x%08lx]\n", pAd->MACVersion)); // Disable DMA. RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word); GloCfg.word &= 0xff0; GloCfg.field.EnTXWriteBackDDONE =1; RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word); RTMP_IO_WRITE32(pAd, WPDMA_RST_IDX , 0xFFFFFFFF); RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0xe1f); RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0xe00); // Load 8051 firmware; Status = NICLoadFirmware(pAd); if (Status != NDIS_STATUS_SUCCESS) { DBGPRINT_ERR(("NICLoadFirmware failed, Status[=0x%08x]\n", Status)); goto err1; } NICLoadRateSwitchingParams(pAd); // Disable interrupts here which is as soon as possible // This statement should never be true. We might consider to remove it later if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE)) { NICDisableInterrupt(pAd); } Status = RTMPAllocDMAMemory(pAd); if (Status != NDIS_STATUS_SUCCESS) { DBGPRINT_ERR(("RTMPAllocDMAMemory failed, Status[=0x%08x]\n", Status)); goto err1; } RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE); // initialize MLME // Status = MlmeInit(pAd); if(Status != NDIS_STATUS_SUCCESS) { DBGPRINT_ERR(("MlmeInit failed, Status[=0x%08x]\n", Status)); goto err2; } // Initialize pAd->StaCfg, pAd->ApCfg, pAd->CommonCfg to manufacture default // UserCfgInit(pAd); // COPY_MAC_ADDR(pAd->ApCfg.MBSSID[apidx].Bssid, netif->hwaddr);// pAd->bForcePrintTX = TRUE; CfgInitHook(pAd); #ifdef BLOCK_NET_IF initblockQueueTab(pAd);#endif // BLOCK_NET_IF //#ifdef CONFIG_STA_SUPPORT NdisAllocateSpinLock(&pAd->MacTabLock); pAd->OpMode = OPMODE_STA;#endif // CONFIG_STA_SUPPORT // // // Init the hardware, we need to init asic before read registry, otherwise mac register will be reset // Status = NICInitializeAdapter(pAd, TRUE); if (Status != NDIS_STATUS_SUCCESS) { DBGPRINT_ERR(("NICInitializeAdapter failed, Status[=0x%08x]\n", Status)); goto err3; } // Read parameters from Config File Status = RTMPReadParametersHook(pAd); printk("1. Phy Mode = %d\n", pAd->CommonCfg.PhyMode); if (Status != NDIS_STATUS_SUCCESS) { DBGPRINT_ERR(("NICReadRegParameters failed, Status[=0x%08x]\n", Status)); goto err4; }#ifdef CONFIG_STA_SUPPORT// pAd->StaCfg.bAutoReconnect = TRUE; NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen); pAd->MlmeAux.AutoReconnectSsidLen = pAd->CommonCfg.SsidLen;#endif // CONFIG_STA_SUPPORT // //Init Ba Capability parameters. pAd->CommonCfg.DesiredHtPhy.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity; pAd->CommonCfg.DesiredHtPhy.AmsduEnable = (USHORT)pAd->CommonCfg.BACapability.field.AmsduEnable; pAd->CommonCfg.DesiredHtPhy.AmsduSize= (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize; pAd->CommonCfg.DesiredHtPhy.MimoPs= (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode; // UPdata to HT IE pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode; pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize; pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity; // after reading Registry, we now know if in AP mode or STA mode // Load 8051 firmware; crash when FW image not existent // Status = NICLoadFirmware(pAd); // if (Status != NDIS_STATUS_SUCCESS) // break; printk("2. Phy Mode = %d\n", pAd->CommonCfg.PhyMode); // We should read EEPROM for all cases. rt2860b NICReadEEPROMParameters(pAd); printk("3. Phy Mode = %d\n", pAd->CommonCfg.PhyMode); // Set PHY to appropriate mode TmpPhy = pAd->CommonCfg.PhyMode; pAd->CommonCfg.PhyMode = 0xff; RTMPSetPhyMode(pAd, TmpPhy); printk("MCS Set = %02x %02x %02x %02x %02x\n", pAd->CommonCfg.HtCapability.MCSSet[0], pAd->CommonCfg.HtCapability.MCSSet[1], pAd->CommonCfg.HtCapability.MCSSet[2], pAd->CommonCfg.HtCapability.MCSSet[3], pAd->CommonCfg.HtCapability.MCSSet[4]); NICInitAsicFromEEPROM(pAd); //rt2860b // // Initialize RF register to default value // AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); AsicLockChannel(pAd, pAd->CommonCfg.Channel); if (pAd && (Status != NDIS_STATUS_SUCCESS)) { BOOLEAN Cancelled; // // Undo everything if it failed // //RTMPCancelTimer(&pAd->RfTuningTimer, &Cancelled); RTMPCancelTimer(&pAd->Mlme.PeriodicTimer, &Cancelled); RTMPCancelTimer(&pAd->Mlme.APSDPeriodicTimer, &Cancelled); if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {// NdisMDeregisterInterrupt(&pAd->Interrupt); RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE); } RTMPFreeAdapter(pAd); } else if (pAd) { // Microsoft HCT require driver send a disconnect event after driver initialization. OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);// pAd->IndicateMediaState = NdisMediaStateDisconnected; RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE); DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event B!\n")); }// end of else DBGPRINT_S(Status, ("<==== RTMPInitialize, Status=%x\n", Status)); return TRUE;err4:err3: MlmeHalt(pAd);err2: RTMPFreeDMAMemory(pAd); RTMPFreeAdapter(pAd);err1:#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) synchronize_irq(net_dev->irq);#endif free_irq(net_dev->irq, net_dev); net_dev->priv = 0;// panic("!!! RT2860 Initialized fail !!!\n"); printk("!!! RT2860 Initialized fail !!!\n"); return FALSE;}void init_thread_task(IN PRTMP_ADAPTER pAd){ POS_COOKIE pObj; pObj = (POS_COOKIE) pAd->OS_Cookie; tasklet_init(&pObj->rx_done_task, rx_done_tasklet, (unsigned long)pAd); tasklet_init(&pObj->mgmt_dma_done_task, mgmt_dma_done_tasklet, (unsigned long)pAd); tasklet_init(&pObj->ac0_dma_done_task, ac0_dma_done_tasklet, (unsigned long)pAd); tasklet_init(&pObj->ac1_dma_done_task, ac1_dma_done_tasklet, (unsigned long)pAd); tasklet_init(&pObj->ac2_dma_done_task, ac2_dma_done_tasklet, (unsigned long)pAd); tasklet_init(&pObj->ac3_dma_done_task, ac3_dma_done_tasklet, (unsigned long)pAd); tasklet_init(&pObj->hcca_dma_done_task, hcca_dma_done_tasklet, (unsigned long)pAd); tasklet_init(&pObj->fifo_statistic_full_task, fifo_statistic_full_tasklet, (unsigned long)pAd);}void kill_thread_task(IN PRTMP_ADAPTER pAd){ POS_COOKIE pObj; pObj = (POS_COOKIE) pAd->OS_Cookie; tasklet_kill(&pObj->rx_done_task); tasklet_kill(&pObj->mgmt_dma_done_task); tasklet_kill(&pObj->ac0_dma_done_task); tasklet_kill(&pObj->ac1_dma_done_task); tasklet_kill(&pObj->ac2_dma_done_task); tasklet_kill(&pObj->ac3_dma_done_task); tasklet_kill(&pObj->hcca_dma_done_task); tasklet_kill(&pObj->fifo_statistic_full_task);}int rt2860_packet_xmit(struct sk_buff *skb){ struct net_device *net_dev = skb->dev; PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) net_dev->priv; struct sk_buff *pkt = (struct sk_buff *) skb; int status = 0; PNDIS_PACKET pPacket = (PNDIS_PACKET) pkt;#ifdef CONFIG_STA_SUPPORT // Drop send request since we are in monitor mode if (MONITOR_ON(pAd)) { RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); goto done; }#endif // CONFIG_STA_SUPPORT // // EapolStart size is 18 if ((skb->len < 14) #ifdef RALINK_ATE || (pAd->ate.Mode != ATE_STOP)#endif // RALINK_ATE // ) { //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);#ifdef CONFIG_5VT_ENHANCE if (*(int*)(skb->cb) == BRIDGE_TAG) { RTMP_SET_PACKET_5VT(pPacket, 1); }#endif#ifdef CONFIG_STA_SUPPORT if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) { // Drop send request since hardware is in reset state RTMP_SendComplete(pAd, pPacket, NDIS_STATUS_FAILURE); } else if (!INFRA_ON(pAd) && !ADHOC_ON(pAd)) { // Drop send request since there are no physical connection yet RTMP_SendComplete(pAd, pPacket, NDIS_STATUS_FAILURE); } else { // Record that orignal packet source is from NDIS layer,so that // later on driver knows how to release this NDIS PACKET RTMP_SET_PACKET_WCID(pPacket, 0); // this field is useless when in STA mode RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS); NDIS_SET_PACKET_STATUS(pPacket, NDIS_STATUS_PENDING); pAd->RalinkCounters.PendingNdisPacketCount ++; RTMPSendPacket(pAd, pPacket); } // Dequeue outgoing frames from TxSwQueue[] and process it RTMPDeQueuePacket(pAd, FALSE, MAX_TX_PROCESS);#endif // CONFIG_STA_SUPPORT // status = 0;done: return status;}static int rt2860_open(struct net_device *net_dev){ PRTMP_ADAPTER pAd= (PRTMP_ADAPTER)net_dev->priv; int retval = 0; POS_COOKIE pObj; if (pAd == NULL) { /* if 1st open fail, pAd will be free; So the net_dev->priv will be NULL in 2rd open */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?