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

📄 zd1211.c

📁 Atheros USB WiFi Card 驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
    #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19))
	    dev->get_wireless_stats = zd1205_iw_getstats;
    #endif
#elif !defined(ZDCONF_WE_STAT_SUPPORT)
	#error "Undefine ZDCONF_WE_STAT_SUPPORT"
#endif
	dev->mtu = ZD1211_MTU;
	dev->set_mac_address = zd1205_set_mac;
 	dev->tx_timeout = &zd1211_tx_timeout;

	//dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM;
	dev->flags |= IFF_MULTICAST;

	//memcpy(macp->ifname, dev->name, IFNAMSIZ);
	//macp->ifname[IFNAMSIZ-1] = 0;

	ZEXIT(1);
	return true;
}				   

int zd1211_alloc_all_urbs(struct zd1205_private *macp)
{
	struct usb_interface *interface = macp->interface;
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
	struct usb_interface_descriptor *iface_desc = &interface->altsetting[0];
#else	

	struct usb_host_interface *iface_desc = &interface->altsetting[0];
#endif	

	struct usb_endpoint_descriptor *endpoint;
	struct usb_endpoint_descriptor *interrupt_in_endpoint[MAX_NUM_PORTS];
	struct usb_endpoint_descriptor *interrupt_out_endpoint[MAX_NUM_PORTS];
	struct usb_endpoint_descriptor *bulk_in_endpoint[MAX_NUM_PORTS];

	struct usb_endpoint_descriptor *bulk_out_endpoint[MAX_NUM_PORTS];

    u8 num_bulk_in = 0;
    u8 num_bulk_out = 0;

    u8 num_interrupt_in = 0;
    u8 num_interrupt_out = 0;

	int i;

    
	/* descriptor matches, let's find the endpoints needed */
	/* check out the endpoints */
    //ZD1211DEBUG(2, "bNumEndpoints = %d\n", iface_desc->bNumEndpoints);
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))    
	for (i = 0; i < iface_desc->bNumEndpoints; ++i) {

		endpoint = &iface_desc->endpoint[i];
#else
	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
		endpoint = &iface_desc->endpoint[i].desc;
#endif		

		if ((endpoint->bEndpointAddress & 0x80) &&


		    ((endpoint->bmAttributes & 3) == 0x02)) {

			/* we found a bulk in endpoint */
			bulk_in_endpoint[num_bulk_in] = endpoint;
			++num_bulk_in;


			macp->wMaxPacketSize = zd_le16_to_cpu(endpoint->wMaxPacketSize);
            if(macp->wMaxPacketSize != 64 && macp->wMaxPacketSize!= 512)
            {
                printk("Something wrong. Mostly, it's a endian issue\n");
            }
            ZD1211DEBUG(0, "bulk in: wMaxPacketSize = %x\n", zd_le16_to_cpu(endpoint->wMaxPacketSize));
		}



		if (((endpoint->bEndpointAddress & 0x80) == 0x00) &&
		    ((endpoint->bmAttributes & 3) == 0x02)) {
			/* we found a bulk out endpoint */
			bulk_out_endpoint[num_bulk_out] = endpoint;
			++num_bulk_out;
            ZD1211DEBUG(0, "bulk out: wMaxPacketSize = %x\n", zd_le16_to_cpu(endpoint->wMaxPacketSize));

		}
		
		if ((endpoint->bEndpointAddress & 0x80) &&


		    ((endpoint->bmAttributes & 3) == 0x03)) {
			/* we found a interrupt in endpoint */
            endpoint->bmAttributes &=  ~3;
            endpoint->bmAttributes |=  2;
			interrupt_in_endpoint[num_interrupt_in] = endpoint;
			++num_interrupt_in;
            macp->in_interval = endpoint->bInterval;
            ZD1211DEBUG(0, "interrupt in: wMaxPacketSize = %x\n", zd_le16_to_cpu(endpoint->wMaxPacketSize));

            ZD1211DEBUG(0, "interrupt in: int_interval = %d\n", endpoint->bInterval);

		}
		
		if (((endpoint->bEndpointAddress & 0x80) == 0x00) &&
		    ((endpoint->bmAttributes & 3) == 0x03)) {
			/* we found a interrupt out endpoint */
            endpoint->bmAttributes &=  ~3;
            endpoint->bmAttributes |=  2;
			interrupt_out_endpoint[num_interrupt_out] = endpoint;
			++num_interrupt_out;
            macp->ep4isIntOut = 0;//1;

            ZD1211DEBUG(0, "interrupt out: wMaxPacketSize = %x\n", zd_le16_to_cpu(endpoint->wMaxPacketSize));
            macp->out_interval = endpoint->bInterval;
		}
	}
	

	macp->num_bulk_in = num_bulk_in;
	macp->num_bulk_out = num_bulk_out;
	macp->num_interrupt_in = num_interrupt_in;

	macp->num_interrupt_out = num_interrupt_out;

	
	macp->rx_urb = USB_ALLOC_URB(0, GFP_KERNEL);
	if (!macp->rx_urb)
		return 0;
		
	macp->tx_urb = USB_ALLOC_URB(0, GFP_KERNEL);
	if (!macp->tx_urb) {
		usb_free_urb(macp->rx_urb);
		return 0;
	}

	
	macp->intr_urb = USB_ALLOC_URB(0, GFP_KERNEL);
	if (!macp->intr_urb) {

		usb_free_urb(macp->rx_urb);
		usb_free_urb(macp->tx_urb);
		return 0;
	}
	
	macp->ctrl_urb = USB_ALLOC_URB(0, GFP_KERNEL);
	if (!macp->ctrl_urb) {
		usb_free_urb(macp->rx_urb);
		usb_free_urb(macp->tx_urb);
		usb_free_urb(macp->intr_urb);
		return 0;


	}


	macp->reg_urb = USB_ALLOC_URB(0, GFP_KERNEL);
	if (!macp->reg_urb) {
		usb_free_urb(macp->rx_urb);
		usb_free_urb(macp->tx_urb);
		usb_free_urb(macp->intr_urb);
		usb_free_urb(macp->ctrl_urb);
		return 0;
	}

