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

📄 kaweth.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
			      data_len,			      KAWETH_CONTROL_TIMEOUT);}/**************************************************************** *     kaweth_trigger_firmware ****************************************************************/static int kaweth_trigger_firmware(struct kaweth_device *kaweth,				   __u8 interrupt){	kaweth->firmware_buf[0] = 0xB6;	kaweth->firmware_buf[1] = 0xC3;	kaweth->firmware_buf[2] = 0x01;	kaweth->firmware_buf[3] = 0x00;	kaweth->firmware_buf[4] = 0x06;	kaweth->firmware_buf[5] = interrupt;	kaweth->firmware_buf[6] = 0x00;	kaweth->firmware_buf[7] = 0x00;	kaweth_dbg("Triggering firmware");	return kaweth_control(kaweth,			      usb_sndctrlpipe(kaweth->dev, 0),			      KAWETH_COMMAND_SCAN,			      USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,			      0,			      0,			      (void *)kaweth->firmware_buf,			      8,			      KAWETH_CONTROL_TIMEOUT);}/**************************************************************** *     kaweth_reset ****************************************************************/static int kaweth_reset(struct kaweth_device *kaweth){	int result;	kaweth_dbg("kaweth_reset(%p)", kaweth);	result = kaweth_control(kaweth,				usb_sndctrlpipe(kaweth->dev, 0),				USB_REQ_SET_CONFIGURATION,				0,				kaweth->dev->config[0].desc.bConfigurationValue,				0,				NULL,				0,				KAWETH_CONTROL_TIMEOUT);	mdelay(10);	kaweth_dbg("kaweth_reset() returns %d.",result);	return result;}static void kaweth_usb_receive(struct urb *, struct pt_regs *regs);static int kaweth_resubmit_rx_urb(struct kaweth_device *, gfp_t);/****************************************************************	int_callback*****************************************************************/static void kaweth_resubmit_int_urb(struct kaweth_device *kaweth, gfp_t mf){	int status;	status = usb_submit_urb (kaweth->irq_urb, mf);	if (unlikely(status == -ENOMEM)) {		kaweth->suspend_lowmem_ctrl = 1;		schedule_delayed_work(&kaweth->lowmem_work, HZ/4);	} else {		kaweth->suspend_lowmem_ctrl = 0;	}	if (status)		err ("can't resubmit intr, %s-%s, status %d",				kaweth->dev->bus->bus_name,				kaweth->dev->devpath, status);}static void int_callback(struct urb *u, struct pt_regs *regs){	struct kaweth_device *kaweth = u->context;	int act_state;	switch (u->status) {	case 0:			/* success */		break;	case -ECONNRESET:	/* unlink */	case -ENOENT:	case -ESHUTDOWN:		return;	/* -EPIPE:  should clear the halt */	default:		/* error */		goto resubmit;	}	/* we check the link state to report changes */	if (kaweth->linkstate != (act_state = ( kaweth->intbuffer[STATE_OFFSET] | STATE_MASK) >> STATE_SHIFT)) {		if (act_state)			netif_carrier_on(kaweth->net);		else			netif_carrier_off(kaweth->net);		kaweth->linkstate = act_state;	}resubmit:	kaweth_resubmit_int_urb(kaweth, GFP_ATOMIC);}static void kaweth_resubmit_tl(void *d){	struct kaweth_device *kaweth = (struct kaweth_device *)d;	if (kaweth->status | KAWETH_STATUS_CLOSING)		return;	if (kaweth->suspend_lowmem_rx)		kaweth_resubmit_rx_urb(kaweth, GFP_NOIO);	if (kaweth->suspend_lowmem_ctrl)		kaweth_resubmit_int_urb(kaweth, GFP_NOIO);}/**************************************************************** *     kaweth_resubmit_rx_urb ****************************************************************/static int kaweth_resubmit_rx_urb(struct kaweth_device *kaweth,						gfp_t mem_flags){	int result;	usb_fill_bulk_urb(kaweth->rx_urb,		      kaweth->dev,		      usb_rcvbulkpipe(kaweth->dev, 1),		      kaweth->rx_buf,		      KAWETH_BUF_SIZE,		      kaweth_usb_receive,		      kaweth);	kaweth->rx_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;	kaweth->rx_urb->transfer_dma = kaweth->rxbufferhandle;	if((result = usb_submit_urb(kaweth->rx_urb, mem_flags))) {		if (result == -ENOMEM) {			kaweth->suspend_lowmem_rx = 1;			schedule_delayed_work(&kaweth->lowmem_work, HZ/4);		}		kaweth_err("resubmitting rx_urb %d failed", result);	} else {		kaweth->suspend_lowmem_rx = 0;	}	return result;}static void kaweth_async_set_rx_mode(struct kaweth_device *kaweth);/**************************************************************** *     kaweth_usb_receive ****************************************************************/static void kaweth_usb_receive(struct urb *urb, struct pt_regs *regs){	struct kaweth_device *kaweth = urb->context;	struct net_device *net = kaweth->net;	int count = urb->actual_length;	int count2 = urb->transfer_buffer_length;	__u16 pkt_len = le16_to_cpup((__le16 *)kaweth->rx_buf);	struct sk_buff *skb;	if(unlikely(urb->status == -ECONNRESET || urb->status == -ESHUTDOWN))	/* we are killed - set a flag and wake the disconnect handler */	{		kaweth->end = 1;		wake_up(&kaweth->term_wait);		return;	}	if (kaweth->status & KAWETH_STATUS_CLOSING)		return;	if(urb->status && urb->status != -EREMOTEIO && count != 1) {		kaweth_err("%s RX status: %d count: %d packet_len: %d",                           net->name,			   urb->status,			   count,			   (int)pkt_len);		kaweth_resubmit_rx_urb(kaweth, GFP_ATOMIC);                return;	}	if(kaweth->net && (count > 2)) {		if(pkt_len > (count - 2)) {			kaweth_err("Packet length too long for USB frame (pkt_len: %x, count: %x)",pkt_len, count);			kaweth_err("Packet len & 2047: %x", pkt_len & 2047);			kaweth_err("Count 2: %x", count2);		        kaweth_resubmit_rx_urb(kaweth, GFP_ATOMIC);                        return;                }		if(!(skb = dev_alloc_skb(pkt_len+2))) {		        kaweth_resubmit_rx_urb(kaweth, GFP_ATOMIC);                        return;		}		skb_reserve(skb, 2);    /* Align IP on 16 byte boundaries */		skb->dev = net;		eth_copy_and_sum(skb, kaweth->rx_buf + 2, pkt_len, 0);		skb_put(skb, pkt_len);		skb->protocol = eth_type_trans(skb, net);		netif_rx(skb);		kaweth->stats.rx_packets++;		kaweth->stats.rx_bytes += pkt_len;	}	kaweth_resubmit_rx_urb(kaweth, GFP_ATOMIC);}/**************************************************************** *     kaweth_open ****************************************************************/static int kaweth_open(struct net_device *net){	struct kaweth_device *kaweth = netdev_priv(net);	int res;	kaweth_dbg("Opening network device.");	res = kaweth_resubmit_rx_urb(kaweth, GFP_KERNEL);	if (res)		return -EIO;	usb_fill_int_urb(		kaweth->irq_urb,		kaweth->dev,		usb_rcvintpipe(kaweth->dev, 3),		kaweth->intbuffer,		INTBUFFERSIZE,		int_callback,		kaweth,		250); /* overriding the descriptor */	kaweth->irq_urb->transfer_dma = kaweth->intbufferhandle;	kaweth->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;	res = usb_submit_urb(kaweth->irq_urb, GFP_KERNEL);	if (res) {		usb_kill_urb(kaweth->rx_urb);		return -EIO;	}	netif_start_queue(net);	kaweth_async_set_rx_mode(kaweth);	return 0;}/**************************************************************** *     kaweth_close ****************************************************************/static int kaweth_close(struct net_device *net){	struct kaweth_device *kaweth = netdev_priv(net);	netif_stop_queue(net);	kaweth->status |= KAWETH_STATUS_CLOSING;	usb_kill_urb(kaweth->irq_urb);	usb_kill_urb(kaweth->rx_urb);	usb_kill_urb(kaweth->tx_urb);	flush_scheduled_work();	/* a scheduled work may have resubmitted,	   we hit them again */	usb_kill_urb(kaweth->irq_urb);	usb_kill_urb(kaweth->rx_urb);	kaweth->status &= ~KAWETH_STATUS_CLOSING;	return 0;}static void kaweth_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info){	strlcpy(info->driver, driver_name, sizeof(info->driver));}static struct ethtool_ops ops = {	.get_drvinfo = kaweth_get_drvinfo};/**************************************************************** *     kaweth_usb_transmit_complete ****************************************************************/static void kaweth_usb_transmit_complete(struct urb *urb, struct pt_regs *regs){	struct kaweth_device *kaweth = urb->context;	struct sk_buff *skb = kaweth->tx_skb;	if (unlikely(urb->status != 0))		if (urb->status != -ENOENT)			kaweth_dbg("%s: TX status %d.", kaweth->net->name, urb->status);	netif_wake_queue(kaweth->net);	dev_kfree_skb_irq(skb);}/**************************************************************** *     kaweth_start_xmit ****************************************************************/static int kaweth_start_xmit(struct sk_buff *skb, struct net_device *net){	struct kaweth_device *kaweth = netdev_priv(net);	__le16 *private_header;	int res;	spin_lock(&kaweth->device_lock);	kaweth_async_set_rx_mode(kaweth);	netif_stop_queue(net);	/* We now decide whether we can put our special header into the sk_buff */	if (skb_cloned(skb) || skb_headroom(skb) < 2) {		/* no such luck - we make our own */		struct sk_buff *copied_skb;		copied_skb = skb_copy_expand(skb, 2, 0, GFP_ATOMIC);		dev_kfree_skb_irq(skb);		skb = copied_skb;		if (!copied_skb) {			kaweth->stats.tx_errors++;			netif_start_queue(net);			spin_unlock(&kaweth->device_lock);			return 0;		}	}	private_header = (__le16 *)__skb_push(skb, 2);	*private_header = cpu_to_le16(skb->len-2);	kaweth->tx_skb = skb;	usb_fill_bulk_urb(kaweth->tx_urb,		      kaweth->dev,		      usb_sndbulkpipe(kaweth->dev, 2),		      private_header,		      skb->len,		      kaweth_usb_transmit_complete,		      kaweth);	kaweth->end = 0;	if((res = usb_submit_urb(kaweth->tx_urb, GFP_ATOMIC)))	{		kaweth_warn("kaweth failed tx_urb %d", res);		kaweth->stats.tx_errors++;		netif_start_queue(net);		dev_kfree_skb_irq(skb);	}	else	{		kaweth->stats.tx_packets++;		kaweth->stats.tx_bytes += skb->len;		net->trans_start = jiffies;	}	spin_unlock(&kaweth->device_lock);	return 0;}/**************************************************************** *     kaweth_set_rx_mode ****************************************************************/static void kaweth_set_rx_mode(struct net_device *net){	struct kaweth_device *kaweth = netdev_priv(net);	__u16 packet_filter_bitmap = KAWETH_PACKET_FILTER_DIRECTED |                                     KAWETH_PACKET_FILTER_BROADCAST |		                     KAWETH_PACKET_FILTER_MULTICAST;	kaweth_dbg("Setting Rx mode to %d", packet_filter_bitmap);	netif_stop_queue(net);	if (net->flags & IFF_PROMISC) {		packet_filter_bitmap |= KAWETH_PACKET_FILTER_PROMISCUOUS;	}	else if ((net->mc_count) || (net->flags & IFF_ALLMULTI)) {		packet_filter_bitmap |= KAWETH_PACKET_FILTER_ALL_MULTICAST;	}	kaweth->packet_filter_bitmap = packet_filter_bitmap;	netif_wake_queue(net);}/**************************************************************** *     kaweth_async_set_rx_mode ****************************************************************/static void kaweth_async_set_rx_mode(struct kaweth_device *kaweth){	__u16 packet_filter_bitmap = kaweth->packet_filter_bitmap;	kaweth->packet_filter_bitmap = 0;	if (packet_filter_bitmap == 0)		return;	{

⌨️ 快捷键说明

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