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

📄 rtmp_main.c

📁 经过修改的在uClinux2.6上正常运行的ralink rt2571芯片组的设备驱动程序.
💻 C
📖 第 1 页 / 共 5 页
字号:
			{
				if (cmdqelmt->buffer != NULL)
			        kfree(cmdqelmt->buffer);
			}
			
			kfree((PCmdQElmt)cmdqelmt);
		}
		else
            cmdqelmt->InUse = FALSE;
            
	}


}

static int usb_rtusb_open(struct net_device *net_dev)
{
	PRTMP_ADAPTER   pAd = (PRTMP_ADAPTER) net_dev->priv;
	NDIS_STATUS     Status = NDIS_STATUS_SUCCESS;
	UCHAR           TmpPhy;
	
	printk("rt73 driver version - %s\n", DRIVER_VERSION);

	init_MUTEX(&(pAd->usbdev_semaphore));
	
	// init mediastate to disconnected
	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
	
	pAd->rx_bh.func = RTUSBRxPacket;
	
	// Initialize pAd->PortCfg to manufacture default
	PortCfgInit(pAd);


	// Init  RTMP_ADAPTER CmdQElements
	Status = RTMPInitAdapterBlock(pAd);
	if (Status != NDIS_STATUS_SUCCESS)
	{
		return Status;
	}

    //
	// Init send data structures and related parameters
    //
	Status = NICInitTransmit(pAd);
	if (Status != NDIS_STATUS_SUCCESS)
	{
		return Status;
	}

	//
	// Init receive data structures and related parameters
	//
	Status = NICInitRecv(pAd);
	if (Status != NDIS_STATUS_SUCCESS)
	{
		goto out;
	}
	

	// Wait for hardware stable
	{
        ULONG MacCsr0 = 0, Index = 0;
		
		do
		{
			Status = RTUSBReadMACRegister(pAd, MAC_CSR0, &MacCsr0);

			if (MacCsr0 != 0)
				break;
			
			RTMPusecDelay(1000);
		} while (Index++ < 1000);
		DBGPRINT(RT_DEBUG_TRACE, "Init: MAC_CSR0=0x%08x, Status=0x%08x\n", MacCsr0, Status);
	}

	// Load 8051 firmware
	Status = NICLoadFirmware(pAd);
    if(Status != NDIS_STATUS_SUCCESS)
    {
        goto out;
    }

	// Initialize Asics
	NICInitializeAsic(pAd);

	// Read RaConfig profile parameters 
#ifdef  READ_PROFILE_FROM_FILE 
	RTMPReadParametersFromFile(pAd);
#endif

	//
	// Read additional info from NIC such as MAC address
	// This function must called after register CSR base address
	//
#ifdef	INIT_FROM_EEPROM
	NICReadEEPROMParameters(pAd);
	NICInitAsicFromEEPROM(pAd);
#endif
	RTUSBWriteHWMACAddress(pAd);

	// external LNA has different R17 base
	if (pAd->NicConfig2.field.ExternalLNA)
	{
		pAd->BbpTuning.R17LowerBoundA += 0x10;
		pAd->BbpTuning.R17UpperBoundA += 0x10;
		pAd->BbpTuning.R17LowerBoundG += 0x10;
		pAd->BbpTuning.R17UpperBoundG += 0x10;
	}

	// hardware initialization after all parameters are acquired from
	// Registry or E2PROM
	TmpPhy = pAd->PortCfg.PhyMode;
	pAd->PortCfg.PhyMode = 0xff;
	RTMPSetPhyMode(pAd, TmpPhy);


	//
	// initialize MLME
    //
	Status = MlmeInit(pAd);
	if(Status != NDIS_STATUS_SUCCESS)
	{
		goto out;
	}

	// mlmethread & RTUSBCmd flag restart
	mlme_kill = 0;
	RTUSBCmd_kill =0;
	CreateThreads(net_dev);

	// at every open handler, copy mac address.
	memcpy(pAd->net_dev->dev_addr, pAd->CurrentAddress, pAd->net_dev->addr_len);

    
	// Clear Reset Flag before starting receiving/transmitting
	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS);


	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
	{
		RTUSBBulkReceive(pAd);
        RTUSBWriteMACRegister(pAd, TXRX_CSR0, 0x025eb032);    // enable RX of MAC block, Staion not drop control frame
        // Initialize RF register to default value
	    AsicSwitchChannel(pAd, pAd->PortCfg.Channel);
	    AsicLockChannel(pAd, pAd->PortCfg.Channel);
	}


    // USB_ID info for UI
    pAd->VendorDesc = 0x148F2573;
   
	// Start net_dev interface tx /rx
	netif_start_queue(net_dev);
	
	netif_carrier_on(net_dev);
	netif_wake_queue(net_dev);
	return 0;