#if 0//(LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
    #if 1 
    macp->IntEPBuffer = kmalloc(MAX_EPINT_BUFFER, GFP_KERNEL);

    #else //always failed? why???
    macp->IntEPBuffer = usb_buffer_alloc(macp->device,
                            MAX_EPINT_BUFFER,
                            GFP_KERNEL,
                            &macp->IntBufferHandle);
    #endif
    if (!macp->IntEPBuffer){
        FPRINT("usb_buffer_alloc failed");
        usb_free_urb(macp->rx_urb);
		usb_free_urb(macp->tx_urb);
		usb_free_urb(macp->intr_urb);
		usb_free_urb(macp->ctrl_urb);

   		usb_free_urb(macp->reg_urb);
        return 0;
    }
#endif        

	return 1;
}




void zd1211_free_all_urbs(struct zd1205_private *macp)

{


	if (macp->rx_urb)
 		usb_free_urb(macp->rx_urb);
	if (macp->tx_urb)	

		usb_free_urb(macp->tx_urb);
	if (macp->intr_urb)	

		usb_free_urb(macp->intr_urb);
	if 	(macp->ctrl_urb)
		usb_free_urb(macp->ctrl_urb);
	if 	(macp->reg_urb)
		usb_free_urb(macp->reg_urb);

#if 0//(LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
    if (macp->IntEPBuffer)
    #if 1
        kfree(macp->IntEPBuffer);
    #else    
        usb_buffer_free(macp->device,
            MAX_EPINT_BUFFER,
            (void *)macp->IntEPBuffer,

            macp->IntBufferHandle);
    #endif    
#endif         	
}


void zd1211_unlink_all_urbs(struct zd1205_private *macp)
{
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,8))
        usb_kill_urb(macp->rx_urb);
        usb_kill_urb(macp->tx_urb);
        usb_kill_urb(macp->ctrl_urb);
        usb_kill_urb(macp->reg_urb);

    if (test_bit(ZD1211_UNPLUG, &macp->flags))
            usb_kill_urb(macp->intr_urb);

