Commit | Line | Data |
---|---|---|
34e49164 C |
1 | // from usbnet.c |
2 | ||
3 | static int gl_interrupt_read (struct usbnet *dev) | |
4 | { | |
5 | struct gl_priv *priv = dev->priv_data; | |
6 | int retval; | |
7 | ||
8 | // issue usb interrupt read | |
9 | if (priv && priv->irq_urb) { | |
10 | // submit urb | |
11 | if ((retval = usb_submit_urb (priv->irq_urb)) != 0) | |
12 | dbg ("gl_interrupt_read: submit fail - %X...", retval); | |
13 | else | |
14 | dbg ("gl_interrupt_read: submit success..."); | |
15 | } | |
16 | ||
17 | return 0; | |
18 | } | |
19 | ||
20 | ||
21 | static void rx_submit (struct usbnet *dev, struct urb *urb, int flags) | |
22 | { | |
23 | struct sk_buff *skb; | |
24 | struct skb_data *entry; | |
25 | int retval = 0; | |
26 | unsigned long lockflags; | |
27 | size_t size; | |
28 | ||
29 | #ifdef CONFIG_USB_NET1080 | |
30 | if (dev->driver_info->flags & FLAG_FRAMING_NC) | |
31 | size = FRAMED_SIZE (dev->net.mtu); | |
32 | else | |
33 | #endif | |
34 | #ifdef CONFIG_USB_GENESYS | |
35 | if (dev->driver_info->flags & FLAG_FRAMING_GL) | |
36 | size = GL_RCV_BUF_SIZE; | |
37 | else | |
38 | #endif | |
39 | size = (sizeof (struct ethhdr) + dev->net.mtu); | |
40 | ||
41 | if ((skb = alloc_skb (size, flags)) == 0) { | |
42 | dbg ("no rx skb"); | |
43 | tasklet_schedule (&dev->bh); | |
44 | usb_free_urb (urb); | |
45 | return; | |
46 | } | |
47 | ||
48 | entry = (struct skb_data *) skb->cb; | |
49 | entry->urb = urb; | |
50 | entry->dev = dev; | |
51 | entry->state = rx_start; | |
52 | entry->length = 0; | |
53 | ||
54 | FILL_BULK_URB (urb, dev->udev, | |
55 | usb_rcvbulkpipe (dev->udev, dev->driver_info->in), | |
56 | skb->data, size, rx_complete, skb); | |
57 | urb->transfer_flags |= USB_ASYNC_UNLINK; | |
58 | #ifdef REALLY_QUEUE | |
59 | urb->transfer_flags |= USB_QUEUE_BULK; | |
60 | #endif | |
61 | #if 0 | |
62 | // Idle-but-posted reads with UHCI really chew up | |
63 | // PCI bandwidth unless FSBR is disabled | |
64 | urb->transfer_flags |= USB_NO_FSBR; | |
65 | #endif | |
66 | ||
67 | spin_lock_irqsave (&dev->rxq.lock, lockflags); | |
68 | ||
69 | if (netif_running (&dev->net)) { | |
70 | if ((retval = usb_submit_urb (urb)) != 0) { | |
71 | dbg ("%s rx submit, %d", dev->net.name, retval); | |
72 | tasklet_schedule (&dev->bh); | |
73 | } else { | |
74 | __skb_queue_tail (&dev->rxq, skb); | |
75 | } | |
76 | } else { | |
77 | dbg ("rx: stopped"); | |
78 | retval = -ENOLINK; | |
79 | } | |
80 | spin_unlock_irqrestore (&dev->rxq.lock, lockflags); | |
81 | if (retval) { | |
82 | dev_kfree_skb_any (skb); | |
83 | usb_free_urb (urb); | |
84 | } | |
85 | } | |
86 | ||
87 | ||
88 | ||
89 | static int usbnet_start_xmit (struct sk_buff *skb, struct net_device *net) | |
90 | { | |
91 | struct usbnet *dev = (struct usbnet *) net->priv; | |
92 | int length = skb->len; | |
93 | int retval = NET_XMIT_SUCCESS; | |
94 | struct urb *urb = 0; | |
95 | struct skb_data *entry; | |
96 | struct driver_info *info = dev->driver_info; | |
97 | unsigned long flags; | |
98 | #ifdef CONFIG_USB_NET1080 | |
99 | struct nc_header *header = 0; | |
100 | struct nc_trailer *trailer = 0; | |
101 | #endif /* CONFIG_USB_NET1080 */ | |
102 | ||
103 | flags = in_interrupt () ? GFP_ATOMIC : GFP_NOIO; /* might be used for nfs */ | |
104 | ||
105 | // some devices want funky USB-level framing, for | |
106 | // win32 driver (usually) and/or hardware quirks | |
107 | if (info->tx_fixup) { | |
108 | skb = info->tx_fixup (dev, skb, flags); | |
109 | if (!skb) { | |
110 | dbg ("can't tx_fixup skb"); | |
111 | goto drop; | |
112 | } | |
113 | } | |
114 | ||
115 | if (!(urb = usb_alloc_urb (0))) { | |
116 | dbg ("no urb"); | |
117 | goto drop; | |
118 | } | |
119 | ||
120 | entry = (struct skb_data *) skb->cb; | |
121 | entry->urb = urb; | |
122 | entry->dev = dev; | |
123 | entry->state = tx_start; | |
124 | entry->length = length; | |
125 | ||
126 | // FIXME: reorganize a bit, so that fixup() fills out NetChip | |
127 | // framing too. (Packet ID update needs the spinlock...) | |
128 | ||
129 | #ifdef CONFIG_USB_NET1080 | |
130 | if (info->flags & FLAG_FRAMING_NC) { | |
131 | header = (struct nc_header *) skb_push (skb, sizeof *header); | |
132 | header->hdr_len = cpu_to_le16 (sizeof (*header)); | |
133 | header->packet_len = cpu_to_le16 (length); | |
134 | if (!((skb->len + sizeof *trailer) & 0x01)) | |
135 | *skb_put (skb, 1) = PAD_BYTE; | |
136 | trailer = (struct nc_trailer *) skb_put (skb, sizeof *trailer); | |
137 | } else | |
138 | #endif /* CONFIG_USB_NET1080 */ | |
139 | ||
140 | /* don't assume the hardware handles USB_ZERO_PACKET */ | |
141 | if ((length % EP_SIZE (dev)) == 0) | |
142 | skb->len++; | |
143 | ||
144 | FILL_BULK_URB (urb, dev->udev, | |
145 | usb_sndbulkpipe (dev->udev, info->out), | |
146 | skb->data, skb->len, tx_complete, skb); | |
147 | urb->transfer_flags |= USB_ASYNC_UNLINK; | |
148 | #ifdef REALLY_QUEUE | |
149 | urb->transfer_flags |= USB_QUEUE_BULK; | |
150 | #endif | |
151 | // FIXME urb->timeout = ... jiffies ... ; | |
152 | ||
153 | spin_lock_irqsave (&dev->txq.lock, flags); | |
154 | ||
155 | #ifdef CONFIG_USB_NET1080 | |
156 | if (info->flags & FLAG_FRAMING_NC) { | |
157 | header->packet_id = cpu_to_le16 (dev->packet_id++); | |
158 | put_unaligned (header->packet_id, &trailer->packet_id); | |
159 | #if 0 | |
160 | devdbg (dev, "frame >tx h %d p %d id %d", | |
161 | header->hdr_len, header->packet_len, | |
162 | header->packet_id); | |
163 | #endif | |
164 | } | |
165 | #endif /* CONFIG_USB_NET1080 */ | |
166 | ||
167 | netif_stop_queue (net); | |
168 | if ((retval = usb_submit_urb (urb)) != 0) { | |
169 | netif_start_queue (net); | |
170 | dbg ("%s tx: submit urb err %d", net->name, retval); | |
171 | } else { | |
172 | net->trans_start = jiffies; | |
173 | __skb_queue_tail (&dev->txq, skb); | |
174 | if (dev->txq.qlen < TX_QLEN) | |
175 | netif_start_queue (net); | |
176 | } | |
177 | spin_unlock_irqrestore (&dev->txq.lock, flags); | |
178 | ||
179 | if (retval) { | |
180 | devdbg (dev, "drop, code %d", retval); | |
181 | drop: | |
182 | retval = NET_XMIT_DROP; | |
183 | dev->stats.tx_dropped++; | |
184 | if (skb) | |
185 | dev_kfree_skb_any (skb); | |
186 | usb_free_urb (urb); | |
187 | #ifdef VERBOSE | |
188 | } else { | |
189 | devdbg (dev, "> tx, len %d, type 0x%x", | |
190 | length, skb->protocol); | |
191 | #endif | |
192 | } | |
193 | return retval; | |
194 | } |