out:
	ReleaseAdapter(pAd, TRUE, FALSE);
	return 0;

}

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
static int usb_rtusb_close(struct net_device *net_dev)
{
	PRTMP_ADAPTER   pAd = (PRTMP_ADAPTER) net_dev->priv;
	int             ret;
    int	            i = 0;
	
	DECLARE_WAIT_QUEUE_HEAD (unlink_wakeup); 
	DECLARE_WAITQUEUE (wait, current);
	
	DBGPRINT(RT_DEBUG_TRACE,"-->rt73_close\n");
	
	netif_carrier_off(pAd->net_dev);
	netif_stop_queue(pAd->net_dev);

	DBGPRINT(RT_DEBUG_INFO,"Ensure there are no more active urbs \n");
	// ensure there are no more active urbs. 
	add_wait_queue (&unlink_wakeup, &wait);
	pAd->wait = &unlink_wakeup;
	// maybe wait for deletions to finish.
	while ((i < 10) && atomic_read(&pAd->PendingRx) > 0) {
		//msleep(UNLINK_TIMEOUT_MS);
		i++;
		DBGPRINT (RT_DEBUG_INFO,"waited for %d urb to complete\n", atomic_read(&pAd->PendingRx));
	}
	pAd->wait = NULL;
	remove_wait_queue (&unlink_wakeup, &wait); 

	if (pAd->MLMEThr_pid >= 0) 
	{
		mlme_kill = 1;
		RTUSBMlmeUp(pAd);
		wmb(); // need to check
		ret = kill_proc (pAd->MLMEThr_pid, SIGTERM, 1);
		if (ret) 
		{
			printk (KERN_ERR "%s: unable to signal thread\n", pAd->net_dev->name);
			return ret;
		}
		wait_for_completion (&pAd->notify);
	}
	if (pAd->RTUSBCmdThr_pid>= 0) 
	{
		RTUSBCmd_kill = 1;
		RTUSBCMDUp(pAd);
		wmb(); // need to check
		ret = kill_proc (pAd->RTUSBCmdThr_pid, SIGTERM, 1);
		if (ret) 
		{
			printk (KERN_ERR "%s: unable to signal thread\n", pAd->net_dev->name);
			return ret;
		}
	    wait_for_completion (&pAd->notify);
	}
	
	RTUSBHalt(pAd, TRUE);
	DBGPRINT(RT_DEBUG_TRACE,"<--rt73_close\n");

	return 0;
}

INT MlmeThread(
    IN void * Context)
{
	PRTMP_ADAPTER	pAd = (PRTMP_ADAPTER)Context;

	daemonize();
	current->flags |= PF_NOFREEZE;
	/* signal that we've started the thread */
	complete(&(pAd->notify));
#if 1
	while (1)
	{
		//if(down_interruptible(&pAd->mlme_semaphore))
			//break;

		/* lock the device pointers */
		down(&(pAd->mlme_semaphore));

		if (mlme_kill)
			break;

		/* lock the device pointers , need to check if required*/
		down(&(pAd->usbdev_semaphore));
		MlmeHandler(pAd);		

		/* unlock the device pointers */
		up(&(pAd->usbdev_semaphore));
	}
#else
	// I tried this way for thread handling
	while(1)
	{
		timeout = next_tick;
		do {
			timeout = interruptible_sleep_on_timeout (&pAd->MLMEThr_wait, timeout);
			/* make swsusp happy with our thread */
			if (current->flags & PF_FREEZE)
				refrigerator(PF_FREEZE);
			DBGPRINT(RT_DEBUG_TRACE, "current->flags  = 0x%x\n",current->flags );
		} while (!signal_pending (current) && (timeout > 0));

		if (signal_pending (current)) {
			flush_signals(current);
		}

		if (mlme_kill)
			break;
	}
#endif

	/* notify the exit routine that we're actually exiting now 
	 *
	 * complete()/wait_for_completion() is similar to up()/down(),
	 * except that complete() is safe in the case where the structure
	 * is getting deleted in a parallel mode of execution (i.e. just
	 * after the down() -- that's necessary for the thread-shutdown
	 * case.
	 *
	 * complete_and_exit() goes even further than this -- it is safe in
	 * the case that the thread of the caller is going away (not just
	 * the structure) -- this is necessary for the module-remove case.
	 * This is important in preemption kernels, which transfer the flow
	 * of execution immediately upon a complete().
	 */
	complete_and_exit (&pAd->notify, 0);
	DBGPRINT(RT_DEBUG_TRACE, "<---MlmeThread\n");

}
INT RTUSBCmdThread(
    IN void * Context)
{

aslkd;askdf
	PRTMP_ADAPTER	pAd = (PRTMP_ADAPTER)Context;

	daemonize();
	current->flags |= PF_NOFREEZE;
	/* signal that we've started the thread */
	complete(&(pAd->notify));

	while (1)
	{
		//if(down_interruptible(&pAd->mlme_semaphore))
			//break;

		/* lock the device pointers */
		down(&(pAd->RTUSBCmd_semaphore));

		if (RTUSBCmd_kill)
			break;

		/* lock the device pointers , need to check if required*/
		down(&(pAd->usbdev_semaphore));
		CMDHandler(pAd);		

		/* unlock the device pointers */
		up(&(pAd->usbdev_semaphore));
	}

	/* notify the exit routine that we're actually exiting now 
	 *
	 * complete()/wait_for_completion() is similar to up()/down(),
	 * except that complete() is safe in the case where the structure
	 * is getting deleted in a parallel mode of execution (i.e. just
	 * after the down() -- that's necessary for the thread-shutdown
	 * case.
	 *
	 * complete_and_exit() goes even further than this -- it is safe in
	 * the case that the thread of the caller is going away (not just
	 * the structure) -- this is necessary for the module-remove case.
	 * This is important in preemption kernels, which transfer the flow
	 * of execution immediately upon a complete().
	 */
	complete_and_exit (&pAd->notify, 0);
	DBGPRINT(RT_DEBUG_TRACE, "<---RTUSBCmdThread\n");

}