#else
	usb_unlink_urb(macp->rx_urb);
	usb_unlink_urb(macp->tx_urb);
	usb_unlink_urb(macp->ctrl_urb);
	usb_unlink_urb(macp->reg_urb);

    if (test_bit(ZD1211_UNPLUG, &macp->flags))
	    usb_unlink_urb(macp->intr_urb);
#endif


}

#define MAX_RX_MERGE_PACKET_NUM		3
void zd1211_rx_isr(unsigned long parm)
{
	struct zd1205_private *macp = (struct zd1205_private *)parm;
	struct urb *urb = macp->read_urb;
	struct rx_list_elem *rx_struct;
#if fMERGE_RX_FRAME 
	struct rx_list_elem *rx_struct_array[MAX_RX_MERGE_PACKET_NUM];
	int total_rx_struct = 1, rx_array_cnt = 0;
	int i;
	u32 tmpLen = 0;
	u16 last_pkt_len;
#endif
	u32 TotalLength = urb->actual_length;
	u8 *pRxBuffer;
	struct sk_buff *skb;
	zd1205_RFD_t *rfd = NULL;
    unsigned long flags;


	spin_lock(&macp->intr_lock);

	ZD1211DEBUG(4, "actual_length = %x\n", urb->actual_length);
	rx_struct = list_entry(macp->active_rx_list.next,
				struct rx_list_elem, list_elem);

	skb = rx_struct->skb;
	rfd = RFD_POINTER(skb, macp);
	pRxBuffer = &rfd->RxBuffer[macp->rxOffset];

#if 0    
	//for debug only
	zd1205_dump_data("pRxBuffer", (u8 *)pRxBuffer, TotalLength);
	//zd1211_submit_rx_urb(macp);
	//return;
#endif

#if fMERGE_RX_FRAME 
	if (rx_struct->UnFinishFrmLen){
		TotalLength += rx_struct->UnFinishFrmLen; 
		rx_struct->UnFinishFrmLen = 0;
		macp->CompLenInfoCnt++;
		//ZD1211DEBUG(0, "Got Rx Frames Length Info!!\n");
	}
    
	last_pkt_len = TotalLength & (macp->wMaxPacketSize - 1);

	if (last_pkt_len <= (macp->wMaxPacketSize - 4)){
        if (zd_get_LE_U16(pRxBuffer + (TotalLength/sizeof(u16)-1)*2 ) == 0x697E) {
		//if (((u16 *) pRxBuffer)[TotalLength / sizeof(u16) - 1] == 0x697E){
			total_rx_struct = 3;
			//ZD1211DEBUG(0, "Got merged Rx Frames!!\n");
			//zd1205_dump_data("pRxBuffer", (u8 *)pRxBuffer, TotalLength);            
			macp->Continue2Rx++;
		}
		else
			macp->NoMergedRxCnt++;
       
		//ZD1211DEBUG(3, "last_pkt_len = %x\n", last_pkt_len);
		//zd1205_dump_data("pRxBuffer", (u8 *)pRxBuffer, TotalLength);
       
		for (i=0; i<total_rx_struct; i++){
			int CurFrmLen;
			
			if (total_rx_struct> 1){
                CurFrmLen=zd_get_LE_U16(pRxBuffer+(TotalLength/sizeof(u16)+i-4)*2); 
				//ZD1211DEBUG(2, "CurFrmLen = %x\n", CurFrmLen);
			}
			else
				CurFrmLen = TotalLength;

			if (CurFrmLen == 0){
				break;
			}

            flags = dot11Obj.EnterCS();
			rx_struct_array[i] = list_entry(macp->active_rx_list.next,
								struct rx_list_elem, list_elem);
			list_del(&(rx_struct_array[i]->list_elem));
#if ZDCONF_DEFER_RX == 1
            list_add_tail(&(rx_struct_array[i]->list_elem), &(macp->wait_rx_list));
#endif
            dot11Obj.ExitCS(flags);

			rx_array_cnt++;

			ZD1211DEBUG(2, "CurFrmLen = %x\n", CurFrmLen);
			
			skb = rx_struct_array[i]->skb;
			rfd = RFD_POINTER(skb, macp);

			rfd->CbStatus = RFD_STATUS_COMPLETE;
			rfd->ActualCount = CurFrmLen;

			if (i > 0){
				memcpy(&rfd->RxBuffer[macp->rxOffset],
				pRxBuffer + tmpLen,
				rfd->ActualCount);
			}        

			tmpLen += (rfd->ActualCount & ~0x03);

			if (rfd->ActualCount & 0x03)
				tmpLen += 4;
			rfd->ActualCount += macp->rxOffset;
		}
	}
	else {
		// last_pkt_len = 509, 510, 511
		// wait next Rx
		//ZD1211DEBUG(0, "Wait Rx Frames Length Info!!\n");
		//ZD1211DEBUG(2, "last_pkt_len = %x\n", last_pkt_len);
		macp->WaitLenInfoCnt++;
		rx_struct->UnFinishFrmLen = ((TotalLength / macp->wMaxPacketSize) + 1) 
					* (macp->wMaxPacketSize);
		//zd1205_dump_data("pRxBuffer", (u8 *)pRxBuffer, TotalLength);
	}


	if(zd1211_submit_rx_urb(macp))
	{
		printk("No available buffer. Reallocate\n");
		zd1211_alloc_rx((unsigned long)macp);
		if(zd1211_submit_rx_urb(macp))
			printk("zd1211_submit_rx_urb fail. Abort\n");
        set_bit(0, &macp->rxurb_submit);
	}

	if (!rx_struct->UnFinishFrmLen){
#if ZDCONF_DEFER_RX == 1
        defer_kevent(macp, KEVENT_DEFER_RX);
#else
		macp->total_rx_cnt = rx_array_cnt;
		macp->rx_struct_array = rx_struct_array;
		zd1205_rx_isr(macp);
#endif
	}


#else
	rfd->CbStatus = RFD_STATUS_COMPLETE;
	rfd->ActualCount = TotalLength + macp->rxOffset;
	zd1205_rx_isr(macp);
#endif

	if (dot11Obj.QueueFlag & MGT_QUEUE_SET)
		defer_kevent(macp, KEVENT_PROCESS_SIGNAL);
	spin_unlock(&macp->intr_lock);
}	