static void *usb_rtusb_probe(struct usb_device *dev, UINT interface,
				const struct usb_device_id *id_table)
{	
	PRTMP_ADAPTER       pAd = (PRTMP_ADAPTER)NULL;
	int                 i;
	struct net_device   *netdev;
	int                 res = -ENOMEM;
	
	for (i = 0; i < rtusb_usb_id_len; i++)
	{
		if (dev->descriptor.idVendor == rtusb_usb_id[i].idVendor &&
			dev->descriptor.idProduct == rtusb_usb_id[i].idProduct)
		{
			printk("idVendor = 0x%x, idProduct = 0x%x \n",dev->descriptor.idVendor, dev->descriptor.idProduct);
			break;
		}
	}
	if (i == rtusb_usb_id_len) {
		printk("Device Descriptor not matching\n");
		return NULL;
	}

	netdev = alloc_etherdev(sizeof (*pAd));
	if(!netdev)
	{
		printk("alloc_etherdev failed\n");
			
		MOD_DEC_USE_COUNT;
		usb_dec_dev_use(dev);
		return NULL;
	}
	
	pAd = netdev->priv;
	pAd->net_dev = netdev;
	netif_stop_queue(netdev);
	pAd->config = dev->config;
	pAd->pUsb_Dev= dev;
	SET_MODULE_OWNER(pAd->net_dev);
	ether_setup(pAd->net_dev);
	
	netdev->open = usb_rtusb_open;
	netdev->hard_start_xmit = RTMPSendPackets;
	netdev->stop = usb_rtusb_close;
	netdev->priv = pAd;
	netdev->get_stats = rt73_get_ether_stats;
#if WIRELESS_EXT >= 11
	netdev->get_wireless_stats = rt73_get_wireless_stats;
	netdev->wireless_handlers = (struct iw_handler_def *) &rt73_iw_handler_def;
#endif
	netdev->do_ioctl = rt73_ioctl;
	pAd->net_dev->hard_header_len = 14;
	pAd->net_dev->mtu = 1500;
	pAd->net_dev->addr_len = 6;
	pAd->net_dev->weight = 64;

	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);

	{// find available 
		int 	i=0;
		char	slot_name[IFNAMSIZ];
		struct  net_device	*device;
		struct  usb_interface *ifp= &dev->actconfig->interface[interface];  // get interface from system           
        struct  usb_interface_descriptor *as;
        struct  usb_endpoint_descriptor *ep;             

		for (i = 0; i < 8; i++)
		{
			sprintf(slot_name, "rausb%d", i);
			
			read_lock_bh(&dev_base_lock); // avoid multiple init
			for (device = dev_base; device != NULL; device = device->next)
			{
				if (strncmp(device->name, slot_name, 4) == 0)
				{
					break;
				}
			}
			read_unlock_bh(&dev_base_lock);

			if(device == NULL)	break;
		}
		if(i == 8)
		{
			DBGPRINT(RT_DEBUG_ERROR, "No available slot name\n");
			return NULL;
		}

		sprintf(pAd->net_dev->name, "rausb%d", i);
		DBGPRINT(RT_DEBUG_ERROR, "usb device name %s\n",pAd->net_dev->name);

        /* get Max Packet Size from usb_dev endpoint */
//        ifp = dev->actconfig->interface + i;
        as = ifp->altsetting + ifp->act_altsetting;
        ep = as->endpoint;

        pAd->BulkOutMaxPacketSize = (USHORT)ep[i].wMaxPacketSize;
        DBGPRINT(RT_DEBUG_TRACE, "BulkOutMaxPacketSize  %d\n", pAd->BulkOutMaxPacketSize);


⌨️ 快捷键说明

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