#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
void zd1211_rx_comp_cb(struct urb *urb)
#else
void zd1211_rx_comp_cb(struct urb *urb, struct pt_regs *regs)
#endif




{
	struct zd1205_private *macp = urb->context;
    static unsigned long lastErr = 0;


    macp->lastRxComp = jiffies;
    if ((!macp) || !test_bit(ZD1211_RUNNING, &macp->flags))
    {
        if(!macp)
            printk("macp is NULL in %s\n", __FUNCTION__);
		return;
    }
  

	if (!netif_device_present(macp->device))
    {
        printk("Error2 in %s\n", __FUNCTION__);
		return;
    }

    if (urb->status != 0){
        //Error occurs frequent when disconnect
        if(jiffies-lastErr > HZ)
            printk("Wrong @ %s, status=%d(%ld).", __FUNCTION__,urb->status,jiffies);
        lastErr = jiffies;
        if(urb->status == -EOVERFLOW)
        {
            printk("It's OK\n");
        }
        else
            printk("\n");
        zd1211_DumpErrorCode(macp, urb->status);
		if ((urb->status != -ENOENT) &&
			(macp->bUSBDeveiceAttached == 1) && 
		    (urb->status != -ECONNRESET) &&
            (urb->status != -ESHUTDOWN)) {
			    //printk("nonzero read bulk status received: %d\n", urb->status);
            #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))    
                if (urb->status == USB_ST_INTERNALERROR)
                {
                    printk("Error3 in %s\n", __FUNCTION__);
                    //return;
                }

            #else

                if (urb->status == -EPIPE){
                    printk("nonzero read bulk status received: -EPIPE\n");
                    //return;
                }

                if (urb->status == -EPROTO){
                    printk("nonzero read bulk status received: -EPROTO\n");
                    //return;
                }                 



            #endif        
                    

				if(zd1211_submit_rx_urb(macp))
				{
						printk("No available buffer. Reallocate\n");
						zd1211_alloc_rx((unsigned long)macp);
						if(zd1211_submit_rx_urb(macp))
								printk("zd1211_submit_rx_urb fail. Abort\n");
                        set_bit(0, &macp->rxurb_submit);
				

⌨️ 快捷键说明

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